From: Evan Hunt Date: Tue, 3 Oct 2017 08:11:36 +0000 (-0700) Subject: [master] dnssec-signzone can now add sync records X-Git-Tag: v9.12.0b1~109 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=e515fae2ae833b99ed036fe0af050111f6b335c7;p=thirdparty%2Fbind9.git [master] dnssec-signzone can now add sync records 4751. [func] "dnssec-signzone -S" can now automatically add parent synchronization records (CDS and CDNSKEY) according to key metadata set using the -Psync and -Dsync options to dnssec-keygen and dnssec-settime. [RT #46149] --- diff --git a/CHANGES b/CHANGES index bcc9f823d75..bad33a357fe 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,9 @@ +4751. [func] "dnssec-signzone -S" can now automatically add parent + synchronization records (CDS and CDNSKEY) according + to key metadata set using the -Psync and -Dsync + options to dnssec-keygen and dnssec-settime. + [RT #46149] + 4750. [func] "rndc managed-keys destroy" shuts down RFC 5011 key maintenance and deletes the managed-keys database. If followed by "rndc reconfig" or a server restart, diff --git a/bin/dnssec/dnssec-signzone.c b/bin/dnssec/dnssec-signzone.c index 82985f407d6..55c97b6deb5 100644 --- a/bin/dnssec/dnssec-signzone.c +++ b/bin/dnssec/dnssec-signzone.c @@ -2591,45 +2591,114 @@ report(const char *format, ...) { putc('\n', stderr); } +static void +clear_keylist(dns_dnsseckeylist_t *list, isc_mem_t *mctx) { + dns_dnsseckey_t *key; + while (!ISC_LIST_EMPTY(*list)) { + key = ISC_LIST_HEAD(*list); + ISC_LIST_UNLINK(*list, key, link); + dns_dnsseckey_destroy(mctx, &key); + } +} + static void build_final_keylist(void) { isc_result_t result; + dns_dbnode_t *node = NULL; dns_dbversion_t *ver = NULL; dns_diff_t diff; - dns_dnsseckeylist_t matchkeys; + dns_dnsseckeylist_t rmkeys, matchkeys; char name[DNS_NAME_FORMATSIZE]; + dns_rdataset_t cdsset, cdnskeyset, soaset; + isc_stdtime_t now; + dns_ttl_t ttl; + + ISC_LIST_INIT(rmkeys); + ISC_LIST_INIT(matchkeys); + + dns_rdataset_init(&soaset); + dns_rdataset_init(&cdsset); + dns_rdataset_init(&cdnskeyset); + + isc_stdtime_get(&now); /* * Find keys that match this zone in the key repository. */ - ISC_LIST_INIT(matchkeys); result = dns_dnssec_findmatchingkeys(gorigin, directory, mctx, &matchkeys); - if (result == ISC_R_NOTFOUND) + if (result == ISC_R_NOTFOUND) { result = ISC_R_SUCCESS; + } check_result(result, "dns_dnssec_findmatchingkeys"); result = dns_db_newversion(gdb, &ver); check_result(result, "dns_db_newversion"); + result = dns_db_getoriginnode(gdb, &node); + check_result(result, "dns_db_getoriginnode"); + + /* Get the SOA record's TTL */ + result = dns_db_findrdataset(gdb, node, ver, dns_rdatatype_soa, + dns_rdatatype_none, 0, &soaset, NULL); + check_result(result, "dns_db_findrdataset"); + ttl = soaset.ttl; + dns_rdataset_disassociate(&soaset); + + /* Get the CDS rdataset */ + result = dns_db_findrdataset(gdb, node, ver, dns_rdatatype_cds, + dns_rdatatype_none, 0, &cdsset, NULL); + if (result != ISC_R_SUCCESS && + dns_rdataset_isassociated(&cdsset)) + { + dns_rdataset_disassociate(&cdsset); + } + + /* Get the CDNSKEY rdataset */ + result = dns_db_findrdataset(gdb, node, ver, dns_rdatatype_cdnskey, + dns_rdatatype_none, 0, &cdnskeyset, NULL); + if (result != ISC_R_SUCCESS && + dns_rdataset_isassociated(&cdnskeyset)) + { + dns_rdataset_disassociate(&cdnskeyset); + } + dns_diff_init(mctx, &diff); /* * Update keylist with information from from the key repository. */ - dns_dnssec_updatekeys(&keylist, &matchkeys, NULL, gorigin, keyttl, + dns_dnssec_updatekeys(&keylist, &matchkeys, &rmkeys, gorigin, keyttl, &diff, ignore_kskflag, mctx, report); + /* + * Update keylist with sync records. + */ + dns_dnssec_syncupdate(&keylist, &rmkeys, &cdsset, &cdnskeyset, + now, ttl, &diff, mctx); + dns_name_format(gorigin, name, sizeof(name)); result = dns_diff_applysilently(&diff, gdb, ver); - if (result != ISC_R_SUCCESS) + if (result != ISC_R_SUCCESS) { fatal("failed to update DNSKEY RRset at node '%s': %s", name, isc_result_totext(result)); + } + dns_db_detachnode(gdb, &node); dns_db_closeversion(gdb, &ver, ISC_TRUE); dns_diff_clear(&diff); + + if (dns_rdataset_isassociated(&cdsset)) { + dns_rdataset_disassociate(&cdsset); + } + if (dns_rdataset_isassociated(&cdnskeyset)) { + dns_rdataset_disassociate(&cdnskeyset); + } + + clear_keylist(&rmkeys, mctx); + clear_keylist(&matchkeys, mctx); } static void @@ -3616,8 +3685,9 @@ main(int argc, char *argv[]) { * do not have private keys associated and were * not specified on the command line. */ - if (argc == 0 || smartsign) + if (argc == 0 || smartsign) { loadzonekeys(!smartsign, ISC_FALSE); + } loadexplicitkeys(argv, argc, ISC_FALSE); loadexplicitkeys(dskeyfile, ndskeys, ISC_TRUE); loadzonekeys(!smartsign, ISC_TRUE); @@ -3627,8 +3697,9 @@ main(int argc, char *argv[]) { * key files with metadata, and merge them with the keylist * we have now. */ - if (smartsign) + if (smartsign) { build_final_keylist(); + } /* Now enumerate the key list */ for (key = ISC_LIST_HEAD(keylist); diff --git a/bin/tests/system/smartsign/tests.sh b/bin/tests/system/smartsign/tests.sh index 5614ba1edfb..e2ece3c4568 100644 --- a/bin/tests/system/smartsign/tests.sh +++ b/bin/tests/system/smartsign/tests.sh @@ -51,6 +51,9 @@ echo I:revoking key cksk3=`$KEYGEN -q -a rsasha1 -r $RANDFILE -fk $czone` cksk4=`$REVOKE $cksk3` +echo I:setting up sync key +cksk5=`$KEYGEN -q -a rsasha1 -r $RANDFILE -fk -P now+1mo -A now+1mo -Psync now $czone` + echo I:generating parent keys pzsk=`$KEYGEN -q -a rsasha1 -r $RANDFILE $pzone` pksk=`$KEYGEN -q -a rsasha1 -r $RANDFILE -fk $pzone` @@ -337,5 +340,22 @@ grep -w "$ckpublished" dnskey.sigs > /dev/null || ret=1 if [ $ret != 0 ]; then echo "I:failed"; fi status=`expr $status + $ret` +echo "I:checking sync record publication" +ret=0 +grep CDNSKEY $cfile.signed > /dev/null || ret=1 +grep CDS $cfile.signed > /dev/null || ret=1 +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +echo "I:checking sync record deletion" +ret=0 +$SETTIME -P now -A now -Dsync now ${cksk5} > /dev/null +$SIGNER -Sg -r $RANDFILE -o $czone -f $cfile.new $cfile.signed > /dev/null 2>&1 +mv $cfile.new $cfile.signed +grep CDNSKEY $cfile.signed > /dev/null && ret=1 +grep CDS $cfile.signed > /dev/null && ret=1 +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + echo "I:exit status: $status" [ $status -eq 0 ] || exit 1 diff --git a/doc/arm/notes.xml b/doc/arm/notes.xml index 11dfa4e8619..6ffa87d3d8c 100644 --- a/doc/arm/notes.xml +++ b/doc/arm/notes.xml @@ -412,6 +412,15 @@ etc. [RT #32456] + + + dnssec-signzone -S can now add or remove + synchronization records (CDS and CDNSKEY) based on key metadata + set by the -Psync and -Dsync + options to dnssec-keygen, + dnssec-settime, etc. [RT #46149] + +