blob: ed8e02bedb401571de11f5f84de8d002bc8fdfb9 [file] [log] [blame]
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/**
* Copyright (c) 2014-2016, Regents of the University of California.
*
* This file is part of NDNS (Named Data Networking Domain Name Service).
* See AUTHORS.md for complete list of NDNS authors and contributors.
*
* NDNS 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.
*
* NDNS 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
* NDNS, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
*/
#include "../../src/mgmt/management-tool.hpp"
#include "../../boost-test.hpp"
#include <boost/test/output_test_stream.hpp>
using boost::test_tools::output_test_stream;
#include "ndns-enum.hpp"
#include "ndns-label.hpp"
#include "ndns-tlv.hpp"
#include <vector>
#include <iostream>
#include <fstream>
#include <string>
#include <boost/filesystem.hpp>
#include <boost/algorithm/string/replace.hpp>
#include <ndn-cxx/security/key-chain.hpp>
#include <ndn-cxx/security/validator.hpp>
#include <ndn-cxx/util/io.hpp>
#include <ndn-cxx/util/regex.hpp>
namespace ndn {
namespace ndns {
namespace tests {
BOOST_AUTO_TEST_SUITE(ManagementTool)
static const boost::filesystem::path TEST_DATABASE = TEST_CONFIG_PATH "/management_tool.db";
static const boost::filesystem::path TEST_CERTDIR = TEST_CONFIG_PATH "/management_tool_certs";
static const Name FAKE_ROOT("/fake-root/123456789");
/**
* @brief Recursive copy a directory using Boost Filesystem
*
* Based on from http://stackoverflow.com/q/8593608/2150331
*/
void
copyDir(const boost::filesystem::path& source, const boost::filesystem::path& destination)
{
namespace fs = boost::filesystem;
fs::create_directory(destination);
for (fs::directory_iterator file(source); file != fs::directory_iterator(); ++file) {
fs::path current(file->path());
if (is_directory(current)) {
copyDir(current, destination / current.filename());
}
else {
// cannot use fs::copy_file, see https://svn.boost.org/trac/boost/ticket/10038
// fs::copy works, as it doesn't use problematic private API
copy(current, destination / current.filename());
}
}
}
class TestHome : boost::noncopyable
{
public:
TestHome()
{
if (std::getenv("HOME"))
m_origHome = std::getenv("HOME");
setenv("HOME", TEST_CONFIG_PATH "/tests/unit/mgmt/", 1);
boost::filesystem::remove_all(TEST_CONFIG_PATH "/tests/unit/mgmt/");
boost::filesystem::create_directories(TEST_CONFIG_PATH "/tests/unit/mgmt");
copyDir("tests/unit/mgmt/.ndn", TEST_CONFIG_PATH "/tests/unit/mgmt/.ndn");
}
~TestHome()
{
if (!m_origHome.empty())
setenv("HOME", m_origHome.c_str(), 1);
else
unsetenv("HOME");
}
protected:
std::string m_origHome;
};
class ManagementToolFixture : public TestHome
{
public:
class Error : public std::runtime_error
{
public:
explicit
Error(const std::string& what)
: std::runtime_error(what)
{
}
};
class PreviousStateCleaner
{
public:
PreviousStateCleaner()
{
boost::filesystem::remove(TEST_DATABASE);
boost::filesystem::remove_all(TEST_CERTDIR);
}
};
ManagementToolFixture()
: m_keyChain("sqlite3", "file")
, m_tool(TEST_DATABASE.string().c_str(), m_keyChain)
, m_dbMgr(TEST_DATABASE.string().c_str())
, rootKsk("/KEY/ksk-1416974006376/ID-CERT/%FD%00%00%01I%EA%3Bx%BD")
, rootDsk("/KEY/dsk-1416974006466/ID-CERT/%FD%00%00%01I%EA%3By%28")
, otherKsk("/ndns-test/KEY/ksk-1416974006577/ID-CERT/%FD%00%00%01I%EA%3By%7F")
, otherDsk("/ndns-test/KEY/dsk-1416974006659/ID-CERT/%FD%00%00%01I%EA%3Bz%0E")
{
boost::filesystem::create_directory(TEST_CERTDIR);
}
~ManagementToolFixture()
{
}
std::vector<Name>
getKeys(const Name& identity)
{
std::vector<Name> keys;
m_keyChain.getAllKeyNamesOfIdentity(identity, keys, false);
m_keyChain.getAllKeyNamesOfIdentity(identity, keys, true);
return keys;
}
std::vector<Name>
getCerts(const Name& identity)
{
std::vector<Name> certs;
for (auto&& name : getKeys(identity)) {
m_keyChain.getAllCertificateNamesOfKey(name, certs, false);
m_keyChain.getAllCertificateNamesOfKey(name, certs, true);
}
return certs;
}
Rrset
findRrSet(Zone& zone, const Name& label, const name::Component& type)
{
Rrset rrset(&zone);
rrset.setLabel(label);
rrset.setType(type);
if (!m_dbMgr.find(rrset))
throw Error("Record not found");
else
return rrset;
}
Name
getLabel(const Zone& zone, const Name& fullName)
{
size_t zoneNameSize = zone.getName().size();
return fullName.getSubName(zoneNameSize + 1, fullName.size() - zoneNameSize - 3);
}
IdentityCertificate
findIdCert(Zone& zone, const Name& fullName)
{
Rrset rrset = findRrSet(zone, getLabel(zone, fullName), label::CERT_RR_TYPE);
IdentityCertificate cert;
cert.wireDecode(rrset.getData());
return cert;
}
Response
findResponse(Zone& zone, const Name& label, const name::Component& type)
{
Rrset rrset = findRrSet(zone, label, type);
Data data(rrset.getData());
Response resp;
resp.fromData("", zone.getName(), data);
return resp;
}
public:
PreviousStateCleaner cleaner; // must be first variable
ndn::KeyChain m_keyChain;
ndns::ManagementTool m_tool;
ndns::DbMgr m_dbMgr;
// Names of pre-created certificates
// Uncomment and run InitPreconfiguredKeys test case and then update names in the
// constructor.
Name rootKsk;
Name rootDsk;
Name otherKsk;
Name otherDsk;
};
// BOOST_FIXTURE_TEST_CASE(InitPreconfiguredKeys, ManagementToolFixture)
// {
// using time::seconds;
// auto generateCerts = [this] (const Name& zone, const Name& parentCert = Name()) -> Name {
// // to re-generate certificates, uncomment and then update rootKsk/rootDsk names
// Name kskName = m_keyChain.generateRsaKeyPair(zone, true);
// auto kskCert = m_keyChain
// .prepareUnsignedIdentityCertificate(kskName, zone, time::fromUnixTimestamp(seconds(0)),
// time::fromUnixTimestamp(seconds(2147483648)), {});
// if (parentCert.empty()) {
// m_keyChain.selfSign(*kskCert);
// }
// else {
// m_keyChain.sign(*kskCert, parentCert);
// }
// m_keyChain.addCertificate(*kskCert);
// Name dskName = m_keyChain.generateRsaKeyPair(zone, false);
// auto dskCert = m_keyChain
// .prepareUnsignedIdentityCertificate(dskName, zone, time::fromUnixTimestamp(seconds(0)),
// time::fromUnixTimestamp(seconds(2147483648)), {});
// m_keyChain.sign(*dskCert, kskCert->getName());
// m_keyChain.addCertificate(*dskCert);
// return dskCert->getName();
// };
// Name rootDsk = generateCerts(ROOT_ZONE);
// generateCerts("/ndns-test", rootDsk);
// copyDir(TEST_CONFIG_PATH "/tests/unit/mgmt/.ndn", "/tmp/.ndn");
// std::cout << "Manually copy contents of /tmp/.ndn into tests/unit/mgmt/.ndn" << std::endl;
// }
BOOST_FIXTURE_TEST_CASE(CreateDeleteRootZone, ManagementToolFixture)
{
m_tool.createZone(ROOT_ZONE, ROOT_ZONE, time::seconds(4600), time::seconds(4600),
rootKsk, rootDsk);
Zone zone(ROOT_ZONE);
BOOST_REQUIRE_EQUAL(m_dbMgr.find(zone), true);
BOOST_REQUIRE_NO_THROW(findIdCert(zone, rootDsk));
BOOST_CHECK_EQUAL(findIdCert(zone, rootDsk).getName(), rootDsk);
BOOST_CHECK_NO_THROW(m_tool.deleteZone(ROOT_ZONE));
BOOST_CHECK_EQUAL(m_dbMgr.find(zone), false);
}
BOOST_FIXTURE_TEST_CASE(CreateDeleteChildZone, ManagementToolFixture)
{
Name parentZoneName("/ndns-test");
Name zoneName = Name(parentZoneName).append("child-zone");
BOOST_CHECK_EQUAL(m_keyChain.doesIdentityExist(zoneName), false);
// will generate keys automatically
m_tool.createZone(zoneName, parentZoneName);
BOOST_CHECK_EQUAL(m_keyChain.doesIdentityExist(zoneName), true);
std::vector<Name>&& certs = getCerts(zoneName);
BOOST_REQUIRE_EQUAL(certs.size(), 2);
std::sort(certs.begin(), certs.end());
// Name& ksk = certs[0];
Name& dsk = certs[1];
Zone zone(zoneName);
BOOST_REQUIRE_EQUAL(m_dbMgr.find(zone), true);
BOOST_REQUIRE_NO_THROW(findIdCert(zone, dsk));
BOOST_CHECK_EQUAL(findIdCert(zone, dsk).getName(), dsk);
BOOST_CHECK_NO_THROW(m_tool.deleteZone(zoneName));
BOOST_CHECK_THROW(m_tool.deleteZone(zoneName), ndns::ManagementTool::Error);
BOOST_CHECK_THROW(m_tool.deleteZone("/non/existing/zone"), ndns::ManagementTool::Error);
}
BOOST_FIXTURE_TEST_CASE(CreateZoneWithTtl, ManagementToolFixture)
{
Name parentZoneName("/ndns-test");
Name zoneName = Name(parentZoneName).append("child-zone");
m_tool.createZone(zoneName, parentZoneName, time::seconds(4200), time::days(30));
BOOST_CHECK_EQUAL(m_keyChain.doesIdentityExist(zoneName), true);
std::vector<Name>&& certs = getCerts(zoneName);
BOOST_REQUIRE_EQUAL(certs.size(), 2);
std::sort(certs.begin(), certs.end());
// Name& ksk = certs[0];
Name& dsk = certs[1];
// Check zone ttl
Zone zone(zoneName);
BOOST_REQUIRE_EQUAL(m_dbMgr.find(zone), true);
BOOST_CHECK_EQUAL(zone.getTtl(), time::seconds(4200));
// Check dsk rrset ttl
Rrset rrset;
BOOST_REQUIRE_NO_THROW(rrset = findRrSet(zone, getLabel(zone, dsk), label::CERT_RR_TYPE));
BOOST_CHECK_EQUAL(rrset.getTtl(), time::seconds(4200));
// Check certificate freshnessPeriod and validity
IdentityCertificate cert;
BOOST_REQUIRE_NO_THROW(cert = findIdCert(zone, dsk));
BOOST_CHECK_EQUAL(cert.getMetaInfo().getFreshnessPeriod(), time::seconds(4200));
BOOST_CHECK_EQUAL(cert.getNotAfter() - cert.getNotBefore(), time::days(30));
m_tool.deleteZone(zoneName);
}
BOOST_FIXTURE_TEST_CASE(ZoneCreatePreconditions, ManagementToolFixture)
{
BOOST_CHECK_NO_THROW(m_tool.createZone("/net/ndnsim", "/net"));
BOOST_CHECK_THROW(m_tool.createZone("/net/ndnsim", "/net"), ndns::ManagementTool::Error);
std::vector<Name>&& certs = getCerts("/net/ndnsim");
BOOST_REQUIRE_EQUAL(certs.size(), 2);
std::sort(certs.begin(), certs.end());
Name& ksk = certs[0];
Name& dsk = certs[1];
m_tool.deleteZone("/net/ndnsim");
// identity will still exist after the zone is deleted
BOOST_CHECK_THROW(m_tool.createZone("/net/ndnsim", "/net/ndnsim"), ndns::ManagementTool::Error);
BOOST_CHECK_THROW(m_tool.createZone("/net/ndnsim", "/com"), ndns::ManagementTool::Error);
BOOST_CHECK_NO_THROW(m_tool.createZone("/net/ndnsim", "/",
time::seconds(1), time::days(1), ksk, dsk));
BOOST_CHECK_EQUAL(getCerts("/net/ndnsim").size(), 2);
m_tool.deleteZone("/net/ndnsim");
// no ksk and dsk will be generated
BOOST_CHECK_NO_THROW(m_tool.createZone("/net/ndnsim", "/",
time::seconds(1), time::days(1), Name(), dsk));
BOOST_CHECK_EQUAL(getCerts("/net/ndnsim").size(), 2);
m_tool.deleteZone("/net/ndnsim");
BOOST_CHECK_NO_THROW(m_tool.createZone("/net/ndnsim", "/",
time::seconds(1), time::days(1), ksk, Name()));
BOOST_CHECK_EQUAL(getCerts("/net/ndnsim").size(), 3);
m_tool.deleteZone("/net/ndnsim");
BOOST_CHECK_THROW(m_tool.createZone("/net/ndnsim", "/net",
time::seconds(1), time::days(1), "/com/ndnsim"),
ndns::ManagementTool::Error);
m_keyChain.deleteIdentity("/net/ndnsim");
Name cert = m_keyChain.createIdentity("/net/ndnsim");
BOOST_CHECK_NO_THROW(m_tool.createZone("/net/ndnsim", "/net",
time::seconds(1), time::days(1), cert));
cert = m_keyChain.createIdentity("/com/ndnsim");
BOOST_CHECK_THROW(m_tool.createZone("/net/ndnsim", "/net",
time::seconds(1), time::days(1), cert),
ndns::ManagementTool::Error);
cert = m_keyChain.createIdentity("/net/ndnsim/www");
BOOST_CHECK_THROW(m_tool.createZone("/net/ndnsim", "/net",
time::seconds(1), time::days(1), cert),
ndns::ManagementTool::Error);
cert = m_keyChain.createIdentity("/net/ndnsim");
m_keyChain.deleteKeyPairInTpm(m_keyChain.getCertificate(cert)->getPublicKeyName());
BOOST_CHECK_THROW(m_tool.createZone("/net/ndnsim", "/net",
time::seconds(1), time::days(1), cert),
ndns::ManagementTool::Error);
// for root zone special case (requires a valid KSK to be specified)
BOOST_CHECK_THROW(m_tool.createZone("/", "/"), ndns::ManagementTool::Error);
BOOST_CHECK_NO_THROW(m_tool.createZone("/", "/", time::seconds(1), time::days(1),
rootKsk));
}
class OutputTester
{
public:
OutputTester()
: savedBuf(std::clog.rdbuf())
{
std::cout.rdbuf(buffer.rdbuf());
}
~OutputTester()
{
std::cout.rdbuf(savedBuf);
}
public:
std::stringstream buffer;
std::streambuf* savedBuf;
};
BOOST_FIXTURE_TEST_CASE(ExportCertificate, ManagementToolFixture)
{
std::string outputFile = TEST_CERTDIR.string() + "/ss.cert";
BOOST_REQUIRE_THROW(m_tool.exportCertificate("/random/name", outputFile),
ndns::ManagementTool::Error);
BOOST_REQUIRE_EQUAL(boost::filesystem::exists(outputFile), false);
// doesn't check the zone, export from KeyChain directly
BOOST_CHECK_NO_THROW(m_tool.exportCertificate(otherDsk, outputFile));
BOOST_REQUIRE_EQUAL(boost::filesystem::exists(outputFile), true);
std::string dskValue =
"Bv0C3Ac3CAluZG5zLXRlc3QIA0tFWQgRZHNrLTE0MTY5NzQwMDY2NTkIB0lELUNF\n"
"UlQICf0AAAFJ6jt6DhQDGAECFf0BYTCCAV0wIhgPMTk3MDAxMDEwMDAwMDBaGA8y\n"
"MDM4MDExOTAzMTQwOFowEzARBgNVBCkTCi9uZG5zLXRlc3QwggEgMA0GCSqGSIb3\n"
"DQEBAQUAA4IBDQAwggEIAoIBAQDIFUL7Fz8mmxxIT8l3FtWm+CuH9+iQ0Uj/a30P\n"
"mKe4gWvtxzhb4vIngYbXGv2iUzHswdqYlTVeDdW6eOFKMvyY5p5eVtLqDFZ7EEK0\n"
"0rpTh648HjCSz+Awgp2nbiYAAVvhP6YF+NxGBH412uPI7kLY6ozypsNmYP+K4SYT\n"
"oY9ee4xLSjqzXfLMyP1h8OHcN/aNmccRJlyYblCmCDbZPnzu3ttHHwdrYQLeFvb0\n"
"B5grCAQoPHwkfxkEnzQBA/fbUdvKNdayEkuibPLlIlmj2cBtk5iVk8JCSibP3Zlz\n"
"36Sks1DAO+1EvCRnjoH5vYmkpMUBFue+6A40IQG4brM2CiIRAgERFjMbAQEcLgcs\n"
"CAluZG5zLXRlc3QIA0tFWQgRa3NrLTE0MTY5NzQwMDY1NzcIB0lELUNFUlQX/QEA\n"
"GP2bQqp/7rfb8tShwDbXihWrPojwEFqlfwLibK9aM1RxwpHVqbtRsPYmuWc87LaU\n"
"OztPOZinHGL80ypFC+wYadVGnE8MPdTkUYUik7mbHDEsYWADoyGMVhoZv+OTJ/5m\n"
"MUh/kR1FMiqtZcIQtLB3cdCeGlZBl9wm2SvhMKVUym3RsQO46RpnmsEQcCfWMBZg\n"
"u5U6mhYIpiQPZ/sYyZ9zXstwsIfaF1p0V+1dW5y99PZJXIegVKhkGGU0ibjYoJy7\n"
"6uUjqBBDX8KMdt6n/Zy1/pGG1eOchMyV0JZ8+MJxWuiTEh5PJeYMFHTV/BVp8aPy\n"
"8UNqhMpjAZwW6pdvOZADVg==\n";
{
std::ifstream ifs(outputFile.c_str());
std::string actualValue((std::istreambuf_iterator<char>(ifs)),
std::istreambuf_iterator<char>());
BOOST_CHECK_EQUAL(actualValue, dskValue);
}
boost::filesystem::remove(outputFile);
// doesn't check the zone, export from KeyChain directly
BOOST_CHECK_NO_THROW(m_tool.exportCertificate(otherKsk, outputFile));
boost::filesystem::remove(outputFile);
Name zoneName("/ndns-test");
m_tool.createZone(zoneName, ROOT_ZONE, time::seconds(4200), time::days(30),
otherKsk, otherDsk);
m_keyChain.deleteCertificate(otherKsk);
m_keyChain.deleteCertificate(otherDsk);
// retrieve cert from the zone
BOOST_CHECK_NO_THROW(m_tool.exportCertificate(otherDsk, outputFile));
{
std::ifstream ifs(outputFile.c_str());
std::string actualValue((std::istreambuf_iterator<char>(ifs)),
std::istreambuf_iterator<char>());
BOOST_CHECK_EQUAL(actualValue, dskValue);
}
boost::filesystem::remove(outputFile);
BOOST_REQUIRE_THROW(m_tool.exportCertificate(otherKsk, outputFile),
ndns::ManagementTool::Error);
// output to std::cout
std::string acutalOutput;
{
OutputTester tester;
m_tool.exportCertificate(otherDsk, "-");
acutalOutput = tester.buffer.str();
}
BOOST_CHECK_EQUAL(acutalOutput, dskValue);
}
BOOST_FIXTURE_TEST_CASE(AddRrSet1, ManagementToolFixture)
{
// check pre-condition
BOOST_CHECK_THROW(m_tool.addRrSet(ROOT_ZONE, "/test", label::NS_RR_TYPE, NDNS_RESP),
ndns::ManagementTool::Error);
Name zoneName("/ndns-test");
Zone zone(zoneName);
m_dbMgr.insert(zone);
BOOST_CHECK_THROW(m_tool.addRrSet(ROOT_ZONE, "/test", label::NS_RR_TYPE, NDNS_UNKNOWN),
ndns::ManagementTool::Error);
BOOST_CHECK_THROW(m_tool.addRrSet(zoneName, "/test", label::CERT_RR_TYPE, NDNS_RAW),
ndns::ManagementTool::Error);
BOOST_CHECK_THROW(m_tool.addRrSet(ROOT_ZONE, "/test", label::NS_RR_TYPE, NDNS_RAW),
ndns::ManagementTool::Error);
BOOST_CHECK_THROW(m_tool.addRrSet(ROOT_ZONE, "/test", label::TXT_RR_TYPE, NDNS_RAW),
ndns::ManagementTool::Error);
m_dbMgr.remove(zone);
}
BOOST_FIXTURE_TEST_CASE(AddRrSet2, ManagementToolFixture)
{
Name zoneName("/ndns-test");
Zone zone(zoneName);
uint64_t version = 1234;
time::seconds ttl1(4200);
time::seconds ttl2(4500);
m_tool.createZone(zoneName, ROOT_ZONE, ttl1);
//add NS NDNS_AUTH and check user-defined ttl
BOOST_CHECK_NO_THROW(m_tool.addRrSet(zoneName, "/l1", label::NS_RR_TYPE, NDNS_AUTH, 7654,
{}, DEFAULT_CERT, ttl2));
Response response;
BOOST_CHECK_NO_THROW(response = findResponse(zone, "/l1", label::NS_RR_TYPE));
BOOST_CHECK_EQUAL(response.getNdnsType(), NDNS_AUTH);
BOOST_CHECK_EQUAL(response.getVersion(), name::Component::fromVersion(7654));
BOOST_CHECK_EQUAL(response.getFreshnessPeriod(), ttl2);
// add NS NDNS_RESP and check default ttl
BOOST_CHECK_NO_THROW(m_tool.addRrSet(zoneName, "/l2", label::NS_RR_TYPE, NDNS_RESP, 15));
BOOST_CHECK_NO_THROW(response = findResponse(zone, "/l2", label::NS_RR_TYPE));
BOOST_CHECK_EQUAL(response.getNdnsType(), NDNS_RESP);
BOOST_CHECK_EQUAL(response.getVersion(), name::Component::fromVersion(15));
BOOST_CHECK_EQUAL(response.getFreshnessPeriod(), ttl1);
//add TXT NDNS_RESP and check rr
std::string test = "oops";
BOOST_CHECK_NO_THROW(m_tool.addRrSet(zoneName, "/l2", label::TXT_RR_TYPE, NDNS_RESP, version,
{"oops", "again"}));
BOOST_CHECK_NO_THROW(response = findResponse(zone, "/l2", label::TXT_RR_TYPE));
BOOST_REQUIRE_EQUAL(response.getRrs().size(), 2);
{
const Block& block = response.getRrs()[0];
std::string someString(reinterpret_cast<const char*>(block.value()), block.value_size());
BOOST_CHECK_EQUAL("oops", someString);
}
{
const Block& block = response.getRrs()[1];
std::string someString(reinterpret_cast<const char*>(block.value()), block.value_size());
BOOST_CHECK_EQUAL("again", someString);
}
//add user defined type
BOOST_CHECK_THROW(m_tool.addRrSet(zoneName, "/l2", name::Component("USER-DEFINED"), NDNS_RAW,
1112223, {"10.10.0.1", "SECOND_INVALID_DATA"}),
ndns::ManagementTool::Error);
m_tool.addRrSet(zoneName, "/l2", name::Component("USER-DEFINED"), NDNS_RAW, 1112223,
{"10.10.0.1"});
BOOST_CHECK_NO_THROW(response = findResponse(zone, "/l2", name::Component("USER-DEFINED")));
BOOST_CHECK_EQUAL(response.getVersion(), name::Component::fromVersion(1112223));
std::string actualValue(reinterpret_cast<const char*>(response.getAppContent().value()),
response.getAppContent().value_size());
BOOST_CHECK_EQUAL(actualValue, "10.10.0.1");
}
BOOST_FIXTURE_TEST_CASE(AddRrSet3, ManagementToolFixture)
{
// check pre-condition
Name zoneName("/ndns-test");
std::string certPath = TEST_CERTDIR.string();
BOOST_CHECK_THROW(m_tool.addRrSet(zoneName, certPath), ndns::ManagementTool::Error);
m_tool.createZone(zoneName, ROOT_ZONE);
BOOST_CHECK_THROW(m_tool.addRrSet(zoneName, certPath), ndns::ManagementTool::Error);
}
BOOST_FIXTURE_TEST_CASE(AddRrSet4, ManagementToolFixture)
{
Name parentZoneName("/ndns-test");
Name zoneName = Name(parentZoneName).append("/child-zone");
Zone parentZone(parentZoneName);
m_tool.createZone(parentZoneName, ROOT_ZONE, time::seconds(1), time::days(1), otherKsk, otherDsk);
m_tool.createZone(zoneName, parentZoneName);
std::vector<Name>&& certs = getCerts(zoneName);
BOOST_REQUIRE_EQUAL(certs.size(), 2);
std::sort(certs.begin(), certs.end());
Name& ksk = certs[0];
// Name& dsk = certs[1];
std::string output = TEST_CERTDIR.string() + "/ss.cert";
m_tool.exportCertificate(ksk, output);
BOOST_CHECK_NO_THROW(m_tool.addRrSet(parentZoneName, output));
BOOST_CHECK_NO_THROW(findIdCert(parentZone, ksk));
BOOST_CHECK_NO_THROW(m_tool.addRrSet(parentZoneName, "/child-zone",
label::NS_RR_TYPE, NDNS_RESP));
BOOST_CHECK_NO_THROW(findRrSet(parentZone, "/child-zone", label::NS_RR_TYPE));
//add KSK ID-CERT with illegal name and convert it
Name iZoneName = Name(parentZoneName).append("illegal");
Name illegalCertName = m_keyChain.createIdentity(iZoneName);
m_tool.exportCertificate(illegalCertName, output);
BOOST_CHECK_NO_THROW(m_tool.addRrSet(parentZoneName, output));
Name legalCertName =
Name(parentZoneName)
.append("KEY")
.append("illegal")
.append(illegalCertName.getSubName(3));
BOOST_CHECK_NO_THROW(findIdCert(parentZone, legalCertName));
}
BOOST_FIXTURE_TEST_CASE(AddRrSet5, ManagementToolFixture)
{
//check using user provided certificate
Name parentZoneName("/ndns-test");
Name zoneName = Name(parentZoneName).append("child-zone");
Name dskName = m_keyChain.generateRsaKeyPair(parentZoneName, false);
shared_ptr<IdentityCertificate> dskCert = m_keyChain.selfSign(dskName);
m_keyChain.addCertificateAsKeyDefault(*dskCert);
// check addRrSet1
m_tool.createZone(parentZoneName, ROOT_ZONE, time::seconds(1), time::days(1), otherKsk, otherDsk);
m_tool.createZone(zoneName, parentZoneName);
std::vector<Name>&& certs = getCerts(zoneName);
BOOST_REQUIRE_EQUAL(certs.size(), 2);
std::sort(certs.begin(), certs.end());
Name& ksk = certs[0];
// Name& dsk = certs[1];
std::string output = TEST_CERTDIR.string() + "/ss.cert";
m_tool.exportCertificate(ksk, output);
BOOST_CHECK_NO_THROW(m_tool.addRrSet(parentZoneName, output, time::seconds(4600),
dskCert->getName()));
// check addRrSet2
Name label1("/net/ndnsim1");
BOOST_CHECK_NO_THROW(m_tool.addRrSet(parentZoneName, "/l1", label::NS_RR_TYPE, NDNS_AUTH, -1, {},
dskCert->getName()));
}
BOOST_FIXTURE_TEST_CASE(AddRrSet6, ManagementToolFixture)
{
//check invalid output
Name parentZoneName("/ndns-test");
Name zoneName = Name(parentZoneName).append("child-zone");
m_tool.createZone(zoneName, parentZoneName);
Name content = "invalid data packet";
std::string output = TEST_CERTDIR.string() + "/ss.cert";
ndn::io::save(content, output);
BOOST_CHECK_THROW(m_tool.addRrSet(zoneName, output), ndns::ManagementTool::Error);
}
BOOST_FIXTURE_TEST_CASE(AddRrSet7, ManagementToolFixture)
{
//check version control
Name parentZoneName("/ndns-test");
Name zoneName = Name(parentZoneName).append("child-zone");
m_tool.createZone(zoneName, parentZoneName);
Name label("/label");
uint64_t version = 110;
m_tool.addRrSet(zoneName, label, label::NS_RR_TYPE, NDNS_RESP, version);
// throw error when adding duplicated rrset with the same version
BOOST_CHECK_THROW(m_tool.addRrSet(zoneName, label, label::NS_RR_TYPE, NDNS_RESP, version),
ndns::ManagementTool::Error);
version--;
// throw error when adding duplicated rrset with older version
BOOST_CHECK_THROW(m_tool.addRrSet(zoneName, label, label::NS_RR_TYPE, NDNS_RESP, version),
ndns::ManagementTool::Error);
version++;
version++;
BOOST_CHECK_NO_THROW(m_tool.addRrSet(zoneName, label, label::NS_RR_TYPE, NDNS_RESP, version));
Zone zone(zoneName);
m_dbMgr.find(zone);
Rrset rrset;
rrset.setZone(&zone);
rrset.setLabel(label);
rrset.setType(label::NS_RR_TYPE);
m_dbMgr.find(rrset);
BOOST_CHECK_EQUAL(rrset.getVersion(), name::Component::fromVersion(version));
}
BOOST_FIXTURE_TEST_CASE(AddRrSet8, ManagementToolFixture)
{
//check input with different formats
Name parentZoneName("/ndns-test");
Name zoneName = Name(parentZoneName).append("child-zone");
m_tool.createZone(zoneName, parentZoneName);
std::string output = TEST_CERTDIR.string() + "/a.cert";
// base64
Name dskName = m_keyChain.generateRsaKeyPair(zoneName, false);
shared_ptr<IdentityCertificate> dskCert = m_keyChain.selfSign(dskName);
ndn::io::save(*dskCert, output, ndn::io::BASE_64);
BOOST_CHECK_NO_THROW(
m_tool.addRrSet(zoneName, output, DEFAULT_CACHE_TTL, DEFAULT_CERT, ndn::io::BASE_64));
// raw
dskName = m_keyChain.generateRsaKeyPair(zoneName, false);
dskCert = m_keyChain.selfSign(dskName);
ndn::io::save(*dskCert, output, ndn::io::NO_ENCODING);
BOOST_CHECK_NO_THROW(
m_tool.addRrSet(zoneName, output, DEFAULT_CACHE_TTL, DEFAULT_CERT, ndn::io::NO_ENCODING));
// hex
dskName = m_keyChain.generateRsaKeyPair(zoneName, false);
dskCert = m_keyChain.selfSign(dskName);
ndn::io::save(*dskCert, output, ndn::io::HEX);
BOOST_CHECK_NO_THROW(
m_tool.addRrSet(zoneName, output, DEFAULT_CACHE_TTL, DEFAULT_CERT, ndn::io::HEX));
// incorrect encoding input
dskName = m_keyChain.generateRsaKeyPair(zoneName, false);
dskCert = m_keyChain.selfSign(dskName);
ndn::io::save(*dskCert, output, ndn::io::HEX);
BOOST_CHECK_THROW(
m_tool.addRrSet(zoneName, output, DEFAULT_CACHE_TTL, DEFAULT_CERT,
static_cast<ndn::io::IoEncoding>(127)),
ndns::ManagementTool::Error);
}
BOOST_FIXTURE_TEST_CASE(ListAllZones, ManagementToolFixture)
{
m_tool.createZone(ROOT_ZONE, ROOT_ZONE, time::seconds(1), time::days(1), rootKsk, rootDsk);
m_tool.createZone("/ndns-test", ROOT_ZONE, time::seconds(10), time::days(1), otherKsk, otherDsk);
std::string expectedValue =
"/ ; default-ttl=1 default-key=/dsk-1416974006466 "
"default-certificate=/KEY/dsk-1416974006466/ID-CERT/%FD%00%00%01I%EA%3By%28\n"
"/ndns-test ; default-ttl=10 default-key=/ndns-test/dsk-1416974006659 "
"default-certificate=/ndns-test/KEY/dsk-1416974006659/ID-CERT/%FD%00%00%01I%EA%3Bz%0E\n";
output_test_stream testOutput;
m_tool.listAllZones(testOutput);
BOOST_CHECK(testOutput.is_equal(expectedValue));
}
BOOST_FIXTURE_TEST_CASE(ListZone, ManagementToolFixture)
{
m_tool.createZone("/ndns-test", ROOT_ZONE, time::seconds(10), time::days(1), otherKsk, otherDsk);
// Add NS with NDNS_RESP
m_tool.addRrSet("/ndns-test", "/label1", label::NS_RR_TYPE, NDNS_RESP, 100);
// Add NS with NDNS_AUTH
m_tool.addRrSet("/ndns-test", "/label2", label::NS_RR_TYPE, NDNS_AUTH, 100000);
// Add TXT from file
std::string output = TEST_CERTDIR.string() + "/a.rrset";
Response re1;
re1.setZone("/ndns-test");
re1.setQueryType(label::NDNS_ITERATIVE_QUERY);
re1.setRrLabel("/label2");
re1.setRrType(label::TXT_RR_TYPE);
re1.setNdnsType(NDNS_RESP);
re1.setVersion(name::Component::fromVersion(654321));
re1.addRr("First RR");
re1.addRr("Second RR");
re1.addRr("Last RR");
shared_ptr<Data> data1 = re1.toData();
m_keyChain.sign(*data1, otherDsk);
ndn::io::save(*data1, output);
m_tool.addRrSet("/ndns-test", output);
// Add TXT in normal way
m_tool.addRrSet("/ndns-test", "/label3", label::TXT_RR_TYPE, NDNS_RESP, 3333,
{"Hello", "World"}, otherDsk);
// Add User-Defined
Response re2;
re2.setZone("/ndns-test");
re2.setQueryType(label::NDNS_ITERATIVE_QUERY);
re2.setRrLabel("/label4");
re2.setRrType(name::Component("USER-DEFINED"));
re2.setNdnsType(NDNS_RAW);
re2.setVersion(name::Component::fromVersion(1234567));
re2.setAppContent(makeBinaryBlock(ndn::tlv::Content, "Hello", sizeof("Hello")));
shared_ptr<Data> data2 = re2.toData();
m_keyChain.sign(*data2, otherDsk);
ndn::io::save(*data2, output);
m_tool.addRrSet("/ndns-test", output);
output_test_stream testOutput;
m_tool.listZone("/ndns-test", testOutput, true);
std::string expectedValue =
"; Zone /ndns-test\n"
"\n"
"; rrset=/label1 type=NS version=%FDd signed-by=/ndns-test/KEY/dsk-1416974006659/ID-CERT\n"
"/label1 10 NS \n"
"\n"
"/label2 10 NS ; content-type=NDNS-Auth version=%FD%00%01%86%A0 "
"signed-by=/ndns-test/KEY/dsk-1416974006659/ID-CERT\n"
"\n"
"; rrset=/label2 type=TXT version=%FD%00%09%FB%F1 "
"signed-by=/ndns-test/KEY/dsk-1416974006659/ID-CERT\n"
"/label2 10 TXT First RR\n"
"/label2 10 TXT Second RR\n"
"/label2 10 TXT Last RR\n"
"\n"
"; rrset=/label3 type=TXT version=%FD%0D%05 "
"signed-by=/ndns-test/KEY/dsk-1416974006659/ID-CERT\n"
"/label3 10 TXT Hello\n"
"/label3 10 TXT World\n"
"\n"
"/label4 10 USER-DEFINED ; content-type=NDNS-Raw version=%FD%00%12%D6%87 "
"signed-by=/ndns-test/KEY/dsk-1416974006659/ID-CERT\n"
"; FQZIZWxsbwA=\n"
"\n"
"/dsk-1416974006659 10 ID-CERT ; content-type=NDNS-Raw version=%FD%00%00%01I%EA%3Bz%0E "
"signed-by=/ndns-test/KEY/ksk-1416974006577/ID-CERT\n"
"; Certificate name:\n"
"; /ndns-test/KEY/dsk-1416974006659/ID-CERT/%FD%00%00%01I%EA%3Bz%0E\n"
"; Validity:\n"
"; NotBefore: 19700101T000000\n"
"; NotAfter: 20380119T031408\n"
"; Subject Description:\n"
"; 2.5.4.41: /ndns-test\n"
"; Public key bits: (RSA)\n"
"; MIIBIDANBgkqhkiG9w0BAQEFAAOCAQ0AMIIBCAKCAQEAyBVC+xc/JpscSE/JdxbV\n"
"; pvgrh/fokNFI/2t9D5inuIFr7cc4W+LyJ4GG1xr9olMx7MHamJU1Xg3VunjhSjL8\n"
"; mOaeXlbS6gxWexBCtNK6U4euPB4wks/gMIKdp24mAAFb4T+mBfjcRgR+NdrjyO5C\n"
"; 2OqM8qbDZmD/iuEmE6GPXnuMS0o6s13yzMj9YfDh3Df2jZnHESZcmG5Qpgg22T58\n"
"; 7t7bRx8Ha2EC3hb29AeYKwgEKDx8JH8ZBJ80AQP321HbyjXWshJLomzy5SJZo9nA\n"
"; bZOYlZPCQkomz92Zc9+kpLNQwDvtRLwkZ46B+b2JpKTFARbnvugONCEBuG6zNgoi\n"
"; EQIB\n"
"; Signature Information:\n"
"; Signature Type: Unknown Signature Type\n"
"\n";
BOOST_CHECK(testOutput.is_equal(expectedValue));
}
BOOST_FIXTURE_TEST_CASE(GetRrSet, ManagementToolFixture)
{
Name zoneName("/ndns-test");
m_tool.createZone(zoneName, ROOT_ZONE, time::seconds(1), time::days(1), otherKsk, otherDsk);
m_tool.addRrSet(zoneName, "/label", name::Component("TXT"), NDNS_RESP, 100,
{"Value1", "Value2"});
std::string expectedValue =
"Bv0BdwchCAluZG5zLXRlc3QIBE5ETlMIBWxhYmVsCANUWFQIAv1kFAcZAgPotAEB\n"
"FRC/BlZhbHVlMb8GVmFsdWUyFjMbAQEcLgcsCAluZG5zLXRlc3QIA0tFWQgRZHNr\n"
"LTE0MTY5NzQwMDY2NTkIB0lELUNFUlQX/QEAqhzoQmGGeFcUlZ9pEp0ohVoTEw18\n"
"qfB1DN6sssOpjCu3V41SHmoybPPkdW84i/h5n6TmuuePWva+fk6l9Xppd3F4lCX0\n"
"Tb1lyxjnLaQjBKTYxNReM3h55XY7sCvb2RpFCSDZ/PFfzuCwdWAIqcau10H9IjNm\n"
"2NO+m+jW43tnou9TLrNzN80bYFQc4FEwUCJUA4jPf+1NwDUMp9LWN5IILwU+Ttx6\n"
"45u2rK6KXfgcHR3zifwi2IZ9mEjr5bhXxvL8zP+tgaPb0t6O9gujry0an2h+hUH5\n"
"Aldt49RIyipHXO7R2736ZqkUZ553DSIUhaYPuXRlByNbiW6Za+LMPgJaPg==\n";
output_test_stream testOutput;
m_tool.getRrSet(zoneName, "/label", name::Component("TXT"), testOutput);
BOOST_CHECK(testOutput.is_equal(expectedValue));
}
BOOST_FIXTURE_TEST_CASE(RemoveRrSet, ManagementToolFixture)
{
Name zoneName("/ndns-test");
m_tool.createZone(zoneName, ROOT_ZONE);
BOOST_CHECK_NO_THROW(m_tool.addRrSet(zoneName, "/label", label::NS_RR_TYPE, NDNS_RESP));
Zone zone(zoneName);
BOOST_CHECK_NO_THROW(findRrSet(zone, "/label", label::NS_RR_TYPE));
BOOST_CHECK_NO_THROW(m_tool.removeRrSet(zoneName, "/label", label::NS_RR_TYPE));
BOOST_CHECK_THROW(findRrSet(zone, "/label", label::NS_RR_TYPE), Error);
}
BOOST_AUTO_TEST_SUITE_END()
} // namespace tests
} // namespace ndns
} // namespace ndn