PageRenderTime 136ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/contrib/bind9/bin/dnssec/dnssec-signzone.c

https://bitbucket.org/freebsd/freebsd-head/
C | 4016 lines | 3223 code | 459 blank | 334 comment | 808 complexity | 404c53089d2909dfe9ec7a88ec65b188 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, BSD-3-Clause, LGPL-2.0, LGPL-2.1, BSD-2-Clause, 0BSD, JSON, AGPL-1.0, GPL-2.0
  1. /*
  2. * Portions Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
  3. * Portions Copyright (C) 1999-2003 Internet Software Consortium.
  4. *
  5. * Permission to use, copy, modify, and/or distribute this software for any
  6. * purpose with or without fee is hereby granted, provided that the above
  7. * copyright notice and this permission notice appear in all copies.
  8. *
  9. * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS
  10. * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
  11. * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE
  12. * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  13. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  14. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
  15. * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  16. *
  17. * Portions Copyright (C) 1995-2000 by Network Associates, Inc.
  18. *
  19. * Permission to use, copy, modify, and/or distribute this software for any
  20. * purpose with or without fee is hereby granted, provided that the above
  21. * copyright notice and this permission notice appear in all copies.
  22. *
  23. * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS
  24. * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
  25. * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE
  26. * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  27. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  28. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
  29. * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  30. */
  31. /* $Id: dnssec-signzone.c,v 1.262.110.9 2011/07/19 23:47:12 tbox Exp $ */
  32. /*! \file */
  33. #include <config.h>
  34. #include <stdlib.h>
  35. #include <time.h>
  36. #include <isc/app.h>
  37. #include <isc/base32.h>
  38. #include <isc/commandline.h>
  39. #include <isc/entropy.h>
  40. #include <isc/event.h>
  41. #include <isc/file.h>
  42. #include <isc/hash.h>
  43. #include <isc/hex.h>
  44. #include <isc/mem.h>
  45. #include <isc/mutex.h>
  46. #include <isc/os.h>
  47. #include <isc/print.h>
  48. #include <isc/random.h>
  49. #include <isc/rwlock.h>
  50. #include <isc/serial.h>
  51. #include <isc/stdio.h>
  52. #include <isc/stdlib.h>
  53. #include <isc/string.h>
  54. #include <isc/task.h>
  55. #include <isc/time.h>
  56. #include <isc/util.h>
  57. #include <dns/db.h>
  58. #include <dns/dbiterator.h>
  59. #include <dns/diff.h>
  60. #include <dns/dnssec.h>
  61. #include <dns/ds.h>
  62. #include <dns/fixedname.h>
  63. #include <dns/keyvalues.h>
  64. #include <dns/log.h>
  65. #include <dns/master.h>
  66. #include <dns/masterdump.h>
  67. #include <dns/nsec.h>
  68. #include <dns/nsec3.h>
  69. #include <dns/rdata.h>
  70. #include <dns/rdatalist.h>
  71. #include <dns/rdataset.h>
  72. #include <dns/rdataclass.h>
  73. #include <dns/rdatasetiter.h>
  74. #include <dns/rdatastruct.h>
  75. #include <dns/rdatatype.h>
  76. #include <dns/result.h>
  77. #include <dns/soa.h>
  78. #include <dns/time.h>
  79. #include <dst/dst.h>
  80. #include "dnssectool.h"
  81. #ifndef PATH_MAX
  82. #define PATH_MAX 1024 /* AIX, WIN32, and others don't define this. */
  83. #endif
  84. const char *program = "dnssec-signzone";
  85. int verbose;
  86. typedef struct hashlist hashlist_t;
  87. static int nsec_datatype = dns_rdatatype_nsec;
  88. #define IS_NSEC3 (nsec_datatype == dns_rdatatype_nsec3)
  89. #define OPTOUT(x) (((x) & DNS_NSEC3FLAG_OPTOUT) != 0)
  90. #define REVOKE(x) ((dst_key_flags(x) & DNS_KEYFLAG_REVOKE) != 0)
  91. #define BUFSIZE 2048
  92. #define MAXDSKEYS 8
  93. #define SIGNER_EVENTCLASS ISC_EVENTCLASS(0x4453)
  94. #define SIGNER_EVENT_WRITE (SIGNER_EVENTCLASS + 0)
  95. #define SIGNER_EVENT_WORK (SIGNER_EVENTCLASS + 1)
  96. #define SOA_SERIAL_KEEP 0
  97. #define SOA_SERIAL_INCREMENT 1
  98. #define SOA_SERIAL_UNIXTIME 2
  99. typedef struct signer_event sevent_t;
  100. struct signer_event {
  101. ISC_EVENT_COMMON(sevent_t);
  102. dns_fixedname_t *fname;
  103. dns_dbnode_t *node;
  104. };
  105. static dns_dnsseckeylist_t keylist;
  106. static unsigned int keycount = 0;
  107. isc_rwlock_t keylist_lock;
  108. static isc_stdtime_t starttime = 0, endtime = 0, now;
  109. static int cycle = -1;
  110. static int jitter = 0;
  111. static isc_boolean_t tryverify = ISC_FALSE;
  112. static isc_boolean_t printstats = ISC_FALSE;
  113. static isc_mem_t *mctx = NULL;
  114. static isc_entropy_t *ectx = NULL;
  115. static dns_ttl_t zone_soa_min_ttl;
  116. static dns_ttl_t soa_ttl;
  117. static FILE *fp;
  118. static char *tempfile = NULL;
  119. static const dns_master_style_t *masterstyle;
  120. static dns_masterformat_t inputformat = dns_masterformat_text;
  121. static dns_masterformat_t outputformat = dns_masterformat_text;
  122. static unsigned int nsigned = 0, nretained = 0, ndropped = 0;
  123. static unsigned int nverified = 0, nverifyfailed = 0;
  124. static const char *directory = NULL, *dsdir = NULL;
  125. static isc_mutex_t namelock, statslock;
  126. static isc_taskmgr_t *taskmgr = NULL;
  127. static dns_db_t *gdb; /* The database */
  128. static dns_dbversion_t *gversion; /* The database version */
  129. static dns_dbiterator_t *gdbiter; /* The database iterator */
  130. static dns_rdataclass_t gclass; /* The class */
  131. static dns_name_t *gorigin; /* The database origin */
  132. static int nsec3flags = 0;
  133. static dns_iterations_t nsec3iter = 10U;
  134. static unsigned char saltbuf[255];
  135. static unsigned char *salt = saltbuf;
  136. static size_t salt_length = 0;
  137. static isc_task_t *master = NULL;
  138. static unsigned int ntasks = 0;
  139. static isc_boolean_t shuttingdown = ISC_FALSE, finished = ISC_FALSE;
  140. static isc_boolean_t nokeys = ISC_FALSE;
  141. static isc_boolean_t removefile = ISC_FALSE;
  142. static isc_boolean_t generateds = ISC_FALSE;
  143. static isc_boolean_t ignore_kskflag = ISC_FALSE;
  144. static isc_boolean_t keyset_kskonly = ISC_FALSE;
  145. static dns_name_t *dlv = NULL;
  146. static dns_fixedname_t dlv_fixed;
  147. static dns_master_style_t *dsstyle = NULL;
  148. static unsigned int serialformat = SOA_SERIAL_KEEP;
  149. static unsigned int hash_length = 0;
  150. static isc_boolean_t unknownalg = ISC_FALSE;
  151. static isc_boolean_t disable_zone_check = ISC_FALSE;
  152. static isc_boolean_t update_chain = ISC_FALSE;
  153. static isc_boolean_t set_keyttl = ISC_FALSE;
  154. static dns_ttl_t keyttl;
  155. #define INCSTAT(counter) \
  156. if (printstats) { \
  157. LOCK(&statslock); \
  158. counter++; \
  159. UNLOCK(&statslock); \
  160. }
  161. static void
  162. sign(isc_task_t *task, isc_event_t *event);
  163. #define check_dns_dbiterator_current(result) \
  164. check_result((result == DNS_R_NEWORIGIN) ? ISC_R_SUCCESS : result, \
  165. "dns_dbiterator_current()")
  166. static void
  167. dumpnode(dns_name_t *name, dns_dbnode_t *node) {
  168. isc_result_t result;
  169. if (outputformat != dns_masterformat_text)
  170. return;
  171. result = dns_master_dumpnodetostream(mctx, gdb, gversion, node, name,
  172. masterstyle, fp);
  173. check_result(result, "dns_master_dumpnodetostream");
  174. }
  175. /*%
  176. * Sign the given RRset with given key, and add the signature record to the
  177. * given tuple.
  178. */
  179. static void
  180. signwithkey(dns_name_t *name, dns_rdataset_t *rdataset, dst_key_t *key,
  181. dns_ttl_t ttl, dns_diff_t *add, const char *logmsg)
  182. {
  183. isc_result_t result;
  184. isc_stdtime_t jendtime;
  185. char keystr[DST_KEY_FORMATSIZE];
  186. dns_rdata_t trdata = DNS_RDATA_INIT;
  187. unsigned char array[BUFSIZE];
  188. isc_buffer_t b;
  189. dns_difftuple_t *tuple;
  190. dst_key_format(key, keystr, sizeof(keystr));
  191. vbprintf(1, "\t%s %s\n", logmsg, keystr);
  192. jendtime = (jitter != 0) ? isc_random_jitter(endtime, jitter) : endtime;
  193. isc_buffer_init(&b, array, sizeof(array));
  194. result = dns_dnssec_sign(name, rdataset, key, &starttime, &jendtime,
  195. mctx, &b, &trdata);
  196. isc_entropy_stopcallbacksources(ectx);
  197. if (result != ISC_R_SUCCESS) {
  198. char keystr[DST_KEY_FORMATSIZE];
  199. dst_key_format(key, keystr, sizeof(keystr));
  200. fatal("dnskey '%s' failed to sign data: %s",
  201. keystr, isc_result_totext(result));
  202. }
  203. INCSTAT(nsigned);
  204. if (tryverify) {
  205. result = dns_dnssec_verify(name, rdataset, key,
  206. ISC_TRUE, mctx, &trdata);
  207. if (result == ISC_R_SUCCESS) {
  208. vbprintf(3, "\tsignature verified\n");
  209. INCSTAT(nverified);
  210. } else {
  211. vbprintf(3, "\tsignature failed to verify\n");
  212. INCSTAT(nverifyfailed);
  213. }
  214. }
  215. tuple = NULL;
  216. result = dns_difftuple_create(mctx, DNS_DIFFOP_ADD, name, ttl, &trdata,
  217. &tuple);
  218. check_result(result, "dns_difftuple_create");
  219. dns_diff_append(add, &tuple);
  220. }
  221. static inline isc_boolean_t
  222. issigningkey(dns_dnsseckey_t *key) {
  223. return (key->force_sign || key->hint_sign);
  224. }
  225. static inline isc_boolean_t
  226. iszonekey(dns_dnsseckey_t *key) {
  227. return (ISC_TF(dns_name_equal(dst_key_name(key->key), gorigin) &&
  228. dst_key_iszonekey(key->key)));
  229. }
  230. static inline isc_boolean_t
  231. isksk(dns_dnsseckey_t *key) {
  232. return (key->ksk);
  233. }
  234. static inline isc_boolean_t
  235. iszsk(dns_dnsseckey_t *key) {
  236. return (ignore_kskflag || !key->ksk);
  237. }
  238. /*%
  239. * Find the key that generated an RRSIG, if it is in the key list. If
  240. * so, return a pointer to it, otherwise return NULL.
  241. *
  242. * No locking is performed here, this must be done by the caller.
  243. */
  244. static dns_dnsseckey_t *
  245. keythatsigned_unlocked(dns_rdata_rrsig_t *rrsig) {
  246. dns_dnsseckey_t *key;
  247. for (key = ISC_LIST_HEAD(keylist);
  248. key != NULL;
  249. key = ISC_LIST_NEXT(key, link)) {
  250. if (rrsig->keyid == dst_key_id(key->key) &&
  251. rrsig->algorithm == dst_key_alg(key->key) &&
  252. dns_name_equal(&rrsig->signer, dst_key_name(key->key)))
  253. return (key);
  254. }
  255. return (NULL);
  256. }
  257. /*%
  258. * Finds the key that generated a RRSIG, if possible. First look at the keys
  259. * that we've loaded already, and then see if there's a key on disk.
  260. */
  261. static dns_dnsseckey_t *
  262. keythatsigned(dns_rdata_rrsig_t *rrsig) {
  263. isc_result_t result;
  264. dst_key_t *pubkey = NULL, *privkey = NULL;
  265. dns_dnsseckey_t *key = NULL;
  266. isc_rwlock_lock(&keylist_lock, isc_rwlocktype_read);
  267. key = keythatsigned_unlocked(rrsig);
  268. isc_rwlock_unlock(&keylist_lock, isc_rwlocktype_read);
  269. if (key != NULL)
  270. return (key);
  271. /*
  272. * We did not find the key in our list. Get a write lock now, since
  273. * we may be modifying the bits. We could do the tryupgrade() dance,
  274. * but instead just get a write lock and check once again to see if
  275. * it is on our list. It's possible someone else may have added it
  276. * after all.
  277. */
  278. isc_rwlock_lock(&keylist_lock, isc_rwlocktype_write);
  279. key = keythatsigned_unlocked(rrsig);
  280. if (key != NULL) {
  281. isc_rwlock_unlock(&keylist_lock, isc_rwlocktype_write);
  282. return (key);
  283. }
  284. result = dst_key_fromfile(&rrsig->signer, rrsig->keyid,
  285. rrsig->algorithm, DST_TYPE_PUBLIC,
  286. directory, mctx, &pubkey);
  287. if (result != ISC_R_SUCCESS) {
  288. isc_rwlock_unlock(&keylist_lock, isc_rwlocktype_write);
  289. return (NULL);
  290. }
  291. result = dst_key_fromfile(&rrsig->signer, rrsig->keyid,
  292. rrsig->algorithm,
  293. DST_TYPE_PUBLIC | DST_TYPE_PRIVATE,
  294. directory, mctx, &privkey);
  295. if (result == ISC_R_SUCCESS) {
  296. dst_key_free(&pubkey);
  297. dns_dnsseckey_create(mctx, &privkey, &key);
  298. } else {
  299. dns_dnsseckey_create(mctx, &pubkey, &key);
  300. }
  301. key->force_publish = ISC_FALSE;
  302. key->force_sign = ISC_FALSE;
  303. ISC_LIST_APPEND(keylist, key, link);
  304. isc_rwlock_unlock(&keylist_lock, isc_rwlocktype_write);
  305. return (key);
  306. }
  307. /*%
  308. * Check to see if we expect to find a key at this name. If we see a RRSIG
  309. * and can't find the signing key that we expect to find, we drop the rrsig.
  310. * I'm not sure if this is completely correct, but it seems to work.
  311. */
  312. static isc_boolean_t
  313. expecttofindkey(dns_name_t *name) {
  314. unsigned int options = DNS_DBFIND_NOWILD;
  315. dns_fixedname_t fname;
  316. isc_result_t result;
  317. char namestr[DNS_NAME_FORMATSIZE];
  318. dns_fixedname_init(&fname);
  319. result = dns_db_find(gdb, name, gversion, dns_rdatatype_dnskey, options,
  320. 0, NULL, dns_fixedname_name(&fname), NULL, NULL);
  321. switch (result) {
  322. case ISC_R_SUCCESS:
  323. case DNS_R_NXDOMAIN:
  324. case DNS_R_NXRRSET:
  325. return (ISC_TRUE);
  326. case DNS_R_DELEGATION:
  327. case DNS_R_CNAME:
  328. case DNS_R_DNAME:
  329. return (ISC_FALSE);
  330. }
  331. dns_name_format(name, namestr, sizeof(namestr));
  332. fatal("failure looking for '%s DNSKEY' in database: %s",
  333. namestr, isc_result_totext(result));
  334. /* NOTREACHED */
  335. return (ISC_FALSE); /* removes a warning */
  336. }
  337. static inline isc_boolean_t
  338. setverifies(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
  339. dns_rdata_t *rrsig)
  340. {
  341. isc_result_t result;
  342. result = dns_dnssec_verify(name, set, key, ISC_FALSE, mctx, rrsig);
  343. if (result == ISC_R_SUCCESS) {
  344. INCSTAT(nverified);
  345. return (ISC_TRUE);
  346. } else {
  347. INCSTAT(nverifyfailed);
  348. return (ISC_FALSE);
  349. }
  350. }
  351. /*%
  352. * Signs a set. Goes through contortions to decide if each RRSIG should
  353. * be dropped or retained, and then determines if any new SIGs need to
  354. * be generated.
  355. */
  356. static void
  357. signset(dns_diff_t *del, dns_diff_t *add, dns_dbnode_t *node, dns_name_t *name,
  358. dns_rdataset_t *set)
  359. {
  360. dns_rdataset_t sigset;
  361. dns_rdata_t sigrdata = DNS_RDATA_INIT;
  362. dns_rdata_rrsig_t rrsig;
  363. dns_dnsseckey_t *key;
  364. isc_result_t result;
  365. isc_boolean_t nosigs = ISC_FALSE;
  366. isc_boolean_t *wassignedby, *nowsignedby;
  367. int arraysize;
  368. dns_difftuple_t *tuple;
  369. dns_ttl_t ttl;
  370. int i;
  371. char namestr[DNS_NAME_FORMATSIZE];
  372. char typestr[TYPE_FORMATSIZE];
  373. char sigstr[SIG_FORMATSIZE];
  374. dns_name_format(name, namestr, sizeof(namestr));
  375. type_format(set->type, typestr, sizeof(typestr));
  376. ttl = ISC_MIN(set->ttl, endtime - starttime);
  377. dns_rdataset_init(&sigset);
  378. result = dns_db_findrdataset(gdb, node, gversion, dns_rdatatype_rrsig,
  379. set->type, 0, &sigset, NULL);
  380. if (result == ISC_R_NOTFOUND) {
  381. result = ISC_R_SUCCESS;
  382. nosigs = ISC_TRUE;
  383. }
  384. if (result != ISC_R_SUCCESS)
  385. fatal("failed while looking for '%s RRSIG %s': %s",
  386. namestr, typestr, isc_result_totext(result));
  387. vbprintf(1, "%s/%s:\n", namestr, typestr);
  388. arraysize = keycount;
  389. if (!nosigs)
  390. arraysize += dns_rdataset_count(&sigset);
  391. wassignedby = isc_mem_get(mctx, arraysize * sizeof(isc_boolean_t));
  392. nowsignedby = isc_mem_get(mctx, arraysize * sizeof(isc_boolean_t));
  393. if (wassignedby == NULL || nowsignedby == NULL)
  394. fatal("out of memory");
  395. for (i = 0; i < arraysize; i++)
  396. wassignedby[i] = nowsignedby[i] = ISC_FALSE;
  397. if (nosigs)
  398. result = ISC_R_NOMORE;
  399. else
  400. result = dns_rdataset_first(&sigset);
  401. while (result == ISC_R_SUCCESS) {
  402. isc_boolean_t expired, future;
  403. isc_boolean_t keep = ISC_FALSE, resign = ISC_FALSE;
  404. dns_rdataset_current(&sigset, &sigrdata);
  405. result = dns_rdata_tostruct(&sigrdata, &rrsig, NULL);
  406. check_result(result, "dns_rdata_tostruct");
  407. future = isc_serial_lt(now, rrsig.timesigned);
  408. key = keythatsigned(&rrsig);
  409. sig_format(&rrsig, sigstr, sizeof(sigstr));
  410. if (key != NULL && issigningkey(key))
  411. expired = isc_serial_gt(now + cycle, rrsig.timeexpire);
  412. else
  413. expired = isc_serial_gt(now, rrsig.timeexpire);
  414. if (isc_serial_gt(rrsig.timesigned, rrsig.timeexpire)) {
  415. /* rrsig is dropped and not replaced */
  416. vbprintf(2, "\trrsig by %s dropped - "
  417. "invalid validity period\n",
  418. sigstr);
  419. } else if (key == NULL && !future &&
  420. expecttofindkey(&rrsig.signer)) {
  421. /* rrsig is dropped and not replaced */
  422. vbprintf(2, "\trrsig by %s dropped - "
  423. "private dnskey not found\n",
  424. sigstr);
  425. } else if (key == NULL || future) {
  426. vbprintf(2, "\trrsig by %s %s - dnskey not found\n",
  427. expired ? "retained" : "dropped", sigstr);
  428. if (!expired)
  429. keep = ISC_TRUE;
  430. } else if (issigningkey(key)) {
  431. if (!expired && rrsig.originalttl == set->ttl &&
  432. setverifies(name, set, key->key, &sigrdata)) {
  433. vbprintf(2, "\trrsig by %s retained\n", sigstr);
  434. keep = ISC_TRUE;
  435. wassignedby[key->index] = ISC_TRUE;
  436. nowsignedby[key->index] = ISC_TRUE;
  437. } else {
  438. vbprintf(2, "\trrsig by %s dropped - %s\n",
  439. sigstr, expired ? "expired" :
  440. rrsig.originalttl != set->ttl ?
  441. "ttl change" : "failed to verify");
  442. wassignedby[key->index] = ISC_TRUE;
  443. resign = ISC_TRUE;
  444. }
  445. } else if (iszonekey(key)) {
  446. if (!expired && rrsig.originalttl == set->ttl &&
  447. setverifies(name, set, key->key, &sigrdata)) {
  448. vbprintf(2, "\trrsig by %s retained\n", sigstr);
  449. keep = ISC_TRUE;
  450. wassignedby[key->index] = ISC_TRUE;
  451. nowsignedby[key->index] = ISC_TRUE;
  452. } else {
  453. vbprintf(2, "\trrsig by %s dropped - %s\n",
  454. sigstr, expired ? "expired" :
  455. rrsig.originalttl != set->ttl ?
  456. "ttl change" : "failed to verify");
  457. wassignedby[key->index] = ISC_TRUE;
  458. }
  459. } else if (!expired) {
  460. vbprintf(2, "\trrsig by %s retained\n", sigstr);
  461. keep = ISC_TRUE;
  462. } else {
  463. vbprintf(2, "\trrsig by %s expired\n", sigstr);
  464. }
  465. if (keep) {
  466. if (key != NULL)
  467. nowsignedby[key->index] = ISC_TRUE;
  468. INCSTAT(nretained);
  469. if (sigset.ttl != ttl) {
  470. vbprintf(2, "\tfixing ttl %s\n", sigstr);
  471. tuple = NULL;
  472. result = dns_difftuple_create(mctx,
  473. DNS_DIFFOP_DEL,
  474. name, sigset.ttl,
  475. &sigrdata,
  476. &tuple);
  477. check_result(result, "dns_difftuple_create");
  478. dns_diff_append(del, &tuple);
  479. result = dns_difftuple_create(mctx,
  480. DNS_DIFFOP_ADD,
  481. name, ttl,
  482. &sigrdata,
  483. &tuple);
  484. check_result(result, "dns_difftuple_create");
  485. dns_diff_append(add, &tuple);
  486. }
  487. } else {
  488. tuple = NULL;
  489. result = dns_difftuple_create(mctx, DNS_DIFFOP_DEL,
  490. name, sigset.ttl,
  491. &sigrdata, &tuple);
  492. check_result(result, "dns_difftuple_create");
  493. dns_diff_append(del, &tuple);
  494. INCSTAT(ndropped);
  495. }
  496. if (resign) {
  497. INSIST(!keep);
  498. signwithkey(name, set, key->key, ttl, add,
  499. "resigning with dnskey");
  500. nowsignedby[key->index] = ISC_TRUE;
  501. }
  502. dns_rdata_reset(&sigrdata);
  503. dns_rdata_freestruct(&rrsig);
  504. result = dns_rdataset_next(&sigset);
  505. }
  506. if (result == ISC_R_NOMORE)
  507. result = ISC_R_SUCCESS;
  508. check_result(result, "dns_rdataset_first/next");
  509. if (dns_rdataset_isassociated(&sigset))
  510. dns_rdataset_disassociate(&sigset);
  511. for (key = ISC_LIST_HEAD(keylist);
  512. key != NULL;
  513. key = ISC_LIST_NEXT(key, link))
  514. {
  515. if (nowsignedby[key->index])
  516. continue;
  517. if (!issigningkey(key))
  518. continue;
  519. if (set->type == dns_rdatatype_dnskey &&
  520. dns_name_equal(name, gorigin)) {
  521. isc_boolean_t have_ksk;
  522. dns_dnsseckey_t *tmpkey;
  523. have_ksk = isksk(key);
  524. for (tmpkey = ISC_LIST_HEAD(keylist);
  525. tmpkey != NULL;
  526. tmpkey = ISC_LIST_NEXT(tmpkey, link)) {
  527. if (dst_key_alg(key->key) !=
  528. dst_key_alg(tmpkey->key))
  529. continue;
  530. if (REVOKE(tmpkey->key))
  531. continue;
  532. if (isksk(tmpkey))
  533. have_ksk = ISC_TRUE;
  534. }
  535. if (isksk(key) || !have_ksk ||
  536. (iszsk(key) && !keyset_kskonly))
  537. signwithkey(name, set, key->key, ttl, add,
  538. "signing with dnskey");
  539. } else if (iszsk(key)) {
  540. signwithkey(name, set, key->key, ttl, add,
  541. "signing with dnskey");
  542. }
  543. }
  544. isc_mem_put(mctx, wassignedby, arraysize * sizeof(isc_boolean_t));
  545. isc_mem_put(mctx, nowsignedby, arraysize * sizeof(isc_boolean_t));
  546. }
  547. struct hashlist {
  548. unsigned char *hashbuf;
  549. size_t entries;
  550. size_t size;
  551. size_t length;
  552. };
  553. static void
  554. hashlist_init(hashlist_t *l, unsigned int nodes, unsigned int length) {
  555. l->entries = 0;
  556. l->length = length + 1;
  557. if (nodes != 0) {
  558. l->size = nodes;
  559. l->hashbuf = malloc(l->size * l->length);
  560. if (l->hashbuf == NULL)
  561. l->size = 0;
  562. } else {
  563. l->size = 0;
  564. l->hashbuf = NULL;
  565. }
  566. }
  567. static void
  568. hashlist_add(hashlist_t *l, const unsigned char *hash, size_t len)
  569. {
  570. REQUIRE(len <= l->length);
  571. if (l->entries == l->size) {
  572. l->size = l->size * 2 + 100;
  573. l->hashbuf = realloc(l->hashbuf, l->size * l->length);
  574. }
  575. memset(l->hashbuf + l->entries * l->length, 0, l->length);
  576. memcpy(l->hashbuf + l->entries * l->length, hash, len);
  577. l->entries++;
  578. }
  579. static void
  580. hashlist_add_dns_name(hashlist_t *l, /*const*/ dns_name_t *name,
  581. unsigned int hashalg, unsigned int iterations,
  582. const unsigned char *salt, size_t salt_length,
  583. isc_boolean_t speculative)
  584. {
  585. char nametext[DNS_NAME_FORMATSIZE];
  586. unsigned char hash[NSEC3_MAX_HASH_LENGTH + 1];
  587. unsigned int len;
  588. size_t i;
  589. len = isc_iterated_hash(hash, hashalg, iterations, salt, salt_length,
  590. name->ndata, name->length);
  591. if (verbose) {
  592. dns_name_format(name, nametext, sizeof nametext);
  593. for (i = 0 ; i < len; i++)
  594. fprintf(stderr, "%02x", hash[i]);
  595. fprintf(stderr, " %s\n", nametext);
  596. }
  597. hash[len++] = speculative ? 1 : 0;
  598. hashlist_add(l, hash, len);
  599. }
  600. static int
  601. hashlist_comp(const void *a, const void *b) {
  602. return (memcmp(a, b, hash_length + 1));
  603. }
  604. static void
  605. hashlist_sort(hashlist_t *l) {
  606. qsort(l->hashbuf, l->entries, l->length, hashlist_comp);
  607. }
  608. static isc_boolean_t
  609. hashlist_hasdup(hashlist_t *l) {
  610. unsigned char *current;
  611. unsigned char *next = l->hashbuf;
  612. size_t entries = l->entries;
  613. /*
  614. * Skip initial speculative wild card hashs.
  615. */
  616. while (entries > 0U && next[l->length-1] != 0U) {
  617. next += l->length;
  618. entries--;
  619. }
  620. current = next;
  621. while (entries-- > 1U) {
  622. next += l->length;
  623. if (next[l->length-1] != 0)
  624. continue;
  625. if (memcmp(current, next, l->length - 1) == 0)
  626. return (ISC_TRUE);
  627. current = next;
  628. }
  629. return (ISC_FALSE);
  630. }
  631. static const unsigned char *
  632. hashlist_findnext(const hashlist_t *l,
  633. const unsigned char hash[NSEC3_MAX_HASH_LENGTH])
  634. {
  635. unsigned int entries = l->entries;
  636. const unsigned char *next = bsearch(hash, l->hashbuf, l->entries,
  637. l->length, hashlist_comp);
  638. INSIST(next != NULL);
  639. do {
  640. if (next < l->hashbuf + (l->entries - 1) * l->length)
  641. next += l->length;
  642. else
  643. next = l->hashbuf;
  644. if (next[l->length - 1] == 0)
  645. break;
  646. } while (entries-- > 1);
  647. INSIST(entries != 0);
  648. return (next);
  649. }
  650. static isc_boolean_t
  651. hashlist_exists(const hashlist_t *l,
  652. const unsigned char hash[NSEC3_MAX_HASH_LENGTH])
  653. {
  654. if (bsearch(hash, l->hashbuf, l->entries, l->length, hashlist_comp))
  655. return (ISC_TRUE);
  656. else
  657. return (ISC_FALSE);
  658. }
  659. static void
  660. addnowildcardhash(hashlist_t *l, /*const*/ dns_name_t *name,
  661. unsigned int hashalg, unsigned int iterations,
  662. const unsigned char *salt, size_t salt_length)
  663. {
  664. dns_fixedname_t fixed;
  665. dns_name_t *wild;
  666. dns_dbnode_t *node = NULL;
  667. isc_result_t result;
  668. char namestr[DNS_NAME_FORMATSIZE];
  669. dns_fixedname_init(&fixed);
  670. wild = dns_fixedname_name(&fixed);
  671. result = dns_name_concatenate(dns_wildcardname, name, wild, NULL);
  672. if (result == ISC_R_NOSPACE)
  673. return;
  674. check_result(result,"addnowildcardhash: dns_name_concatenate()");
  675. result = dns_db_findnode(gdb, wild, ISC_FALSE, &node);
  676. if (result == ISC_R_SUCCESS) {
  677. dns_db_detachnode(gdb, &node);
  678. return;
  679. }
  680. if (verbose) {
  681. dns_name_format(wild, namestr, sizeof(namestr));
  682. fprintf(stderr, "adding no-wildcardhash for %s\n", namestr);
  683. }
  684. hashlist_add_dns_name(l, wild, hashalg, iterations, salt, salt_length,
  685. ISC_TRUE);
  686. }
  687. static void
  688. opendb(const char *prefix, dns_name_t *name, dns_rdataclass_t rdclass,
  689. dns_db_t **dbp)
  690. {
  691. char filename[PATH_MAX];
  692. isc_buffer_t b;
  693. isc_result_t result;
  694. isc_buffer_init(&b, filename, sizeof(filename));
  695. if (dsdir != NULL) {
  696. /* allow room for a trailing slash */
  697. if (strlen(dsdir) >= isc_buffer_availablelength(&b))
  698. fatal("path '%s' is too long", dsdir);
  699. isc_buffer_putstr(&b, dsdir);
  700. if (dsdir[strlen(dsdir) - 1] != '/')
  701. isc_buffer_putstr(&b, "/");
  702. }
  703. if (strlen(prefix) > isc_buffer_availablelength(&b))
  704. fatal("path '%s' is too long", dsdir);
  705. isc_buffer_putstr(&b, prefix);
  706. result = dns_name_tofilenametext(name, ISC_FALSE, &b);
  707. check_result(result, "dns_name_tofilenametext()");
  708. if (isc_buffer_availablelength(&b) == 0) {
  709. char namestr[DNS_NAME_FORMATSIZE];
  710. dns_name_format(name, namestr, sizeof(namestr));
  711. fatal("name '%s' is too long", namestr);
  712. }
  713. isc_buffer_putuint8(&b, 0);
  714. result = dns_db_create(mctx, "rbt", dns_rootname, dns_dbtype_zone,
  715. rdclass, 0, NULL, dbp);
  716. check_result(result, "dns_db_create()");
  717. result = dns_db_load3(*dbp, filename, inputformat, DNS_MASTER_HINT);
  718. if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE)
  719. dns_db_detach(dbp);
  720. }
  721. /*%
  722. * Load the DS set for a child zone, if a dsset-* file can be found.
  723. * If not, try to find a keyset-* file from an earlier version of
  724. * dnssec-signzone, and build DS records from that.
  725. */
  726. static isc_result_t
  727. loadds(dns_name_t *name, isc_uint32_t ttl, dns_rdataset_t *dsset) {
  728. dns_db_t *db = NULL;
  729. dns_dbversion_t *ver = NULL;
  730. dns_dbnode_t *node = NULL;
  731. isc_result_t result;
  732. dns_rdataset_t keyset;
  733. dns_rdata_t key, ds;
  734. unsigned char dsbuf[DNS_DS_BUFFERSIZE];
  735. dns_diff_t diff;
  736. dns_difftuple_t *tuple = NULL;
  737. opendb("dsset-", name, gclass, &db);
  738. if (db != NULL) {
  739. result = dns_db_findnode(db, name, ISC_FALSE, &node);
  740. if (result == ISC_R_SUCCESS) {
  741. dns_rdataset_init(dsset);
  742. result = dns_db_findrdataset(db, node, NULL,
  743. dns_rdatatype_ds, 0, 0,
  744. dsset, NULL);
  745. dns_db_detachnode(db, &node);
  746. if (result == ISC_R_SUCCESS) {
  747. vbprintf(2, "found DS records\n");
  748. dsset->ttl = ttl;
  749. dns_db_detach(&db);
  750. return (result);
  751. }
  752. }
  753. dns_db_detach(&db);
  754. }
  755. /* No DS records found; try again, looking for DNSKEY records */
  756. opendb("keyset-", name, gclass, &db);
  757. if (db == NULL) {
  758. return (ISC_R_NOTFOUND);
  759. }
  760. result = dns_db_findnode(db, name, ISC_FALSE, &node);
  761. if (result != ISC_R_SUCCESS) {
  762. dns_db_detach(&db);
  763. return (result);
  764. }
  765. dns_rdataset_init(&keyset);
  766. result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_dnskey, 0, 0,
  767. &keyset, NULL);
  768. if (result != ISC_R_SUCCESS) {
  769. dns_db_detachnode(db, &node);
  770. dns_db_detach(&db);
  771. return (result);
  772. }
  773. vbprintf(2, "found DNSKEY records\n");
  774. result = dns_db_newversion(db, &ver);
  775. check_result(result, "dns_db_newversion");
  776. dns_diff_init(mctx, &diff);
  777. for (result = dns_rdataset_first(&keyset);
  778. result == ISC_R_SUCCESS;
  779. result = dns_rdataset_next(&keyset))
  780. {
  781. dns_rdata_init(&key);
  782. dns_rdata_init(&ds);
  783. dns_rdataset_current(&keyset, &key);
  784. result = dns_ds_buildrdata(name, &key, DNS_DSDIGEST_SHA1,
  785. dsbuf, &ds);
  786. check_result(result, "dns_ds_buildrdata");
  787. result = dns_difftuple_create(mctx, DNS_DIFFOP_ADD, name,
  788. ttl, &ds, &tuple);
  789. check_result(result, "dns_difftuple_create");
  790. dns_diff_append(&diff, &tuple);
  791. dns_rdata_reset(&ds);
  792. result = dns_ds_buildrdata(name, &key, DNS_DSDIGEST_SHA256,
  793. dsbuf, &ds);
  794. check_result(result, "dns_ds_buildrdata");
  795. result = dns_difftuple_create(mctx, DNS_DIFFOP_ADD, name,
  796. ttl, &ds, &tuple);
  797. check_result(result, "dns_difftuple_create");
  798. dns_diff_append(&diff, &tuple);
  799. }
  800. result = dns_diff_apply(&diff, db, ver);
  801. check_result(result, "dns_diff_apply");
  802. dns_diff_clear(&diff);
  803. dns_db_closeversion(db, &ver, ISC_TRUE);
  804. result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_ds, 0, 0,
  805. dsset, NULL);
  806. check_result(result, "dns_db_findrdataset");
  807. dns_rdataset_disassociate(&keyset);
  808. dns_db_detachnode(db, &node);
  809. dns_db_detach(&db);
  810. return (result);
  811. }
  812. static isc_boolean_t
  813. delegation(dns_name_t *name, dns_dbnode_t *node, isc_uint32_t *ttlp) {
  814. dns_rdataset_t nsset;
  815. isc_result_t result;
  816. if (dns_name_equal(name, gorigin))
  817. return (ISC_FALSE);
  818. dns_rdataset_init(&nsset);
  819. result = dns_db_findrdataset(gdb, node, gversion, dns_rdatatype_ns,
  820. 0, 0, &nsset, NULL);
  821. if (dns_rdataset_isassociated(&nsset)) {
  822. if (ttlp != NULL)
  823. *ttlp = nsset.ttl;
  824. dns_rdataset_disassociate(&nsset);
  825. }
  826. return (ISC_TF(result == ISC_R_SUCCESS));
  827. }
  828. static isc_boolean_t
  829. secure(dns_name_t *name, dns_dbnode_t *node) {
  830. dns_rdataset_t dsset;
  831. isc_result_t result;
  832. if (dns_name_equal(name, gorigin))
  833. return (ISC_FALSE);
  834. dns_rdataset_init(&dsset);
  835. result = dns_db_findrdataset(gdb, node, gversion, dns_rdatatype_ds,
  836. 0, 0, &dsset, NULL);
  837. if (dns_rdataset_isassociated(&dsset))
  838. dns_rdataset_disassociate(&dsset);
  839. return (ISC_TF(result == ISC_R_SUCCESS));
  840. }
  841. /*%
  842. * Signs all records at a name.
  843. */
  844. static void
  845. signname(dns_dbnode_t *node, dns_name_t *name) {
  846. isc_result_t result;
  847. dns_rdataset_t rdataset;
  848. dns_rdatasetiter_t *rdsiter;
  849. isc_boolean_t isdelegation = ISC_FALSE;
  850. dns_diff_t del, add;
  851. char namestr[DNS_NAME_FORMATSIZE];
  852. dns_rdataset_init(&rdataset);
  853. dns_name_format(name, namestr, sizeof(namestr));
  854. /*
  855. * Determine if this is a delegation point.
  856. */
  857. if (delegation(name, node, NULL))
  858. isdelegation = ISC_TRUE;
  859. /*
  860. * Now iterate through the rdatasets.
  861. */
  862. dns_diff_init(mctx, &del);
  863. dns_diff_init(mctx, &add);
  864. rdsiter = NULL;
  865. result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter);
  866. check_result(result, "dns_db_allrdatasets()");
  867. result = dns_rdatasetiter_first(rdsiter);
  868. while (result == ISC_R_SUCCESS) {
  869. dns_rdatasetiter_current(rdsiter, &rdataset);
  870. /* If this is a RRSIG set, skip it. */
  871. if (rdataset.type == dns_rdatatype_rrsig)
  872. goto skip;
  873. /*
  874. * If this name is a delegation point, skip all records
  875. * except NSEC and DS sets. Otherwise check that there
  876. * isn't a DS record.
  877. */
  878. if (isdelegation) {
  879. if (rdataset.type != nsec_datatype &&
  880. rdataset.type != dns_rdatatype_ds)
  881. goto skip;
  882. } else if (rdataset.type == dns_rdatatype_ds) {
  883. char namebuf[DNS_NAME_FORMATSIZE];
  884. dns_name_format(name, namebuf, sizeof(namebuf));
  885. fatal("'%s': found DS RRset without NS RRset\n",
  886. namebuf);
  887. }
  888. signset(&del, &add, node, name, &rdataset);
  889. skip:
  890. dns_rdataset_disassociate(&rdataset);
  891. result = dns_rdatasetiter_next(rdsiter);
  892. }
  893. if (result != ISC_R_NOMORE)
  894. fatal("rdataset iteration for name '%s' failed: %s",
  895. namestr, isc_result_totext(result));
  896. dns_rdatasetiter_destroy(&rdsiter);
  897. result = dns_diff_applysilently(&del, gdb, gversion);
  898. if (result != ISC_R_SUCCESS)
  899. fatal("failed to delete SIGs at node '%s': %s",
  900. namestr, isc_result_totext(result));
  901. result = dns_diff_applysilently(&add, gdb, gversion);
  902. if (result != ISC_R_SUCCESS)
  903. fatal("failed to add SIGs at node '%s': %s",
  904. namestr, isc_result_totext(result));
  905. dns_diff_clear(&del);
  906. dns_diff_clear(&add);
  907. }
  908. static inline isc_boolean_t
  909. active_node(dns_dbnode_t *node) {
  910. dns_rdatasetiter_t *rdsiter = NULL;
  911. dns_rdatasetiter_t *rdsiter2 = NULL;
  912. isc_boolean_t active = ISC_FALSE;
  913. isc_result_t result;
  914. dns_rdataset_t rdataset;
  915. dns_rdatatype_t type;
  916. dns_rdatatype_t covers;
  917. isc_boolean_t found;
  918. dns_rdataset_init(&rdataset);
  919. result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter);
  920. check_result(result, "dns_db_allrdatasets()");
  921. result = dns_rdatasetiter_first(rdsiter);
  922. while (result == ISC_R_SUCCESS) {
  923. dns_rdatasetiter_current(rdsiter, &rdataset);
  924. if (rdataset.type != dns_rdatatype_nsec &&
  925. rdataset.type != dns_rdatatype_nsec3 &&
  926. rdataset.type != dns_rdatatype_rrsig)
  927. active = ISC_TRUE;
  928. dns_rdataset_disassociate(&rdataset);
  929. if (!active)
  930. result = dns_rdatasetiter_next(rdsiter);
  931. else
  932. result = ISC_R_NOMORE;
  933. }
  934. if (result != ISC_R_NOMORE)
  935. fatal("rdataset iteration failed: %s",
  936. isc_result_totext(result));
  937. if (!active && nsec_datatype == dns_rdatatype_nsec) {
  938. /*%
  939. * The node is empty of everything but NSEC / RRSIG records.
  940. */
  941. for (result = dns_rdatasetiter_first(rdsiter);
  942. result == ISC_R_SUCCESS;
  943. result = dns_rdatasetiter_next(rdsiter)) {
  944. dns_rdatasetiter_current(rdsiter, &rdataset);
  945. result = dns_db_deleterdataset(gdb, node, gversion,
  946. rdataset.type,
  947. rdataset.covers);
  948. check_result(result, "dns_db_deleterdataset()");
  949. dns_rdataset_disassociate(&rdataset);
  950. }
  951. if (result != ISC_R_NOMORE)
  952. fatal("rdataset iteration failed: %s",
  953. isc_result_totext(result));
  954. } else {
  955. /*
  956. * Delete RRSIGs for types that no longer exist.
  957. */
  958. result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter2);
  959. check_result(result, "dns_db_allrdatasets()");
  960. for (result = dns_rdatasetiter_first(rdsiter);
  961. result == ISC_R_SUCCESS;
  962. result = dns_rdatasetiter_next(rdsiter)) {
  963. dns_rdatasetiter_current(rdsiter, &rdataset);
  964. type = rdataset.type;
  965. covers = rdataset.covers;
  966. dns_rdataset_disassociate(&rdataset);
  967. /*
  968. * Delete the NSEC chain if we are signing with
  969. * NSEC3.
  970. */
  971. if (nsec_datatype == dns_rdatatype_nsec3 &&
  972. (type == dns_rdatatype_nsec ||
  973. covers == dns_rdatatype_nsec)) {
  974. result = dns_db_deleterdataset(gdb, node,
  975. gversion, type,
  976. covers);
  977. check_result(result,
  978. "dns_db_deleterdataset(nsec/rrsig)");
  979. continue;
  980. }
  981. if (type != dns_rdatatype_rrsig)
  982. continue;
  983. found = ISC_FALSE;
  984. for (result = dns_rdatasetiter_first(rdsiter2);
  985. !found && result == ISC_R_SUCCESS;
  986. result = dns_rdatasetiter_next(rdsiter2)) {
  987. dns_rdatasetiter_current(rdsiter2, &rdataset);
  988. if (rdataset.type == covers)
  989. found = ISC_TRUE;
  990. dns_rdataset_disassociate(&rdataset);
  991. }
  992. if (!found) {
  993. if (result != ISC_R_NOMORE)
  994. fatal("rdataset iteration failed: %s",
  995. isc_result_totext(result));
  996. result = dns_db_deleterdataset(gdb, node,
  997. gversion, type,
  998. covers);
  999. check_result(result,
  1000. "dns_db_deleterdataset(rrsig)");
  1001. } else if (result != ISC_R_NOMORE &&
  1002. result != ISC_R_SUCCESS)
  1003. fatal("rdataset iteration failed: %s",
  1004. isc_result_totext(result));
  1005. }
  1006. if (result != ISC_R_NOMORE)
  1007. fatal("rdataset iteration failed: %s",
  1008. isc_result_totext(result));
  1009. dns_rdatasetiter_destroy(&rdsiter2);
  1010. }
  1011. dns_rdatasetiter_destroy(&rdsiter);
  1012. return (active);
  1013. }
  1014. /*%
  1015. * Extracts the minimum TTL from the SOA record, and the SOA record's TTL.
  1016. */
  1017. static void
  1018. get_soa_ttls(void) {
  1019. dns_rdataset_t soaset;
  1020. dns_fixedname_t fname;
  1021. dns_name_t *name;
  1022. isc_result_t result;
  1023. dns_rdata_t rdata = DNS_RDATA_INIT;
  1024. dns_fixedname_init(&fname);
  1025. name = dns_fixedname_name(&fname);
  1026. dns_rdataset_init(&soaset);
  1027. result = dns_db_find(gdb, gorigin, gversion, dns_rdatatype_soa,
  1028. 0, 0, NULL, name, &soaset, NULL);
  1029. if (result != ISC_R_SUCCESS)
  1030. fatal("failed to find an SOA at the zone apex: %s",
  1031. isc_result_totext(result));
  1032. result = dns_rdataset_first(&soaset);
  1033. check_result(result, "dns_rdataset_first");
  1034. dns_rdataset_current(&soaset, &rdata);
  1035. zone_soa_min_ttl = dns_soa_getminimum(&rdata);
  1036. soa_ttl = soaset.ttl;
  1037. dns_rdataset_disassociate(&soaset);
  1038. }
  1039. /*%
  1040. * Increment (or set if nonzero) the SOA serial
  1041. */
  1042. static isc_result_t
  1043. setsoaserial(isc_uint32_t serial) {
  1044. isc_result_t result;
  1045. dns_dbnode_t *node = NULL;
  1046. dns_rdataset_t rdataset;
  1047. dns_rdata_t rdata = DNS_RDATA_INIT;
  1048. isc_uint32_t old_serial, new_serial;
  1049. result = dns_db_getoriginnode(gdb, &node);
  1050. if (result != ISC_R_SUCCESS)
  1051. return result;
  1052. dns_rdataset_init(&rdataset);
  1053. result = dns_db_findrdataset(gdb, node, gversion,
  1054. dns_rdatatype_soa, 0,
  1055. 0, &rdataset, NULL);
  1056. if (result != ISC_R_SUCCESS)
  1057. goto cleanup;
  1058. result = dns_rdataset_first(&rdataset);
  1059. RUNTIME_CHECK(result == ISC_R_SUCCESS);
  1060. dns_rdataset_current(&rdataset, &rdata);
  1061. old_serial = dns_soa_getserial(&rdata);
  1062. if (serial) {
  1063. /* Set SOA serial to the value provided. */
  1064. new_serial = serial;
  1065. } else {
  1066. /* Increment SOA serial using RFC 1982 arithmetics */
  1067. new_serial = (old_serial + 1) & 0xFFFFFFFF;
  1068. if (new_serial == 0)
  1069. new_serial = 1;
  1070. }
  1071. /* If the new serial is not likely to cause a zone transfer
  1072. * (a/ixfr) from servers having the old serial, warn the user.
  1073. *
  1074. * RFC1982 section 7 defines the maximum increment to be
  1075. * (2^(32-1))-1. Using u_int32_t arithmetic, we can do a single
  1076. * comparison. (5 - 6 == (2^32)-1, not negative-one)
  1077. */
  1078. if (new_serial == old_serial ||
  1079. (new_serial - old_serial) > 0x7fffffffU)
  1080. fprintf(stderr, "%s: warning: Serial number not advanced, "
  1081. "zone may not transfer\n", program);
  1082. dns_soa_setserial(new_serial, &rdata);
  1083. result = dns_db_deleterdataset(gdb, node, gversion,
  1084. dns_rdatatype_soa, 0);
  1085. check_result(result, "dns_db_deleterdataset");
  1086. if (result != ISC_R_SUCCESS)
  1087. goto cleanup;
  1088. result = dns_db_addrdataset(gdb, node, gversion,
  1089. 0, &rdataset, 0, NULL);
  1090. check_result(result, "dns_db_addrdataset");
  1091. if (result != ISC_R_SUCCESS)
  1092. goto cleanup;
  1093. cleanup:
  1094. dns_rdataset_disassociate(&rdataset);
  1095. if (node != NULL)
  1096. dns_db_detachnode(gdb, &node);
  1097. dns_rdata_reset(&rdata);
  1098. return (result);
  1099. }
  1100. /*%
  1101. * Delete any RRSIG records at a node.
  1102. */
  1103. static void
  1104. cleannode(dns_db_t *db, dns_dbversion_t *version, dns_dbnode_t *node) {
  1105. dns_rdatasetiter_t *rdsiter = NULL;
  1106. dns_rdataset_t set;
  1107. isc_result_t result, dresult;
  1108. if (outputformat != dns_masterformat_text || !disable_zone_check)
  1109. return;
  1110. dns_rdataset_init(&set);
  1111. result = dns_db_allrdatasets(db, node, version, 0, &rdsiter);
  1112. check_result(result, "dns_db_allrdatasets");
  1113. result = dns_rdatasetiter_first(rdsiter);
  1114. while (result == ISC_R_SUCCESS) {
  1115. isc_boolean_t destroy = ISC_FALSE;
  1116. dns_rdatatype_t covers = 0;
  1117. dns_rdatasetiter_current(rdsiter, &set);
  1118. if (set.type == dns_rdatatype_rrsig) {
  1119. covers = set.covers;
  1120. destroy = ISC_TRUE;
  1121. }
  1122. dns_rdataset_disassociate(&set);
  1123. result = dns_rdatasetiter_next(rdsiter);
  1124. if (destroy) {
  1125. dresult = dns_db_deleterdataset(db, node, version,
  1126. dns_rdatatype_rrsig,
  1127. covers);
  1128. check_result(dresult, "dns_db_deleterdataset");
  1129. }
  1130. }
  1131. if (result != ISC_R_NOMORE)
  1132. fatal("rdataset iteration failed: %s",
  1133. isc_result_totext(result));
  1134. dns_rdatasetiter_destroy(&rdsiter);
  1135. }
  1136. /*%
  1137. * Set up the iterator and global state before starting the tasks.
  1138. */
  1139. static void
  1140. presign(void) {
  1141. isc_result_t result;
  1142. gdbiter = NULL;
  1143. result = dns_db_createiterator(gdb, 0, &gdbiter);
  1144. check_result(result, "dns_db_createiterator()");
  1145. }
  1146. /*%
  1147. * Clean up the iterator and global state after the tasks complete.
  1148. */
  1149. static void
  1150. postsign(void) {
  1151. dns_dbiterator_destroy(&gdbiter);
  1152. }
  1153. static isc_boolean_t
  1154. goodsig(dns_rdata_t *sigrdata, dns_name_t *name, dns_rdataset_t *keyrdataset,
  1155. dns_rdataset_t *rdataset)
  1156. {
  1157. dns_rdata_dnskey_t key;
  1158. dns_rdata_rrsig_t sig;
  1159. dst_key_t *dstkey = NULL;
  1160. isc_result_t result;
  1161. dns_rdata_tostruct(sigrdata, &sig, NULL);
  1162. for (result = dns_rdataset_first(keyrdataset);
  1163. result == ISC_R_SUCCESS;
  1164. result = dns_rdataset_next(keyrdataset)) {
  1165. dns_rdata_t rdata = DNS_RDATA_INIT;
  1166. dns_rdataset_current(keyrdataset, &rdata);
  1167. dns_rdata_tostruct(&rdata, &key, NULL);
  1168. result = dns_dnssec_keyfromrdata(gorigin, &rdata, mctx,
  1169. &dstkey);
  1170. if (result != ISC_R_SUCCESS)
  1171. return (ISC_FALSE);
  1172. if (sig.algorithm != key.algorithm ||
  1173. sig.keyid != dst_key_id(dstkey) ||
  1174. !dns_name_equal(&sig.signer, gorigin)) {
  1175. dst_key_free(&dstkey);
  1176. continue;
  1177. }
  1178. result = dns_dnssec_verify(name, rdataset, dstkey, ISC_FALSE,
  1179. mctx, sigrdata);
  1180. dst_key_free(&dstkey);
  1181. if (result == ISC_R_SUCCESS)
  1182. return(ISC_TRUE);
  1183. }
  1184. return (ISC_FALSE);
  1185. }
  1186. static void
  1187. verifyset(dns_rdataset_t *rdataset, dns_name_t *name, dns_dbnode_t *node,
  1188. dns_rdataset_t *keyrdataset, unsigned char *ksk_algorithms,
  1189. unsigned char *bad_algorithms)
  1190. {
  1191. unsigned char set_algorithms[256];
  1192. char namebuf[DNS_NAME_FORMATSIZE];
  1193. char algbuf[80];
  1194. char typebuf[80];
  1195. dns_rdataset_t sigrdataset;
  1196. dns_rdatasetiter_t *rdsiter = NULL;
  1197. isc_result_t result;
  1198. int i;
  1199. dns_rdataset_init(&sigrdataset);
  1200. result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter);
  1201. check_result(result, "dns_db_allrdatasets()");
  1202. for (result = dns_rdatasetiter_first(rdsiter);
  1203. result == ISC_R_SUCCESS;
  1204. result = dns_rdatasetiter_next(rdsiter)) {
  1205. dns_rdatasetiter_current(rdsiter, &sigrdataset);
  1206. if (sigrdataset.type == dns_rdatatype_rrsig &&
  1207. sigrdataset.covers == rdataset->type)
  1208. break;
  1209. dns_rdataset_disassociate(&sigrdataset);
  1210. }
  1211. if (result != ISC_R_SUCCESS) {
  1212. dns_name_format(name, namebuf, sizeof(namebuf));
  1213. type_format(rdataset->type, typebuf, sizeof(typebuf));
  1214. fprintf(stderr, "no signatures for %s/%s\n", namebuf, typebuf);
  1215. for (i = 0; i < 256; i++)
  1216. if (ksk_algorithms[i] != 0)
  1217. bad_algorithms[i] = 1;
  1218. return;
  1219. }
  1220. memset(set_algorithms, 0, sizeof(set_algorithms));
  1221. for (result = dns_rdataset_first(&sigrdataset);
  1222. result == ISC_R_SUCCESS;
  1223. result = dns_rdataset_next(&sigrdataset)) {
  1224. dns_rdata_t rdata = DNS_RDATA_INIT;
  1225. dns_rdata_rrsig_t sig;
  1226. dns_rdataset_current(&sigrdataset, &rdata);
  1227. dns_rdata_tostruct(&rdata, &sig, NULL);
  1228. if (rdataset->ttl != sig.originalttl) {
  1229. dns_name_format(name, namebuf, sizeof(namebuf));
  1230. type_format(rdataset->type, typebuf, sizeof(typebuf));
  1231. fprintf(stderr, "TTL mismatch for %s %s keytag %u\n",
  1232. namebuf, typebuf, sig.keyid);
  1233. continue;
  1234. }
  1235. if ((set_algorithms[sig.algorithm] != 0) ||
  1236. (ksk_algorithms[sig.algorithm] == 0))
  1237. continue;
  1238. if (goodsig(&rdata, name, keyrdataset, rdataset))
  1239. set_algorithms[sig.algorithm] = 1;
  1240. }
  1241. dns_rdatasetiter_destroy(&rdsiter);
  1242. if (memcmp(set_algorithms, ksk_algorithms, sizeof(set_algorithms))) {
  1243. dns_name_format(name, namebuf, sizeof(namebuf));
  1244. type_format(rdataset->type, typebuf, sizeof(typebuf));
  1245. for (i = 0; i < 256; i++)
  1246. if ((ksk_algorithms[i] != 0) &&
  1247. (set_algorithms[i] == 0)) {
  1248. dns_secalg_format(i, algbuf, sizeof(algbuf));
  1249. fprintf(stderr, "Missing %s signature for "
  1250. "%s %s\n", algbuf, namebuf, typebuf);
  1251. bad_algorithms[i] = 1;
  1252. }
  1253. }
  1254. dns_rdataset_disassociate(&sigrdataset);
  1255. }
  1256. static void
  1257. verifynode(dns_name_t *name, dns_dbnode_t *node, isc_boolean_t delegation,
  1258. dns_rdataset_t *keyrdataset, unsigned char *ksk_algorithms,
  1259. unsigned char *bad_algorithms)
  1260. {
  1261. dns_rdataset_t rdataset;
  1262. dns_rdatasetiter_t *rdsiter = NULL;
  1263. isc_result_t result;
  1264. result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter);
  1265. check_result(result, "dns_db_allrdatasets()");
  1266. result = dns_rdatasetiter_first(rdsiter);
  1267. dns_rdataset_init(&rdataset);
  1268. while (result == ISC_R_SUCCESS) {
  1269. dns_rdatasetiter_current(rdsiter, &rdataset);
  1270. if (rdataset.type != dns_rdatatype_rrsig &&
  1271. rdataset.type != dns_rdatatype_dnskey &&
  1272. (!delegation || rdataset.type == dns_rdatatype_ds ||
  1273. rdataset.type == dns_rdatatype_nsec)) {
  1274. verifyset(&rdataset, name, node, keyrdataset,
  1275. ksk_algorithms, bad_algorithms);
  1276. }
  1277. dns_rdataset_disassociate(&rdataset);
  1278. result = dns_rdatasetiter_next(rdsiter);
  1279. }
  1280. if (result != ISC_R_NOMORE)
  1281. fatal("rdataset iteration failed: %s",
  1282. isc_result_totext(result));
  1283. dns_rdatasetiter_destroy(&rdsiter);
  1284. }
  1285. /*%
  1286. * Verify that certain things are sane:
  1287. *
  1288. * The apex has a DNSKEY RRset with at least one KSK, and at least
  1289. * one ZSK if the -x flag was not used.
  1290. *
  1291. * The DNSKEY record was signed with at least one of the KSKs in
  1292. * the DNSKEY RRset.
  1293. *
  1294. * The rest of the zone was signed with at least one of the ZSKs
  1295. * present in the DNSKEY RRset.
  1296. */
  1297. static void
  1298. verifyzone(void) {
  1299. char algbuf[80];
  1300. dns_dbiterator_t *dbiter = NULL;
  1301. dns_dbnode_t *node = NULL, *nextnode = NULL;
  1302. dns_fixedname_t fname, fnextname, fzonecut;
  1303. dns_name_t *name, *nextname, *zonecut;
  1304. dns_rdata_dnskey_t dnskey;
  1305. dns_rdata_t rdata = DNS_RDATA_INIT;
  1306. dns_rdataset_t keyset, soaset;
  1307. dns_rdataset_t keysigs, soasigs;
  1308. int i;
  1309. isc_boolean_t done = ISC_FALSE;
  1310. isc_boolean_t first = ISC_TRUE;
  1311. isc_boolean_t goodksk = ISC_FALSE;
  1312. isc_result_t result;
  1313. unsigned char revoked_ksk[256];
  1314. unsigned char revoked_zsk[256];
  1315. unsigned char standby_ksk[256];
  1316. unsigned char standby_zsk[256];
  1317. unsigned char ksk_algorithms[256];
  1318. unsigned char zsk_algorithms[256];
  1319. unsigned char bad_algorithms[256];
  1320. #ifdef ALLOW_KSKLESS_ZONES
  1321. isc_boolean_t allzsksigned = ISC_TRUE;
  1322. unsigned char self_algorithms[256];
  1323. #endif
  1324. if (disable_zone_check)
  1325. return;
  1326. result = dns_db_findnode(gdb, gorigin, ISC_FALSE, &node);
  1327. if (result != ISC_R_SUCCESS)
  1328. fatal("failed to find the zone's origin: %s",
  1329. isc_result_totext(result));
  1330. dns_rdataset_init(&keyset);
  1331. dns_rdataset_init(&keysigs);
  1332. dns_rdataset_init(&soaset);
  1333. dns_rdataset_init(&soasigs);
  1334. result = dns_db_findrdataset(gdb, node, gversion,
  1335. dns_rdatatype_dnskey,
  1336. 0, 0, &keyset, &keysigs);
  1337. if (result != ISC_R_SUCCESS)
  1338. fatal("cannot find DNSKEY rrset\n");
  1339. result = dns_db_findrdataset(gdb, node, gversion,
  1340. dns_rdatatype_soa,
  1341. 0, 0, &soaset, &soasigs);
  1342. dns_db_detachnode(gdb, &node);
  1343. if (result != ISC_R_SUCCESS)
  1344. fatal("cannot find SOA rrset\n");
  1345. if (!dns_rdataset_isassociated(&keysigs))
  1346. fatal("cannot find DNSKEY RRSIGs\n");
  1347. if (!dns_rdataset_isassociated(&soasigs))
  1348. fatal("cannot find SOA RRSIGs\n");
  1349. memset(revoked_ksk, 0, sizeof(revoked_ksk));
  1350. memset(revoked_zsk, 0, sizeof(revoked_zsk));
  1351. memset(standby_ksk, 0, sizeof(standby_ksk));
  1352. memset(standby_zsk, 0, sizeof(standby_zsk));
  1353. memset(ksk_algorithms, 0, sizeof(ksk_algorithms));
  1354. memset(zsk_algorithms, 0, sizeof(zsk_algorithms));
  1355. memset(bad_algorithms, 0, sizeof(bad_algorithms));
  1356. #ifdef ALLOW_KSKLESS_ZONES
  1357. memset(self_algorithms, 0, sizeof(self_algorithms));
  1358. #endif
  1359. /*
  1360. * Check that the DNSKEY RR has at least one self signing KSK
  1361. * and one ZSK per algorithm in it (or, if -x was used, one
  1362. * self-signing KSK).
  1363. */
  1364. for (result = dns_rdataset_first(&keyset);
  1365. result == ISC_R_SUCCESS;
  1366. result = dns_rdataset_next(&keyset)) {
  1367. dns_rdataset_current(&keyset, &rdata);
  1368. result = dns_rdata_tostruct(&rdata, &dnskey, NULL);
  1369. check_result(result, "dns_rdata_tostruct");
  1370. if ((dnskey.flags & DNS_KEYOWNER_ZONE) == 0)
  1371. ;
  1372. else if ((dnskey.flags & DNS_KEYFLAG_REVOKE) != 0) {
  1373. if ((dnskey.flags & DNS_KEYFLAG_KSK) != 0 &&
  1374. !dns_dnssec_selfsigns(&rdata, gorigin, &keyset,
  1375. &keysigs, ISC_FALSE,
  1376. mctx)) {
  1377. char namebuf[DNS_NAME_FORMATSIZE];
  1378. char buffer[1024];
  1379. isc_buffer_t buf;
  1380. dns_name_format(gorigin, namebuf,
  1381. sizeof(namebuf));
  1382. isc_buffer_init(&buf, buffer, sizeof(buffer));
  1383. result = dns_rdata_totext(&rdata, NULL, &buf);
  1384. check_result(result, "dns_rdata_totext");
  1385. fatal("revoked KSK is not self signed:\n"
  1386. "%s DNSKEY %.*s", namebuf,
  1387. (int)isc_buffer_usedlength(&buf), buffer);
  1388. }
  1389. if ((dnskey.flags & DNS_KEYFLAG_KSK) != 0 &&
  1390. revoked_ksk[dnskey.algorithm] != 255)
  1391. revoked_ksk[dnskey.algorithm]++;
  1392. else if ((dnskey.flags & DNS_KEYFLAG_KSK) == 0 &&
  1393. revoked_zsk[dnskey.algorithm] != 255)
  1394. revoked_zsk[dnskey.algorithm]++;
  1395. } else if ((dnskey.flags & DNS_KEYFLAG_KSK) != 0) {
  1396. if (dns_dnssec_selfsigns(&rdata, gorigin, &keyset,
  1397. &keysigs, ISC_FALSE, mctx)) {
  1398. if (ksk_algorithms[dnskey.algorithm] != 255)
  1399. ksk_algorithms[dnskey.algorithm]++;
  1400. goodksk = ISC_TRUE;
  1401. } else {
  1402. if (standby_ksk[dnskey.algorithm] != 255)
  1403. standby_ksk[dnskey.algorithm]++;
  1404. }
  1405. } else if (dns_dnssec_selfsigns(&rdata, gorigin, &keyset,
  1406. &keysigs, ISC_FALSE,
  1407. mctx)) {
  1408. #ifdef ALLOW_KSKLESS_ZONES
  1409. if (self_algorithms[dnskey.algorithm] != 255)
  1410. self_algorithms[dnskey.algorithm]++;
  1411. #endif
  1412. if (zsk_algorithms[dnskey.algorithm] != 255)
  1413. zsk_algorithms[dnskey.algorithm]++;
  1414. } else if (dns_dnssec_signs(&rdata, gorigin, &soaset,
  1415. &soasigs, ISC_FALSE, mctx)) {
  1416. if (zsk_algorithms[dnskey.algorithm] != 255)
  1417. zsk_algorithms[dnskey.algorithm]++;
  1418. } else {
  1419. if (standby_zsk[dnskey.algorithm] != 255)
  1420. standby_zsk[dnskey.algorithm]++;
  1421. #ifdef ALLOW_KSKLESS_ZONES
  1422. allzsksigned = ISC_FALSE;
  1423. #endif
  1424. }
  1425. dns_rdata_freestruct(&dnskey);
  1426. dns_rdata_reset(&rdata);
  1427. }
  1428. dns_rdataset_disassociate(&keysigs);
  1429. dns_rdataset_disassociate(&soaset);
  1430. dns_rdataset_disassociate(&soasigs);
  1431. #ifdef ALLOW_KSKLESS_ZONES
  1432. if (!goodksk) {
  1433. if (!ignore_kskflag)
  1434. fprintf(stderr, "No self signing KSK found. Using "
  1435. "self signed ZSK's for active "
  1436. "algorithm list.\n");
  1437. memcpy(ksk_algorithms, self_algorithms, sizeof(ksk_algorithms));
  1438. if (!allzsksigned)
  1439. fprintf(stderr, "warning: not all ZSK's are self "
  1440. "signed.\n");
  1441. }
  1442. #else
  1443. if (!goodksk) {
  1444. fatal("No self signed KSK's found");
  1445. }
  1446. #endif
  1447. fprintf(stderr, "Verifying the zone using the following algorithms:");
  1448. for (i = 0; i < 256; i++) {
  1449. #ifdef ALLOW_KSKLESS_ZONES
  1450. if (ksk_algorithms[i] != 0 || zsk_algorithms[i] != 0)
  1451. #else
  1452. if (ksk_algorithms[i] != 0)
  1453. #endif
  1454. {
  1455. dns_secalg_format(i, algbuf, sizeof(algbuf));
  1456. fprintf(stderr, " %s", algbuf);
  1457. }
  1458. }
  1459. fprintf(stderr, ".\n");
  1460. if (!ignore_kskflag && !keyset_kskonly) {
  1461. for (i = 0; i < 256; i++) {
  1462. /*
  1463. * The counts should both be zero or both be non-zero.
  1464. * Mark the algorithm as bad if this is not met.
  1465. */
  1466. if ((ksk_algorithms[i] != 0) ==
  1467. (zsk_algorithms[i] != 0))
  1468. continue;
  1469. dns_secalg_format(i, algbuf, sizeof(algbuf));
  1470. fprintf(stderr, "Missing %s for algorithm %s\n",
  1471. (ksk_algorithms[i] != 0)
  1472. ? "ZSK"
  1473. : "self signing KSK",
  1474. algbuf);
  1475. bad_algorithms[i] = 1;
  1476. }
  1477. }
  1478. /*
  1479. * Check that all the other records were signed by keys that are
  1480. * present in the DNSKEY RRSET.
  1481. */
  1482. dns_fixedname_init(&fname);
  1483. name = dns_fixedname_name(&fname);
  1484. dns_fixedname_init(&fnextname);
  1485. nextname = dns_fixedname_name(&fnextname);
  1486. dns_fixedname_init(&fzonecut);
  1487. zonecut = NULL;
  1488. result = dns_db_createiterator(gdb, DNS_DB_NONSEC3, &dbiter);
  1489. check_result(result, "dns_db_createiterator()");
  1490. result = dns_dbiterator_first(dbiter);
  1491. check_result(result, "dns_dbiterator_first()");
  1492. while (!done) {
  1493. isc_boolean_t isdelegation = ISC_FALSE;
  1494. result = dns_dbiterator_current(dbiter, &node, name);
  1495. check_dns_dbiterator_current(result);
  1496. if (!dns_name_issubdomain(name, gorigin)) {
  1497. dns_db_detachnode(gdb, &node);
  1498. result = dns_dbiterator_next(dbiter);
  1499. if (result == ISC_R_NOMORE)
  1500. done = ISC_TRUE;
  1501. else
  1502. check_result(result, "dns_dbiterator_next()");
  1503. continue;
  1504. }
  1505. if (delegation(name, node, NULL)) {
  1506. zonecut = dns_fixedname_name(&fzonecut);
  1507. dns_name_copy(name, zonecut, NULL);
  1508. isdelegation = ISC_TRUE;
  1509. }
  1510. verifynode(name, node, isdelegation, &keyset,
  1511. ksk_algorithms, bad_algorithms);
  1512. result = dns_dbiterator_next(dbiter);
  1513. nextnode = NULL;
  1514. while (result == ISC_R_SUCCESS) {
  1515. result = dns_dbiterator_current(dbiter, &nextnode,
  1516. nextname);
  1517. check_dns_dbiterator_current(result);
  1518. if (!dns_name_issubdomain(nextname, gorigin) ||
  1519. (zonecut != NULL &&
  1520. dns_name_issubdomain(nextname, zonecut)))
  1521. {
  1522. dns_db_detachnode(gdb, &nextnode);
  1523. result = dns_dbiterator_next(dbiter);
  1524. continue;
  1525. }
  1526. dns_db_detachnode(gdb, &nextnode);
  1527. break;
  1528. }
  1529. if (result == ISC_R_NOMORE) {
  1530. done = ISC_TRUE;
  1531. } else if (result != ISC_R_SUCCESS)
  1532. fatal("iterating through the database failed: %s",
  1533. isc_result_totext(result));
  1534. dns_db_detachnode(gdb, &node);
  1535. }
  1536. dns_dbiterator_destroy(&dbiter);
  1537. result = dns_db_createiterator(gdb, DNS_DB_NSEC3ONLY, &dbiter);
  1538. check_result(result, "dns_db_createiterator()");
  1539. for (result = dns_dbiterator_first(dbiter);
  1540. result == ISC_R_SUCCESS;
  1541. result = dns_dbiterator_next(dbiter) ) {
  1542. result = dns_dbiterator_current(dbiter, &node, name);
  1543. check_dns_dbiterator_current(result);
  1544. verifynode(name, node, ISC_FALSE, &keyset,
  1545. ksk_algorithms, bad_algorithms);
  1546. dns_db_detachnode(gdb, &node);
  1547. }
  1548. dns_dbiterator_destroy(&dbiter);
  1549. dns_rdataset_disassociate(&keyset);
  1550. /*
  1551. * If we made it this far, we have what we consider a properly signed
  1552. * zone. Set the good flag.
  1553. */
  1554. for (i = 0; i < 256; i++) {
  1555. if (bad_algorithms[i] != 0) {
  1556. if (first)
  1557. fprintf(stderr, "The zone is not fully signed "
  1558. "for the following algorithms:");
  1559. dns_secalg_format(i, algbuf, sizeof(algbuf));
  1560. fprintf(stderr, " %s", algbuf);
  1561. first = ISC_FALSE;
  1562. }
  1563. }
  1564. if (!first) {
  1565. fprintf(stderr, ".\n");
  1566. fatal("DNSSEC completeness test failed.");
  1567. }
  1568. if (goodksk || ignore_kskflag) {
  1569. /*
  1570. * Print the success summary.
  1571. */
  1572. fprintf(stderr, "Zone signing complete:\n");
  1573. for (i = 0; i < 256; i++) {
  1574. if ((ksk_algorithms[i] != 0) ||
  1575. (standby_ksk[i] != 0) ||
  1576. (revoked_zsk[i] != 0) ||
  1577. (zsk_algorithms[i] != 0) ||
  1578. (standby_zsk[i] != 0) ||
  1579. (revoked_zsk[i] != 0)) {
  1580. dns_secalg_format(i, algbuf, sizeof(algbuf));
  1581. fprintf(stderr, "Algorithm: %s: KSKs: "
  1582. "%u active, %u stand-by, %u revoked\n",
  1583. algbuf, ksk_algorithms[i],
  1584. standby_ksk[i], revoked_ksk[i]);
  1585. fprintf(stderr, "%*sZSKs: "
  1586. "%u active, %u %s, %u revoked\n",
  1587. (int) strlen(algbuf) + 13, "",
  1588. zsk_algorithms[i],
  1589. standby_zsk[i],
  1590. keyset_kskonly ? "present" : "stand-by",
  1591. revoked_zsk[i]);
  1592. }
  1593. }
  1594. }
  1595. }
  1596. /*%
  1597. * Sign the apex of the zone.
  1598. * Note the origin may not be the first node if there are out of zone
  1599. * records.
  1600. */
  1601. static void
  1602. signapex(void) {
  1603. dns_dbnode_t *node = NULL;
  1604. dns_fixedname_t fixed;
  1605. dns_name_t *name;
  1606. isc_result_t result;
  1607. dns_fixedname_init(&fixed);
  1608. name = dns_fixedname_name(&fixed);
  1609. result = dns_dbiterator_seek(gdbiter, gorigin);
  1610. check_result(result, "dns_dbiterator_seek()");
  1611. result = dns_dbiterator_current(gdbiter, &node, name);
  1612. check_dns_dbiterator_current(result);
  1613. signname(node, name);
  1614. dumpnode(name, node);
  1615. cleannode(gdb, gversion, node);
  1616. dns_db_detachnode(gdb, &node);
  1617. result = dns_dbiterator_first(gdbiter);
  1618. if (result == ISC_R_NOMORE)
  1619. finished = ISC_TRUE;
  1620. else if (result != ISC_R_SUCCESS)
  1621. fatal("failure iterating database: %s",
  1622. isc_result_totext(result));
  1623. }
  1624. /*%
  1625. * Assigns a node to a worker thread. This is protected by the master task's
  1626. * lock.
  1627. */
  1628. static void
  1629. assignwork(isc_task_t *task, isc_task_t *worker) {
  1630. dns_fixedname_t *fname;
  1631. dns_name_t *name;
  1632. dns_dbnode_t *node;
  1633. sevent_t *sevent;
  1634. dns_rdataset_t nsec;
  1635. isc_boolean_t found;
  1636. isc_result_t result;
  1637. static dns_name_t *zonecut = NULL; /* Protected by namelock. */
  1638. static dns_fixedname_t fzonecut; /* Protected by namelock. */
  1639. static unsigned int ended = 0; /* Protected by namelock. */
  1640. if (shuttingdown)
  1641. return;
  1642. LOCK(&namelock);
  1643. if (finished) {
  1644. ended++;
  1645. if (ended == ntasks) {
  1646. isc_task_detach(&task);
  1647. isc_app_shutdown();
  1648. }
  1649. goto unlock;
  1650. }
  1651. fname = isc_mem_get(mctx, sizeof(dns_fixedname_t));
  1652. if (fname == NULL)
  1653. fatal("out of memory");
  1654. dns_fixedname_init(fname);
  1655. name = dns_fixedname_name(fname);
  1656. node = NULL;
  1657. found = ISC_FALSE;
  1658. while (!found) {
  1659. result = dns_dbiterator_current(gdbiter, &node, name);
  1660. check_dns_dbiterator_current(result);
  1661. /*
  1662. * The origin was handled by signapex().
  1663. */
  1664. if (dns_name_equal(name, gorigin)) {
  1665. dns_db_detachnode(gdb, &node);
  1666. goto next;
  1667. }
  1668. /*
  1669. * Sort the zone data from the glue and out-of-zone data.
  1670. * For NSEC zones nodes with zone data have NSEC records.
  1671. * For NSEC3 zones the NSEC3 nodes are zone data but
  1672. * outside of the zone name space. For the rest we need
  1673. * to track the bottom of zone cuts.
  1674. * Nodes which don't need to be signed are dumped here.
  1675. */
  1676. dns_rdataset_init(&nsec);
  1677. result = dns_db_findrdataset(gdb, node, gversion,
  1678. nsec_datatype, 0, 0,
  1679. &nsec, NULL);
  1680. if (dns_rdataset_isassociated(&nsec))
  1681. dns_rdataset_disassociate(&nsec);
  1682. if (result == ISC_R_SUCCESS) {
  1683. found = ISC_TRUE;
  1684. } else if (nsec_datatype == dns_rdatatype_nsec3) {
  1685. if (dns_name_issubdomain(name, gorigin) &&
  1686. (zonecut == NULL ||
  1687. !dns_name_issubdomain(name, zonecut))) {
  1688. if (delegation(name, node, NULL)) {
  1689. dns_fixedname_init(&fzonecut);
  1690. zonecut = dns_fixedname_name(&fzonecut);
  1691. dns_name_copy(name, zonecut, NULL);
  1692. if (!OPTOUT(nsec3flags) ||
  1693. secure(name, node))
  1694. found = ISC_TRUE;
  1695. } else
  1696. found = ISC_TRUE;
  1697. }
  1698. }
  1699. if (!found) {
  1700. dumpnode(name, node);
  1701. dns_db_detachnode(gdb, &node);
  1702. }
  1703. next:
  1704. result = dns_dbiterator_next(gdbiter);
  1705. if (result == ISC_R_NOMORE) {
  1706. finished = ISC_TRUE;
  1707. break;
  1708. } else if (result != ISC_R_SUCCESS)
  1709. fatal("failure iterating database: %s",
  1710. isc_result_totext(result));
  1711. }
  1712. if (!found) {
  1713. ended++;
  1714. if (ended == ntasks) {
  1715. isc_task_detach(&task);
  1716. isc_app_shutdown();
  1717. }
  1718. isc_mem_put(mctx, fname, sizeof(dns_fixedname_t));
  1719. goto unlock;
  1720. }
  1721. sevent = (sevent_t *)
  1722. isc_event_allocate(mctx, task, SIGNER_EVENT_WORK,
  1723. sign, NULL, sizeof(sevent_t));
  1724. if (sevent == NULL)
  1725. fatal("failed to allocate event\n");
  1726. sevent->node = node;
  1727. sevent->fname = fname;
  1728. isc_task_send(worker, ISC_EVENT_PTR(&sevent));
  1729. unlock:
  1730. UNLOCK(&namelock);
  1731. }
  1732. /*%
  1733. * Start a worker task
  1734. */
  1735. static void
  1736. startworker(isc_task_t *task, isc_event_t *event) {
  1737. isc_task_t *worker;
  1738. worker = (isc_task_t *)event->ev_arg;
  1739. assignwork(task, worker);
  1740. isc_event_free(&event);
  1741. }
  1742. /*%
  1743. * Write a node to the output file, and restart the worker task.
  1744. */
  1745. static void
  1746. writenode(isc_task_t *task, isc_event_t *event) {
  1747. isc_task_t *worker;
  1748. sevent_t *sevent = (sevent_t *)event;
  1749. worker = (isc_task_t *)event->ev_sender;
  1750. dumpnode(dns_fixedname_name(sevent->fname), sevent->node);
  1751. cleannode(gdb, gversion, sevent->node);
  1752. dns_db_detachnode(gdb, &sevent->node);
  1753. isc_mem_put(mctx, sevent->fname, sizeof(dns_fixedname_t));
  1754. assignwork(task, worker);
  1755. isc_event_free(&event);
  1756. }
  1757. /*%
  1758. * Sign a database node.
  1759. */
  1760. static void
  1761. sign(isc_task_t *task, isc_event_t *event) {
  1762. dns_fixedname_t *fname;
  1763. dns_dbnode_t *node;
  1764. sevent_t *sevent, *wevent;
  1765. sevent = (sevent_t *)event;
  1766. node = sevent->node;
  1767. fname = sevent->fname;
  1768. isc_event_free(&event);
  1769. signname(node, dns_fixedname_name(fname));
  1770. wevent = (sevent_t *)
  1771. isc_event_allocate(mctx, task, SIGNER_EVENT_WRITE,
  1772. writenode, NULL, sizeof(sevent_t));
  1773. if (wevent == NULL)
  1774. fatal("failed to allocate event\n");
  1775. wevent->node = node;
  1776. wevent->fname = fname;
  1777. isc_task_send(master, ISC_EVENT_PTR(&wevent));
  1778. }
  1779. /*%
  1780. * Update / remove the DS RRset. Preserve RRSIG(DS) if possible.
  1781. */
  1782. static void
  1783. add_ds(dns_name_t *name, dns_dbnode_t *node, isc_uint32_t nsttl) {
  1784. dns_rdataset_t dsset;
  1785. dns_rdataset_t sigdsset;
  1786. isc_result_t result;
  1787. dns_rdataset_init(&dsset);
  1788. dns_rdataset_init(&sigdsset);
  1789. result = dns_db_findrdataset(gdb, node, gversion,
  1790. dns_rdatatype_ds,
  1791. 0, 0, &dsset, &sigdsset);
  1792. if (result == ISC_R_SUCCESS) {
  1793. dns_rdataset_disassociate(&dsset);
  1794. result = dns_db_deleterdataset(gdb, node, gversion,
  1795. dns_rdatatype_ds, 0);
  1796. check_result(result, "dns_db_deleterdataset");
  1797. }
  1798. result = loadds(name, nsttl, &dsset);
  1799. if (result == ISC_R_SUCCESS) {
  1800. result = dns_db_addrdataset(gdb, node, gversion, 0,
  1801. &dsset, 0, NULL);
  1802. check_result(result, "dns_db_addrdataset");
  1803. dns_rdataset_disassociate(&dsset);
  1804. if (dns_rdataset_isassociated(&sigdsset))
  1805. dns_rdataset_disassociate(&sigdsset);
  1806. } else if (dns_rdataset_isassociated(&sigdsset)) {
  1807. result = dns_db_deleterdataset(gdb, node, gversion,
  1808. dns_rdatatype_rrsig,
  1809. dns_rdatatype_ds);
  1810. check_result(result, "dns_db_deleterdataset");
  1811. dns_rdataset_disassociate(&sigdsset);
  1812. }
  1813. }
  1814. /*
  1815. * Remove records of the given type and their signatures.
  1816. */
  1817. static void
  1818. remove_records(dns_dbnode_t *node, dns_rdatatype_t which) {
  1819. isc_result_t result;
  1820. dns_rdatatype_t type, covers;
  1821. dns_rdatasetiter_t *rdsiter = NULL;
  1822. dns_rdataset_t rdataset;
  1823. dns_rdataset_init(&rdataset);
  1824. /*
  1825. * Delete any records of the given type at the apex.
  1826. */
  1827. result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter);
  1828. check_result(result, "dns_db_allrdatasets()");
  1829. for (result = dns_rdatasetiter_first(rdsiter);
  1830. result == ISC_R_SUCCESS;
  1831. result = dns_rdatasetiter_next(rdsiter)) {
  1832. dns_rdatasetiter_current(rdsiter, &rdataset);
  1833. type = rdataset.type;
  1834. covers = rdataset.covers;
  1835. dns_rdataset_disassociate(&rdataset);
  1836. if (type == which || covers == which) {
  1837. if (which == dns_rdatatype_nsec && !update_chain)
  1838. fatal("Zone contains NSEC records. Use -u "
  1839. "to update to NSEC3.");
  1840. if (which == dns_rdatatype_nsec3param && !update_chain)
  1841. fatal("Zone contains NSEC3 chains. Use -u "
  1842. "to update to NSEC.");
  1843. result = dns_db_deleterdataset(gdb, node, gversion,
  1844. type, covers);
  1845. check_result(result, "dns_db_deleterdataset()");
  1846. continue;
  1847. }
  1848. }
  1849. dns_rdatasetiter_destroy(&rdsiter);
  1850. }
  1851. /*%
  1852. * Generate NSEC records for the zone and remove NSEC3/NSEC3PARAM records.
  1853. */
  1854. static void
  1855. nsecify(void) {
  1856. dns_dbiterator_t *dbiter = NULL;
  1857. dns_dbnode_t *node = NULL, *nextnode = NULL;
  1858. dns_fixedname_t fname, fnextname, fzonecut;
  1859. dns_name_t *name, *nextname, *zonecut;
  1860. dns_rdataset_t rdataset;
  1861. dns_rdatasetiter_t *rdsiter = NULL;
  1862. dns_rdatatype_t type, covers;
  1863. isc_boolean_t done = ISC_FALSE;
  1864. isc_result_t result;
  1865. isc_uint32_t nsttl = 0;
  1866. dns_rdataset_init(&rdataset);
  1867. dns_fixedname_init(&fname);
  1868. name = dns_fixedname_name(&fname);
  1869. dns_fixedname_init(&fnextname);
  1870. nextname = dns_fixedname_name(&fnextname);
  1871. dns_fixedname_init(&fzonecut);
  1872. zonecut = NULL;
  1873. /*
  1874. * Remove any NSEC3 chains.
  1875. */
  1876. result = dns_db_createiterator(gdb, DNS_DB_NSEC3ONLY, &dbiter);
  1877. check_result(result, "dns_db_createiterator()");
  1878. for (result = dns_dbiterator_first(dbiter);
  1879. result == ISC_R_SUCCESS;
  1880. result = dns_dbiterator_next(dbiter)) {
  1881. result = dns_dbiterator_current(dbiter, &node, name);
  1882. check_dns_dbiterator_current(result);
  1883. result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter);
  1884. check_result(result, "dns_db_allrdatasets()");
  1885. for (result = dns_rdatasetiter_first(rdsiter);
  1886. result == ISC_R_SUCCESS;
  1887. result = dns_rdatasetiter_next(rdsiter)) {
  1888. dns_rdatasetiter_current(rdsiter, &rdataset);
  1889. type = rdataset.type;
  1890. covers = rdataset.covers;
  1891. dns_rdataset_disassociate(&rdataset);
  1892. result = dns_db_deleterdataset(gdb, node, gversion,
  1893. type, covers);
  1894. check_result(result,
  1895. "dns_db_deleterdataset(nsec3param/rrsig)");
  1896. }
  1897. dns_rdatasetiter_destroy(&rdsiter);
  1898. dns_db_detachnode(gdb, &node);
  1899. }
  1900. dns_dbiterator_destroy(&dbiter);
  1901. result = dns_db_createiterator(gdb, DNS_DB_NONSEC3, &dbiter);
  1902. check_result(result, "dns_db_createiterator()");
  1903. result = dns_dbiterator_first(dbiter);
  1904. check_result(result, "dns_dbiterator_first()");
  1905. while (!done) {
  1906. result = dns_dbiterator_current(dbiter, &node, name);
  1907. check_dns_dbiterator_current(result);
  1908. /*
  1909. * Skip out-of-zone records.
  1910. */
  1911. if (!dns_name_issubdomain(name, gorigin)) {
  1912. result = dns_dbiterator_next(dbiter);
  1913. if (result == ISC_R_NOMORE)
  1914. done = ISC_TRUE;
  1915. else
  1916. check_result(result, "dns_dbiterator_next()");
  1917. dns_db_detachnode(gdb, &node);
  1918. continue;
  1919. }
  1920. if (dns_name_equal(name, gorigin))
  1921. remove_records(node, dns_rdatatype_nsec3param);
  1922. if (delegation(name, node, &nsttl)) {
  1923. zonecut = dns_fixedname_name(&fzonecut);
  1924. dns_name_copy(name, zonecut, NULL);
  1925. if (generateds)
  1926. add_ds(name, node, nsttl);
  1927. }
  1928. result = dns_dbiterator_next(dbiter);
  1929. nextnode = NULL;
  1930. while (result == ISC_R_SUCCESS) {
  1931. isc_boolean_t active = ISC_FALSE;
  1932. result = dns_dbiterator_current(dbiter, &nextnode,
  1933. nextname);
  1934. check_dns_dbiterator_current(result);
  1935. active = active_node(nextnode);
  1936. if (!active) {
  1937. dns_db_detachnode(gdb, &nextnode);
  1938. result = dns_dbiterator_next(dbiter);
  1939. continue;
  1940. }
  1941. if (!dns_name_issubdomain(nextname, gorigin) ||
  1942. (zonecut != NULL &&
  1943. dns_name_issubdomain(nextname, zonecut)))
  1944. {
  1945. dns_db_detachnode(gdb, &nextnode);
  1946. result = dns_dbiterator_next(dbiter);
  1947. continue;
  1948. }
  1949. dns_db_detachnode(gdb, &nextnode);
  1950. break;
  1951. }
  1952. if (result == ISC_R_NOMORE) {
  1953. dns_name_clone(gorigin, nextname);
  1954. done = ISC_TRUE;
  1955. } else if (result != ISC_R_SUCCESS)
  1956. fatal("iterating through the database failed: %s",
  1957. isc_result_totext(result));
  1958. dns_dbiterator_pause(dbiter);
  1959. result = dns_nsec_build(gdb, gversion, node, nextname,
  1960. zone_soa_min_ttl);
  1961. check_result(result, "dns_nsec_build()");
  1962. dns_db_detachnode(gdb, &node);
  1963. }
  1964. dns_dbiterator_destroy(&dbiter);
  1965. }
  1966. static void
  1967. addnsec3param(const unsigned char *salt, size_t salt_length,
  1968. unsigned int iterations)
  1969. {
  1970. dns_dbnode_t *node = NULL;
  1971. dns_rdata_nsec3param_t nsec3param;
  1972. unsigned char nsec3parambuf[5 + 255];
  1973. dns_rdatalist_t rdatalist;
  1974. dns_rdataset_t rdataset;
  1975. dns_rdata_t rdata = DNS_RDATA_INIT;
  1976. isc_buffer_t b;
  1977. isc_result_t result;
  1978. dns_rdataset_init(&rdataset);
  1979. nsec3param.common.rdclass = gclass;
  1980. nsec3param.common.rdtype = dns_rdatatype_nsec3param;
  1981. ISC_LINK_INIT(&nsec3param.common, link);
  1982. nsec3param.mctx = NULL;
  1983. nsec3param.flags = 0;
  1984. nsec3param.hash = unknownalg ? DNS_NSEC3_UNKNOWNALG : dns_hash_sha1;
  1985. nsec3param.iterations = iterations;
  1986. nsec3param.salt_length = salt_length;
  1987. DE_CONST(salt, nsec3param.salt);
  1988. isc_buffer_init(&b, nsec3parambuf, sizeof(nsec3parambuf));
  1989. result = dns_rdata_fromstruct(&rdata, gclass,
  1990. dns_rdatatype_nsec3param,
  1991. &nsec3param, &b);
  1992. check_result(result, "dns_rdata_fromstruct()");
  1993. rdatalist.rdclass = rdata.rdclass;
  1994. rdatalist.type = rdata.type;
  1995. rdatalist.covers = 0;
  1996. rdatalist.ttl = 0;
  1997. ISC_LIST_INIT(rdatalist.rdata);
  1998. ISC_LIST_APPEND(rdatalist.rdata, &rdata, link);
  1999. result = dns_rdatalist_tordataset(&rdatalist, &rdataset);
  2000. check_result(result, "dns_rdatalist_tordataset()");
  2001. result = dns_db_findnode(gdb, gorigin, ISC_TRUE, &node);
  2002. check_result(result, "dns_db_find(gorigin)");
  2003. /*
  2004. * Delete any current NSEC3PARAM records.
  2005. */
  2006. result = dns_db_deleterdataset(gdb, node, gversion,
  2007. dns_rdatatype_nsec3param, 0);
  2008. if (result == DNS_R_UNCHANGED)
  2009. result = ISC_R_SUCCESS;
  2010. check_result(result, "dddnsec3param: dns_db_deleterdataset()");
  2011. result = dns_db_addrdataset(gdb, node, gversion, 0, &rdataset,
  2012. DNS_DBADD_MERGE, NULL);
  2013. if (result == DNS_R_UNCHANGED)
  2014. result = ISC_R_SUCCESS;
  2015. check_result(result, "addnsec3param: dns_db_addrdataset()");
  2016. dns_db_detachnode(gdb, &node);
  2017. }
  2018. static void
  2019. addnsec3(dns_name_t *name, dns_dbnode_t *node,
  2020. const unsigned char *salt, size_t salt_length,
  2021. unsigned int iterations, hashlist_t *hashlist,
  2022. dns_ttl_t ttl)
  2023. {
  2024. unsigned char hash[NSEC3_MAX_HASH_LENGTH];
  2025. const unsigned char *nexthash;
  2026. unsigned char nsec3buffer[DNS_NSEC3_BUFFERSIZE];
  2027. dns_fixedname_t hashname;
  2028. dns_rdatalist_t rdatalist;
  2029. dns_rdataset_t rdataset;
  2030. dns_rdata_t rdata = DNS_RDATA_INIT;
  2031. isc_result_t result;
  2032. dns_dbnode_t *nsec3node = NULL;
  2033. char namebuf[DNS_NAME_FORMATSIZE];
  2034. size_t hash_length;
  2035. dns_name_format(name, namebuf, sizeof(namebuf));
  2036. dns_fixedname_init(&hashname);
  2037. dns_rdataset_init(&rdataset);
  2038. dns_name_downcase(name, name, NULL);
  2039. result = dns_nsec3_hashname(&hashname, hash, &hash_length,
  2040. name, gorigin, dns_hash_sha1, iterations,
  2041. salt, salt_length);
  2042. check_result(result, "addnsec3: dns_nsec3_hashname()");
  2043. nexthash = hashlist_findnext(hashlist, hash);
  2044. result = dns_nsec3_buildrdata(gdb, gversion, node,
  2045. unknownalg ?
  2046. DNS_NSEC3_UNKNOWNALG : dns_hash_sha1,
  2047. nsec3flags, iterations,
  2048. salt, salt_length,
  2049. nexthash, ISC_SHA1_DIGESTLENGTH,
  2050. nsec3buffer, &rdata);
  2051. check_result(result, "addnsec3: dns_nsec3_buildrdata()");
  2052. rdatalist.rdclass = rdata.rdclass;
  2053. rdatalist.type = rdata.type;
  2054. rdatalist.covers = 0;
  2055. rdatalist.ttl = ttl;
  2056. ISC_LIST_INIT(rdatalist.rdata);
  2057. ISC_LIST_APPEND(rdatalist.rdata, &rdata, link);
  2058. result = dns_rdatalist_tordataset(&rdatalist, &rdataset);
  2059. check_result(result, "dns_rdatalist_tordataset()");
  2060. result = dns_db_findnsec3node(gdb, dns_fixedname_name(&hashname),
  2061. ISC_TRUE, &nsec3node);
  2062. check_result(result, "addnsec3: dns_db_findnode()");
  2063. result = dns_db_addrdataset(gdb, nsec3node, gversion, 0, &rdataset,
  2064. 0, NULL);
  2065. if (result == DNS_R_UNCHANGED)
  2066. result = ISC_R_SUCCESS;
  2067. check_result(result, "addnsec3: dns_db_addrdataset()");
  2068. dns_db_detachnode(gdb, &nsec3node);
  2069. }
  2070. /*%
  2071. * Clean out NSEC3 record and RRSIG(NSEC3) that are not in the hash list.
  2072. *
  2073. * Extract the hash from the first label of 'name' then see if it
  2074. * is in hashlist. If 'name' is not in the hashlist then delete the
  2075. * any NSEC3 records which have the same parameters as the chain we
  2076. * are building.
  2077. *
  2078. * XXXMPA Should we also check that it of the form <hash>.<origin>?
  2079. */
  2080. static void
  2081. nsec3clean(dns_name_t *name, dns_dbnode_t *node,
  2082. unsigned int hashalg, unsigned int iterations,
  2083. const unsigned char *salt, size_t salt_length, hashlist_t *hashlist)
  2084. {
  2085. dns_label_t label;
  2086. dns_rdata_nsec3_t nsec3;
  2087. dns_rdata_t rdata, delrdata;
  2088. dns_rdatalist_t rdatalist;
  2089. dns_rdataset_t rdataset, delrdataset;
  2090. isc_boolean_t delete_rrsigs = ISC_FALSE;
  2091. isc_buffer_t target;
  2092. isc_result_t result;
  2093. unsigned char hash[NSEC3_MAX_HASH_LENGTH + 1];
  2094. isc_boolean_t exists;
  2095. /*
  2096. * Get the first label.
  2097. */
  2098. dns_name_getlabel(name, 0, &label);
  2099. /*
  2100. * We want just the label contents.
  2101. */
  2102. isc_region_consume(&label, 1);
  2103. /*
  2104. * Decode base32hex string.
  2105. */
  2106. isc_buffer_init(&target, hash, sizeof(hash) - 1);
  2107. result = isc_base32hex_decoderegion(&label, &target);
  2108. if (result != ISC_R_SUCCESS)
  2109. return;
  2110. hash[isc_buffer_usedlength(&target)] = 0;
  2111. exists = hashlist_exists(hashlist, hash);
  2112. /*
  2113. * Verify that the NSEC3 parameters match the current ones
  2114. * otherwise we are dealing with a different NSEC3 chain.
  2115. */
  2116. dns_rdataset_init(&rdataset);
  2117. dns_rdataset_init(&delrdataset);
  2118. result = dns_db_findrdataset(gdb, node, gversion, dns_rdatatype_nsec3,
  2119. 0, 0, &rdataset, NULL);
  2120. if (result != ISC_R_SUCCESS)
  2121. return;
  2122. /*
  2123. * Delete any NSEC3 records which are not part of the current
  2124. * NSEC3 chain.
  2125. */
  2126. for (result = dns_rdataset_first(&rdataset);
  2127. result == ISC_R_SUCCESS;
  2128. result = dns_rdataset_next(&rdataset)) {
  2129. dns_rdata_init(&rdata);
  2130. dns_rdataset_current(&rdataset, &rdata);
  2131. result = dns_rdata_tostruct(&rdata, &nsec3, NULL);
  2132. check_result(result, "dns_rdata_tostruct");
  2133. if (exists && nsec3.hash == hashalg &&
  2134. nsec3.iterations == iterations &&
  2135. nsec3.salt_length == salt_length &&
  2136. !memcmp(nsec3.salt, salt, salt_length))
  2137. continue;
  2138. rdatalist.rdclass = rdata.rdclass;
  2139. rdatalist.type = rdata.type;
  2140. rdatalist.covers = 0;
  2141. rdatalist.ttl = rdataset.ttl;
  2142. ISC_LIST_INIT(rdatalist.rdata);
  2143. dns_rdata_init(&delrdata);
  2144. dns_rdata_clone(&rdata, &delrdata);
  2145. ISC_LIST_APPEND(rdatalist.rdata, &delrdata, link);
  2146. result = dns_rdatalist_tordataset(&rdatalist, &delrdataset);
  2147. check_result(result, "dns_rdatalist_tordataset()");
  2148. result = dns_db_subtractrdataset(gdb, node, gversion,
  2149. &delrdataset, 0, NULL);
  2150. dns_rdataset_disassociate(&delrdataset);
  2151. if (result != ISC_R_SUCCESS && result != DNS_R_NXRRSET)
  2152. check_result(result, "dns_db_subtractrdataset(NSEC3)");
  2153. delete_rrsigs = ISC_TRUE;
  2154. }
  2155. dns_rdataset_disassociate(&rdataset);
  2156. if (result != ISC_R_NOMORE)
  2157. check_result(result, "dns_rdataset_first/next");
  2158. if (!delete_rrsigs)
  2159. return;
  2160. /*
  2161. * Delete the NSEC3 RRSIGs
  2162. */
  2163. result = dns_db_deleterdataset(gdb, node, gversion,
  2164. dns_rdatatype_rrsig,
  2165. dns_rdatatype_nsec3);
  2166. if (result != ISC_R_SUCCESS && result != DNS_R_UNCHANGED)
  2167. check_result(result, "dns_db_deleterdataset(RRSIG(NSEC3))");
  2168. }
  2169. static void
  2170. rrset_remove_duplicates(dns_name_t *name, dns_rdataset_t *rdataset,
  2171. dns_diff_t *diff)
  2172. {
  2173. dns_difftuple_t *tuple = NULL;
  2174. isc_result_t result;
  2175. unsigned int count1 = 0;
  2176. dns_rdataset_t tmprdataset;
  2177. dns_rdataset_init(&tmprdataset);
  2178. for (result = dns_rdataset_first(rdataset);
  2179. result == ISC_R_SUCCESS;
  2180. result = dns_rdataset_next(rdataset)) {
  2181. dns_rdata_t rdata1 = DNS_RDATA_INIT;
  2182. unsigned int count2 = 0;
  2183. count1++;
  2184. dns_rdataset_current(rdataset, &rdata1);
  2185. dns_rdataset_clone(rdataset, &tmprdataset);
  2186. for (result = dns_rdataset_first(&tmprdataset);
  2187. result == ISC_R_SUCCESS;
  2188. result = dns_rdataset_next(&tmprdataset)) {
  2189. dns_rdata_t rdata2 = DNS_RDATA_INIT;
  2190. count2++;
  2191. if (count1 >= count2)
  2192. continue;
  2193. dns_rdataset_current(&tmprdataset, &rdata2);
  2194. if (dns_rdata_casecompare(&rdata1, &rdata2) == 0) {
  2195. result = dns_difftuple_create(mctx,
  2196. DNS_DIFFOP_DEL,
  2197. name,
  2198. rdataset->ttl,
  2199. &rdata2, &tuple);
  2200. check_result(result, "dns_difftuple_create");
  2201. dns_diff_append(diff, &tuple);
  2202. }
  2203. }
  2204. dns_rdataset_disassociate(&tmprdataset);
  2205. }
  2206. }
  2207. static void
  2208. remove_duplicates(void) {
  2209. isc_result_t result;
  2210. dns_dbiterator_t *dbiter = NULL;
  2211. dns_rdatasetiter_t *rdsiter = NULL;
  2212. dns_diff_t diff;
  2213. dns_dbnode_t *node = NULL;
  2214. dns_rdataset_t rdataset;
  2215. dns_fixedname_t fname;
  2216. dns_name_t *name;
  2217. dns_diff_init(mctx, &diff);
  2218. dns_fixedname_init(&fname);
  2219. name = dns_fixedname_name(&fname);
  2220. dns_rdataset_init(&rdataset);
  2221. result = dns_db_createiterator(gdb, 0, &dbiter);
  2222. check_result(result, "dns_db_createiterator()");
  2223. for (result = dns_dbiterator_first(dbiter);
  2224. result == ISC_R_SUCCESS;
  2225. result = dns_dbiterator_next(dbiter)) {
  2226. result = dns_dbiterator_current(dbiter, &node, name);
  2227. check_dns_dbiterator_current(result);
  2228. result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter);
  2229. check_result(result, "dns_db_allrdatasets()");
  2230. for (result = dns_rdatasetiter_first(rdsiter);
  2231. result == ISC_R_SUCCESS;
  2232. result = dns_rdatasetiter_next(rdsiter)) {
  2233. dns_rdatasetiter_current(rdsiter, &rdataset);
  2234. rrset_remove_duplicates(name, &rdataset, &diff);
  2235. dns_rdataset_disassociate(&rdataset);
  2236. }
  2237. if (result != ISC_R_NOMORE)
  2238. fatal("rdatasets iteration failed.");
  2239. dns_rdatasetiter_destroy(&rdsiter);
  2240. dns_db_detachnode(gdb, &node);
  2241. }
  2242. if (result != ISC_R_NOMORE)
  2243. fatal("zone iteration failed.");
  2244. if (!ISC_LIST_EMPTY(diff.tuples)) {
  2245. result = dns_diff_applysilently(&diff, gdb, gversion);
  2246. check_result(result, "dns_diff_applysilently");
  2247. }
  2248. dns_diff_clear(&diff);
  2249. dns_dbiterator_destroy(&dbiter);
  2250. }
  2251. /*
  2252. * Generate NSEC3 records for the zone.
  2253. */
  2254. static void
  2255. nsec3ify(unsigned int hashalg, unsigned int iterations,
  2256. const unsigned char *salt, size_t salt_length, hashlist_t *hashlist)
  2257. {
  2258. dns_dbiterator_t *dbiter = NULL;
  2259. dns_dbnode_t *node = NULL, *nextnode = NULL;
  2260. dns_fixedname_t fname, fnextname, fzonecut;
  2261. dns_name_t *name, *nextname, *zonecut;
  2262. dns_rdataset_t rdataset;
  2263. int order;
  2264. isc_boolean_t active;
  2265. isc_boolean_t done = ISC_FALSE;
  2266. isc_result_t result;
  2267. isc_uint32_t nsttl = 0;
  2268. unsigned int count, nlabels;
  2269. dns_rdataset_init(&rdataset);
  2270. dns_fixedname_init(&fname);
  2271. name = dns_fixedname_name(&fname);
  2272. dns_fixedname_init(&fnextname);
  2273. nextname = dns_fixedname_name(&fnextname);
  2274. dns_fixedname_init(&fzonecut);
  2275. zonecut = NULL;
  2276. /*
  2277. * Walk the zone generating the hash names.
  2278. */
  2279. result = dns_db_createiterator(gdb, DNS_DB_NONSEC3, &dbiter);
  2280. check_result(result, "dns_db_createiterator()");
  2281. result = dns_dbiterator_first(dbiter);
  2282. check_result(result, "dns_dbiterator_first()");
  2283. while (!done) {
  2284. result = dns_dbiterator_current(dbiter, &node, name);
  2285. check_dns_dbiterator_current(result);
  2286. /*
  2287. * Skip out-of-zone records.
  2288. */
  2289. if (!dns_name_issubdomain(name, gorigin)) {
  2290. result = dns_dbiterator_next(dbiter);
  2291. if (result == ISC_R_NOMORE)
  2292. done = ISC_TRUE;
  2293. else
  2294. check_result(result, "dns_dbiterator_next()");
  2295. dns_db_detachnode(gdb, &node);
  2296. continue;
  2297. }
  2298. if (dns_name_equal(name, gorigin))
  2299. remove_records(node, dns_rdatatype_nsec);
  2300. result = dns_dbiterator_next(dbiter);
  2301. nextnode = NULL;
  2302. while (result == ISC_R_SUCCESS) {
  2303. result = dns_dbiterator_current(dbiter, &nextnode,
  2304. nextname);
  2305. check_dns_dbiterator_current(result);
  2306. active = active_node(nextnode);
  2307. if (!active) {
  2308. dns_db_detachnode(gdb, &nextnode);
  2309. result = dns_dbiterator_next(dbiter);
  2310. continue;
  2311. }
  2312. if (!dns_name_issubdomain(nextname, gorigin) ||
  2313. (zonecut != NULL &&
  2314. dns_name_issubdomain(nextname, zonecut))) {
  2315. dns_db_detachnode(gdb, &nextnode);
  2316. result = dns_dbiterator_next(dbiter);
  2317. continue;
  2318. }
  2319. if (delegation(nextname, nextnode, &nsttl)) {
  2320. zonecut = dns_fixedname_name(&fzonecut);
  2321. dns_name_copy(nextname, zonecut, NULL);
  2322. if (generateds)
  2323. add_ds(nextname, nextnode, nsttl);
  2324. if (OPTOUT(nsec3flags) &&
  2325. !secure(nextname, nextnode)) {
  2326. dns_db_detachnode(gdb, &nextnode);
  2327. result = dns_dbiterator_next(dbiter);
  2328. continue;
  2329. }
  2330. }
  2331. dns_db_detachnode(gdb, &nextnode);
  2332. break;
  2333. }
  2334. if (result == ISC_R_NOMORE) {
  2335. dns_name_copy(gorigin, nextname, NULL);
  2336. done = ISC_TRUE;
  2337. } else if (result != ISC_R_SUCCESS)
  2338. fatal("iterating through the database failed: %s",
  2339. isc_result_totext(result));
  2340. dns_name_downcase(name, name, NULL);
  2341. hashlist_add_dns_name(hashlist, name, hashalg, iterations,
  2342. salt, salt_length, ISC_FALSE);
  2343. dns_db_detachnode(gdb, &node);
  2344. /*
  2345. * Add hashs for empty nodes. Use closest encloser logic.
  2346. * The closest encloser either has data or is a empty
  2347. * node for another <name,nextname> span so we don't add
  2348. * it here. Empty labels on nextname are within the span.
  2349. */
  2350. dns_name_downcase(nextname, nextname, NULL);
  2351. dns_name_fullcompare(name, nextname, &order, &nlabels);
  2352. addnowildcardhash(hashlist, name, hashalg, iterations,
  2353. salt, salt_length);
  2354. count = dns_name_countlabels(nextname);
  2355. while (count > nlabels + 1) {
  2356. count--;
  2357. dns_name_split(nextname, count, NULL, nextname);
  2358. hashlist_add_dns_name(hashlist, nextname, hashalg,
  2359. iterations, salt, salt_length,
  2360. ISC_FALSE);
  2361. addnowildcardhash(hashlist, nextname, hashalg,
  2362. iterations, salt, salt_length);
  2363. }
  2364. }
  2365. dns_dbiterator_destroy(&dbiter);
  2366. /*
  2367. * We have all the hashes now so we can sort them.
  2368. */
  2369. hashlist_sort(hashlist);
  2370. /*
  2371. * Check for duplicate hashes. If found the salt needs to
  2372. * be changed.
  2373. */
  2374. if (hashlist_hasdup(hashlist))
  2375. fatal("Duplicate hash detected. Pick a different salt.");
  2376. /*
  2377. * Generate the nsec3 records.
  2378. */
  2379. zonecut = NULL;
  2380. done = ISC_FALSE;
  2381. addnsec3param(salt, salt_length, iterations);
  2382. /*
  2383. * Clean out NSEC3 records which don't match this chain.
  2384. */
  2385. result = dns_db_createiterator(gdb, DNS_DB_NSEC3ONLY, &dbiter);
  2386. check_result(result, "dns_db_createiterator()");
  2387. for (result = dns_dbiterator_first(dbiter);
  2388. result == ISC_R_SUCCESS;
  2389. result = dns_dbiterator_next(dbiter)) {
  2390. result = dns_dbiterator_current(dbiter, &node, name);
  2391. check_dns_dbiterator_current(result);
  2392. nsec3clean(name, node, hashalg, iterations, salt, salt_length,
  2393. hashlist);
  2394. dns_db_detachnode(gdb, &node);
  2395. }
  2396. dns_dbiterator_destroy(&dbiter);
  2397. /*
  2398. * Generate / complete the new chain.
  2399. */
  2400. result = dns_db_createiterator(gdb, DNS_DB_NONSEC3, &dbiter);
  2401. check_result(result, "dns_db_createiterator()");
  2402. result = dns_dbiterator_first(dbiter);
  2403. check_result(result, "dns_dbiterator_first()");
  2404. while (!done) {
  2405. result = dns_dbiterator_current(dbiter, &node, name);
  2406. check_dns_dbiterator_current(result);
  2407. /*
  2408. * Skip out-of-zone records.
  2409. */
  2410. if (!dns_name_issubdomain(name, gorigin)) {
  2411. result = dns_dbiterator_next(dbiter);
  2412. if (result == ISC_R_NOMORE)
  2413. done = ISC_TRUE;
  2414. else
  2415. check_result(result, "dns_dbiterator_next()");
  2416. dns_db_detachnode(gdb, &node);
  2417. continue;
  2418. }
  2419. result = dns_dbiterator_next(dbiter);
  2420. nextnode = NULL;
  2421. while (result == ISC_R_SUCCESS) {
  2422. result = dns_dbiterator_current(dbiter, &nextnode,
  2423. nextname);
  2424. check_dns_dbiterator_current(result);
  2425. active = active_node(nextnode);
  2426. if (!active) {
  2427. dns_db_detachnode(gdb, &nextnode);
  2428. result = dns_dbiterator_next(dbiter);
  2429. continue;
  2430. }
  2431. if (!dns_name_issubdomain(nextname, gorigin) ||
  2432. (zonecut != NULL &&
  2433. dns_name_issubdomain(nextname, zonecut))) {
  2434. dns_db_detachnode(gdb, &nextnode);
  2435. result = dns_dbiterator_next(dbiter);
  2436. continue;
  2437. }
  2438. if (delegation(nextname, nextnode, NULL)) {
  2439. zonecut = dns_fixedname_name(&fzonecut);
  2440. dns_name_copy(nextname, zonecut, NULL);
  2441. if (OPTOUT(nsec3flags) &&
  2442. !secure(nextname, nextnode)) {
  2443. dns_db_detachnode(gdb, &nextnode);
  2444. result = dns_dbiterator_next(dbiter);
  2445. continue;
  2446. }
  2447. }
  2448. dns_db_detachnode(gdb, &nextnode);
  2449. break;
  2450. }
  2451. if (result == ISC_R_NOMORE) {
  2452. dns_name_copy(gorigin, nextname, NULL);
  2453. done = ISC_TRUE;
  2454. } else if (result != ISC_R_SUCCESS)
  2455. fatal("iterating through the database failed: %s",
  2456. isc_result_totext(result));
  2457. /*
  2458. * We need to pause here to release the lock on the database.
  2459. */
  2460. dns_dbiterator_pause(dbiter);
  2461. addnsec3(name, node, salt, salt_length, iterations,
  2462. hashlist, zone_soa_min_ttl);
  2463. dns_db_detachnode(gdb, &node);
  2464. /*
  2465. * Add NSEC3's for empty nodes. Use closest encloser logic.
  2466. */
  2467. dns_name_fullcompare(name, nextname, &order, &nlabels);
  2468. count = dns_name_countlabels(nextname);
  2469. while (count > nlabels + 1) {
  2470. count--;
  2471. dns_name_split(nextname, count, NULL, nextname);
  2472. addnsec3(nextname, NULL, salt, salt_length,
  2473. iterations, hashlist, zone_soa_min_ttl);
  2474. }
  2475. }
  2476. dns_dbiterator_destroy(&dbiter);
  2477. }
  2478. /*%
  2479. * Load the zone file from disk
  2480. */
  2481. static void
  2482. loadzone(char *file, char *origin, dns_rdataclass_t rdclass, dns_db_t **db) {
  2483. isc_buffer_t b;
  2484. int len;
  2485. dns_fixedname_t fname;
  2486. dns_name_t *name;
  2487. isc_result_t result;
  2488. len = strlen(origin);
  2489. isc_buffer_init(&b, origin, len);
  2490. isc_buffer_add(&b, len);
  2491. dns_fixedname_init(&fname);
  2492. name = dns_fixedname_name(&fname);
  2493. result = dns_name_fromtext(name, &b, dns_rootname, 0, NULL);
  2494. if (result != ISC_R_SUCCESS)
  2495. fatal("failed converting name '%s' to dns format: %s",
  2496. origin, isc_result_totext(result));
  2497. result = dns_db_create(mctx, "rbt", name, dns_dbtype_zone,
  2498. rdclass, 0, NULL, db);
  2499. check_result(result, "dns_db_create()");
  2500. result = dns_db_load2(*db, file, inputformat);
  2501. if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE)
  2502. fatal("failed loading zone from '%s': %s",
  2503. file, isc_result_totext(result));
  2504. }
  2505. /*%
  2506. * Finds all public zone keys in the zone, and attempts to load the
  2507. * private keys from disk.
  2508. */
  2509. static void
  2510. loadzonekeys(isc_boolean_t preserve_keys, isc_boolean_t load_public) {
  2511. dns_dbnode_t *node;
  2512. dns_dbversion_t *currentversion = NULL;
  2513. isc_result_t result;
  2514. dns_rdataset_t rdataset, keysigs, soasigs;
  2515. node = NULL;
  2516. result = dns_db_findnode(gdb, gorigin, ISC_FALSE, &node);
  2517. if (result != ISC_R_SUCCESS)
  2518. fatal("failed to find the zone's origin: %s",
  2519. isc_result_totext(result));
  2520. dns_db_currentversion(gdb, &currentversion);
  2521. dns_rdataset_init(&rdataset);
  2522. dns_rdataset_init(&soasigs);
  2523. dns_rdataset_init(&keysigs);
  2524. /* Make note of the keys which signed the SOA, if any */
  2525. result = dns_db_findrdataset(gdb, node, currentversion,
  2526. dns_rdatatype_soa, 0, 0,
  2527. &rdataset, &soasigs);
  2528. if (result != ISC_R_SUCCESS)
  2529. goto cleanup;
  2530. /* Preserve the TTL of the DNSKEY RRset, if any */
  2531. dns_rdataset_disassociate(&rdataset);
  2532. result = dns_db_findrdataset(gdb, node, currentversion,
  2533. dns_rdatatype_dnskey, 0, 0,
  2534. &rdataset, &keysigs);
  2535. if (result != ISC_R_SUCCESS)
  2536. goto cleanup;
  2537. if (set_keyttl && keyttl != rdataset.ttl) {
  2538. fprintf(stderr, "User-specified TTL (%d) conflicts "
  2539. "with existing DNSKEY RRset TTL.\n",
  2540. keyttl);
  2541. fprintf(stderr, "Imported keys will use the RRSet "
  2542. "TTL (%d) instead.\n",
  2543. rdataset.ttl);
  2544. }
  2545. keyttl = rdataset.ttl;
  2546. /* Load keys corresponding to the existing DNSKEY RRset. */
  2547. result = dns_dnssec_keylistfromrdataset(gorigin, directory, mctx,
  2548. &rdataset, &keysigs, &soasigs,
  2549. preserve_keys, load_public,
  2550. &keylist);
  2551. if (result != ISC_R_SUCCESS)
  2552. fatal("failed to load the zone keys: %s",
  2553. isc_result_totext(result));
  2554. cleanup:
  2555. if (dns_rdataset_isassociated(&rdataset))
  2556. dns_rdataset_disassociate(&rdataset);
  2557. if (dns_rdataset_isassociated(&keysigs))
  2558. dns_rdataset_disassociate(&keysigs);
  2559. if (dns_rdataset_isassociated(&soasigs))
  2560. dns_rdataset_disassociate(&soasigs);
  2561. dns_db_detachnode(gdb, &node);
  2562. dns_db_closeversion(gdb, &currentversion, ISC_FALSE);
  2563. }
  2564. static void
  2565. loadexplicitkeys(char *keyfiles[], int n, isc_boolean_t setksk) {
  2566. isc_result_t result;
  2567. int i;
  2568. for (i = 0; i < n; i++) {
  2569. dns_dnsseckey_t *key = NULL;
  2570. dst_key_t *newkey = NULL;
  2571. result = dst_key_fromnamedfile(keyfiles[i], directory,
  2572. DST_TYPE_PUBLIC |
  2573. DST_TYPE_PRIVATE,
  2574. mctx, &newkey);
  2575. if (result != ISC_R_SUCCESS)
  2576. fatal("cannot load dnskey %s: %s", keyfiles[i],
  2577. isc_result_totext(result));
  2578. if (!dns_name_equal(gorigin, dst_key_name(newkey)))
  2579. fatal("key %s not at origin\n", keyfiles[i]);
  2580. if (!dst_key_isprivate(newkey))
  2581. fatal("cannot sign zone with non-private dnskey %s",
  2582. keyfiles[i]);
  2583. /* Skip any duplicates */
  2584. for (key = ISC_LIST_HEAD(keylist);
  2585. key != NULL;
  2586. key = ISC_LIST_NEXT(key, link)) {
  2587. if (dst_key_id(key->key) == dst_key_id(newkey) &&
  2588. dst_key_alg(key->key) == dst_key_alg(newkey))
  2589. break;
  2590. }
  2591. if (key == NULL) {
  2592. /* We haven't seen this key before */
  2593. dns_dnsseckey_create(mctx, &newkey, &key);
  2594. ISC_LIST_APPEND(keylist, key, link);
  2595. key->source = dns_keysource_user;
  2596. } else {
  2597. dst_key_free(&key->key);
  2598. key->key = newkey;
  2599. }
  2600. key->force_publish = ISC_TRUE;
  2601. key->force_sign = ISC_TRUE;
  2602. if (setksk)
  2603. key->ksk = ISC_TRUE;
  2604. }
  2605. }
  2606. static void
  2607. report(const char *format, ...) {
  2608. va_list args;
  2609. va_start(args, format);
  2610. vfprintf(stderr, format, args);
  2611. va_end(args);
  2612. putc('\n', stderr);
  2613. }
  2614. static void
  2615. build_final_keylist() {
  2616. isc_result_t result;
  2617. dns_dbversion_t *ver = NULL;
  2618. dns_diff_t diff;
  2619. dns_dnsseckeylist_t matchkeys;
  2620. char name[DNS_NAME_FORMATSIZE];
  2621. /*
  2622. * Find keys that match this zone in the key repository.
  2623. */
  2624. ISC_LIST_INIT(matchkeys);
  2625. result = dns_dnssec_findmatchingkeys(gorigin, directory,
  2626. mctx, &matchkeys);
  2627. if (result == ISC_R_NOTFOUND)
  2628. result = ISC_R_SUCCESS;
  2629. check_result(result, "dns_dnssec_findmatchingkeys");
  2630. result = dns_db_newversion(gdb, &ver);
  2631. check_result(result, "dns_db_newversion");
  2632. dns_diff_init(mctx, &diff);
  2633. /*
  2634. * Update keylist with information from from the key repository.
  2635. */
  2636. dns_dnssec_updatekeys(&keylist, &matchkeys, NULL, gorigin, keyttl,
  2637. &diff, ignore_kskflag, mctx, report);
  2638. dns_name_format(gorigin, name, sizeof(name));
  2639. result = dns_diff_applysilently(&diff, gdb, ver);
  2640. if (result != ISC_R_SUCCESS)
  2641. fatal("failed to update DNSKEY RRset at node '%s': %s",
  2642. name, isc_result_totext(result));
  2643. dns_db_closeversion(gdb, &ver, ISC_TRUE);
  2644. dns_diff_clear(&diff);
  2645. }
  2646. static void
  2647. warnifallksk(dns_db_t *db) {
  2648. dns_dbversion_t *currentversion = NULL;
  2649. dns_dbnode_t *node = NULL;
  2650. dns_rdataset_t rdataset;
  2651. dns_rdata_t rdata = DNS_RDATA_INIT;
  2652. isc_result_t result;
  2653. dns_rdata_dnskey_t dnskey;
  2654. isc_boolean_t have_non_ksk = ISC_FALSE;
  2655. dns_db_currentversion(db, &currentversion);
  2656. result = dns_db_findnode(db, gorigin, ISC_FALSE, &node);
  2657. if (result != ISC_R_SUCCESS)
  2658. fatal("failed to find the zone's origin: %s",
  2659. isc_result_totext(result));
  2660. dns_rdataset_init(&rdataset);
  2661. result = dns_db_findrdataset(db, node, currentversion,
  2662. dns_rdatatype_dnskey, 0, 0, &rdataset,
  2663. NULL);
  2664. if (result != ISC_R_SUCCESS)
  2665. fatal("failed to find keys at the zone apex: %s",
  2666. isc_result_totext(result));
  2667. result = dns_rdataset_first(&rdataset);
  2668. check_result(result, "dns_rdataset_first");
  2669. while (result == ISC_R_SUCCESS) {
  2670. dns_rdata_reset(&rdata);
  2671. dns_rdataset_current(&rdataset, &rdata);
  2672. result = dns_rdata_tostruct(&rdata, &dnskey, NULL);
  2673. check_result(result, "dns_rdata_tostruct");
  2674. if ((dnskey.flags & DNS_KEYFLAG_KSK) == 0) {
  2675. have_non_ksk = ISC_TRUE;
  2676. result = ISC_R_NOMORE;
  2677. } else
  2678. result = dns_rdataset_next(&rdataset);
  2679. dns_rdata_freestruct(&dnskey);
  2680. }
  2681. dns_rdataset_disassociate(&rdataset);
  2682. dns_db_detachnode(db, &node);
  2683. dns_db_closeversion(db, &currentversion, ISC_FALSE);
  2684. if (!have_non_ksk && !ignore_kskflag) {
  2685. if (disable_zone_check)
  2686. fprintf(stderr, "%s: warning: No non-KSK DNSKEY found; "
  2687. "supply a ZSK or use '-z'.\n",
  2688. program);
  2689. else
  2690. fatal("No non-KSK DNSKEY found; "
  2691. "supply a ZSK or use '-z'.");
  2692. }
  2693. }
  2694. static void
  2695. set_nsec3params(isc_boolean_t update_chain, isc_boolean_t set_salt,
  2696. isc_boolean_t set_optout, isc_boolean_t set_iter)
  2697. {
  2698. isc_result_t result;
  2699. dns_dbversion_t *ver = NULL;
  2700. dns_dbnode_t *node = NULL;
  2701. dns_rdataset_t rdataset;
  2702. dns_rdata_t rdata = DNS_RDATA_INIT;
  2703. dns_rdata_nsec3_t nsec3;
  2704. dns_fixedname_t fname;
  2705. dns_name_t *hashname;
  2706. unsigned char orig_salt[256];
  2707. size_t orig_saltlen;
  2708. dns_hash_t orig_hash;
  2709. isc_uint16_t orig_iter;
  2710. dns_db_currentversion(gdb, &ver);
  2711. dns_rdataset_init(&rdataset);
  2712. orig_saltlen = sizeof(orig_salt);
  2713. result = dns_db_getnsec3parameters(gdb, ver, &orig_hash, NULL,
  2714. &orig_iter, orig_salt,
  2715. &orig_saltlen);
  2716. if (result != ISC_R_SUCCESS)
  2717. goto cleanup;
  2718. nsec_datatype = dns_rdatatype_nsec3;
  2719. if (!update_chain && set_salt) {
  2720. if (salt_length != orig_saltlen ||
  2721. memcmp(saltbuf, orig_salt, salt_length) != 0)
  2722. fatal("An NSEC3 chain exists with a different salt. "
  2723. "Use -u to update it.");
  2724. } else if (!set_salt) {
  2725. salt_length = orig_saltlen;
  2726. memcpy(saltbuf, orig_salt, orig_saltlen);
  2727. salt = saltbuf;
  2728. }
  2729. if (!update_chain && set_iter) {
  2730. if (nsec3iter != orig_iter)
  2731. fatal("An NSEC3 chain exists with different "
  2732. "iterations. Use -u to update it.");
  2733. } else if (!set_iter)
  2734. nsec3iter = orig_iter;
  2735. /*
  2736. * Find an NSEC3 record to get the current OPTOUT value.
  2737. * (This assumes all NSEC3 records agree.)
  2738. */
  2739. dns_fixedname_init(&fname);
  2740. hashname = dns_fixedname_name(&fname);
  2741. result = dns_nsec3_hashname(&fname, NULL, NULL,
  2742. gorigin, gorigin, dns_hash_sha1,
  2743. orig_iter, orig_salt, orig_saltlen);
  2744. check_result(result, "dns_nsec3_hashname");
  2745. result = dns_db_findnsec3node(gdb, hashname, ISC_FALSE, &node);
  2746. if (result != ISC_R_SUCCESS)
  2747. goto cleanup;
  2748. result = dns_db_findrdataset(gdb, node, ver, dns_rdatatype_nsec3,
  2749. 0, 0, &rdataset, NULL);
  2750. if (result != ISC_R_SUCCESS)
  2751. goto cleanup;
  2752. result = dns_rdataset_first(&rdataset);
  2753. check_result(result, "dns_rdataset_first");
  2754. dns_rdataset_current(&rdataset, &rdata);
  2755. result = dns_rdata_tostruct(&rdata, &nsec3, NULL);
  2756. check_result(result, "dns_rdata_tostruct");
  2757. if (!update_chain && set_optout) {
  2758. if (nsec3flags != nsec3.flags)
  2759. fatal("An NSEC3 chain exists with%s OPTOUT. "
  2760. "Use -u -%s to %s it.",
  2761. OPTOUT(nsec3.flags) ? "" : "out",
  2762. OPTOUT(nsec3.flags) ? "AA" : "A",
  2763. OPTOUT(nsec3.flags) ? "clear" : "set");
  2764. } else if (!set_optout)
  2765. nsec3flags = nsec3.flags;
  2766. dns_rdata_freestruct(&nsec3);
  2767. cleanup:
  2768. if (dns_rdataset_isassociated(&rdataset))
  2769. dns_rdataset_disassociate(&rdataset);
  2770. if (node != NULL)
  2771. dns_db_detachnode(gdb, &node);
  2772. dns_db_closeversion(gdb, &ver, ISC_FALSE);
  2773. }
  2774. static void
  2775. writeset(const char *prefix, dns_rdatatype_t type) {
  2776. char *filename;
  2777. char namestr[DNS_NAME_FORMATSIZE];
  2778. dns_db_t *db = NULL;
  2779. dns_dbversion_t *version = NULL;
  2780. dns_diff_t diff;
  2781. dns_difftuple_t *tuple = NULL;
  2782. dns_fixedname_t fixed;
  2783. dns_name_t *name;
  2784. dns_rdata_t rdata, ds;
  2785. isc_boolean_t have_ksk = ISC_FALSE;
  2786. isc_boolean_t have_non_ksk = ISC_FALSE;
  2787. isc_buffer_t b;
  2788. isc_buffer_t namebuf;
  2789. isc_region_t r;
  2790. isc_result_t result;
  2791. dns_dnsseckey_t *key, *tmpkey;
  2792. unsigned char dsbuf[DNS_DS_BUFFERSIZE];
  2793. unsigned char keybuf[DST_KEY_MAXSIZE];
  2794. unsigned int filenamelen;
  2795. const dns_master_style_t *style =
  2796. (type == dns_rdatatype_dnskey) ? masterstyle : dsstyle;
  2797. isc_buffer_init(&namebuf, namestr, sizeof(namestr));
  2798. result = dns_name_tofilenametext(gorigin, ISC_FALSE, &namebuf);
  2799. check_result(result, "dns_name_tofilenametext");
  2800. isc_buffer_putuint8(&namebuf, 0);
  2801. filenamelen = strlen(prefix) + strlen(namestr);
  2802. if (dsdir != NULL)
  2803. filenamelen += strlen(dsdir) + 1;
  2804. filename = isc_mem_get(mctx, filenamelen + 1);
  2805. if (filename == NULL)
  2806. fatal("out of memory");
  2807. if (dsdir != NULL)
  2808. sprintf(filename, "%s/", dsdir);
  2809. else
  2810. filename[0] = 0;
  2811. strcat(filename, prefix);
  2812. strcat(filename, namestr);
  2813. dns_diff_init(mctx, &diff);
  2814. if (type == dns_rdatatype_dlv) {
  2815. dns_name_t tname;
  2816. unsigned int labels;
  2817. dns_name_init(&tname, NULL);
  2818. dns_fixedname_init(&fixed);
  2819. name = dns_fixedname_name(&fixed);
  2820. labels = dns_name_countlabels(gorigin);
  2821. dns_name_getlabelsequence(gorigin, 0, labels - 1, &tname);
  2822. result = dns_name_concatenate(&tname, dlv, name, NULL);
  2823. check_result(result, "dns_name_concatenate");
  2824. } else
  2825. name = gorigin;
  2826. for (key = ISC_LIST_HEAD(keylist);
  2827. key != NULL;
  2828. key = ISC_LIST_NEXT(key, link))
  2829. {
  2830. if (REVOKE(key->key))
  2831. continue;
  2832. if (isksk(key)) {
  2833. have_ksk = ISC_TRUE;
  2834. have_non_ksk = ISC_FALSE;
  2835. } else {
  2836. have_ksk = ISC_FALSE;
  2837. have_non_ksk = ISC_TRUE;
  2838. }
  2839. for (tmpkey = ISC_LIST_HEAD(keylist);
  2840. tmpkey != NULL;
  2841. tmpkey = ISC_LIST_NEXT(tmpkey, link)) {
  2842. if (dst_key_alg(key->key) != dst_key_alg(tmpkey->key))
  2843. continue;
  2844. if (REVOKE(tmpkey->key))
  2845. continue;
  2846. if (isksk(tmpkey))
  2847. have_ksk = ISC_TRUE;
  2848. else
  2849. have_non_ksk = ISC_TRUE;
  2850. }
  2851. if (have_ksk && have_non_ksk && !isksk(key))
  2852. continue;
  2853. dns_rdata_init(&rdata);
  2854. dns_rdata_init(&ds);
  2855. isc_buffer_init(&b, keybuf, sizeof(keybuf));
  2856. result = dst_key_todns(key->key, &b);
  2857. check_result(result, "dst_key_todns");
  2858. isc_buffer_usedregion(&b, &r);
  2859. dns_rdata_fromregion(&rdata, gclass, dns_rdatatype_dnskey, &r);
  2860. if (type != dns_rdatatype_dnskey) {
  2861. result = dns_ds_buildrdata(gorigin, &rdata,
  2862. DNS_DSDIGEST_SHA1,
  2863. dsbuf, &ds);
  2864. check_result(result, "dns_ds_buildrdata");
  2865. if (type == dns_rdatatype_dlv)
  2866. ds.type = dns_rdatatype_dlv;
  2867. result = dns_difftuple_create(mctx, DNS_DIFFOP_ADD,
  2868. name, 0, &ds, &tuple);
  2869. check_result(result, "dns_difftuple_create");
  2870. dns_diff_append(&diff, &tuple);
  2871. dns_rdata_reset(&ds);
  2872. result = dns_ds_buildrdata(gorigin, &rdata,
  2873. DNS_DSDIGEST_SHA256,
  2874. dsbuf, &ds);
  2875. check_result(result, "dns_ds_buildrdata");
  2876. if (type == dns_rdatatype_dlv)
  2877. ds.type = dns_rdatatype_dlv;
  2878. result = dns_difftuple_create(mctx, DNS_DIFFOP_ADD,
  2879. name, 0, &ds, &tuple);
  2880. } else
  2881. result = dns_difftuple_create(mctx, DNS_DIFFOP_ADD,
  2882. gorigin, zone_soa_min_ttl,
  2883. &rdata, &tuple);
  2884. check_result(result, "dns_difftuple_create");
  2885. dns_diff_append(&diff, &tuple);
  2886. }
  2887. result = dns_db_create(mctx, "rbt", dns_rootname, dns_dbtype_zone,
  2888. gclass, 0, NULL, &db);
  2889. check_result(result, "dns_db_create");
  2890. result = dns_db_newversion(db, &version);
  2891. check_result(result, "dns_db_newversion");
  2892. result = dns_diff_apply(&diff, db, version);
  2893. check_result(result, "dns_diff_apply");
  2894. dns_diff_clear(&diff);
  2895. result = dns_master_dump(mctx, db, version, style, filename);
  2896. check_result(result, "dns_master_dump");
  2897. isc_mem_put(mctx, filename, filenamelen + 1);
  2898. dns_db_closeversion(db, &version, ISC_FALSE);
  2899. dns_db_detach(&db);
  2900. }
  2901. static void
  2902. print_time(FILE *fp) {
  2903. time_t currenttime;
  2904. if (outputformat != dns_masterformat_text)
  2905. return;
  2906. currenttime = time(NULL);
  2907. fprintf(fp, "; File written on %s", ctime(&currenttime));
  2908. }
  2909. static void
  2910. print_version(FILE *fp) {
  2911. if (outputformat != dns_masterformat_text)
  2912. return;
  2913. fprintf(fp, "; dnssec_signzone version " VERSION "\n");
  2914. }
  2915. ISC_PLATFORM_NORETURN_PRE static void
  2916. usage(void) ISC_PLATFORM_NORETURN_POST;
  2917. static void
  2918. usage(void) {
  2919. fprintf(stderr, "Usage:\n");
  2920. fprintf(stderr, "\t%s [options] zonefile [keys]\n", program);
  2921. fprintf(stderr, "\n");
  2922. fprintf(stderr, "Version: %s\n", VERSION);
  2923. fprintf(stderr, "Options: (default value in parenthesis) \n");
  2924. fprintf(stderr, "\t-S:\tsmart signing: automatically finds key files\n"
  2925. "\t\tfor the zone and determines how they are to "
  2926. "be used\n");
  2927. fprintf(stderr, "\t-K directory:\n");
  2928. fprintf(stderr, "\t\tdirectory to find key files (.)\n");
  2929. fprintf(stderr, "\t-d directory:\n");
  2930. fprintf(stderr, "\t\tdirectory to find dsset-* files (.)\n");
  2931. fprintf(stderr, "\t-g:\t");
  2932. fprintf(stderr, "update DS records based on child zones' "
  2933. "dsset-* files\n");
  2934. fprintf(stderr, "\t-s [YYYYMMDDHHMMSS|+offset]:\n");
  2935. fprintf(stderr, "\t\tRRSIG start time - absolute|offset (now - 1 hour)\n");
  2936. fprintf(stderr, "\t-e [YYYYMMDDHHMMSS|+offset|\"now\"+offset]:\n");
  2937. fprintf(stderr, "\t\tRRSIG end time - absolute|from start|from now "
  2938. "(now + 30 days)\n");
  2939. fprintf(stderr, "\t-i interval:\n");
  2940. fprintf(stderr, "\t\tcycle interval - resign "
  2941. "if < interval from end ( (end-start)/4 )\n");
  2942. fprintf(stderr, "\t-j jitter:\n");
  2943. fprintf(stderr, "\t\trandomize signature end time up to jitter seconds\n");
  2944. fprintf(stderr, "\t-v debuglevel (0)\n");
  2945. fprintf(stderr, "\t-o origin:\n");
  2946. fprintf(stderr, "\t\tzone origin (name of zonefile)\n");
  2947. fprintf(stderr, "\t-f outfile:\n");
  2948. fprintf(stderr, "\t\tfile the signed zone is written in "
  2949. "(zonefile + .signed)\n");
  2950. fprintf(stderr, "\t-I format:\n");
  2951. fprintf(stderr, "\t\tfile format of input zonefile (text)\n");
  2952. fprintf(stderr, "\t-O format:\n");
  2953. fprintf(stderr, "\t\tfile format of signed zone file (text)\n");
  2954. fprintf(stderr, "\t-N format:\n");
  2955. fprintf(stderr, "\t\tsoa serial format of signed zone file (keep)\n");
  2956. fprintf(stderr, "\t-r randomdev:\n");
  2957. fprintf(stderr, "\t\ta file containing random data\n");
  2958. fprintf(stderr, "\t-a:\t");
  2959. fprintf(stderr, "verify generated signatures\n");
  2960. fprintf(stderr, "\t-c class (IN)\n");
  2961. fprintf(stderr, "\t-E engine:\n");
  2962. #ifdef USE_PKCS11
  2963. fprintf(stderr, "\t\tname of an OpenSSL engine to use "
  2964. "(default is \"pkcs11\")\n");
  2965. #else
  2966. fprintf(stderr, "\t\tname of an OpenSSL engine to use\n");
  2967. #endif
  2968. fprintf(stderr, "\t-p:\t");
  2969. fprintf(stderr, "use pseudorandom data (faster but less secure)\n");
  2970. fprintf(stderr, "\t-P:\t");
  2971. fprintf(stderr, "disable post-sign verification\n");
  2972. fprintf(stderr, "\t-T TTL:\tTTL for newly added DNSKEYs\n");
  2973. fprintf(stderr, "\t-t:\t");
  2974. fprintf(stderr, "print statistics\n");
  2975. fprintf(stderr, "\t-u:\t");
  2976. fprintf(stderr, "update or replace an existing NSEC/NSEC3 chain\n");
  2977. fprintf(stderr, "\t-x:\tsign DNSKEY record with KSKs only, not ZSKs\n");
  2978. fprintf(stderr, "\t-z:\tsign all records with KSKs\n");
  2979. fprintf(stderr, "\t-C:\tgenerate a keyset file, for compatibility\n"
  2980. "\t\twith older versions of dnssec-signzone -g\n");
  2981. fprintf(stderr, "\t-n ncpus (number of cpus present)\n");
  2982. fprintf(stderr, "\t-k key_signing_key\n");
  2983. fprintf(stderr, "\t-l lookasidezone\n");
  2984. fprintf(stderr, "\t-3 NSEC3 salt\n");
  2985. fprintf(stderr, "\t-H NSEC3 iterations (10)\n");
  2986. fprintf(stderr, "\t-A NSEC3 optout\n");
  2987. fprintf(stderr, "\n");
  2988. fprintf(stderr, "Signing Keys: ");
  2989. fprintf(stderr, "(default: all zone keys that have private keys)\n");
  2990. fprintf(stderr, "\tkeyfile (Kname+alg+tag)\n");
  2991. exit(0);
  2992. }
  2993. static void
  2994. removetempfile(void) {
  2995. if (removefile)
  2996. isc_file_remove(tempfile);
  2997. }
  2998. static void
  2999. print_stats(isc_time_t *timer_start, isc_time_t *timer_finish,
  3000. isc_time_t *sign_start, isc_time_t *sign_finish)
  3001. {
  3002. isc_uint64_t time_us; /* Time in microseconds */
  3003. isc_uint64_t time_ms; /* Time in milliseconds */
  3004. isc_uint64_t sig_ms; /* Signatures per millisecond */
  3005. printf("Signatures generated: %10d\n", nsigned);
  3006. printf("Signatures retained: %10d\n", nretained);
  3007. printf("Signatures dropped: %10d\n", ndropped);
  3008. printf("Signatures successfully verified: %10d\n", nverified);
  3009. printf("Signatures unsuccessfully verified: %10d\n", nverifyfailed);
  3010. time_us = isc_time_microdiff(sign_finish, sign_start);
  3011. time_ms = time_us / 1000;
  3012. printf("Signing time in seconds: %7u.%03u\n",
  3013. (unsigned int) (time_ms / 1000),
  3014. (unsigned int) (time_ms % 1000));
  3015. if (time_us > 0) {
  3016. sig_ms = ((isc_uint64_t)nsigned * 1000000000) / time_us;
  3017. printf("Signatures per second: %7u.%03u\n",
  3018. (unsigned int) sig_ms / 1000,
  3019. (unsigned int) sig_ms % 1000);
  3020. }
  3021. time_us = isc_time_microdiff(timer_finish, timer_start);
  3022. time_ms = time_us / 1000;
  3023. printf("Runtime in seconds: %7u.%03u\n",
  3024. (unsigned int) (time_ms / 1000),
  3025. (unsigned int) (time_ms % 1000));
  3026. }
  3027. int
  3028. main(int argc, char *argv[]) {
  3029. int i, ch;
  3030. char *startstr = NULL, *endstr = NULL, *classname = NULL;
  3031. char *origin = NULL, *file = NULL, *output = NULL;
  3032. char *inputformatstr = NULL, *outputformatstr = NULL;
  3033. char *serialformatstr = NULL;
  3034. char *dskeyfile[MAXDSKEYS];
  3035. int ndskeys = 0;
  3036. char *endp;
  3037. isc_time_t timer_start, timer_finish;
  3038. isc_time_t sign_start, sign_finish;
  3039. dns_dnsseckey_t *key;
  3040. isc_result_t result;
  3041. isc_log_t *log = NULL;
  3042. isc_boolean_t pseudorandom = ISC_FALSE;
  3043. #ifdef USE_PKCS11
  3044. const char *engine = "pkcs11";
  3045. #else
  3046. const char *engine = NULL;
  3047. #endif
  3048. unsigned int eflags;
  3049. isc_boolean_t free_output = ISC_FALSE;
  3050. int tempfilelen;
  3051. dns_rdataclass_t rdclass;
  3052. isc_task_t **tasks = NULL;
  3053. isc_buffer_t b;
  3054. int len;
  3055. hashlist_t hashlist;
  3056. isc_boolean_t smartsign = ISC_FALSE;
  3057. isc_boolean_t make_keyset = ISC_FALSE;
  3058. isc_boolean_t set_salt = ISC_FALSE;
  3059. isc_boolean_t set_optout = ISC_FALSE;
  3060. isc_boolean_t set_iter = ISC_FALSE;
  3061. #define CMDLINE_FLAGS \
  3062. "3:AaCc:Dd:E:e:f:FghH:i:I:j:K:k:l:m:n:N:o:O:pPr:s:ST:tuUv:xz"
  3063. /*
  3064. * Process memory debugging argument first.
  3065. */
  3066. while ((ch = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != -1) {
  3067. switch (ch) {
  3068. case 'm':
  3069. if (strcasecmp(isc_commandline_argument, "record") == 0)
  3070. isc_mem_debugging |= ISC_MEM_DEBUGRECORD;
  3071. if (strcasecmp(isc_commandline_argument, "trace") == 0)
  3072. isc_mem_debugging |= ISC_MEM_DEBUGTRACE;
  3073. if (strcasecmp(isc_commandline_argument, "usage") == 0)
  3074. isc_mem_debugging |= ISC_MEM_DEBUGUSAGE;
  3075. if (strcasecmp(isc_commandline_argument, "size") == 0)
  3076. isc_mem_debugging |= ISC_MEM_DEBUGSIZE;
  3077. if (strcasecmp(isc_commandline_argument, "mctx") == 0)
  3078. isc_mem_debugging |= ISC_MEM_DEBUGCTX;
  3079. break;
  3080. default:
  3081. break;
  3082. }
  3083. }
  3084. isc_commandline_reset = ISC_TRUE;
  3085. masterstyle = &dns_master_style_explicitttl;
  3086. check_result(isc_app_start(), "isc_app_start");
  3087. result = isc_mem_create(0, 0, &mctx);
  3088. if (result != ISC_R_SUCCESS)
  3089. fatal("out of memory");
  3090. dns_result_register();
  3091. isc_commandline_errprint = ISC_FALSE;
  3092. while ((ch = isc_commandline_parse(argc, argv, CMDLINE_FLAGS)) != -1) {
  3093. switch (ch) {
  3094. case '3':
  3095. set_salt = ISC_TRUE;
  3096. nsec_datatype = dns_rdatatype_nsec3;
  3097. if (strcmp(isc_commandline_argument, "-") != 0) {
  3098. isc_buffer_t target;
  3099. char *sarg;
  3100. sarg = isc_commandline_argument;
  3101. isc_buffer_init(&target, saltbuf,
  3102. sizeof(saltbuf));
  3103. result = isc_hex_decodestring(sarg, &target);
  3104. check_result(result,
  3105. "isc_hex_decodestring(salt)");
  3106. salt_length = isc_buffer_usedlength(&target);
  3107. }
  3108. break;
  3109. case 'A':
  3110. set_optout = ISC_TRUE;
  3111. if (OPTOUT(nsec3flags))
  3112. nsec3flags &= ~DNS_NSEC3FLAG_OPTOUT;
  3113. else
  3114. nsec3flags |= DNS_NSEC3FLAG_OPTOUT;
  3115. break;
  3116. case 'a':
  3117. tryverify = ISC_TRUE;
  3118. break;
  3119. case 'C':
  3120. make_keyset = ISC_TRUE;
  3121. break;
  3122. case 'c':
  3123. classname = isc_commandline_argument;
  3124. break;
  3125. case 'd':
  3126. dsdir = isc_commandline_argument;
  3127. if (strlen(dsdir) == 0U)
  3128. fatal("DS directory must be non-empty string");
  3129. result = try_dir(dsdir);
  3130. if (result != ISC_R_SUCCESS)
  3131. fatal("cannot open directory %s: %s",
  3132. dsdir, isc_result_totext(result));
  3133. break;
  3134. case 'E':
  3135. engine = isc_commandline_argument;
  3136. break;
  3137. case 'e':
  3138. endstr = isc_commandline_argument;
  3139. break;
  3140. case 'f':
  3141. output = isc_commandline_argument;
  3142. break;
  3143. case 'g':
  3144. generateds = ISC_TRUE;
  3145. break;
  3146. case 'H':
  3147. set_iter = ISC_TRUE;
  3148. nsec3iter = strtoul(isc_commandline_argument, &endp, 0);
  3149. if (*endp != '\0')
  3150. fatal("iterations must be numeric");
  3151. if (nsec3iter > 0xffffU)
  3152. fatal("iterations too big");
  3153. break;
  3154. case 'h':
  3155. usage();
  3156. break;
  3157. case 'I':
  3158. inputformatstr = isc_commandline_argument;
  3159. break;
  3160. case 'i':
  3161. endp = NULL;
  3162. cycle = strtol(isc_commandline_argument, &endp, 0);
  3163. if (*endp != '\0' || cycle < 0)
  3164. fatal("cycle period must be numeric and "
  3165. "positive");
  3166. break;
  3167. case 'j':
  3168. endp = NULL;
  3169. jitter = strtol(isc_commandline_argument, &endp, 0);
  3170. if (*endp != '\0' || jitter < 0)
  3171. fatal("jitter must be numeric and positive");
  3172. break;
  3173. case 'K':
  3174. directory = isc_commandline_argument;
  3175. break;
  3176. case 'k':
  3177. if (ndskeys == MAXDSKEYS)
  3178. fatal("too many key-signing keys specified");
  3179. dskeyfile[ndskeys++] = isc_commandline_argument;
  3180. break;
  3181. case 'l':
  3182. len = strlen(isc_commandline_argument);
  3183. isc_buffer_init(&b, isc_commandline_argument, len);
  3184. isc_buffer_add(&b, len);
  3185. dns_fixedname_init(&dlv_fixed);
  3186. dlv = dns_fixedname_name(&dlv_fixed);
  3187. result = dns_name_fromtext(dlv, &b, dns_rootname, 0,
  3188. NULL);
  3189. check_result(result, "dns_name_fromtext(dlv)");
  3190. break;
  3191. case 'm':
  3192. break;
  3193. case 'N':
  3194. serialformatstr = isc_commandline_argument;
  3195. break;
  3196. case 'n':
  3197. endp = NULL;
  3198. ntasks = strtol(isc_commandline_argument, &endp, 0);
  3199. if (*endp != '\0' || ntasks > ISC_INT32_MAX)
  3200. fatal("number of cpus must be numeric");
  3201. break;
  3202. case 'O':
  3203. outputformatstr = isc_commandline_argument;
  3204. break;
  3205. case 'o':
  3206. origin = isc_commandline_argument;
  3207. break;
  3208. case 'P':
  3209. disable_zone_check = ISC_TRUE;
  3210. break;
  3211. case 'p':
  3212. pseudorandom = ISC_TRUE;
  3213. break;
  3214. case 'r':
  3215. setup_entropy(mctx, isc_commandline_argument, &ectx);
  3216. break;
  3217. case 'S':
  3218. smartsign = ISC_TRUE;
  3219. break;
  3220. case 's':
  3221. startstr = isc_commandline_argument;
  3222. break;
  3223. case 'T':
  3224. endp = NULL;
  3225. set_keyttl = ISC_TRUE;
  3226. keyttl = strtottl(isc_commandline_argument);
  3227. break;
  3228. case 't':
  3229. printstats = ISC_TRUE;
  3230. break;
  3231. case 'U': /* Undocumented for testing only. */
  3232. unknownalg = ISC_TRUE;
  3233. break;
  3234. case 'u':
  3235. update_chain = ISC_TRUE;
  3236. break;
  3237. case 'v':
  3238. endp = NULL;
  3239. verbose = strtol(isc_commandline_argument, &endp, 0);
  3240. if (*endp != '\0')
  3241. fatal("verbose level must be numeric");
  3242. break;
  3243. case 'x':
  3244. keyset_kskonly = ISC_TRUE;
  3245. break;
  3246. case 'z':
  3247. ignore_kskflag = ISC_TRUE;
  3248. break;
  3249. case 'F':
  3250. /* Reserved for FIPS mode */
  3251. /* FALLTHROUGH */
  3252. case '?':
  3253. if (isc_commandline_option != '?')
  3254. fprintf(stderr, "%s: invalid argument -%c\n",
  3255. program, isc_commandline_option);
  3256. usage();
  3257. break;
  3258. default:
  3259. fprintf(stderr, "%s: unhandled option -%c\n",
  3260. program, isc_commandline_option);
  3261. exit(1);
  3262. }
  3263. }
  3264. if (ectx == NULL)
  3265. setup_entropy(mctx, NULL, &ectx);
  3266. eflags = ISC_ENTROPY_BLOCKING;
  3267. if (!pseudorandom)
  3268. eflags |= ISC_ENTROPY_GOODONLY;
  3269. result = isc_hash_create(mctx, ectx, DNS_NAME_MAXWIRE);
  3270. if (result != ISC_R_SUCCESS)
  3271. fatal("could not create hash context");
  3272. result = dst_lib_init2(mctx, ectx, engine, eflags);
  3273. if (result != ISC_R_SUCCESS)
  3274. fatal("could not initialize dst: %s",
  3275. isc_result_totext(result));
  3276. isc_stdtime_get(&now);
  3277. if (startstr != NULL) {
  3278. starttime = strtotime(startstr, now, now);
  3279. } else
  3280. starttime = now - 3600; /* Allow for some clock skew. */
  3281. if (endstr != NULL) {
  3282. endtime = strtotime(endstr, now, starttime);
  3283. } else
  3284. endtime = starttime + (30 * 24 * 60 * 60);
  3285. if (cycle == -1)
  3286. cycle = (endtime - starttime) / 4;
  3287. if (ntasks == 0)
  3288. ntasks = isc_os_ncpus() * 2;
  3289. vbprintf(4, "using %d cpus\n", ntasks);
  3290. rdclass = strtoclass(classname);
  3291. if (directory == NULL)
  3292. directory = ".";
  3293. setup_logging(verbose, mctx, &log);
  3294. argc -= isc_commandline_index;
  3295. argv += isc_commandline_index;
  3296. if (argc < 1)
  3297. usage();
  3298. file = argv[0];
  3299. argc -= 1;
  3300. argv += 1;
  3301. if (origin == NULL)
  3302. origin = file;
  3303. if (output == NULL) {
  3304. free_output = ISC_TRUE;
  3305. output = isc_mem_allocate(mctx,
  3306. strlen(file) + strlen(".signed") + 1);
  3307. if (output == NULL)
  3308. fatal("out of memory");
  3309. sprintf(output, "%s.signed", file);
  3310. }
  3311. if (inputformatstr != NULL) {
  3312. if (strcasecmp(inputformatstr, "text") == 0)
  3313. inputformat = dns_masterformat_text;
  3314. else if (strcasecmp(inputformatstr, "raw") == 0)
  3315. inputformat = dns_masterformat_raw;
  3316. else
  3317. fatal("unknown file format: %s\n", inputformatstr);
  3318. }
  3319. if (outputformatstr != NULL) {
  3320. if (strcasecmp(outputformatstr, "text") == 0)
  3321. outputformat = dns_masterformat_text;
  3322. else if (strcasecmp(outputformatstr, "raw") == 0)
  3323. outputformat = dns_masterformat_raw;
  3324. else
  3325. fatal("unknown file format: %s\n", outputformatstr);
  3326. }
  3327. if (serialformatstr != NULL) {
  3328. if (strcasecmp(serialformatstr, "keep") == 0)
  3329. serialformat = SOA_SERIAL_KEEP;
  3330. else if (strcasecmp(serialformatstr, "increment") == 0 ||
  3331. strcasecmp(serialformatstr, "incr") == 0)
  3332. serialformat = SOA_SERIAL_INCREMENT;
  3333. else if (strcasecmp(serialformatstr, "unixtime") == 0)
  3334. serialformat = SOA_SERIAL_UNIXTIME;
  3335. else
  3336. fatal("unknown soa serial format: %s\n",
  3337. serialformatstr);
  3338. }
  3339. result = dns_master_stylecreate(&dsstyle, DNS_STYLEFLAG_NO_TTL,
  3340. 0, 24, 0, 0, 0, 8, mctx);
  3341. check_result(result, "dns_master_stylecreate");
  3342. gdb = NULL;
  3343. TIME_NOW(&timer_start);
  3344. loadzone(file, origin, rdclass, &gdb);
  3345. gorigin = dns_db_origin(gdb);
  3346. gclass = dns_db_class(gdb);
  3347. get_soa_ttls();
  3348. if (!set_keyttl)
  3349. keyttl = soa_ttl;
  3350. /*
  3351. * Check for any existing NSEC3 parameters in the zone,
  3352. * and use them as defaults if -u was not specified.
  3353. */
  3354. if (update_chain && !set_optout && !set_iter && !set_salt)
  3355. nsec_datatype = dns_rdatatype_nsec;
  3356. else
  3357. set_nsec3params(update_chain, set_salt, set_optout, set_iter);
  3358. if (IS_NSEC3) {
  3359. isc_boolean_t answer;
  3360. hash_length = dns_nsec3_hashlength(dns_hash_sha1);
  3361. hashlist_init(&hashlist, dns_db_nodecount(gdb) * 2,
  3362. hash_length);
  3363. result = dns_nsec_nseconly(gdb, gversion, &answer);
  3364. check_result(result, "dns_nsec_nseconly");
  3365. if (answer)
  3366. fatal("NSEC3 generation requested with "
  3367. "NSEC only DNSKEY");
  3368. }
  3369. /*
  3370. * We need to do this early on, as we start messing with the list
  3371. * of keys rather early.
  3372. */
  3373. ISC_LIST_INIT(keylist);
  3374. isc_rwlock_init(&keylist_lock, 0, 0);
  3375. /*
  3376. * Fill keylist with:
  3377. * 1) Keys listed in the DNSKEY set that have
  3378. * private keys associated, *if* no keys were
  3379. * set on the command line.
  3380. * 2) ZSKs set on the command line
  3381. * 3) KSKs set on the command line
  3382. * 4) Any keys remaining in the DNSKEY set which
  3383. * do not have private keys associated and were
  3384. * not specified on the command line.
  3385. */
  3386. if (argc == 0 || smartsign)
  3387. loadzonekeys(!smartsign, ISC_FALSE);
  3388. loadexplicitkeys(argv, argc, ISC_FALSE);
  3389. loadexplicitkeys(dskeyfile, ndskeys, ISC_TRUE);
  3390. loadzonekeys(!smartsign, ISC_TRUE);
  3391. /*
  3392. * If we're doing smart signing, look in the key repository for
  3393. * key files with metadata, and merge them with the keylist
  3394. * we have now.
  3395. */
  3396. if (smartsign)
  3397. build_final_keylist();
  3398. /* Now enumerate the key list */
  3399. for (key = ISC_LIST_HEAD(keylist);
  3400. key != NULL;
  3401. key = ISC_LIST_NEXT(key, link)) {
  3402. key->index = keycount++;
  3403. }
  3404. if (keycount == 0) {
  3405. if (disable_zone_check)
  3406. fprintf(stderr, "%s: warning: No keys specified "
  3407. "or found\n", program);
  3408. else
  3409. fatal("No signing keys specified or found.");
  3410. nokeys = ISC_TRUE;
  3411. }
  3412. warnifallksk(gdb);
  3413. if (IS_NSEC3) {
  3414. unsigned int max;
  3415. result = dns_nsec3_maxiterations(gdb, NULL, mctx, &max);
  3416. check_result(result, "dns_nsec3_maxiterations()");
  3417. if (nsec3iter > max)
  3418. fatal("NSEC3 iterations too big for weakest DNSKEY "
  3419. "strength. Maximum iterations allowed %u.", max);
  3420. }
  3421. gversion = NULL;
  3422. result = dns_db_newversion(gdb, &gversion);
  3423. check_result(result, "dns_db_newversion()");
  3424. switch (serialformat) {
  3425. case SOA_SERIAL_INCREMENT:
  3426. setsoaserial(0);
  3427. break;
  3428. case SOA_SERIAL_UNIXTIME:
  3429. setsoaserial(now);
  3430. break;
  3431. case SOA_SERIAL_KEEP:
  3432. default:
  3433. /* do nothing */
  3434. break;
  3435. }
  3436. remove_duplicates();
  3437. if (IS_NSEC3)
  3438. nsec3ify(dns_hash_sha1, nsec3iter, salt, salt_length,
  3439. &hashlist);
  3440. else
  3441. nsecify();
  3442. if (!nokeys) {
  3443. writeset("dsset-", dns_rdatatype_ds);
  3444. if (make_keyset)
  3445. writeset("keyset-", dns_rdatatype_dnskey);
  3446. if (dlv != NULL) {
  3447. writeset("dlvset-", dns_rdatatype_dlv);
  3448. }
  3449. }
  3450. tempfilelen = strlen(output) + 20;
  3451. tempfile = isc_mem_get(mctx, tempfilelen);
  3452. if (tempfile == NULL)
  3453. fatal("out of memory");
  3454. result = isc_file_mktemplate(output, tempfile, tempfilelen);
  3455. check_result(result, "isc_file_mktemplate");
  3456. fp = NULL;
  3457. result = isc_file_openunique(tempfile, &fp);
  3458. if (result != ISC_R_SUCCESS)
  3459. fatal("failed to open temporary output file: %s",
  3460. isc_result_totext(result));
  3461. removefile = ISC_TRUE;
  3462. setfatalcallback(&removetempfile);
  3463. print_time(fp);
  3464. print_version(fp);
  3465. result = isc_taskmgr_create(mctx, ntasks, 0, &taskmgr);
  3466. if (result != ISC_R_SUCCESS)
  3467. fatal("failed to create task manager: %s",
  3468. isc_result_totext(result));
  3469. master = NULL;
  3470. result = isc_task_create(taskmgr, 0, &master);
  3471. if (result != ISC_R_SUCCESS)
  3472. fatal("failed to create task: %s", isc_result_totext(result));
  3473. tasks = isc_mem_get(mctx, ntasks * sizeof(isc_task_t *));
  3474. if (tasks == NULL)
  3475. fatal("out of memory");
  3476. for (i = 0; i < (int)ntasks; i++) {
  3477. tasks[i] = NULL;
  3478. result = isc_task_create(taskmgr, 0, &tasks[i]);
  3479. if (result != ISC_R_SUCCESS)
  3480. fatal("failed to create task: %s",
  3481. isc_result_totext(result));
  3482. }
  3483. RUNTIME_CHECK(isc_mutex_init(&namelock) == ISC_R_SUCCESS);
  3484. if (printstats)
  3485. RUNTIME_CHECK(isc_mutex_init(&statslock) == ISC_R_SUCCESS);
  3486. presign();
  3487. TIME_NOW(&sign_start);
  3488. signapex();
  3489. if (!finished) {
  3490. /*
  3491. * There is more work to do. Spread it out over multiple
  3492. * processors if possible.
  3493. */
  3494. for (i = 0; i < (int)ntasks; i++) {
  3495. result = isc_app_onrun(mctx, master, startworker,
  3496. tasks[i]);
  3497. if (result != ISC_R_SUCCESS)
  3498. fatal("failed to start task: %s",
  3499. isc_result_totext(result));
  3500. }
  3501. (void)isc_app_run();
  3502. if (!finished)
  3503. fatal("process aborted by user");
  3504. } else
  3505. isc_task_detach(&master);
  3506. shuttingdown = ISC_TRUE;
  3507. for (i = 0; i < (int)ntasks; i++)
  3508. isc_task_detach(&tasks[i]);
  3509. isc_taskmgr_destroy(&taskmgr);
  3510. isc_mem_put(mctx, tasks, ntasks * sizeof(isc_task_t *));
  3511. postsign();
  3512. TIME_NOW(&sign_finish);
  3513. verifyzone();
  3514. if (outputformat != dns_masterformat_text) {
  3515. result = dns_master_dumptostream2(mctx, gdb, gversion,
  3516. masterstyle, outputformat,
  3517. fp);
  3518. check_result(result, "dns_master_dumptostream2");
  3519. }
  3520. result = isc_stdio_close(fp);
  3521. check_result(result, "isc_stdio_close");
  3522. removefile = ISC_FALSE;
  3523. result = isc_file_rename(tempfile, output);
  3524. if (result != ISC_R_SUCCESS)
  3525. fatal("failed to rename temp file to %s: %s\n",
  3526. output, isc_result_totext(result));
  3527. DESTROYLOCK(&namelock);
  3528. if (printstats)
  3529. DESTROYLOCK(&statslock);
  3530. printf("%s\n", output);
  3531. dns_db_closeversion(gdb, &gversion, ISC_FALSE);
  3532. dns_db_detach(&gdb);
  3533. while (!ISC_LIST_EMPTY(keylist)) {
  3534. key = ISC_LIST_HEAD(keylist);
  3535. ISC_LIST_UNLINK(keylist, key, link);
  3536. dns_dnsseckey_destroy(mctx, &key);
  3537. }
  3538. isc_mem_put(mctx, tempfile, tempfilelen);
  3539. if (free_output)
  3540. isc_mem_free(mctx, output);
  3541. dns_master_styledestroy(&dsstyle, mctx);
  3542. cleanup_logging(&log);
  3543. dst_lib_destroy();
  3544. isc_hash_destroy();
  3545. cleanup_entropy(&ectx);
  3546. dns_name_destroy();
  3547. if (verbose > 10)
  3548. isc_mem_stats(mctx, stdout);
  3549. isc_mem_destroy(&mctx);
  3550. (void) isc_app_finish();
  3551. if (printstats) {
  3552. TIME_NOW(&timer_finish);
  3553. print_stats(&timer_start, &timer_finish,
  3554. &sign_start, &sign_finish);
  3555. }
  3556. return (0);
  3557. }