]>
Commit | Line | Data |
---|---|---|
1d211b1b | 1 | #include "dnsseckeeper.hh" |
d3151289 | 2 | #include "dnssecinfra.hh" |
1d211b1b | 3 | #include "statbag.hh" |
01fde57c | 4 | #include "base32.hh" |
1d211b1b BH |
5 | #include <boost/foreach.hpp> |
6 | #include <boost/program_options.hpp> | |
20002664 BH |
7 | #include "dnsbackend.hh" |
8 | #include "ueberbackend.hh" | |
9 | #include "arguments.hh" | |
10 | #include "packetcache.hh" | |
11 | ||
12 | StatBag S; | |
13 | PacketCache PC; | |
1d211b1b BH |
14 | |
15 | using namespace boost; | |
16 | namespace po = boost::program_options; | |
17 | po::variables_map g_vm; | |
18 | ||
39a8b5c0 | 19 | string s_programname="pdns"; |
20002664 BH |
20 | |
21 | ArgvMap &arg() | |
22 | { | |
23 | static ArgvMap arg; | |
24 | return arg; | |
25 | } | |
26 | ||
1d211b1b BH |
27 | string humanTime(time_t t) |
28 | { | |
29 | char ret[256]; | |
30 | struct tm tm; | |
31 | localtime_r(&t, &tm); | |
32 | strftime(ret, sizeof(ret)-1, "%c", &tm); // %h:%M %Y-%m-%d | |
33 | return ret; | |
34 | } | |
35 | ||
7d9dcde0 | 36 | void loadMainConfig(const std::string& configdir) |
20002664 | 37 | { |
7d9dcde0 | 38 | ::arg().set("config-dir","Location of configuration directory (pdns.conf)")=configdir; |
20002664 BH |
39 | |
40 | ::arg().set("launch","Which backends to launch"); | |
6dfa0aa0 | 41 | ::arg().set("dnssec","if we should do dnssec")="true"; |
4f6cf113 | 42 | ::arg().set("config-name","Name of this virtual configuration - will rename the binary image")=g_vm["config-name"].as<string>(); |
20002664 BH |
43 | ::arg().setCmd("help","Provide a helpful message"); |
44 | //::arg().laxParse(argc,argv); | |
45 | ||
46 | if(::arg().mustDo("help")) { | |
47 | cerr<<"syntax:"<<endl<<endl; | |
48 | cerr<<::arg().helpstring(::arg()["help"])<<endl; | |
49 | exit(99); | |
50 | } | |
51 | ||
52 | if(::arg()["config-name"]!="") | |
53 | s_programname+="-"+::arg()["config-name"]; | |
54 | ||
55 | string configname=::arg()["config-dir"]+"/"+s_programname+".conf"; | |
56 | cleanSlashes(configname); | |
57 | ||
58 | cerr<<"configname: '"<<configname<<"'\n"; | |
59 | ||
60 | ::arg().laxFile(configname.c_str()); | |
a7e0acd8 | 61 | ::arg().set("module-dir","Default directory for modules")=LIBDIR; |
20002664 BH |
62 | BackendMakers().launch(::arg()["launch"]); // vrooooom! |
63 | ::arg().laxFile(configname.c_str()); | |
9abd98d3 | 64 | //cerr<<"Backend: "<<::arg()["launch"]<<", '" << ::arg()["gmysql-dbname"] <<"'" <<endl; |
20002664 BH |
65 | |
66 | S.declare("qsize-q","Number of questions waiting for database attention"); | |
67 | ||
68 | S.declare("deferred-cache-inserts","Amount of cache inserts that were deferred because of maintenance"); | |
69 | S.declare("deferred-cache-lookup","Amount of cache lookups that were deferred because of maintenance"); | |
70 | ||
71 | S.declare("query-cache-hit","Number of hits on the query cache"); | |
72 | S.declare("query-cache-miss","Number of misses on the query cache"); | |
73 | ::arg().set("max-cache-entries", "Maximum number of cache entries")="1000000"; | |
74 | ::arg().set("recursor","If recursion is desired, IP address of a recursing nameserver")="no"; | |
75 | ::arg().set("recursive-cache-ttl","Seconds to store packets in the PacketCache")="10"; | |
76 | ::arg().set("cache-ttl","Seconds to store packets in the PacketCache")="20"; | |
77 | ::arg().set("negquery-cache-ttl","Seconds to store packets in the PacketCache")="60"; | |
78 | ::arg().set("query-cache-ttl","Seconds to store packets in the PacketCache")="20"; | |
79 | ::arg().set("soa-refresh-default","Default SOA refresh")="10800"; | |
80 | ::arg().set("soa-retry-default","Default SOA retry")="3600"; | |
81 | ::arg().set("soa-expire-default","Default SOA expire")="604800"; | |
82 | ::arg().setSwitch("query-logging","Hint backends that queries should be logged")="no"; | |
83 | ::arg().set("soa-minimum-ttl","Default SOA mininum ttl")="3600"; | |
a7e0acd8 | 84 | |
20002664 BH |
85 | UeberBackend::go(); |
86 | } | |
87 | ||
f28f2324 | 88 | void rectifyZone(DNSSECKeeper& dk, const std::string& zone) |
20002664 | 89 | { |
20002664 BH |
90 | UeberBackend* B = new UeberBackend("default"); |
91 | SOAData sd; | |
81b39e4b BH |
92 | |
93 | if(!B->getSOA(zone, sd)) { | |
f28f2324 | 94 | cerr<<"No SOA known for '"<<zone<<"', is such a zone in the database?"<<endl; |
01fde57c | 95 | return; |
20002664 | 96 | } |
81b39e4b | 97 | sd.db->list(zone, sd.domain_id); |
20002664 | 98 | DNSResourceRecord rr; |
81b39e4b | 99 | |
f28f2324 | 100 | set<string> qnames, nsset; |
20002664 BH |
101 | |
102 | while(sd.db->get(rr)) { | |
81b39e4b | 103 | qnames.insert(rr.qname); |
f28f2324 BH |
104 | if(rr.qtype.getCode() == QType::NS && !pdns_iequals(rr.qname, zone)) |
105 | nsset.insert(rr.qname); | |
81b39e4b | 106 | } |
9abd98d3 | 107 | |
c3c89361 | 108 | NSEC3PARAMRecordContent ns3pr; |
f28f2324 BH |
109 | bool narrow; |
110 | dk.getNSEC3PARAM(zone, &ns3pr, &narrow); | |
c3c89361 | 111 | string hashed; |
9abd98d3 BH |
112 | if(ns3pr.d_salt.empty()) |
113 | cerr<<"Adding NSEC ordering information"<<endl; | |
f28f2324 BH |
114 | else if(!narrow) |
115 | cerr<<"Adding NSEC3 hashed ordering information for '"<<zone<<"'"<<endl; | |
116 | else | |
117 | cerr<<"Erasing NSEC3 ordering since we are narrow, only setting 'auth' fields"<<endl; | |
9abd98d3 | 118 | |
81b39e4b BH |
119 | BOOST_FOREACH(const string& qname, qnames) |
120 | { | |
f28f2324 BH |
121 | string shorter(qname); |
122 | bool auth=true; | |
123 | do { | |
124 | if(nsset.count(shorter)) { | |
125 | auth=false; | |
126 | break; | |
127 | } | |
128 | }while(chopOff(shorter)); | |
129 | ||
c3c89361 | 130 | if(ns3pr.d_salt.empty()) // NSEC |
f28f2324 | 131 | sd.db->updateDNSSECOrderAndAuth(sd.domain_id, zone, qname, auth); |
c3c89361 | 132 | else { |
f28f2324 BH |
133 | if(!narrow) { |
134 | hashed=toLower(toBase32Hex(hashQNameWithSalt(ns3pr.d_iterations, ns3pr.d_salt, qname))); | |
135 | cerr<<"'"<<qname<<"' -> '"<< hashed <<"'"<<endl; | |
136 | } | |
137 | sd.db->updateDNSSECOrderAndAuthAbsolute(sd.domain_id, qname, hashed, auth); | |
c3c89361 | 138 | } |
20002664 BH |
139 | } |
140 | cerr<<"Done listing"<<endl; | |
141 | } | |
142 | ||
5d2e58b0 BH |
143 | void checkZone(DNSSECKeeper& dk, const std::string& zone) |
144 | { | |
5d2e58b0 BH |
145 | UeberBackend* B = new UeberBackend("default"); |
146 | SOAData sd; | |
147 | ||
148 | if(!B->getSOA(zone, sd)) { | |
149 | cerr<<"No SOA!"<<endl; | |
150 | return; | |
151 | } | |
5d2e58b0 BH |
152 | sd.db->list(zone, sd.domain_id); |
153 | DNSResourceRecord rr; | |
154 | uint64_t numrecords=0, numerrors=0; | |
155 | ||
035297ad BH |
156 | while(sd.db->get(rr)) { |
157 | if(rr.qtype.getCode() == QType::MX) | |
158 | rr.content = lexical_cast<string>(rr.priority)+" "+rr.content; | |
7ddd79a7 BH |
159 | if(rr.auth == 0 && rr.qtype.getCode()!=QType::NS && rr.qtype.getCode()!=QType::A) |
160 | { | |
161 | cerr<<"Following record is auth=0, run pdnssec rectify-zone?: "<<rr.qname<<" IN " <<rr.qtype.getName()<< " " << rr.content<<endl; | |
162 | } | |
035297ad BH |
163 | try { |
164 | shared_ptr<DNSRecordContent> drc(DNSRecordContent::mastermake(rr.qtype.getCode(), 1, rr.content)); | |
165 | string tmp=drc->serialize(rr.qname); | |
5d2e58b0 | 166 | } |
035297ad BH |
167 | catch(std::exception& e) |
168 | { | |
169 | cerr<<"Following record had a problem: "<<rr.qname<<" IN " <<rr.qtype.getName()<< " " << rr.content<<endl; | |
170 | cerr<<"Error was: "<<e.what()<<endl; | |
171 | numerrors++; | |
172 | } | |
173 | numrecords++; | |
174 | } | |
175 | cerr<<"Checked "<<numrecords<<" records, "<<numerrors<<" errors"<<endl; | |
5d2e58b0 BH |
176 | } |
177 | ||
ade1b1e9 BH |
178 | void showZone(DNSSECKeeper& dk, const std::string& zone) |
179 | { | |
180 | NSEC3PARAMRecordContent ns3pr; | |
181 | bool narrow; | |
182 | dk.getNSEC3PARAM(zone, &ns3pr, &narrow); | |
183 | ||
184 | if(ns3pr.d_salt.empty()) | |
7ddd79a7 | 185 | cout<<"Zone has NSEC semantics"<<endl; |
ade1b1e9 | 186 | else |
7ddd79a7 | 187 | cout<<"Zone has " << (narrow ? "NARROW " : "") <<"hashed NSEC3 semantics, configuration: "<<ns3pr.getZoneRepresentation()<<endl; |
ade1b1e9 BH |
188 | |
189 | DNSSECKeeper::keyset_t keyset=dk.getKeys(zone); | |
190 | ||
191 | if(keyset.empty()) { | |
192 | cerr << "No keys for zone '"<<zone<<"'."<<endl; | |
193 | } | |
194 | else { | |
195 | cout << "keys: "<<endl; | |
196 | BOOST_FOREACH(DNSSECKeeper::keyset_t::value_type value, keyset) { | |
197 | cout<<"ID = "<<value.second.id<<" ("<<(value.second.keyOrZone ? "KSK" : "ZSK")<<"), tag = "<<value.first.getDNSKEY().getTag(); | |
198 | cout<<", algo = "<<(int)value.first.d_algorithm<<", bits = "<<value.first.d_key.getConstContext().len*8<<"\tActive: "<<value.second.active<< endl; // humanTime(value.second.beginValidity)<<" - "<<humanTime(value.second.endValidity)<<endl; | |
199 | if(value.second.keyOrZone) { | |
200 | cout<<"KSK DNSKEY = "<<zone<<" IN DNSKEY "<< value.first.getDNSKEY().getZoneRepresentation() << endl; | |
201 | cout<<"DS = "<<zone<<" IN DS "<<makeDSFromDNSKey(zone, value.first.getDNSKEY(), 1).getZoneRepresentation() << endl; | |
202 | cout<<"DS = "<<zone<<" IN DS "<<makeDSFromDNSKey(zone, value.first.getDNSKEY(), 2).getZoneRepresentation() << endl << endl; | |
203 | } | |
204 | } | |
205 | } | |
206 | } | |
5d2e58b0 | 207 | |
1d211b1b | 208 | int main(int argc, char** argv) |
20002664 | 209 | try |
1d211b1b BH |
210 | { |
211 | po::options_description desc("Allowed options"); | |
212 | desc.add_options() | |
213 | ("help,h", "produce help message") | |
1d211b1b BH |
214 | ("verbose,v", po::value<bool>(), "be verbose") |
215 | ("force", "force an action") | |
aa952078 | 216 | ("config-name", po::value<string>()->default_value(""), "virtual configuration name") |
7d9dcde0 | 217 | ("config-dir", po::value<string>()->default_value(SYSCONFDIR), "location of pdns.conf") |
1d211b1b BH |
218 | ("commands", po::value<vector<string> >()); |
219 | ||
220 | po::positional_options_description p; | |
221 | p.add("commands", -1); | |
222 | po::store(po::command_line_parser(argc, argv).options(desc).positional(p).run(), g_vm); | |
223 | po::notify(g_vm); | |
224 | ||
225 | vector<string> cmds; | |
226 | ||
227 | if(g_vm.count("commands")) | |
228 | cmds = g_vm["commands"].as<vector<string> >(); | |
229 | ||
230 | if(cmds.empty() || g_vm.count("help")) { | |
f28f2324 BH |
231 | cerr<<"Usage: \npdnssec [options] [show-zone] [secure-zone] [rectify-zone] [add-zone-key] [deactivate-zone-key] [remove-zone-key] [activate-zone-key]\n"; |
232 | cerr<<" [import-zone-key] [export-zone-key] [set-nsec3] [unset-nsec3] [export-zone-dnskey]\n\n"; | |
233 | cerr<<"activate-zone-key ZONE KEY-ID Activate the key with key id KEY-ID in ZONE\n"; | |
7ddd79a7 BH |
234 | cerr<<"add-zone-key ZONE [zsk|ksk] Add a ZSK or KSK to a zone\n"; |
235 | cerr<<" [bits] [rsasha1|rsasha256] and specify algorithm & bits\n"; | |
236 | cerr<<"check-zone ZONE Check a zone for correctness\n"; | |
f28f2324 BH |
237 | cerr<<"deactivate-zone-key Dectivate the key with key id KEY-ID in ZONE\n"; |
238 | cerr<<"export-zone-dnskey ZONE KEY-ID Export to stdout the public DNSKEY described\n"; | |
239 | cerr<<"export-zone-key ZONE KEY-ID Export to stdout the private key described\n"; | |
7ddd79a7 BH |
240 | cerr<<"import-zone-key ZONE FILE Import from a file a private key, ZSK or KSK\n"; |
241 | cerr<<" [ksk|zsk] Defaults to KSK\n"; | |
f28f2324 BH |
242 | cerr<<"rectify-zone ZONE Fix up DNSSEC fields (order, auth)\n"; |
243 | cerr<<"remove-zone-key ZONE KEY-ID Remove key with KEY-ID from ZONE\n"; | |
244 | cerr<<"secure-zone Add KSK and two ZSKs\n"; | |
245 | cerr<<"set-nsec3 'params' [narrow] Enable NSEC3 with PARAMs. Optionally narrow\n"; | |
246 | cerr<<"show-zone ZONE Show DNSSEC (public) key details about a zone\n"; | |
247 | cerr<<"unset-nsec3 ZONE Switch back to NSEC\n\n"; | |
248 | ||
7d9dcde0 | 249 | cerr<<"Options:"<<endl; |
1d211b1b BH |
250 | cerr<<desc<<endl; |
251 | return 0; | |
252 | } | |
a7e0acd8 | 253 | |
7d9dcde0 | 254 | loadMainConfig(g_vm["config-dir"].as<string>()); |
6dfa0aa0 | 255 | reportAllTypes(); |
976b6541 | 256 | DNSSECKeeper dk; |
1d211b1b | 257 | |
f28f2324 | 258 | if(cmds[0] == "rectify-zone" || cmds[0] == "order-zone") { |
81b39e4b BH |
259 | if(cmds.size() != 2) { |
260 | cerr << "Error: "<<cmds[0]<<" takes exactly 1 parameter"<<endl; | |
261 | return 0; | |
262 | } | |
f28f2324 | 263 | rectifyZone(dk, cmds[1]); |
20002664 | 264 | } |
9abd98d3 | 265 | else if(cmds[0] == "check-zone") { |
5d2e58b0 BH |
266 | if(cmds.size() != 2) { |
267 | cerr << "Error: "<<cmds[0]<<" takes exactly 1 parameter"<<endl; | |
268 | return 0; | |
269 | } | |
270 | checkZone(dk, cmds[1]); | |
271 | } | |
da11ed0e BH |
272 | |
273 | else if(cmds[0] == "show-zone") { | |
a0472099 BH |
274 | if(cmds.size() != 2) { |
275 | cerr << "Error: "<<cmds[0]<<" takes exactly 1 parameter"<<endl; | |
276 | return 0; | |
277 | } | |
1d211b1b | 278 | const string& zone=cmds[1]; |
ade1b1e9 | 279 | showZone(dk, zone); |
1d211b1b | 280 | } |
bed962b5 BH |
281 | else if(cmds[0] == "activate-zone-key") { |
282 | const string& zone=cmds[1]; | |
283 | unsigned int id=atoi(cmds[2].c_str()); | |
284 | dk.activateKey(zone, id); | |
285 | } | |
286 | else if(cmds[0] == "deactivate-zone-key") { | |
287 | const string& zone=cmds[1]; | |
288 | unsigned int id=atoi(cmds[2].c_str()); | |
289 | dk.deactivateKey(zone, id); | |
290 | } | |
291 | else if(cmds[0] == "add-zone-key") { | |
292 | const string& zone=cmds[1]; | |
36c394e5 BH |
293 | // need to get algorithm, bits & ksk or zsk from commandline |
294 | bool keyOrZone=false; | |
295 | int bits=0; | |
a254438f | 296 | int algorithm=5; |
36c394e5 BH |
297 | for(unsigned int n=2; n < cmds.size(); ++n) { |
298 | if(pdns_iequals(cmds[n], "zsk")) | |
299 | keyOrZone = false; | |
300 | else if(pdns_iequals(cmds[n], "ksk")) | |
301 | keyOrZone = true; | |
a254438f BH |
302 | else if(pdns_iequals(cmds[n], "rsasha1")) |
303 | algorithm=5; | |
304 | else if(pdns_iequals(cmds[n], "rsasha256")) | |
305 | algorithm=8; | |
36c394e5 BH |
306 | else if(atoi(cmds[n].c_str())) |
307 | bits = atoi(cmds[n].c_str()); | |
308 | else { | |
a254438f | 309 | cerr<<"Unknown algorithm, key flag or size '"<<cmds[n]<<"'"<<endl; |
36c394e5 BH |
310 | } |
311 | } | |
a254438f | 312 | cerr<<"Adding a " << (keyOrZone ? "KSK" : "ZSK")<<" with algorithm = "<<algorithm<<endl; |
36c394e5 BH |
313 | if(bits) |
314 | cerr<<"Requesting specific key size of "<<bits<<" bits"<<endl; | |
a254438f | 315 | dk.addKey(zone, keyOrZone, algorithm, bits); |
bed962b5 BH |
316 | } |
317 | else if(cmds[0] == "remove-zone-key") { | |
318 | const string& zone=cmds[1]; | |
319 | unsigned int id=atoi(cmds[2].c_str()); | |
320 | dk.removeKey(zone, id); | |
321 | } | |
322 | ||
c3c89361 | 323 | else if(cmds[0] == "secure-zone") { |
a9175ad6 | 324 | if(cmds.size() != 2) { |
a0472099 | 325 | cerr << "Error: "<<cmds[0]<<" takes exactly 1 parameter"<<endl; |
a9175ad6 BH |
326 | return 0; |
327 | } | |
1d211b1b BH |
328 | const string& zone=cmds[1]; |
329 | DNSSECPrivateKey dpk; | |
330 | ||
ade1b1e9 BH |
331 | if(dk.haveActiveKSKFor(zone)) { |
332 | cerr << "There is a KSK already for zone '"<<zone<<"', remove with pdnssec remove-zone-key if needed"<<endl; | |
1d211b1b BH |
333 | return 0; |
334 | } | |
335 | ||
ade1b1e9 | 336 | dk.secureZone(zone, 8); |
1d211b1b | 337 | |
ade1b1e9 | 338 | if(!dk.haveActiveKSKFor(zone)) { |
1d211b1b | 339 | cerr << "This should not happen, still no key!" << endl; |
6dfa0aa0 | 340 | return 0; |
1d211b1b | 341 | } |
1d211b1b | 342 | |
bed962b5 | 343 | DNSSECKeeper::keyset_t zskset=dk.getKeys(zone, false); |
1d211b1b | 344 | |
ade1b1e9 BH |
345 | if(!zskset.empty()) { |
346 | cerr<<"There were ZSKs already for zone '"<<zone<<"', no need to add more"<<endl; | |
1d211b1b BH |
347 | return 0; |
348 | } | |
349 | ||
ade1b1e9 BH |
350 | dk.addKey(zone, false, 8); |
351 | dk.addKey(zone, false, 8, 0, false); // not active | |
352 | rectifyZone(dk, zone); | |
353 | showZone(dk, zone); | |
1d211b1b | 354 | } |
da11ed0e BH |
355 | else if(cmds[0]=="set-nsec3") { |
356 | string nsec3params = cmds.size() > 2 ? cmds[2] : "1 0 1 ab"; | |
22c5aa60 | 357 | bool narrow = cmds.size() > 3 && cmds[3]=="narrow"; |
da11ed0e | 358 | NSEC3PARAMRecordContent ns3pr(nsec3params); |
22c5aa60 | 359 | dk.setNSEC3PARAM(cmds[1], ns3pr, narrow); |
da11ed0e BH |
360 | } |
361 | else if(cmds[0]=="unset-nsec3") { | |
362 | dk.unsetNSEC3PARAM(cmds[1]); | |
363 | } | |
364 | else if(cmds[0]=="export-zone-key") { | |
7ddd79a7 BH |
365 | if(cmds.size() < 3) { |
366 | cerr<<"Syntax: pdnssec export-zone-key zone-name id"<<endl; | |
367 | cerr<<cmds.size()<<endl; | |
368 | exit(1); | |
369 | } | |
370 | ||
da11ed0e BH |
371 | string zone=cmds[1]; |
372 | unsigned int id=atoi(cmds[2].c_str()); | |
373 | DNSSECPrivateKey dpk=dk.getKeyById(zone, id); | |
339fe708 | 374 | cout << dpk.d_key.convertToISC(dpk.d_algorithm) <<endl; |
4496f66f | 375 | } |
976b6541 | 376 | else if(cmds[0]=="import-zone-key") { |
c34fc2df | 377 | if(cmds.size() < 3) { |
7ddd79a7 | 378 | cerr<<"Syntax: pdnssec import-zone-key zone-name filename [zsk|ksk]"<<endl; |
4496f66f BH |
379 | exit(1); |
380 | } | |
976b6541 BH |
381 | string zone=cmds[1]; |
382 | string fname=cmds[2]; | |
383 | DNSSECPrivateKey dpk; | |
7ddd79a7 BH |
384 | DNSKEYRecordContent drc = getRSAKeyFromISC(&dpk.d_key.getContext(), fname.c_str()); |
385 | dpk.d_algorithm = drc.d_algorithm; | |
386 | ||
387 | if(dpk.d_algorithm == 7) | |
388 | dpk.d_algorithm = 5; | |
389 | ||
390 | cerr<<(int)dpk.d_algorithm<<endl; | |
aa952078 BH |
391 | |
392 | if(cmds.size() > 3) { | |
393 | if(pdns_iequals(cmds[3], "ZSK")) | |
394 | dpk.d_flags = 256; | |
395 | else if(pdns_iequals(cmds[3], "KSK")) | |
396 | dpk.d_flags = 257; | |
397 | else { | |
398 | cerr<<"Unknown key flag '"<<cmds[3]<<"'\n"; | |
399 | exit(1); | |
400 | } | |
401 | } | |
402 | else | |
403 | dpk.d_flags = 257; | |
404 | ||
7ddd79a7 | 405 | dk.addKey(zone, dpk); |
976b6541 | 406 | } |
da11ed0e | 407 | else if(cmds[0]=="export-zone-dnskey") { |
7ddd79a7 BH |
408 | if(cmds.size() < 3) { |
409 | cerr<<"Syntax: pdnssec export-zone-dnskey zone-name id"<<endl; | |
410 | exit(1); | |
411 | } | |
412 | ||
da11ed0e BH |
413 | string zone=cmds[1]; |
414 | unsigned int id=atoi(cmds[2].c_str()); | |
415 | DNSSECPrivateKey dpk=dk.getKeyById(zone, id); | |
416 | cout << zone<<" IN DNSKEY "<<dpk.getDNSKEY().getZoneRepresentation() <<endl; | |
f8b25763 BH |
417 | if(dpk.d_flags == 257) { |
418 | cout << zone << " IN DS "<<makeDSFromDNSKey(zone, dpk.getDNSKEY(), 1).getZoneRepresentation() << endl; | |
419 | cout << zone << " IN DS "<<makeDSFromDNSKey(zone, dpk.getDNSKEY(), 2).getZoneRepresentation() << endl; | |
420 | } | |
da11ed0e | 421 | } |
1d211b1b BH |
422 | else { |
423 | cerr<<"Unknown command '"<<cmds[0]<<"'\n"; | |
424 | return 1; | |
425 | } | |
426 | return 0; | |
427 | } | |
20002664 BH |
428 | catch(AhuException& ae) { |
429 | cerr<<"Error: "<<ae.reason<<endl; | |
430 | } | |
14133ba3 BH |
431 | catch(std::exception& e) { |
432 | cerr<<"Error: "<<e.what()<<endl; | |
433 | } |