blob: 0ddf57b853b99094e0415d0732e9e33410241a10 [file] [log] [blame]
Jiewen Tan870b29b2014-11-17 19:09:49 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Junxiao Shi767f35c2016-07-23 01:54:42 +00003 * Copyright (c) 2014-2016, Regents of the University of California.
Jiewen Tan870b29b2014-11-17 19:09:49 -08004 *
5 * This file is part of NDNS (Named Data Networking Domain Name Service).
6 * See AUTHORS.md for complete list of NDNS authors and contributors.
7 *
8 * NDNS is free software: you can redistribute it and/or modify it under the terms
9 * of the GNU General Public License as published by the Free Software Foundation,
10 * either version 3 of the License, or (at your option) any later version.
11 *
12 * NDNS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
13 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 * PURPOSE. See the GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * NDNS, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include "management-tool.hpp"
21#include "logger.hpp"
22#include "ndns-label.hpp"
23#include "ndns-tlv.hpp"
24
25#include <string>
26#include <iomanip>
27
28#include <boost/filesystem/operations.hpp>
29#include <boost/filesystem/path.hpp>
30#include <boost/algorithm/string/replace.hpp>
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -080031#include <boost/lexical_cast.hpp>
Jiewen Tan870b29b2014-11-17 19:09:49 -080032
Jiewen Tan870b29b2014-11-17 19:09:49 -080033#include <ndn-cxx/util/regex.hpp>
Jiewen Tand1dd86d2015-03-20 10:26:28 -070034#include <ndn-cxx/util/indented-stream.hpp>
Jiewen Tan870b29b2014-11-17 19:09:49 -080035#include <ndn-cxx/encoding/oid.hpp>
36#include <ndn-cxx/security/cryptopp.hpp>
Yumin Xia5dd9f2b2016-10-26 20:48:05 -070037#include <ndn-cxx/link.hpp>
Jiewen Tan870b29b2014-11-17 19:09:49 -080038
39namespace ndn {
40namespace ndns {
41
Alexander Afanasyevc7c99002015-10-09 17:27:30 -070042NDNS_LOG_INIT("ManagementTool")
Jiewen Tan870b29b2014-11-17 19:09:49 -080043
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -080044ManagementTool::ManagementTool(const std::string& dbFile, KeyChain& keyChain)
45 : m_keyChain(keyChain)
46 , m_dbMgr(dbFile)
Jiewen Tan870b29b2014-11-17 19:09:49 -080047{
48}
49
50void
51ManagementTool::createZone(const Name &zoneName,
52 const Name& parentZoneName,
53 const time::seconds& cacheTtl,
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -080054 const time::seconds& certValidity,
Jiewen Tan870b29b2014-11-17 19:09:49 -080055 const Name& kskCertName,
56 const Name& dskCertName)
57{
58 bool isRoot = zoneName == ROOT_ZONE;
59
60 //check preconditions
61 Zone zone(zoneName, cacheTtl);
62 if (m_dbMgr.find(zone)) {
63 throw Error(zoneName.toUri() + " is already presented in the NDNS db");
64 }
65
66 if (!isRoot && parentZoneName.equals(zoneName)) {
67 throw Error("Parent zone name can not be the zone itself");
68 }
69
70 if (!isRoot && !parentZoneName.isPrefixOf(zoneName)) {
71 throw Error(parentZoneName.toUri() + " is not a prefix of " + zoneName.toUri());
72 }
73
Jiewen Tan01693fd2015-03-25 20:34:45 -070074 // if dsk is provided, there is no need to check ksk
Jiewen Tan870b29b2014-11-17 19:09:49 -080075 if (dskCertName != DEFAULT_CERT) {
76 if (!matchCertificate(dskCertName, zoneName)) {
77 throw Error("Cannot verify DSK certificate");
78 }
79 }
Jiewen Tan01693fd2015-03-25 20:34:45 -070080 else if (kskCertName != DEFAULT_CERT) {
81 if (!matchCertificate(kskCertName, zoneName)) {
82 throw Error("Cannot verify KSK certificate");
83 }
84 }
Jiewen Tan870b29b2014-11-17 19:09:49 -080085
86 if (kskCertName == DEFAULT_CERT && isRoot) {
87 throw Error("Cannot generate KSK for root zone");
88 }
89
90 //first generate KSK and DSK to the keyChain system, and add DSK as default
91 NDNS_LOG_INFO("Start generating KSK and DSK and their corresponding certificates");
Jiewen Tan870b29b2014-11-17 19:09:49 -080092 Name dskName;
93 shared_ptr<IdentityCertificate> dskCert;
94 if (dskCertName == DEFAULT_CERT) {
Jiewen Tan01693fd2015-03-25 20:34:45 -070095 // if no dsk provided, then generate a dsk either signed by ksk auto generated or user provided
96 time::system_clock::TimePoint notBefore = time::system_clock::now();
97 time::system_clock::TimePoint notAfter = notBefore + certValidity;
98 shared_ptr<IdentityCertificate> kskCert;
99
100 if (kskCertName == DEFAULT_CERT) {
101 //create KSK's certificate
102 Name kskName = m_keyChain.generateRsaKeyPair(zoneName, true);
103 std::vector<CertificateSubjectDescription> kskDesc;
104 kskCert = m_keyChain.prepareUnsignedIdentityCertificate(kskName, zoneName, notBefore,
105 notAfter, kskDesc, parentZoneName);
106 kskCert->setFreshnessPeriod(cacheTtl);
107
108 m_keyChain.selfSign(*kskCert);
109 m_keyChain.addCertificate(*kskCert);
110 NDNS_LOG_INFO("Generated KSK: " << kskCert->getName());
111 }
112 else {
113 kskCert = m_keyChain.getCertificate(kskCertName);
114 }
115
Jiewen Tan870b29b2014-11-17 19:09:49 -0800116 dskName = m_keyChain.generateRsaKeyPairAsDefault(zoneName, false);
117 //create DSK's certificate
118 std::vector<CertificateSubjectDescription> dskDesc;
119 dskCert = m_keyChain.prepareUnsignedIdentityCertificate(dskName, zoneName, notBefore, notAfter,
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800120 dskDesc, zoneName);
121 dskCert->setFreshnessPeriod(cacheTtl);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800122 m_keyChain.sign(*dskCert, kskCert->getName());
123 m_keyChain.addCertificateAsKeyDefault(*dskCert);
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800124 NDNS_LOG_INFO("Generated DSK: " << dskCert->getName());
Jiewen Tan870b29b2014-11-17 19:09:49 -0800125 }
126 else {
127 dskCert = m_keyChain.getCertificate(dskCertName);
128 dskName = dskCert->getPublicKeyName();
129 m_keyChain.setDefaultKeyNameForIdentity(dskName);
130 m_keyChain.setDefaultCertificateNameForKey(dskCert->getName());
131 }
132
133 //second add zone to the database
134 NDNS_LOG_INFO("Start adding new zone to data base");
135 addZone(zone);
136
137 //third create ID-cert
138 NDNS_LOG_INFO("Start creating DSK's ID-CERT");
139 addIdCert(zone, dskCert, cacheTtl);
140}
141
142void
143ManagementTool::deleteZone(const Name& zoneName)
144{
145 //check pre-conditions
146 Zone zone(zoneName);
147 if (!m_dbMgr.find(zone)) {
148 throw Error(zoneName.toUri() + " is not presented in the NDNS db");
149 }
150
151 //first remove all rrsets of this zone from local ndns database
152 std::vector<Rrset> rrsets = m_dbMgr.findRrsets(zone);
153 for (Rrset& rrset : rrsets) {
154 m_dbMgr.remove(rrset);
155 }
156
157 //second remove zone from local ndns database
158 removeZone(zone);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800159}
160
161void
162ManagementTool::exportCertificate(const Name& certName, const std::string& outFile)
163{
164 //search for the certificate, start from KeyChain then local NDNS database
165 shared_ptr<IdentityCertificate> cert;
166 if (m_keyChain.doesCertificateExist(certName)) {
167 cert = m_keyChain.getCertificate(certName);
168 }
169 else {
170 shared_ptr<Regex> regex = make_shared<Regex>("(<>*)<KEY>(<>+)<ID-CERT><>");
171 if (regex->match(certName) != true) {
172 throw Error("Certificate name is illegal");
173 }
174 Name zoneName = regex->expand("\\1");
175 Name label = regex->expand("\\2");
176
177 Zone zone(zoneName);
178 Rrset rrset(&zone);
179 rrset.setLabel(label);
180 rrset.setType(label::CERT_RR_TYPE);
181 if (m_dbMgr.find(rrset)) {
182 Data data(rrset.getData());
183 cert = make_shared<IdentityCertificate>(data);
184 }
185 else {
186 throw Error("Cannot find the cert: " + certName.toUri());
187 }
188 }
189
190 if (outFile == DEFAULT_IO) {
191 ndn::io::save(*cert, std::cout);
192 }
193 else {
194 ndn::io::save(*cert, outFile);
195 NDNS_LOG_INFO("save cert to file: " << outFile);
196 }
197}
198
199void
Yumin Xia5dd9f2b2016-10-26 20:48:05 -0700200ManagementTool::addRrset(Rrset& rrset)
Jiewen Tan870b29b2014-11-17 19:09:49 -0800201{
Jiewen Tan8cd35ea2015-03-20 00:44:23 -0700202 checkRrsetVersion(rrset);
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800203 NDNS_LOG_INFO("Added " << rrset);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800204 m_dbMgr.insert(rrset);
205}
206
207void
208ManagementTool::addRrSet(const Name& zoneName,
209 const std::string& inFile,
210 const time::seconds& ttl,
Jiewen Tan74d745c2015-03-20 01:40:41 -0700211 const Name& inputDskCertName,
212 const ndn::io::IoEncoding encoding)
Jiewen Tan870b29b2014-11-17 19:09:49 -0800213{
214 //check precondition
215 Zone zone(zoneName);
216 if (!m_dbMgr.find(zone)) {
217 throw Error(zoneName.toUri() + " is not presented in the NDNS db");
218 }
219
220 Name dskName;
221 Name dskCertName = inputDskCertName;
222 if (dskCertName == DEFAULT_CERT) {
223 dskName = m_keyChain.getDefaultKeyNameForIdentity(zoneName);
224 dskCertName = m_keyChain.getDefaultCertificateNameForKey(dskName);
225 }
226 else {
227 if (!matchCertificate(dskCertName, zoneName)) {
228 throw Error("Cannot verify certificate");
229 }
230 }
231
232 if (inFile != DEFAULT_IO) {
233 boost::filesystem::path dir = boost::filesystem::path(inFile);
234 if (!boost::filesystem::exists(dir) || boost::filesystem::is_directory(dir)) {
235 throw Error("Data: " + inFile + " does not exist");
236 }
237 }
238
239 //first load the data
240 shared_ptr<Data> data;
241 if (inFile == DEFAULT_IO)
Jiewen Tan74d745c2015-03-20 01:40:41 -0700242 data = ndn::io::load<ndn::Data>(std::cin, encoding);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800243 else
Jiewen Tan74d745c2015-03-20 01:40:41 -0700244 data = ndn::io::load<ndn::Data>(inFile, encoding);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800245
Jiewen Tand2d21822015-03-19 15:37:03 -0700246 if (data == nullptr) {
Jiewen Tan74d745c2015-03-20 01:40:41 -0700247 throw Error("input does not contain a valid Data packet");
Jiewen Tand2d21822015-03-19 15:37:03 -0700248 }
249
Alexander Afanasyevfde570c2016-12-19 16:02:55 -0800250 // determine whether the data is a self-signed certificate
Jiewen Tan870b29b2014-11-17 19:09:49 -0800251 shared_ptr<Regex> regex1 = make_shared<Regex>("(<>*)<KEY>(<>+)<ID-CERT><>");
252 if (regex1->match(data->getName())) {
253 IdentityCertificate scert(*data);
254 Name keyName = scert.getPublicKeyName();
Alexander Afanasyevfde570c2016-12-19 16:02:55 -0800255 if (keyName.getPrefix(zoneName.size()) != zoneName) {
256 throw Error("the input key does not belong to the zone");
257 }
258
Jiewen Tan870b29b2014-11-17 19:09:49 -0800259 Name keyLocator = scert.getSignature().getKeyLocator().getName();
260
Alexander Afanasyevfde570c2016-12-19 16:02:55 -0800261 // if it is, extract the content and name from the data, and resign it using the dsk.
Jiewen Tan870b29b2014-11-17 19:09:49 -0800262 shared_ptr<Regex> regex2 = make_shared<Regex>("(<>*)<KEY>(<>+)<ID-CERT>");
263 BOOST_VERIFY(regex2->match(keyLocator) == true);
264 if (keyName == regex2->expand("\\1\\2")) {
Alexander Afanasyevfde570c2016-12-19 16:02:55 -0800265
266 Name canonicalName;
267 canonicalName
268 .append(zoneName)
269 .append("KEY")
270 .append(keyName.getSubName(zoneName.size(), keyName.size() - zoneName.size()))
271 .append("ID-CERT")
272 .append(data->getName().get(-1));
273
274 if (data->getName() != canonicalName) {
275 // name need to be adjusted
276 auto newData = make_shared<Data>();
277 newData->setName(canonicalName);
278 newData->setMetaInfo(data->getMetaInfo());
279 newData->setContent(data->getContent());
280 m_keyChain.sign(*newData);
281
282 data = newData;
Jiewen Tan870b29b2014-11-17 19:09:49 -0800283 }
Jiewen Tan870b29b2014-11-17 19:09:49 -0800284 }
285 }
286
287 // create response for the input data
288 Response re;
Yumin Xia6343c5b2016-10-20 15:45:50 -0700289 re.fromData(zoneName, *data);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800290 Name label = re.getRrLabel();
291 name::Component type = re.getRrType();
292
293 Rrset rrset(&zone);
294 rrset.setLabel(label);
295 rrset.setType(type);
296 if (ttl == DEFAULT_RR_TTL)
297 rrset.setTtl(zone.getTtl());
298 else
299 rrset.setTtl(ttl);
300 rrset.setVersion(re.getVersion());
301 rrset.setData(data->wireEncode());
302
Jiewen Tan8cd35ea2015-03-20 00:44:23 -0700303 checkRrsetVersion(rrset);
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800304 NDNS_LOG_INFO("Added " << rrset);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800305 m_dbMgr.insert(rrset);
306}
307
308void
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800309ManagementTool::listZone(const Name& zoneName, std::ostream& os, const bool printRaw)
310{
Jiewen Tan870b29b2014-11-17 19:09:49 -0800311 Zone zone(zoneName);
312 if (!m_dbMgr.find(zone)) {
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800313 throw Error("Zone " + zoneName.toUri() + " is not found in the database");
Jiewen Tan870b29b2014-11-17 19:09:49 -0800314 }
315
316 //first output the zone name
317 os << "; Zone " << zoneName.toUri() << std::endl << std::endl;
318
319 //second output all rrsets
320 std::vector<Rrset> rrsets = m_dbMgr.findRrsets(zone);
321
322 //set width for different columns
323 size_t labelWidth = 0;
324 size_t ttlWidth = 0;
325 size_t typeWidth = 0;
326 for (Rrset& rrset : rrsets) {
327 Data data(rrset.getData());
328 Response re;
Yumin Xia6343c5b2016-10-20 15:45:50 -0700329 re.fromData(zoneName, data);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800330
331 if (rrset.getLabel().toUri().size() > labelWidth)
332 labelWidth = rrset.getLabel().toUri().size();
333
334 std::stringstream seconds;
335 seconds << rrset.getTtl().count();
336 if (seconds.str().size() > ttlWidth)
337 ttlWidth = seconds.str().size();
338
339 if (rrset.getType().toUri().size() > typeWidth)
340 typeWidth = rrset.getType().toUri().size();
341 }
342
343 //output
344 for (Rrset& rrset : rrsets) {
345 Data data(rrset.getData());
346 Response re;
Yumin Xia6343c5b2016-10-20 15:45:50 -0700347 re.fromData(zoneName, data);
Yumin Xiaa484ba72016-11-10 20:40:12 -0800348 int iteration = re.getContentType() == NDNS_BLOB || re.getContentType() == NDNS_AUTH ?
Jiewen Tan870b29b2014-11-17 19:09:49 -0800349 1 : re.getRrs().size();
350 const std::vector<Block> &rrs = re.getRrs();
351
Yumin Xiaa484ba72016-11-10 20:40:12 -0800352 if (re.getContentType() != NDNS_BLOB) {
Jiewen Tan870b29b2014-11-17 19:09:49 -0800353 os << "; rrset=" << rrset.getLabel().toUri()
354 << " type=" << rrset.getType().toUri()
355 << " version=" << rrset.getVersion().toUri()
356 << " signed-by=" << data.getSignature().getKeyLocator().getName().toUri()
357 << std::endl;
358 }
359
360 for (int i = 0; i < iteration; i++) {
361 os.setf(os.left);
362 os.width(labelWidth + 2);
363 os << rrset.getLabel().toUri();
364
365 os.width(ttlWidth + 2);
366 os << rrset.getTtl().count();
367
368 os.width(typeWidth + 2);
369 os << rrset.getType().toUri();
370
Yumin Xiaa484ba72016-11-10 20:40:12 -0800371 if (re.getContentType() != NDNS_BLOB) {
Jiewen Tan870b29b2014-11-17 19:09:49 -0800372 using namespace CryptoPP;
373 if (rrset.getType() == label::TXT_RR_TYPE) {
374 os.write(reinterpret_cast<const char*>(rrs[i].value()), rrs[i].value_size());
375 os << std::endl;
376 }
377 else if (rrset.getType() == label::NS_RR_TYPE) {
Yumin Xia5dd9f2b2016-10-26 20:48:05 -0700378 BOOST_ASSERT(iteration == 1);
Yumin Xiaa484ba72016-11-10 20:40:12 -0800379 if (re.getContentType() == NDNS_AUTH) {
Yumin Xia5dd9f2b2016-10-26 20:48:05 -0700380 const std::string authStr = "NDNS-Auth";
381 os << authStr;
382 } else {
383 Link link(rrset.getData());
384 const Link::DelegationSet& ds = link.getDelegations();
385 for (const auto& i: ds) {
386 std::string str = boost::lexical_cast<std::string>(i.first)
387 + "," + i.second.toUri() + ";";
388 os << str;
389 }
390 }
Jiewen Tan870b29b2014-11-17 19:09:49 -0800391 os << std::endl;
392 }
393 else {
394 StringSource ss(rrs[i].wire(), rrs[i].size(), true,
395 new Base64Encoder(new FileSink(os), true, 64));
396 }
397 }
398 }
399
Yumin Xiaa484ba72016-11-10 20:40:12 -0800400 if (re.getContentType() == NDNS_BLOB) {
Jiewen Tan870b29b2014-11-17 19:09:49 -0800401 os.width();
Yumin Xiaa484ba72016-11-10 20:40:12 -0800402 os << "; content-type=" << re.getContentType()
Jiewen Tan870b29b2014-11-17 19:09:49 -0800403 << " version=" << rrset.getVersion().toUri()
404 << " signed-by=" << data.getSignature().getKeyLocator().getName().toUri();
405 os << std::endl;
406
Yumin Xiaa484ba72016-11-10 20:40:12 -0800407 if (printRaw && re.getContentType() == NDNS_BLOB) {
Jiewen Tand1dd86d2015-03-20 10:26:28 -0700408 util::IndentedStream istream(os, "; ");
Jiewen Tan870b29b2014-11-17 19:09:49 -0800409
Jiewen Tand1dd86d2015-03-20 10:26:28 -0700410 if (re.getRrType() == label::CERT_RR_TYPE) {
411 shared_ptr<Data> data = re.toData();
412 IdentityCertificate cert(*data);
413 cert.printCertificate(istream);
414 }
415 else {
416 using namespace CryptoPP;
417 StringSource ss(re.getAppContent().wire(), re.getAppContent().size(), true,
418 new Base64Encoder(new FileSink(istream), true, 64));
Jiewen Tan870b29b2014-11-17 19:09:49 -0800419 }
Jiewen Tan870b29b2014-11-17 19:09:49 -0800420 }
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800421 os << std::endl;
Jiewen Tan870b29b2014-11-17 19:09:49 -0800422 }
423 else {
424 os << std::endl;
425 }
426 }
427}
428
429void
430ManagementTool::listAllZones(std::ostream& os) {
431 std::vector<Zone> zones = m_dbMgr.listZones();
432
433 size_t nameWidth = 0;
434 for (const Zone& zone : zones) {
435 if (zone.getName().toUri().size() > nameWidth)
436 nameWidth = zone.getName().toUri().size();
437 }
438
439 for (const Zone& zone : zones) {
440 os.setf(os.left);
441 os.width(nameWidth + 2);
442 os << zone.getName().toUri();
443
444 os << "; default-ttl=" << zone.getTtl().count();
445 os << " default-key=" << m_keyChain.getDefaultKeyNameForIdentity(zone.getName());
446 os << " default-certificate="
447 << m_keyChain.getDefaultCertificateNameForIdentity(zone.getName());
448 os << std::endl;
449 }
450}
451
452void
453ManagementTool::removeRrSet(const Name& zoneName, const Name& label, const name::Component& type)
454{
455 Zone zone(zoneName);
456 Rrset rrset(&zone);
457 rrset.setLabel(label);
458 rrset.setType(type);
459
460 if (!m_dbMgr.find(rrset)) {
461 return;
462 }
463 NDNS_LOG_INFO("Remove rrset with zone-id: " << zone.getId() << " label: " << label << " type: "
464 << type);
465 m_dbMgr.remove(rrset);
466}
467
468void
469ManagementTool::getRrSet(const Name& zoneName,
470 const Name& label,
471 const name::Component& type,
472 std::ostream& os)
473{
474 Zone zone(zoneName);
475 Rrset rrset(&zone);
476 rrset.setLabel(label);
477 rrset.setType(type);
478
479 if (!m_dbMgr.find(rrset)) {
480 os << "No record is found" << std::endl;
481 return;
482 }
483
484 using namespace CryptoPP;
485 StringSource ss(rrset.getData().wire(), rrset.getData().size(), true,
486 new Base64Encoder(new FileSink(os), true, 64));
487}
488
489void
490ManagementTool::addIdCert(Zone& zone, shared_ptr<IdentityCertificate> cert,
491 const time::seconds& ttl)
492{
493 Rrset rrset(&zone);
494 size_t size = zone.getName().size();
495 Name label = cert->getName().getSubName(size + 1, cert->getName().size() - size - 3);
496 rrset.setLabel(label);
497 rrset.setType(label::CERT_RR_TYPE);
498 rrset.setTtl(ttl);
499 rrset.setVersion(cert->getName().get(-1));
500 rrset.setData(cert->wireEncode());
501
502 if (m_dbMgr.find(rrset)) {
503 throw Error("ID-CERT with label=" + label.toUri() +
504 " is already presented in local NDNS databse");
505 }
506 NDNS_LOG_INFO("Add rrset with zone-id: " << zone.getId() << " label: " << label << " type: "
507 << label::CERT_RR_TYPE);
508 m_dbMgr.insert(rrset);
509}
510
511void
512ManagementTool::addZone(Zone& zone)
513{
514 if (m_dbMgr.find(zone)) {
515 throw Error("Zone with Name=" + zone.getName().toUri() +
516 " is already presented in local NDNS databse");
517 }
518 NDNS_LOG_INFO("Add zone with Name: " << zone.getName().toUri());
519 m_dbMgr.insert(zone);
520}
521
522void
523ManagementTool::removeZone(Zone& zone)
524{
525 if (!m_dbMgr.find(zone)) {
526 return;
527 }
528 NDNS_LOG_INFO("Remove zone with Name: " << zone.getName().toUri());
529 m_dbMgr.remove(zone);
530}
531
532bool
533ManagementTool::matchCertificate(const Name& certName, const Name& identity)
534{
535 if (!m_keyChain.doesCertificateExist(certName)) {
536 NDNS_LOG_WARN(certName.toUri() << " is not presented in KeyChain");
537 return false;
538 }
539
540 //check its public key information
541 shared_ptr<IdentityCertificate> cert = m_keyChain.getCertificate(certName);
542 Name keyName = cert->getPublicKeyName();
543
544 if (!identity.isPrefixOf(keyName) || identity.size()!=keyName.size()-1) {
545 NDNS_LOG_WARN(keyName.toUri() << " is not a key of " << identity.toUri());
546 return false;
547 }
548
Alexander Afanasyev74975e12016-08-01 14:24:03 -0700549 if (!m_keyChain.doesKeyExistInTpm(keyName, KeyClass::PRIVATE)) {
550 NDNS_LOG_WARN("Private key: " << keyName.toUri() << " is not present in KeyChain");
Jiewen Tan870b29b2014-11-17 19:09:49 -0800551 return false;
552 }
553
554 return true;
555}
556
Jiewen Tan8cd35ea2015-03-20 00:44:23 -0700557void
558ManagementTool::checkRrsetVersion(const Rrset& rrset)
559{
560 Rrset originalRrset(rrset);
561 if (m_dbMgr.find(originalRrset)) {
562 // update only if rrset has a newer version
563 if (originalRrset.getVersion() == rrset.getVersion()) {
564 throw Error("Duplicate: " + boost::lexical_cast<std::string>(originalRrset));
565 }
566 else if (originalRrset.getVersion() > rrset.getVersion()) {
567 throw Error("Newer version exists: " + boost::lexical_cast<std::string>(originalRrset));
568 }
569
570 m_dbMgr.remove(originalRrset);
571 }
572}
573
Jiewen Tan870b29b2014-11-17 19:09:49 -0800574} // namespace ndns
575} // namespace ndn