diff --git a/daemon/mgmt/command-validator.cpp b/daemon/mgmt/command-validator.cpp
deleted file mode 100644
index 715b5d5..0000000
--- a/daemon/mgmt/command-validator.cpp
+++ /dev/null
@@ -1,222 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014  Regents of the University of California,
- *                     Arizona Board of Regents,
- *                     Colorado State University,
- *                     University Pierre & Marie Curie, Sorbonne University,
- *                     Washington University in St. Louis,
- *                     Beijing Institute of Technology
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- **/
-
-#include "command-validator.hpp"
-#include "core/logger.hpp"
-
-#include <ndn-cxx/util/io.hpp>
-#include <ndn-cxx/security/identity-certificate.hpp>
-
-#include <boost/filesystem.hpp>
-#include <fstream>
-
-namespace nfd {
-
-NFD_LOG_INIT("CommandValidator");
-
-CommandValidator::CommandValidator()
-{
-
-}
-
-CommandValidator::~CommandValidator()
-{
-
-}
-
-void
-CommandValidator::setConfigFile(ConfigFile& configFile)
-{
-  configFile.addSectionHandler("authorizations",
-                               bind(&CommandValidator::onConfig, this, _1, _2, _3));
-}
-
-static inline void
-aggregateErrors(std::stringstream& ss, const std::string& msg)
-{
-  if (!ss.str().empty())
-    {
-      ss << "\n";
-    }
-  ss << msg;
-}
-
-void
-CommandValidator::onConfig(const ConfigSection& section,
-                           bool isDryRun,
-                           const std::string& filename)
-{
-  using namespace boost::filesystem;
-
-  const ConfigSection EMPTY_SECTION;
-
-  m_validator.reset();
-
-  if (section.begin() == section.end())
-    {
-      BOOST_THROW_EXCEPTION(ConfigFile::Error("No authorize sections found"));
-    }
-
-  std::stringstream dryRunErrors;
-  ConfigSection::const_iterator authIt;
-  for (authIt = section.begin(); authIt != section.end(); authIt++)
-    {
-      std::string certfile;
-      try
-        {
-          certfile = authIt->second.get<std::string>("certfile");
-        }
-      catch (const std::runtime_error& e)
-        {
-          std::string msg = "No certfile specified";
-          if (!isDryRun)
-            {
-              BOOST_THROW_EXCEPTION(ConfigFile::Error(msg));
-            }
-          aggregateErrors(dryRunErrors, msg);
-          continue;
-        }
-
-      shared_ptr<ndn::IdentityCertificate> id;
-
-      if (certfile != "any")
-        {
-          path certfilePath = absolute(certfile, path(filename).parent_path());
-          NFD_LOG_DEBUG("generated certfile path: " << certfilePath.native());
-
-          std::ifstream in;
-          in.open(certfilePath.c_str());
-          if (!in.is_open())
-            {
-              std::string msg = "Unable to open certificate file " + certfilePath.native();
-              if (!isDryRun)
-                {
-                  BOOST_THROW_EXCEPTION(ConfigFile::Error(msg));
-                }
-              aggregateErrors(dryRunErrors, msg);
-              continue;
-            }
-
-          try
-            {
-              id = ndn::io::load<ndn::IdentityCertificate>(in);
-            }
-          catch (const std::runtime_error& error)
-            {
-              // do nothing
-            }
-
-          if (!static_cast<bool>(id)) {
-            std::string msg = "Malformed certificate file " + certfilePath.native();
-            if (!isDryRun)
-              {
-                BOOST_THROW_EXCEPTION(ConfigFile::Error(msg));
-              }
-            aggregateErrors(dryRunErrors, msg);
-            continue;
-          }
-
-          in.close();
-        }
-
-      std::string keyNameForLogging;
-      if (static_cast<bool>(id))
-        keyNameForLogging = id->getPublicKeyName().toUri();
-      else
-        {
-          keyNameForLogging = "wildcard";
-          NFD_LOG_WARN("Wildcard identity is intended for demo purpose only and " <<
-                       "SHOULD NOT be used in production environment");
-        }
-      const ConfigSection* privileges = 0;
-      try
-        {
-          privileges = &authIt->second.get_child("privileges");
-        }
-      catch (const std::runtime_error& error)
-        {
-          std::string msg = "No privileges section found for certificate file " +
-            certfile + " (" + keyNameForLogging + ")";
-          if (!isDryRun)
-            {
-              BOOST_THROW_EXCEPTION(ConfigFile::Error(msg));
-            }
-          aggregateErrors(dryRunErrors, msg);
-          continue;
-        }
-
-      if (privileges->begin() == privileges->end())
-        {
-          NFD_LOG_WARN("No privileges specified for certificate file " << certfile
-                       << " (" << keyNameForLogging << ")");
-        }
-
-      ConfigSection::const_iterator privIt;
-      for (privIt = privileges->begin(); privIt != privileges->end(); privIt++)
-        {
-          const std::string& privilegeName = privIt->first;
-          if (m_supportedPrivileges.find(privilegeName) != m_supportedPrivileges.end())
-            {
-              NFD_LOG_INFO("Giving privilege \"" << privilegeName
-                           << "\" to identity " << keyNameForLogging);
-              if (!isDryRun)
-                {
-                  const std::string regex = "^<localhost><nfd><" + privilegeName + ">";
-                  if (static_cast<bool>(id))
-                    m_validator.addInterestRule(regex, *id);
-                  else
-                    m_validator.addInterestBypassRule(regex);
-                }
-            }
-          else
-            {
-              // Invalid configuration
-              std::string msg = "Invalid privilege \"" + privilegeName +
-                "\" for certificate file " + certfile + " (" + keyNameForLogging + ")";
-              if (!isDryRun)
-                {
-                  BOOST_THROW_EXCEPTION(ConfigFile::Error(msg));
-                }
-              aggregateErrors(dryRunErrors, msg);
-            }
-        }
-    }
-
-  if (!dryRunErrors.str().empty())
-    {
-      BOOST_THROW_EXCEPTION(ConfigFile::Error(dryRunErrors.str()));
-    }
-}
-
-void
-CommandValidator::addSupportedPrivilege(const std::string& privilege)
-{
-  if (m_supportedPrivileges.find(privilege) != m_supportedPrivileges.end())
-    {
-      BOOST_THROW_EXCEPTION(CommandValidator::Error("Duplicated privilege: " + privilege));
-    }
-  m_supportedPrivileges.insert(privilege);
-}
-
-} // namespace nfd
diff --git a/daemon/mgmt/command-validator.hpp b/daemon/mgmt/command-validator.hpp
deleted file mode 100644
index dc7d675..0000000
--- a/daemon/mgmt/command-validator.hpp
+++ /dev/null
@@ -1,116 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2016,  Regents of the University of California,
- *                           Arizona Board of Regents,
- *                           Colorado State University,
- *                           University Pierre & Marie Curie, Sorbonne University,
- *                           Washington University in St. Louis,
- *                           Beijing Institute of Technology,
- *                           The University of Memphis.
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef NFD_DAEMON_MGMT_COMMAND_VALIDATOR_HPP
-#define NFD_DAEMON_MGMT_COMMAND_VALIDATOR_HPP
-
-#include "core/config-file.hpp"
-#include <ndn-cxx/util/command-interest-validator.hpp>
-
-namespace nfd {
-
-class CommandValidator
-{
-public:
-
-  class Error : public std::runtime_error
-  {
-  public:
-    explicit
-    Error(const std::string& what)
-      : std::runtime_error(what)
-    {
-
-    }
-  };
-
-  CommandValidator();
-
-  ~CommandValidator();
-
-  void
-  setConfigFile(ConfigFile& configFile);
-
-  /**
-   * \param section "authorizations" section to parse
-   * \param isDryRun true if performing a dry run of configuration, false otherwise
-   * \param filename filename of configuration file
-   * \throws ConfigFile::Error on parse error
-   */
-  void
-  onConfig(const ConfigSection& section, bool isDryRun, const std::string& filename);
-
-  /**
-   * \param privilege name of privilege to add
-   * \throws CommandValidator::Error on duplicated privilege
-   */
-  void
-  addSupportedPrivilege(const std::string& privilege);
-
-  void
-  addInterestRule(const std::string& regex,
-                  const ndn::IdentityCertificate& certificate);
-
-  void
-  addInterestRule(const std::string& regex,
-                  const Name& keyName,
-                  const ndn::PublicKey& publicKey);
-
-  void
-  validate(const Interest& interest,
-           const ndn::OnInterestValidated& onValidated,
-           const ndn::OnInterestValidationFailed& onValidationFailed);
-
-private:
-  ndn::CommandInterestValidator m_validator;
-  std::set<std::string> m_supportedPrivileges;
-};
-
-inline void
-CommandValidator::addInterestRule(const std::string& regex,
-                                  const ndn::IdentityCertificate& certificate)
-{
-  m_validator.addInterestRule(regex, certificate);
-}
-
-inline void
-CommandValidator::addInterestRule(const std::string& regex,
-                                  const Name& keyName,
-                                  const ndn::PublicKey& publicKey)
-{
-  m_validator.addInterestRule(regex, keyName, publicKey);
-}
-
-inline void
-CommandValidator::validate(const Interest& interest,
-                           const ndn::OnInterestValidated& onValidated,
-                           const ndn::OnInterestValidationFailed& onValidationFailed)
-{
-  m_validator.validate(interest, onValidated, onValidationFailed);
-}
-
-} // namespace nfd
-
-#endif // NFD_DAEMON_MGMT_COMMAND_VALIDATOR_HPP
diff --git a/tests/daemon/mgmt/command-validator.t.cpp b/tests/daemon/mgmt/command-validator.t.cpp
deleted file mode 100644
index f29ff6d..0000000
--- a/tests/daemon/mgmt/command-validator.t.cpp
+++ /dev/null
@@ -1,656 +0,0 @@
-/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
-/**
- * Copyright (c) 2014-2015,  Regents of the University of California,
- *                           Arizona Board of Regents,
- *                           Colorado State University,
- *                           University Pierre & Marie Curie, Sorbonne University,
- *                           Washington University in St. Louis,
- *                           Beijing Institute of Technology,
- *                           The University of Memphis.
- *
- * This file is part of NFD (Named Data Networking Forwarding Daemon).
- * See AUTHORS.md for complete list of NFD authors and contributors.
- *
- * NFD is free software: you can redistribute it and/or modify it under the terms
- * of the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE.  See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * NFD, e.g., in COPYING.md file.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "mgmt/command-validator.hpp"
-#include "core/config-file.hpp"
-
-#include "tests/test-common.hpp"
-
-#include <ndn-cxx/util/command-interest-generator.hpp>
-#include <ndn-cxx/util/io.hpp>
-#include <boost/filesystem.hpp>
-#include <fstream>
-
-namespace nfd {
-namespace tests {
-
-NFD_LOG_INIT("CommandValidatorTest");
-
-BOOST_FIXTURE_TEST_SUITE(MgmtCommandValidator, BaseFixture)
-
-// authorizations
-// {
-//   authorize
-//   {
-//     certfile "tests/daemon/mgmt/cert1.ndncert"
-//     privileges
-//     {
-//       fib
-//       stats
-//     }
-//   }
-
-//   authorize
-//   {
-//     certfile "tests/daemon/mgmt/cert2.ndncert"
-//     privileges
-//     {
-//       faces
-//     }
-//   }
-// }
-
-const std::string CONFIG =
-"authorizations\n"
-"{\n"
-"  authorize\n"
-"  {\n"
-"    certfile \"tests/daemon/mgmt/cert1.ndncert\"\n"
-"    privileges\n"
-"    {\n"
-"      fib\n"
-"      stats\n"
-"    }\n"
-"  }\n"
-"  authorize\n"
-"  {\n"
-"    certfile \"tests/daemon/mgmt/cert2.ndncert\"\n"
-"    privileges\n"
-"    {\n"
-"      faces\n"
-"    }\n"
-"  }\n"
-  "}\n";
-
-const boost::filesystem::path CONFIG_PATH =
-  boost::filesystem::current_path() /= std::string("unit-test-nfd.conf");
-
-class CommandValidatorTester
-{
-public:
-
-  CommandValidatorTester()
-    : m_validated(false),
-      m_validationFailed(false)
-  {
-
-  }
-
-  void
-  generateIdentity(const Name& prefix)
-  {
-    m_identityName = prefix;
-    m_identityName.appendVersion();
-
-    const Name certName = m_keys.createIdentity(m_identityName);
-
-    m_certificate = m_keys.getCertificate(certName);
-  }
-
-  void
-  saveIdentityToFile(const char* filename)
-  {
-    std::ofstream out;
-    out.open(filename);
-
-    BOOST_REQUIRE(out.is_open());
-    BOOST_REQUIRE(static_cast<bool>(m_certificate));
-
-    ndn::io::save<ndn::IdentityCertificate>(*m_certificate, out);
-
-    out.close();
-  }
-
-  const Name&
-  getIdentityName() const
-  {
-    BOOST_REQUIRE_NE(m_identityName, Name());
-    return m_identityName;
-  }
-
-  const Name&
-  getPublicKeyName() const
-  {
-    BOOST_REQUIRE(static_cast<bool>(m_certificate));
-    return m_certificate->getPublicKeyName();
-  }
-
-  void
-  onValidated(const shared_ptr<const Interest>& interest)
-  {
-    // NFD_LOG_DEBUG("validated command");
-    m_validated = true;
-  }
-
-  void
-  onValidationFailed(const shared_ptr<const Interest>& interest, const std::string& info)
-  {
-    NFD_LOG_DEBUG("validation failed: " << info);
-    m_validationFailed = true;
-  }
-
-  bool
-  commandValidated() const
-  {
-    return m_validated;
-  }
-
-  bool
-  commandValidationFailed() const
-  {
-    return m_validationFailed;
-  }
-
-  void
-  resetValidation()
-  {
-    m_validated = false;
-    m_validationFailed = false;
-  }
-
-  ~CommandValidatorTester()
-  {
-    m_keys.deleteIdentity(m_identityName);
-  }
-
-private:
-  bool m_validated;
-  bool m_validationFailed;
-
-  ndn::KeyChain m_keys;
-  Name m_identityName;
-  shared_ptr<ndn::IdentityCertificate> m_certificate;
-};
-
-class TwoValidatorFixture : public BaseFixture
-{
-public:
-  TwoValidatorFixture()
-  {
-    m_tester1.generateIdentity("/test/CommandValidator/TwoKeys/id1");
-    m_tester1.saveIdentityToFile("tests/daemon/mgmt/cert1.ndncert");
-
-    m_tester2.generateIdentity("/test/CommandValidator/TwoKeys/id2");
-    m_tester2.saveIdentityToFile("tests/daemon/mgmt/cert2.ndncert");
-  }
-
-  ~TwoValidatorFixture()
-  {
-    boost::system::error_code error;
-    boost::filesystem::remove("tests/daemon/mgmt/cert1.ndncert", error);
-    boost::filesystem::remove("tests/daemon/mgmt/cert2.ndncert", error);
-  }
-
-protected:
-  CommandValidatorTester m_tester1;
-  CommandValidatorTester m_tester2;
-};
-
-BOOST_FIXTURE_TEST_CASE(TwoKeys, TwoValidatorFixture)
-{
-  shared_ptr<Interest> fibCommand = make_shared<Interest>("/localhost/nfd/fib/insert");
-  shared_ptr<Interest> statsCommand = make_shared<Interest>("/localhost/nfd/stats/dosomething");
-  shared_ptr<Interest> facesCommand = make_shared<Interest>("/localhost/nfd/faces/create");
-
-  ndn::CommandInterestGenerator generator;
-  generator.generateWithIdentity(*fibCommand, m_tester1.getIdentityName());
-  generator.generateWithIdentity(*statsCommand, m_tester1.getIdentityName());
-  generator.generateWithIdentity(*facesCommand, m_tester2.getIdentityName());
-
-  ConfigFile config;
-  CommandValidator validator;
-  validator.addSupportedPrivilege("faces");
-  validator.addSupportedPrivilege("fib");
-  validator.addSupportedPrivilege("stats");
-
-  validator.setConfigFile(config);
-
-  config.parse(CONFIG, false, CONFIG_PATH.native());
-
-  validator.validate(*fibCommand,
-                     bind(&CommandValidatorTester::onValidated, &m_tester1, _1),
-                     bind(&CommandValidatorTester::onValidationFailed, &m_tester1, _1, _2));
-
-  BOOST_REQUIRE(m_tester1.commandValidated());
-  m_tester1.resetValidation();
-
-  validator.validate(*statsCommand,
-                     bind(&CommandValidatorTester::onValidated, &m_tester1, _1),
-                     bind(&CommandValidatorTester::onValidationFailed, &m_tester1, _1, _2));
-
-  BOOST_REQUIRE(m_tester1.commandValidated());
-
-  validator.validate(*facesCommand,
-                     bind(&CommandValidatorTester::onValidated, &m_tester2, _1),
-                     bind(&CommandValidatorTester::onValidationFailed, &m_tester2, _1, _2));
-
-  BOOST_REQUIRE(m_tester2.commandValidated());
-  m_tester2.resetValidation();
-
-  // use cert2 for fib command (authorized for cert1 only)
-  shared_ptr<Interest> unauthorizedFibCommand = make_shared<Interest>("/localhost/nfd/fib/insert");
-  generator.generateWithIdentity(*unauthorizedFibCommand, m_tester2.getIdentityName());
-
-  validator.validate(*unauthorizedFibCommand,
-                     bind(&CommandValidatorTester::onValidated, &m_tester2, _1),
-                     bind(&CommandValidatorTester::onValidationFailed, &m_tester2, _1, _2));
-
-  BOOST_REQUIRE(m_tester2.commandValidationFailed());
-}
-
-BOOST_FIXTURE_TEST_CASE(TwoKeysDryRun, TwoValidatorFixture)
-{
-  CommandValidatorTester tester1;
-  tester1.generateIdentity("/test/CommandValidator/TwoKeys/id1");
-  tester1.saveIdentityToFile("tests/daemon/mgmt/cert1.ndncert");
-
-  CommandValidatorTester tester2;
-  tester2.generateIdentity("/test/CommandValidator/TwoKeys/id2");
-  tester2.saveIdentityToFile("tests/daemon/mgmt/cert2.ndncert");
-
-  shared_ptr<Interest> fibCommand = make_shared<Interest>("/localhost/nfd/fib/insert");
-  shared_ptr<Interest> statsCommand = make_shared<Interest>("/localhost/nfd/stats/dosomething");
-  shared_ptr<Interest> facesCommand = make_shared<Interest>("/localhost/nfd/faces/create");
-
-  ndn::CommandInterestGenerator generator;
-  generator.generateWithIdentity(*fibCommand, m_tester1.getIdentityName());
-  generator.generateWithIdentity(*statsCommand, m_tester1.getIdentityName());
-  generator.generateWithIdentity(*facesCommand, m_tester2.getIdentityName());
-
-  ConfigFile config;
-  CommandValidator validator;
-  validator.addSupportedPrivilege("faces");
-  validator.addSupportedPrivilege("fib");
-  validator.addSupportedPrivilege("stats");
-
-  validator.setConfigFile(config);
-
-  config.parse(CONFIG, true, CONFIG_PATH.native());
-
-  validator.validate(*fibCommand,
-                     bind(&CommandValidatorTester::onValidated, &m_tester1, _1),
-                     bind(&CommandValidatorTester::onValidationFailed, &m_tester1, _1, _2));
-
-  BOOST_REQUIRE(m_tester1.commandValidationFailed());
-  m_tester1.resetValidation();
-
-  validator.validate(*statsCommand,
-                     bind(&CommandValidatorTester::onValidated, &m_tester1, _1),
-                     bind(&CommandValidatorTester::onValidationFailed, &m_tester1, _1, _2));
-
-  BOOST_REQUIRE(m_tester1.commandValidationFailed());
-
-  validator.validate(*facesCommand,
-                     bind(&CommandValidatorTester::onValidated, &m_tester2, _1),
-                     bind(&CommandValidatorTester::onValidationFailed, &m_tester2, _1, _2));
-
-  BOOST_REQUIRE(m_tester2.commandValidationFailed());
-  m_tester2.resetValidation();
-
-  // use cert2 for fib command (authorized for cert1 only)
-  shared_ptr<Interest> unauthorizedFibCommand = make_shared<Interest>("/localhost/nfd/fib/insert");
-  generator.generateWithIdentity(*unauthorizedFibCommand, m_tester2.getIdentityName());
-
-  validator.validate(*unauthorizedFibCommand,
-                     bind(&CommandValidatorTester::onValidated, &m_tester2, _1),
-                     bind(&CommandValidatorTester::onValidationFailed, &m_tester2, _1, _2));
-
-  BOOST_REQUIRE(m_tester2.commandValidationFailed());
-}
-
-BOOST_AUTO_TEST_CASE(NoAuthorizeSections)
-{
-  const std::string NO_AUTHORIZE_CONFIG =
-    "authorizations\n"
-    "{\n"
-    "}\n";
-
-  ConfigFile config;
-  CommandValidator validator;
-
-  validator.setConfigFile(config);
-  BOOST_CHECK_THROW(config.parse(NO_AUTHORIZE_CONFIG, false, CONFIG_PATH.native()), ConfigFile::Error);
-}
-
-BOOST_AUTO_TEST_CASE(NoPrivilegesSections)
-{
-  const std::string NO_PRIVILEGES_CONFIG =
-    "authorizations\n"
-    "{\n"
-    "  authorize\n"
-    "  {\n"
-    "    certfile \"tests/daemon/mgmt/cert1.ndncert\"\n"
-    "  }\n"
-    "}\n";
-
-  ConfigFile config;
-  CommandValidator validator;
-
-  validator.setConfigFile(config);
-
-  BOOST_CHECK_THROW(config.parse(NO_PRIVILEGES_CONFIG, false, CONFIG_PATH.native()), ConfigFile::Error);
-}
-
-BOOST_AUTO_TEST_CASE(InvalidCertfile)
-{
-  const std::string INVALID_CERT_CONFIG =
-    "authorizations\n"
-    "{\n"
-    "  authorize\n"
-    "  {\n"
-    "    certfile \"tests/daemon/mgmt/notacertfile.ndncert\"\n"
-    "    privileges\n"
-    "    {\n"
-    "      fib\n"
-    "      stats\n"
-    "    }\n"
-    "  }\n"
-    "}\n";
-
-  ConfigFile config;
-  CommandValidator validator;
-
-  validator.setConfigFile(config);
-  BOOST_CHECK_THROW(config.parse(INVALID_CERT_CONFIG, false, CONFIG_PATH.native()), ConfigFile::Error);
-}
-
-BOOST_AUTO_TEST_CASE(NoCertfile)
-{
-  const std::string NO_CERT_CONFIG =
-    "authorizations\n"
-    "{\n"
-    "  authorize\n"
-    "  {\n"
-    "    privileges\n"
-    "    {\n"
-    "      fib\n"
-    "      stats\n"
-    "    }\n"
-    "  }\n"
-    "}\n";
-
-
-  ConfigFile config;
-  CommandValidator validator;
-
-  validator.setConfigFile(config);
-  BOOST_CHECK_THROW(config.parse(NO_CERT_CONFIG, false, CONFIG_PATH.native()), ConfigFile::Error);
-}
-
-BOOST_AUTO_TEST_CASE(MalformedCert)
-{
-    const std::string MALFORMED_CERT_CONFIG =
-    "authorizations\n"
-    "{\n"
-    "  authorize\n"
-    "  {\n"
-    "    certfile \"tests/daemon/mgmt/malformed.ndncert\"\n"
-    "    privileges\n"
-    "    {\n"
-    "      fib\n"
-    "      stats\n"
-    "    }\n"
-    "  }\n"
-    "}\n";
-
-
-  ConfigFile config;
-  CommandValidator validator;
-
-  validator.setConfigFile(config);
-  BOOST_CHECK_THROW(config.parse(MALFORMED_CERT_CONFIG, false, CONFIG_PATH.native()), ConfigFile::Error);
-}
-
-bool
-validateErrorMessage(const std::string& expectedMessage, const ConfigFile::Error& error)
-{
-  bool gotExpected = error.what() == expectedMessage;
-  if (!gotExpected)
-    {
-      NFD_LOG_WARN("\ncaught exception: " << error.what()
-                    << "\n\nexpected exception: " << expectedMessage);
-    }
-  return gotExpected;
-}
-
-BOOST_AUTO_TEST_CASE(NoAuthorizeSectionsDryRun)
-{
-  const std::string NO_AUTHORIZE_CONFIG =
-    "authorizations\n"
-    "{\n"
-    "}\n";
-
-  ConfigFile config;
-  CommandValidator validator;
-
-  validator.setConfigFile(config);
-  BOOST_CHECK_EXCEPTION(config.parse(NO_AUTHORIZE_CONFIG, true, CONFIG_PATH.native()),
-                        ConfigFile::Error,
-                        bind(&validateErrorMessage,
-                             "No authorize sections found", _1));
-}
-
-BOOST_FIXTURE_TEST_CASE(NoPrivilegesSectionsDryRun, TwoValidatorFixture)
-{
-  const std::string NO_PRIVILEGES_CONFIG =
-    "authorizations\n"
-    "{\n"
-    "  authorize\n"
-    "  {\n"
-    "    certfile \"tests/daemon/mgmt/cert1.ndncert\"\n"
-    "  }\n"
-    "  authorize\n"
-    "  {\n"
-    "    certfile \"tests/daemon/mgmt/cert2.ndncert\"\n"
-    "  }\n"
-    "}\n";
-
-  ConfigFile config;
-  CommandValidator validator;
-
-  validator.setConfigFile(config);
-
-  std::stringstream expectedError;
-  expectedError << "No privileges section found for certificate file tests/daemon/mgmt/cert1.ndncert "
-                << "(" << m_tester1.getPublicKeyName().toUri() << ")\n"
-                << "No privileges section found for certificate file tests/daemon/mgmt/cert2.ndncert "
-                << "(" << m_tester2.getPublicKeyName().toUri() << ")";
-
-  BOOST_CHECK_EXCEPTION(config.parse(NO_PRIVILEGES_CONFIG, true, CONFIG_PATH.native()),
-                        ConfigFile::Error,
-                        bind(&validateErrorMessage, expectedError.str(), _1));
-}
-
-BOOST_AUTO_TEST_CASE(InvalidCertfileDryRun)
-{
-  using namespace boost::filesystem;
-
-  const std::string INVALID_KEY_CONFIG =
-    "authorizations\n"
-    "{\n"
-    "  authorize\n"
-    "  {\n"
-    "    certfile \"tests/daemon/mgmt/notacertfile.ndncert\"\n"
-    "    privileges\n"
-    "    {\n"
-    "      fib\n"
-    "      stats\n"
-    "    }\n"
-    "  }\n"
-    "  authorize\n"
-    "  {\n"
-    "    certfile \"tests/daemon/mgmt/stillnotacertfile.ndncert\"\n"
-    "    privileges\n"
-    "    {\n"
-    "    }\n"
-    "  }\n"
-    "}\n";
-
-  ConfigFile config;
-  CommandValidator validator;
-
-  validator.setConfigFile(config);
-
-  std::stringstream error;
-  error << "Unable to open certificate file "
-        << absolute("tests/daemon/mgmt/notacertfile.ndncert").native() << "\n"
-        << "Unable to open certificate file "
-        << absolute("tests/daemon/mgmt/stillnotacertfile.ndncert").native();
-
-  BOOST_CHECK_EXCEPTION(config.parse(INVALID_KEY_CONFIG, true, CONFIG_PATH.native()),
-                        ConfigFile::Error,
-                        bind(&validateErrorMessage, error.str(), _1));
-}
-
-BOOST_AUTO_TEST_CASE(NoCertfileDryRun)
-{
-  const std::string NO_CERT_CONFIG =
-    "authorizations\n"
-    "{\n"
-    "  authorize\n"
-    "  {\n"
-    "    privileges\n"
-    "    {\n"
-    "      fib\n"
-    "      stats\n"
-    "    }\n"
-    "  }\n"
-    "  authorize\n"
-    "  {\n"
-    "  }\n"
-    "}\n";
-
-
-  ConfigFile config;
-  CommandValidator validator;
-
-  validator.setConfigFile(config);
-  BOOST_CHECK_EXCEPTION(config.parse(NO_CERT_CONFIG, true, CONFIG_PATH.native()),
-                        ConfigFile::Error,
-                        bind(&validateErrorMessage,
-                             "No certfile specified\n"
-                             "No certfile specified", _1));
-}
-
-BOOST_AUTO_TEST_CASE(MalformedCertDryRun)
-{
-  using namespace boost::filesystem;
-
-  const std::string MALFORMED_CERT_CONFIG =
-    "authorizations\n"
-    "{\n"
-    "  authorize\n"
-    "  {\n"
-    "    certfile \"tests/daemon/mgmt/malformed.ndncert\"\n"
-    "    privileges\n"
-    "    {\n"
-    "      fib\n"
-    "      stats\n"
-    "    }\n"
-    "  }\n"
-    "  authorize\n"
-    "  {\n"
-    "    certfile \"tests/daemon/mgmt/malformed.ndncert\"\n"
-    "  }\n"
-    "}\n";
-
-
-  ConfigFile config;
-  CommandValidator validator;
-
-  validator.setConfigFile(config);
-
-  std::stringstream error;
-  error << "Malformed certificate file "
-        << absolute("tests/daemon/mgmt/malformed.ndncert").native() << "\n"
-        << "Malformed certificate file "
-        << absolute("tests/daemon/mgmt/malformed.ndncert").native();
-
-  BOOST_CHECK_EXCEPTION(config.parse(MALFORMED_CERT_CONFIG, true, CONFIG_PATH.native()),
-                        ConfigFile::Error,
-                        bind(&validateErrorMessage, error.str(), _1));
-}
-
-BOOST_FIXTURE_TEST_CASE(Wildcard, TwoValidatorFixture)
-{
-  const std::string WILDCARD_CERT_CONFIG =
-    "authorizations\n"
-    "{\n"
-    "  authorize\n"
-    "  {\n"
-    "    certfile any\n"
-    "    privileges\n"
-    "    {\n"
-    "      faces\n"
-    "      stats\n"
-    "    }\n"
-    "  }\n"
-    "}\n";
-
-  shared_ptr<Interest> fibCommand = make_shared<Interest>("/localhost/nfd/fib/insert");
-  shared_ptr<Interest> statsCommand = make_shared<Interest>("/localhost/nfd/stats/dosomething");
-  shared_ptr<Interest> facesCommand = make_shared<Interest>("/localhost/nfd/faces/create");
-
-  ndn::CommandInterestGenerator generator;
-  generator.generateWithIdentity(*fibCommand, m_tester1.getIdentityName());
-  generator.generateWithIdentity(*statsCommand, m_tester1.getIdentityName());
-  generator.generateWithIdentity(*facesCommand, m_tester1.getIdentityName());
-
-  ConfigFile config;
-  CommandValidator validator;
-  validator.addSupportedPrivilege("faces");
-  validator.addSupportedPrivilege("fib");
-  validator.addSupportedPrivilege("stats");
-
-  validator.setConfigFile(config);
-
-  config.parse(WILDCARD_CERT_CONFIG, false, CONFIG_PATH.native());
-
-  validator.validate(*fibCommand,
-                     bind(&CommandValidatorTester::onValidated, &m_tester1, _1),
-                     bind(&CommandValidatorTester::onValidationFailed, &m_tester1, _1, _2));
-
-  BOOST_REQUIRE(m_tester1.commandValidationFailed());
-  m_tester1.resetValidation();
-
-  validator.validate(*statsCommand,
-                     bind(&CommandValidatorTester::onValidated, &m_tester1, _1),
-                     bind(&CommandValidatorTester::onValidationFailed, &m_tester1, _1, _2));
-
-  BOOST_REQUIRE(m_tester1.commandValidated());
-  m_tester1.resetValidation();
-
-  validator.validate(*facesCommand,
-                     bind(&CommandValidatorTester::onValidated, &m_tester1, _1),
-                     bind(&CommandValidatorTester::onValidationFailed, &m_tester1, _1, _2));
-
-  BOOST_REQUIRE(m_tester1.commandValidated());
-  m_tester1.resetValidation();
-}
-
-BOOST_AUTO_TEST_SUITE_END()
-
-} // namespace tests
-} // namespace nfd
