blob: 9edd131302e5d5fa56bc14884c4f27e16d7fbdb1 [file] [log] [blame]
Jiewen Tan870b29b2014-11-17 19:09:49 -08001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (c) 2014, Regents of the University of California.
4 *
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>
34#include <ndn-cxx/encoding/oid.hpp>
35#include <ndn-cxx/security/cryptopp.hpp>
36
37namespace ndn {
38namespace ndns {
39
40NDNS_LOG_INIT("ManagementTool");
41
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -080042ManagementTool::ManagementTool(const std::string& dbFile, KeyChain& keyChain)
43 : m_keyChain(keyChain)
44 , m_dbMgr(dbFile)
Jiewen Tan870b29b2014-11-17 19:09:49 -080045{
46}
47
48void
49ManagementTool::createZone(const Name &zoneName,
50 const Name& parentZoneName,
51 const time::seconds& cacheTtl,
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -080052 const time::seconds& certValidity,
Jiewen Tan870b29b2014-11-17 19:09:49 -080053 const Name& kskCertName,
54 const Name& dskCertName)
55{
56 bool isRoot = zoneName == ROOT_ZONE;
57
58 //check preconditions
59 Zone zone(zoneName, cacheTtl);
60 if (m_dbMgr.find(zone)) {
61 throw Error(zoneName.toUri() + " is already presented in the NDNS db");
62 }
63
64 if (!isRoot && parentZoneName.equals(zoneName)) {
65 throw Error("Parent zone name can not be the zone itself");
66 }
67
68 if (!isRoot && !parentZoneName.isPrefixOf(zoneName)) {
69 throw Error(parentZoneName.toUri() + " is not a prefix of " + zoneName.toUri());
70 }
71
72 if (kskCertName != DEFAULT_CERT) {
73 if (!matchCertificate(kskCertName, zoneName)) {
74 throw Error("Cannot verify KSK certificate");
75 }
76 }
77
78 if (dskCertName != DEFAULT_CERT) {
79 if (!matchCertificate(dskCertName, zoneName)) {
80 throw Error("Cannot verify DSK certificate");
81 }
82 }
83
84 if (kskCertName == DEFAULT_CERT && isRoot) {
85 throw Error("Cannot generate KSK for root zone");
86 }
87
88 //first generate KSK and DSK to the keyChain system, and add DSK as default
89 NDNS_LOG_INFO("Start generating KSK and DSK and their corresponding certificates");
90 time::system_clock::TimePoint notBefore = time::system_clock::now();
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -080091 time::system_clock::TimePoint notAfter = notBefore + certValidity;
Jiewen Tan870b29b2014-11-17 19:09:49 -080092 shared_ptr<IdentityCertificate> kskCert;
93
94 if (kskCertName == DEFAULT_CERT) {
95 //create KSK's certificate
96 Name kskName = m_keyChain.generateRsaKeyPair(zoneName, true);
97 std::vector<CertificateSubjectDescription> kskDesc;
98 kskCert = m_keyChain.prepareUnsignedIdentityCertificate(kskName, zoneName, notBefore, notAfter,
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -080099 kskDesc, parentZoneName);
100 kskCert->setFreshnessPeriod(cacheTtl);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800101
102 m_keyChain.selfSign(*kskCert);
103 m_keyChain.addCertificate(*kskCert);
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800104 NDNS_LOG_INFO("Generated KSK: " << kskCert->getName());
Jiewen Tan870b29b2014-11-17 19:09:49 -0800105 }
106 else {
107 kskCert = m_keyChain.getCertificate(kskCertName);
108 }
109
110 Name dskName;
111 shared_ptr<IdentityCertificate> dskCert;
112 if (dskCertName == DEFAULT_CERT) {
113 dskName = m_keyChain.generateRsaKeyPairAsDefault(zoneName, false);
114 //create DSK's certificate
115 std::vector<CertificateSubjectDescription> dskDesc;
116 dskCert = m_keyChain.prepareUnsignedIdentityCertificate(dskName, zoneName, notBefore, notAfter,
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800117 dskDesc, zoneName);
118 dskCert->setFreshnessPeriod(cacheTtl);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800119 m_keyChain.sign(*dskCert, kskCert->getName());
120 m_keyChain.addCertificateAsKeyDefault(*dskCert);
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800121 NDNS_LOG_INFO("Generated DSK: " << dskCert->getName());
Jiewen Tan870b29b2014-11-17 19:09:49 -0800122 }
123 else {
124 dskCert = m_keyChain.getCertificate(dskCertName);
125 dskName = dskCert->getPublicKeyName();
126 m_keyChain.setDefaultKeyNameForIdentity(dskName);
127 m_keyChain.setDefaultCertificateNameForKey(dskCert->getName());
128 }
129
130 //second add zone to the database
131 NDNS_LOG_INFO("Start adding new zone to data base");
132 addZone(zone);
133
134 //third create ID-cert
135 NDNS_LOG_INFO("Start creating DSK's ID-CERT");
136 addIdCert(zone, dskCert, cacheTtl);
137}
138
139void
140ManagementTool::deleteZone(const Name& zoneName)
141{
142 //check pre-conditions
143 Zone zone(zoneName);
144 if (!m_dbMgr.find(zone)) {
145 throw Error(zoneName.toUri() + " is not presented in the NDNS db");
146 }
147
148 //first remove all rrsets of this zone from local ndns database
149 std::vector<Rrset> rrsets = m_dbMgr.findRrsets(zone);
150 for (Rrset& rrset : rrsets) {
151 m_dbMgr.remove(rrset);
152 }
153
154 //second remove zone from local ndns database
155 removeZone(zone);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800156}
157
158void
159ManagementTool::exportCertificate(const Name& certName, const std::string& outFile)
160{
161 //search for the certificate, start from KeyChain then local NDNS database
162 shared_ptr<IdentityCertificate> cert;
163 if (m_keyChain.doesCertificateExist(certName)) {
164 cert = m_keyChain.getCertificate(certName);
165 }
166 else {
167 shared_ptr<Regex> regex = make_shared<Regex>("(<>*)<KEY>(<>+)<ID-CERT><>");
168 if (regex->match(certName) != true) {
169 throw Error("Certificate name is illegal");
170 }
171 Name zoneName = regex->expand("\\1");
172 Name label = regex->expand("\\2");
173
174 Zone zone(zoneName);
175 Rrset rrset(&zone);
176 rrset.setLabel(label);
177 rrset.setType(label::CERT_RR_TYPE);
178 if (m_dbMgr.find(rrset)) {
179 Data data(rrset.getData());
180 cert = make_shared<IdentityCertificate>(data);
181 }
182 else {
183 throw Error("Cannot find the cert: " + certName.toUri());
184 }
185 }
186
187 if (outFile == DEFAULT_IO) {
188 ndn::io::save(*cert, std::cout);
189 }
190 else {
191 ndn::io::save(*cert, outFile);
192 NDNS_LOG_INFO("save cert to file: " << outFile);
193 }
194}
195
196void
197ManagementTool::addRrSet(const Name& zoneName,
198 const Name& label,
199 const name::Component& type,
200 NdnsType ndnsType,
201 const uint64_t version,
202 const std::vector<std::string>& contents,
203 const Name& inputDskCertName,
204 const time::seconds& ttl)
205{
206 // check pre-condition
207 Zone zone(zoneName);
208 if (!m_dbMgr.find(zone)) {
209 throw Error(zoneName.toUri() + " is not presented in the NDNS db");
210 }
211
212 if (ndnsType == NDNS_UNKNOWN) {
213 throw Error("The ndns type is unknown");
214 }
215
216 if (type == label::CERT_RR_TYPE) {
217 throw Error("It cannot handle ID-CERT rrset type");
218 }
219
220 // check strange rr type and ndns type combination
221 if (type == label::NS_RR_TYPE && ndnsType == NDNS_RAW) {
222 throw Error("NS cannot be of the type NDNS_RAW");
223 }
224
225 if (type == label::TXT_RR_TYPE && ndnsType != NDNS_RESP) {
226 throw Error("TXT cannot be of the type NDNS_RAW or NDNS_AUTH");
227 }
228
229 if (ndnsType == NDNS_RAW && contents.size() != 1) {
230 throw Error("NDNS_RAW must contain a single content element");
231 }
232
233 Name dskName;
234 Name dskCertName = inputDskCertName;
235 if (dskCertName == DEFAULT_CERT) {
236 dskName = m_keyChain.getDefaultKeyNameForIdentity(zoneName);
237 dskCertName = m_keyChain.getDefaultCertificateNameForKey(dskName);
238 }
239 else {
240 if (!matchCertificate(dskCertName, zoneName)) {
241 throw Error("Cannot verify certificate");
242 }
243 }
244
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800245 time::seconds actualTtl = ttl;
246 if (ttl == DEFAULT_RR_TTL)
247 actualTtl = zone.getTtl();
248
Jiewen Tan870b29b2014-11-17 19:09:49 -0800249 // set rrset
250 Rrset rrset(&zone);
251 rrset.setLabel(label);
252 rrset.setType(type);
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800253 rrset.setTtl(actualTtl);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800254
255 // set response
256 Response re;
257 re.setZone(zoneName);
258 re.setQueryType(label::NDNS_ITERATIVE_QUERY);
259 re.setRrLabel(label);
260 re.setRrType(type);
261 re.setNdnsType(ndnsType);
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800262 re.setFreshnessPeriod(actualTtl);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800263
264 //set content according to ndns type
265 if (ndnsType == NDNS_RAW) {
266 Block tmp = ndn::dataBlock(ndn::tlv::Content, contents[0].c_str(), contents[0].length());
267 re.setAppContent(tmp);
268 }
269 else if (ndnsType != NDNS_AUTH) {
270 if (contents.empty()) {
271 re.addRr("");
272 }
273 else {
274 for (const auto& item : contents) {
275 re.addRr(item);
276 }
277 }
278 }
279
Jiewen Tan870b29b2014-11-17 19:09:49 -0800280 if (version != VERSION_USE_UNIX_TIMESTAMP) {
281 name::Component tmp = name::Component::fromVersion(version);
282 re.setVersion(tmp);
283 }
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800284 shared_ptr<Data> data = re.toData();
Jiewen Tan870b29b2014-11-17 19:09:49 -0800285 m_keyChain.sign(*data, dskCertName);
286
287 rrset.setVersion(re.getVersion());
288 rrset.setData(data->wireEncode());
289
Jiewen Tan8cd35ea2015-03-20 00:44:23 -0700290 checkRrsetVersion(rrset);
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800291 NDNS_LOG_INFO("Added " << rrset);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800292 m_dbMgr.insert(rrset);
293}
294
295void
296ManagementTool::addRrSet(const Name& zoneName,
297 const std::string& inFile,
298 const time::seconds& ttl,
Jiewen Tan74d745c2015-03-20 01:40:41 -0700299 const Name& inputDskCertName,
300 const ndn::io::IoEncoding encoding)
Jiewen Tan870b29b2014-11-17 19:09:49 -0800301{
302 //check precondition
303 Zone zone(zoneName);
304 if (!m_dbMgr.find(zone)) {
305 throw Error(zoneName.toUri() + " is not presented in the NDNS db");
306 }
307
308 Name dskName;
309 Name dskCertName = inputDskCertName;
310 if (dskCertName == DEFAULT_CERT) {
311 dskName = m_keyChain.getDefaultKeyNameForIdentity(zoneName);
312 dskCertName = m_keyChain.getDefaultCertificateNameForKey(dskName);
313 }
314 else {
315 if (!matchCertificate(dskCertName, zoneName)) {
316 throw Error("Cannot verify certificate");
317 }
318 }
319
320 if (inFile != DEFAULT_IO) {
321 boost::filesystem::path dir = boost::filesystem::path(inFile);
322 if (!boost::filesystem::exists(dir) || boost::filesystem::is_directory(dir)) {
323 throw Error("Data: " + inFile + " does not exist");
324 }
325 }
326
327 //first load the data
328 shared_ptr<Data> data;
329 if (inFile == DEFAULT_IO)
Jiewen Tan74d745c2015-03-20 01:40:41 -0700330 data = ndn::io::load<ndn::Data>(std::cin, encoding);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800331 else
Jiewen Tan74d745c2015-03-20 01:40:41 -0700332 data = ndn::io::load<ndn::Data>(inFile, encoding);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800333
Jiewen Tand2d21822015-03-19 15:37:03 -0700334 if (data == nullptr) {
Jiewen Tan74d745c2015-03-20 01:40:41 -0700335 throw Error("input does not contain a valid Data packet");
Jiewen Tand2d21822015-03-19 15:37:03 -0700336 }
337
Jiewen Tan870b29b2014-11-17 19:09:49 -0800338 //determine whether the data is a self-signed certificate
339 shared_ptr<Regex> regex1 = make_shared<Regex>("(<>*)<KEY>(<>+)<ID-CERT><>");
340 if (regex1->match(data->getName())) {
341 IdentityCertificate scert(*data);
342 Name keyName = scert.getPublicKeyName();
343 Name keyLocator = scert.getSignature().getKeyLocator().getName();
344
345 //if it is, extract the content and name from the data, and resign it using the dsk.
346 shared_ptr<Regex> regex2 = make_shared<Regex>("(<>*)<KEY>(<>+)<ID-CERT>");
347 BOOST_VERIFY(regex2->match(keyLocator) == true);
348 if (keyName == regex2->expand("\\1\\2")) {
349 shared_ptr<Data> pre = data;
350 Name name = pre->getName();
351 //check whether the name is legal or not. if not converting it to a legal name
352 if (zoneName != regex1->expand("\\1")) {
353 Name comp1 = regex1->expand("\\1").getSubName(zoneName.size());
354 Name comp2 = regex1->expand("\\2");
355 name = zoneName;
356 name.append("KEY");
357 name.append(comp1);
358 name.append(comp2);
359 name.append("ID-CERT");
360 name.append(pre->getName().get(-1));
361 }
362
363 data = make_shared<Data>();
364 data->setName(name);
365 data->setContent(pre->getContent());
366
367 m_keyChain.sign(*data, dskCertName);
368 }
369 }
370
371 // create response for the input data
372 Response re;
373 Name hint;
374 re.fromData(hint, zoneName, *data);
375 Name label = re.getRrLabel();
376 name::Component type = re.getRrType();
377
378 Rrset rrset(&zone);
379 rrset.setLabel(label);
380 rrset.setType(type);
381 if (ttl == DEFAULT_RR_TTL)
382 rrset.setTtl(zone.getTtl());
383 else
384 rrset.setTtl(ttl);
385 rrset.setVersion(re.getVersion());
386 rrset.setData(data->wireEncode());
387
Jiewen Tan8cd35ea2015-03-20 00:44:23 -0700388 checkRrsetVersion(rrset);
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800389 NDNS_LOG_INFO("Added " << rrset);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800390 m_dbMgr.insert(rrset);
391}
392
393void
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800394ManagementTool::listZone(const Name& zoneName, std::ostream& os, const bool printRaw)
395{
Jiewen Tan870b29b2014-11-17 19:09:49 -0800396 Zone zone(zoneName);
397 if (!m_dbMgr.find(zone)) {
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800398 throw Error("Zone " + zoneName.toUri() + " is not found in the database");
Jiewen Tan870b29b2014-11-17 19:09:49 -0800399 }
400
401 //first output the zone name
402 os << "; Zone " << zoneName.toUri() << std::endl << std::endl;
403
404 //second output all rrsets
405 std::vector<Rrset> rrsets = m_dbMgr.findRrsets(zone);
406
407 //set width for different columns
408 size_t labelWidth = 0;
409 size_t ttlWidth = 0;
410 size_t typeWidth = 0;
411 for (Rrset& rrset : rrsets) {
412 Data data(rrset.getData());
413 Response re;
414 Name hint;
415 re.fromData(hint, zoneName, data);
416
417 if (rrset.getLabel().toUri().size() > labelWidth)
418 labelWidth = rrset.getLabel().toUri().size();
419
420 std::stringstream seconds;
421 seconds << rrset.getTtl().count();
422 if (seconds.str().size() > ttlWidth)
423 ttlWidth = seconds.str().size();
424
425 if (rrset.getType().toUri().size() > typeWidth)
426 typeWidth = rrset.getType().toUri().size();
427 }
428
429 //output
430 for (Rrset& rrset : rrsets) {
431 Data data(rrset.getData());
432 Response re;
433 Name hint;
434 re.fromData(hint, zoneName, data);
435 int iteration = re.getNdnsType() == NDNS_RAW || re.getNdnsType() == NDNS_AUTH ?
436 1 : re.getRrs().size();
437 const std::vector<Block> &rrs = re.getRrs();
438
439 if (re.getNdnsType() != NDNS_RAW && re.getNdnsType() != NDNS_AUTH) {
440 os << "; rrset=" << rrset.getLabel().toUri()
441 << " type=" << rrset.getType().toUri()
442 << " version=" << rrset.getVersion().toUri()
443 << " signed-by=" << data.getSignature().getKeyLocator().getName().toUri()
444 << std::endl;
445 }
446
447 for (int i = 0; i < iteration; i++) {
448 os.setf(os.left);
449 os.width(labelWidth + 2);
450 os << rrset.getLabel().toUri();
451
452 os.width(ttlWidth + 2);
453 os << rrset.getTtl().count();
454
455 os.width(typeWidth + 2);
456 os << rrset.getType().toUri();
457
458 if (re.getNdnsType() != NDNS_RAW && re.getNdnsType() != NDNS_AUTH) {
459 using namespace CryptoPP;
460 if (rrset.getType() == label::TXT_RR_TYPE) {
461 os.write(reinterpret_cast<const char*>(rrs[i].value()), rrs[i].value_size());
462 os << std::endl;
463 }
464 else if (rrset.getType() == label::NS_RR_TYPE) {
465 //TODO output the NS data once we have it
466 os << std::endl;
467 }
468 else {
469 StringSource ss(rrs[i].wire(), rrs[i].size(), true,
470 new Base64Encoder(new FileSink(os), true, 64));
471 }
472 }
473 }
474
475 if (re.getNdnsType() == NDNS_RAW || re.getNdnsType() == NDNS_AUTH) {
476 os.width();
477 os << "; content-type=" << re.getNdnsType()
478 << " version=" << rrset.getVersion().toUri()
479 << " signed-by=" << data.getSignature().getKeyLocator().getName().toUri();
480 os << std::endl;
481
482 if (printRaw && re.getNdnsType() == NDNS_RAW) {
483 using namespace CryptoPP;
484 std::stringstream sstream;
485 StringSource ss(re.getAppContent().wire(), re.getAppContent().size(), true,
486 new Base64Encoder(new FileSink(sstream), true, 64));
487
488 std::string content = sstream.str();
489 std::string delimiter = "\n";
490 size_t pos = 0;
491 std::string token;
492 while ((pos = content.find(delimiter)) != std::string::npos) {
493 token = content.substr(0, pos);
494 os << "; " << token << std::endl;
495 content.erase(0, pos + delimiter.length());
496 }
Jiewen Tan870b29b2014-11-17 19:09:49 -0800497 }
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800498 os << std::endl;
Jiewen Tan870b29b2014-11-17 19:09:49 -0800499 }
500 else {
501 os << std::endl;
502 }
503 }
504}
505
506void
507ManagementTool::listAllZones(std::ostream& os) {
508 std::vector<Zone> zones = m_dbMgr.listZones();
509
510 size_t nameWidth = 0;
511 for (const Zone& zone : zones) {
512 if (zone.getName().toUri().size() > nameWidth)
513 nameWidth = zone.getName().toUri().size();
514 }
515
516 for (const Zone& zone : zones) {
517 os.setf(os.left);
518 os.width(nameWidth + 2);
519 os << zone.getName().toUri();
520
521 os << "; default-ttl=" << zone.getTtl().count();
522 os << " default-key=" << m_keyChain.getDefaultKeyNameForIdentity(zone.getName());
523 os << " default-certificate="
524 << m_keyChain.getDefaultCertificateNameForIdentity(zone.getName());
525 os << std::endl;
526 }
527}
528
529void
530ManagementTool::removeRrSet(const Name& zoneName, const Name& label, const name::Component& type)
531{
532 Zone zone(zoneName);
533 Rrset rrset(&zone);
534 rrset.setLabel(label);
535 rrset.setType(type);
536
537 if (!m_dbMgr.find(rrset)) {
538 return;
539 }
540 NDNS_LOG_INFO("Remove rrset with zone-id: " << zone.getId() << " label: " << label << " type: "
541 << type);
542 m_dbMgr.remove(rrset);
543}
544
545void
546ManagementTool::getRrSet(const Name& zoneName,
547 const Name& label,
548 const name::Component& type,
549 std::ostream& os)
550{
551 Zone zone(zoneName);
552 Rrset rrset(&zone);
553 rrset.setLabel(label);
554 rrset.setType(type);
555
556 if (!m_dbMgr.find(rrset)) {
557 os << "No record is found" << std::endl;
558 return;
559 }
560
561 using namespace CryptoPP;
562 StringSource ss(rrset.getData().wire(), rrset.getData().size(), true,
563 new Base64Encoder(new FileSink(os), true, 64));
564}
565
566void
567ManagementTool::addIdCert(Zone& zone, shared_ptr<IdentityCertificate> cert,
568 const time::seconds& ttl)
569{
570 Rrset rrset(&zone);
571 size_t size = zone.getName().size();
572 Name label = cert->getName().getSubName(size + 1, cert->getName().size() - size - 3);
573 rrset.setLabel(label);
574 rrset.setType(label::CERT_RR_TYPE);
575 rrset.setTtl(ttl);
576 rrset.setVersion(cert->getName().get(-1));
577 rrset.setData(cert->wireEncode());
578
579 if (m_dbMgr.find(rrset)) {
580 throw Error("ID-CERT with label=" + label.toUri() +
581 " is already presented in local NDNS databse");
582 }
583 NDNS_LOG_INFO("Add rrset with zone-id: " << zone.getId() << " label: " << label << " type: "
584 << label::CERT_RR_TYPE);
585 m_dbMgr.insert(rrset);
586}
587
588void
589ManagementTool::addZone(Zone& zone)
590{
591 if (m_dbMgr.find(zone)) {
592 throw Error("Zone with Name=" + zone.getName().toUri() +
593 " is already presented in local NDNS databse");
594 }
595 NDNS_LOG_INFO("Add zone with Name: " << zone.getName().toUri());
596 m_dbMgr.insert(zone);
597}
598
599void
600ManagementTool::removeZone(Zone& zone)
601{
602 if (!m_dbMgr.find(zone)) {
603 return;
604 }
605 NDNS_LOG_INFO("Remove zone with Name: " << zone.getName().toUri());
606 m_dbMgr.remove(zone);
607}
608
609bool
610ManagementTool::matchCertificate(const Name& certName, const Name& identity)
611{
612 if (!m_keyChain.doesCertificateExist(certName)) {
613 NDNS_LOG_WARN(certName.toUri() << " is not presented in KeyChain");
614 return false;
615 }
616
617 //check its public key information
618 shared_ptr<IdentityCertificate> cert = m_keyChain.getCertificate(certName);
619 Name keyName = cert->getPublicKeyName();
620
621 if (!identity.isPrefixOf(keyName) || identity.size()!=keyName.size()-1) {
622 NDNS_LOG_WARN(keyName.toUri() << " is not a key of " << identity.toUri());
623 return false;
624 }
625
626 if (!m_keyChain.doesKeyExistInTpm(keyName, KEY_CLASS_PRIVATE)) {
627 NDNS_LOG_WARN("Private key: " << keyName.toUri() << " is not presented in KeyChain");
628 return false;
629 }
630
631 return true;
632}
633
Jiewen Tan8cd35ea2015-03-20 00:44:23 -0700634void
635ManagementTool::checkRrsetVersion(const Rrset& rrset)
636{
637 Rrset originalRrset(rrset);
638 if (m_dbMgr.find(originalRrset)) {
639 // update only if rrset has a newer version
640 if (originalRrset.getVersion() == rrset.getVersion()) {
641 throw Error("Duplicate: " + boost::lexical_cast<std::string>(originalRrset));
642 }
643 else if (originalRrset.getVersion() > rrset.getVersion()) {
644 throw Error("Newer version exists: " + boost::lexical_cast<std::string>(originalRrset));
645 }
646
647 m_dbMgr.remove(originalRrset);
648 }
649}
650
Jiewen Tan870b29b2014-11-17 19:09:49 -0800651} // namespace ndns
652} // namespace ndn