blob: 6dd2cb9e63bac2fde9d807818b3473356e9e6d99 [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>
37
38namespace ndn {
39namespace ndns {
40
Alexander Afanasyevc7c99002015-10-09 17:27:30 -070041NDNS_LOG_INIT("ManagementTool")
Jiewen Tan870b29b2014-11-17 19:09:49 -080042
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -080043ManagementTool::ManagementTool(const std::string& dbFile, KeyChain& keyChain)
44 : m_keyChain(keyChain)
45 , m_dbMgr(dbFile)
Jiewen Tan870b29b2014-11-17 19:09:49 -080046{
47}
48
49void
50ManagementTool::createZone(const Name &zoneName,
51 const Name& parentZoneName,
52 const time::seconds& cacheTtl,
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -080053 const time::seconds& certValidity,
Jiewen Tan870b29b2014-11-17 19:09:49 -080054 const Name& kskCertName,
55 const Name& dskCertName)
56{
57 bool isRoot = zoneName == ROOT_ZONE;
58
59 //check preconditions
60 Zone zone(zoneName, cacheTtl);
61 if (m_dbMgr.find(zone)) {
62 throw Error(zoneName.toUri() + " is already presented in the NDNS db");
63 }
64
65 if (!isRoot && parentZoneName.equals(zoneName)) {
66 throw Error("Parent zone name can not be the zone itself");
67 }
68
69 if (!isRoot && !parentZoneName.isPrefixOf(zoneName)) {
70 throw Error(parentZoneName.toUri() + " is not a prefix of " + zoneName.toUri());
71 }
72
Jiewen Tan01693fd2015-03-25 20:34:45 -070073 // if dsk is provided, there is no need to check ksk
Jiewen Tan870b29b2014-11-17 19:09:49 -080074 if (dskCertName != DEFAULT_CERT) {
75 if (!matchCertificate(dskCertName, zoneName)) {
76 throw Error("Cannot verify DSK certificate");
77 }
78 }
Jiewen Tan01693fd2015-03-25 20:34:45 -070079 else if (kskCertName != DEFAULT_CERT) {
80 if (!matchCertificate(kskCertName, zoneName)) {
81 throw Error("Cannot verify KSK certificate");
82 }
83 }
Jiewen Tan870b29b2014-11-17 19:09:49 -080084
85 if (kskCertName == DEFAULT_CERT && isRoot) {
86 throw Error("Cannot generate KSK for root zone");
87 }
88
89 //first generate KSK and DSK to the keyChain system, and add DSK as default
90 NDNS_LOG_INFO("Start generating KSK and DSK and their corresponding certificates");
Jiewen Tan870b29b2014-11-17 19:09:49 -080091 Name dskName;
92 shared_ptr<IdentityCertificate> dskCert;
93 if (dskCertName == DEFAULT_CERT) {
Jiewen Tan01693fd2015-03-25 20:34:45 -070094 // if no dsk provided, then generate a dsk either signed by ksk auto generated or user provided
95 time::system_clock::TimePoint notBefore = time::system_clock::now();
96 time::system_clock::TimePoint notAfter = notBefore + certValidity;
97 shared_ptr<IdentityCertificate> kskCert;
98
99 if (kskCertName == DEFAULT_CERT) {
100 //create KSK's certificate
101 Name kskName = m_keyChain.generateRsaKeyPair(zoneName, true);
102 std::vector<CertificateSubjectDescription> kskDesc;
103 kskCert = m_keyChain.prepareUnsignedIdentityCertificate(kskName, zoneName, notBefore,
104 notAfter, kskDesc, parentZoneName);
105 kskCert->setFreshnessPeriod(cacheTtl);
106
107 m_keyChain.selfSign(*kskCert);
108 m_keyChain.addCertificate(*kskCert);
109 NDNS_LOG_INFO("Generated KSK: " << kskCert->getName());
110 }
111 else {
112 kskCert = m_keyChain.getCertificate(kskCertName);
113 }
114
Jiewen Tan870b29b2014-11-17 19:09:49 -0800115 dskName = m_keyChain.generateRsaKeyPairAsDefault(zoneName, false);
116 //create DSK's certificate
117 std::vector<CertificateSubjectDescription> dskDesc;
118 dskCert = m_keyChain.prepareUnsignedIdentityCertificate(dskName, zoneName, notBefore, notAfter,
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800119 dskDesc, zoneName);
120 dskCert->setFreshnessPeriod(cacheTtl);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800121 m_keyChain.sign(*dskCert, kskCert->getName());
122 m_keyChain.addCertificateAsKeyDefault(*dskCert);
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800123 NDNS_LOG_INFO("Generated DSK: " << dskCert->getName());
Jiewen Tan870b29b2014-11-17 19:09:49 -0800124 }
125 else {
126 dskCert = m_keyChain.getCertificate(dskCertName);
127 dskName = dskCert->getPublicKeyName();
128 m_keyChain.setDefaultKeyNameForIdentity(dskName);
129 m_keyChain.setDefaultCertificateNameForKey(dskCert->getName());
130 }
131
132 //second add zone to the database
133 NDNS_LOG_INFO("Start adding new zone to data base");
134 addZone(zone);
135
136 //third create ID-cert
137 NDNS_LOG_INFO("Start creating DSK's ID-CERT");
138 addIdCert(zone, dskCert, cacheTtl);
139}
140
141void
142ManagementTool::deleteZone(const Name& zoneName)
143{
144 //check pre-conditions
145 Zone zone(zoneName);
146 if (!m_dbMgr.find(zone)) {
147 throw Error(zoneName.toUri() + " is not presented in the NDNS db");
148 }
149
150 //first remove all rrsets of this zone from local ndns database
151 std::vector<Rrset> rrsets = m_dbMgr.findRrsets(zone);
152 for (Rrset& rrset : rrsets) {
153 m_dbMgr.remove(rrset);
154 }
155
156 //second remove zone from local ndns database
157 removeZone(zone);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800158}
159
160void
161ManagementTool::exportCertificate(const Name& certName, const std::string& outFile)
162{
163 //search for the certificate, start from KeyChain then local NDNS database
164 shared_ptr<IdentityCertificate> cert;
165 if (m_keyChain.doesCertificateExist(certName)) {
166 cert = m_keyChain.getCertificate(certName);
167 }
168 else {
169 shared_ptr<Regex> regex = make_shared<Regex>("(<>*)<KEY>(<>+)<ID-CERT><>");
170 if (regex->match(certName) != true) {
171 throw Error("Certificate name is illegal");
172 }
173 Name zoneName = regex->expand("\\1");
174 Name label = regex->expand("\\2");
175
176 Zone zone(zoneName);
177 Rrset rrset(&zone);
178 rrset.setLabel(label);
179 rrset.setType(label::CERT_RR_TYPE);
180 if (m_dbMgr.find(rrset)) {
181 Data data(rrset.getData());
182 cert = make_shared<IdentityCertificate>(data);
183 }
184 else {
185 throw Error("Cannot find the cert: " + certName.toUri());
186 }
187 }
188
189 if (outFile == DEFAULT_IO) {
190 ndn::io::save(*cert, std::cout);
191 }
192 else {
193 ndn::io::save(*cert, outFile);
194 NDNS_LOG_INFO("save cert to file: " << outFile);
195 }
196}
197
198void
199ManagementTool::addRrSet(const Name& zoneName,
200 const Name& label,
201 const name::Component& type,
202 NdnsType ndnsType,
203 const uint64_t version,
204 const std::vector<std::string>& contents,
205 const Name& inputDskCertName,
206 const time::seconds& ttl)
207{
208 // check pre-condition
209 Zone zone(zoneName);
210 if (!m_dbMgr.find(zone)) {
211 throw Error(zoneName.toUri() + " is not presented in the NDNS db");
212 }
213
214 if (ndnsType == NDNS_UNKNOWN) {
215 throw Error("The ndns type is unknown");
216 }
217
218 if (type == label::CERT_RR_TYPE) {
219 throw Error("It cannot handle ID-CERT rrset type");
220 }
221
222 // check strange rr type and ndns type combination
223 if (type == label::NS_RR_TYPE && ndnsType == NDNS_RAW) {
224 throw Error("NS cannot be of the type NDNS_RAW");
225 }
226
227 if (type == label::TXT_RR_TYPE && ndnsType != NDNS_RESP) {
228 throw Error("TXT cannot be of the type NDNS_RAW or NDNS_AUTH");
229 }
230
231 if (ndnsType == NDNS_RAW && contents.size() != 1) {
232 throw Error("NDNS_RAW must contain a single content element");
233 }
234
235 Name dskName;
236 Name dskCertName = inputDskCertName;
237 if (dskCertName == DEFAULT_CERT) {
238 dskName = m_keyChain.getDefaultKeyNameForIdentity(zoneName);
239 dskCertName = m_keyChain.getDefaultCertificateNameForKey(dskName);
240 }
241 else {
242 if (!matchCertificate(dskCertName, zoneName)) {
243 throw Error("Cannot verify certificate");
244 }
245 }
246
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800247 time::seconds actualTtl = ttl;
248 if (ttl == DEFAULT_RR_TTL)
249 actualTtl = zone.getTtl();
250
Jiewen Tan870b29b2014-11-17 19:09:49 -0800251 // set rrset
252 Rrset rrset(&zone);
253 rrset.setLabel(label);
254 rrset.setType(type);
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800255 rrset.setTtl(actualTtl);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800256
257 // set response
258 Response re;
259 re.setZone(zoneName);
260 re.setQueryType(label::NDNS_ITERATIVE_QUERY);
261 re.setRrLabel(label);
262 re.setRrType(type);
263 re.setNdnsType(ndnsType);
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800264 re.setFreshnessPeriod(actualTtl);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800265
266 //set content according to ndns type
267 if (ndnsType == NDNS_RAW) {
Junxiao Shi767f35c2016-07-23 01:54:42 +0000268 Block tmp = makeBinaryBlock(ndn::tlv::Content, contents[0].c_str(), contents[0].length());
Jiewen Tan870b29b2014-11-17 19:09:49 -0800269 re.setAppContent(tmp);
270 }
271 else if (ndnsType != NDNS_AUTH) {
272 if (contents.empty()) {
273 re.addRr("");
274 }
275 else {
276 for (const auto& item : contents) {
277 re.addRr(item);
278 }
279 }
280 }
281
Jiewen Tan870b29b2014-11-17 19:09:49 -0800282 if (version != VERSION_USE_UNIX_TIMESTAMP) {
283 name::Component tmp = name::Component::fromVersion(version);
284 re.setVersion(tmp);
285 }
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800286 shared_ptr<Data> data = re.toData();
Jiewen Tan870b29b2014-11-17 19:09:49 -0800287 m_keyChain.sign(*data, dskCertName);
288
289 rrset.setVersion(re.getVersion());
290 rrset.setData(data->wireEncode());
291
Jiewen Tan8cd35ea2015-03-20 00:44:23 -0700292 checkRrsetVersion(rrset);
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800293 NDNS_LOG_INFO("Added " << rrset);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800294 m_dbMgr.insert(rrset);
295}
296
297void
298ManagementTool::addRrSet(const Name& zoneName,
299 const std::string& inFile,
300 const time::seconds& ttl,
Jiewen Tan74d745c2015-03-20 01:40:41 -0700301 const Name& inputDskCertName,
302 const ndn::io::IoEncoding encoding)
Jiewen Tan870b29b2014-11-17 19:09:49 -0800303{
304 //check precondition
305 Zone zone(zoneName);
306 if (!m_dbMgr.find(zone)) {
307 throw Error(zoneName.toUri() + " is not presented in the NDNS db");
308 }
309
310 Name dskName;
311 Name dskCertName = inputDskCertName;
312 if (dskCertName == DEFAULT_CERT) {
313 dskName = m_keyChain.getDefaultKeyNameForIdentity(zoneName);
314 dskCertName = m_keyChain.getDefaultCertificateNameForKey(dskName);
315 }
316 else {
317 if (!matchCertificate(dskCertName, zoneName)) {
318 throw Error("Cannot verify certificate");
319 }
320 }
321
322 if (inFile != DEFAULT_IO) {
323 boost::filesystem::path dir = boost::filesystem::path(inFile);
324 if (!boost::filesystem::exists(dir) || boost::filesystem::is_directory(dir)) {
325 throw Error("Data: " + inFile + " does not exist");
326 }
327 }
328
329 //first load the data
330 shared_ptr<Data> data;
331 if (inFile == DEFAULT_IO)
Jiewen Tan74d745c2015-03-20 01:40:41 -0700332 data = ndn::io::load<ndn::Data>(std::cin, encoding);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800333 else
Jiewen Tan74d745c2015-03-20 01:40:41 -0700334 data = ndn::io::load<ndn::Data>(inFile, encoding);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800335
Jiewen Tand2d21822015-03-19 15:37:03 -0700336 if (data == nullptr) {
Jiewen Tan74d745c2015-03-20 01:40:41 -0700337 throw Error("input does not contain a valid Data packet");
Jiewen Tand2d21822015-03-19 15:37:03 -0700338 }
339
Alexander Afanasyevfde570c2016-12-19 16:02:55 -0800340 // determine whether the data is a self-signed certificate
Jiewen Tan870b29b2014-11-17 19:09:49 -0800341 shared_ptr<Regex> regex1 = make_shared<Regex>("(<>*)<KEY>(<>+)<ID-CERT><>");
342 if (regex1->match(data->getName())) {
343 IdentityCertificate scert(*data);
344 Name keyName = scert.getPublicKeyName();
Alexander Afanasyevfde570c2016-12-19 16:02:55 -0800345 if (keyName.getPrefix(zoneName.size()) != zoneName) {
346 throw Error("the input key does not belong to the zone");
347 }
348
Jiewen Tan870b29b2014-11-17 19:09:49 -0800349 Name keyLocator = scert.getSignature().getKeyLocator().getName();
350
Alexander Afanasyevfde570c2016-12-19 16:02:55 -0800351 // if it is, extract the content and name from the data, and resign it using the dsk.
Jiewen Tan870b29b2014-11-17 19:09:49 -0800352 shared_ptr<Regex> regex2 = make_shared<Regex>("(<>*)<KEY>(<>+)<ID-CERT>");
353 BOOST_VERIFY(regex2->match(keyLocator) == true);
354 if (keyName == regex2->expand("\\1\\2")) {
Alexander Afanasyevfde570c2016-12-19 16:02:55 -0800355
356 Name canonicalName;
357 canonicalName
358 .append(zoneName)
359 .append("KEY")
360 .append(keyName.getSubName(zoneName.size(), keyName.size() - zoneName.size()))
361 .append("ID-CERT")
362 .append(data->getName().get(-1));
363
364 if (data->getName() != canonicalName) {
365 // name need to be adjusted
366 auto newData = make_shared<Data>();
367 newData->setName(canonicalName);
368 newData->setMetaInfo(data->getMetaInfo());
369 newData->setContent(data->getContent());
370 m_keyChain.sign(*newData);
371
372 data = newData;
Jiewen Tan870b29b2014-11-17 19:09:49 -0800373 }
Jiewen Tan870b29b2014-11-17 19:09:49 -0800374 }
375 }
376
377 // create response for the input data
378 Response re;
Yumin Xia6343c5b2016-10-20 15:45:50 -0700379 re.fromData(zoneName, *data);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800380 Name label = re.getRrLabel();
381 name::Component type = re.getRrType();
382
383 Rrset rrset(&zone);
384 rrset.setLabel(label);
385 rrset.setType(type);
386 if (ttl == DEFAULT_RR_TTL)
387 rrset.setTtl(zone.getTtl());
388 else
389 rrset.setTtl(ttl);
390 rrset.setVersion(re.getVersion());
391 rrset.setData(data->wireEncode());
392
Jiewen Tan8cd35ea2015-03-20 00:44:23 -0700393 checkRrsetVersion(rrset);
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800394 NDNS_LOG_INFO("Added " << rrset);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800395 m_dbMgr.insert(rrset);
396}
397
398void
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800399ManagementTool::listZone(const Name& zoneName, std::ostream& os, const bool printRaw)
400{
Jiewen Tan870b29b2014-11-17 19:09:49 -0800401 Zone zone(zoneName);
402 if (!m_dbMgr.find(zone)) {
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800403 throw Error("Zone " + zoneName.toUri() + " is not found in the database");
Jiewen Tan870b29b2014-11-17 19:09:49 -0800404 }
405
406 //first output the zone name
407 os << "; Zone " << zoneName.toUri() << std::endl << std::endl;
408
409 //second output all rrsets
410 std::vector<Rrset> rrsets = m_dbMgr.findRrsets(zone);
411
412 //set width for different columns
413 size_t labelWidth = 0;
414 size_t ttlWidth = 0;
415 size_t typeWidth = 0;
416 for (Rrset& rrset : rrsets) {
417 Data data(rrset.getData());
418 Response re;
Yumin Xia6343c5b2016-10-20 15:45:50 -0700419 re.fromData(zoneName, data);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800420
421 if (rrset.getLabel().toUri().size() > labelWidth)
422 labelWidth = rrset.getLabel().toUri().size();
423
424 std::stringstream seconds;
425 seconds << rrset.getTtl().count();
426 if (seconds.str().size() > ttlWidth)
427 ttlWidth = seconds.str().size();
428
429 if (rrset.getType().toUri().size() > typeWidth)
430 typeWidth = rrset.getType().toUri().size();
431 }
432
433 //output
434 for (Rrset& rrset : rrsets) {
435 Data data(rrset.getData());
436 Response re;
Yumin Xia6343c5b2016-10-20 15:45:50 -0700437 re.fromData(zoneName, data);
Jiewen Tan870b29b2014-11-17 19:09:49 -0800438 int iteration = re.getNdnsType() == NDNS_RAW || re.getNdnsType() == NDNS_AUTH ?
439 1 : re.getRrs().size();
440 const std::vector<Block> &rrs = re.getRrs();
441
442 if (re.getNdnsType() != NDNS_RAW && re.getNdnsType() != NDNS_AUTH) {
443 os << "; rrset=" << rrset.getLabel().toUri()
444 << " type=" << rrset.getType().toUri()
445 << " version=" << rrset.getVersion().toUri()
446 << " signed-by=" << data.getSignature().getKeyLocator().getName().toUri()
447 << std::endl;
448 }
449
450 for (int i = 0; i < iteration; i++) {
451 os.setf(os.left);
452 os.width(labelWidth + 2);
453 os << rrset.getLabel().toUri();
454
455 os.width(ttlWidth + 2);
456 os << rrset.getTtl().count();
457
458 os.width(typeWidth + 2);
459 os << rrset.getType().toUri();
460
461 if (re.getNdnsType() != NDNS_RAW && re.getNdnsType() != NDNS_AUTH) {
462 using namespace CryptoPP;
463 if (rrset.getType() == label::TXT_RR_TYPE) {
464 os.write(reinterpret_cast<const char*>(rrs[i].value()), rrs[i].value_size());
465 os << std::endl;
466 }
467 else if (rrset.getType() == label::NS_RR_TYPE) {
468 //TODO output the NS data once we have it
469 os << std::endl;
470 }
471 else {
472 StringSource ss(rrs[i].wire(), rrs[i].size(), true,
473 new Base64Encoder(new FileSink(os), true, 64));
474 }
475 }
476 }
477
478 if (re.getNdnsType() == NDNS_RAW || re.getNdnsType() == NDNS_AUTH) {
479 os.width();
480 os << "; content-type=" << re.getNdnsType()
481 << " version=" << rrset.getVersion().toUri()
482 << " signed-by=" << data.getSignature().getKeyLocator().getName().toUri();
483 os << std::endl;
484
485 if (printRaw && re.getNdnsType() == NDNS_RAW) {
Jiewen Tand1dd86d2015-03-20 10:26:28 -0700486 util::IndentedStream istream(os, "; ");
Jiewen Tan870b29b2014-11-17 19:09:49 -0800487
Jiewen Tand1dd86d2015-03-20 10:26:28 -0700488 if (re.getRrType() == label::CERT_RR_TYPE) {
489 shared_ptr<Data> data = re.toData();
490 IdentityCertificate cert(*data);
491 cert.printCertificate(istream);
492 }
493 else {
494 using namespace CryptoPP;
495 StringSource ss(re.getAppContent().wire(), re.getAppContent().size(), true,
496 new Base64Encoder(new FileSink(istream), true, 64));
Jiewen Tan870b29b2014-11-17 19:09:49 -0800497 }
Jiewen Tan870b29b2014-11-17 19:09:49 -0800498 }
Alexander Afanasyevd6b3bda2014-11-25 17:33:58 -0800499 os << std::endl;
Jiewen Tan870b29b2014-11-17 19:09:49 -0800500 }
501 else {
502 os << std::endl;
503 }
504 }
505}
506
507void
508ManagementTool::listAllZones(std::ostream& os) {
509 std::vector<Zone> zones = m_dbMgr.listZones();
510
511 size_t nameWidth = 0;
512 for (const Zone& zone : zones) {
513 if (zone.getName().toUri().size() > nameWidth)
514 nameWidth = zone.getName().toUri().size();
515 }
516
517 for (const Zone& zone : zones) {
518 os.setf(os.left);
519 os.width(nameWidth + 2);
520 os << zone.getName().toUri();
521
522 os << "; default-ttl=" << zone.getTtl().count();
523 os << " default-key=" << m_keyChain.getDefaultKeyNameForIdentity(zone.getName());
524 os << " default-certificate="
525 << m_keyChain.getDefaultCertificateNameForIdentity(zone.getName());
526 os << std::endl;
527 }
528}
529
530void
531ManagementTool::removeRrSet(const Name& zoneName, const Name& label, const name::Component& type)
532{
533 Zone zone(zoneName);
534 Rrset rrset(&zone);
535 rrset.setLabel(label);
536 rrset.setType(type);
537
538 if (!m_dbMgr.find(rrset)) {
539 return;
540 }
541 NDNS_LOG_INFO("Remove rrset with zone-id: " << zone.getId() << " label: " << label << " type: "
542 << type);
543 m_dbMgr.remove(rrset);
544}
545
546void
547ManagementTool::getRrSet(const Name& zoneName,
548 const Name& label,
549 const name::Component& type,
550 std::ostream& os)
551{
552 Zone zone(zoneName);
553 Rrset rrset(&zone);
554 rrset.setLabel(label);
555 rrset.setType(type);
556
557 if (!m_dbMgr.find(rrset)) {
558 os << "No record is found" << std::endl;
559 return;
560 }
561
562 using namespace CryptoPP;
563 StringSource ss(rrset.getData().wire(), rrset.getData().size(), true,
564 new Base64Encoder(new FileSink(os), true, 64));
565}
566
567void
568ManagementTool::addIdCert(Zone& zone, shared_ptr<IdentityCertificate> cert,
569 const time::seconds& ttl)
570{
571 Rrset rrset(&zone);
572 size_t size = zone.getName().size();
573 Name label = cert->getName().getSubName(size + 1, cert->getName().size() - size - 3);
574 rrset.setLabel(label);
575 rrset.setType(label::CERT_RR_TYPE);
576 rrset.setTtl(ttl);
577 rrset.setVersion(cert->getName().get(-1));
578 rrset.setData(cert->wireEncode());
579
580 if (m_dbMgr.find(rrset)) {
581 throw Error("ID-CERT with label=" + label.toUri() +
582 " is already presented in local NDNS databse");
583 }
584 NDNS_LOG_INFO("Add rrset with zone-id: " << zone.getId() << " label: " << label << " type: "
585 << label::CERT_RR_TYPE);
586 m_dbMgr.insert(rrset);
587}
588
589void
590ManagementTool::addZone(Zone& zone)
591{
592 if (m_dbMgr.find(zone)) {
593 throw Error("Zone with Name=" + zone.getName().toUri() +
594 " is already presented in local NDNS databse");
595 }
596 NDNS_LOG_INFO("Add zone with Name: " << zone.getName().toUri());
597 m_dbMgr.insert(zone);
598}
599
600void
601ManagementTool::removeZone(Zone& zone)
602{
603 if (!m_dbMgr.find(zone)) {
604 return;
605 }
606 NDNS_LOG_INFO("Remove zone with Name: " << zone.getName().toUri());
607 m_dbMgr.remove(zone);
608}
609
610bool
611ManagementTool::matchCertificate(const Name& certName, const Name& identity)
612{
613 if (!m_keyChain.doesCertificateExist(certName)) {
614 NDNS_LOG_WARN(certName.toUri() << " is not presented in KeyChain");
615 return false;
616 }
617
618 //check its public key information
619 shared_ptr<IdentityCertificate> cert = m_keyChain.getCertificate(certName);
620 Name keyName = cert->getPublicKeyName();
621
622 if (!identity.isPrefixOf(keyName) || identity.size()!=keyName.size()-1) {
623 NDNS_LOG_WARN(keyName.toUri() << " is not a key of " << identity.toUri());
624 return false;
625 }
626
Alexander Afanasyev74975e12016-08-01 14:24:03 -0700627 if (!m_keyChain.doesKeyExistInTpm(keyName, KeyClass::PRIVATE)) {
628 NDNS_LOG_WARN("Private key: " << keyName.toUri() << " is not present in KeyChain");
Jiewen Tan870b29b2014-11-17 19:09:49 -0800629 return false;
630 }
631
632 return true;
633}
634
Jiewen Tan8cd35ea2015-03-20 00:44:23 -0700635void
636ManagementTool::checkRrsetVersion(const Rrset& rrset)
637{
638 Rrset originalRrset(rrset);
639 if (m_dbMgr.find(originalRrset)) {
640 // update only if rrset has a newer version
641 if (originalRrset.getVersion() == rrset.getVersion()) {
642 throw Error("Duplicate: " + boost::lexical_cast<std::string>(originalRrset));
643 }
644 else if (originalRrset.getVersion() > rrset.getVersion()) {
645 throw Error("Newer version exists: " + boost::lexical_cast<std::string>(originalRrset));
646 }
647
648 m_dbMgr.remove(originalRrset);
649 }
650}
651
Jiewen Tan870b29b2014-11-17 19:09:49 -0800652} // namespace ndns
653} // namespace ndn