From: Mark Andrews Date: Thu, 3 Jun 2010 03:13:32 +0000 (+0000) Subject: 2911. [bug] dnssec-signzone didn't handle out of zone records well. X-Git-Tag: v9.7.1b1~78^2~6 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=675cc80975eb7d15e0d9f1d5f424baafaf189fde;p=thirdparty%2Fbind9.git 2911. [bug] dnssec-signzone didn't handle out of zone records well. [RT #21367] --- diff --git a/CHANGES b/CHANGES index 80454f51c12..2356f604777 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +2911. [bug] dnssec-signzone didn't handle out of zone records well. + [RT #21367] + 2910. [func] Sanity check Kerberos credentials. [RT #20986] 2909. [bug] named-checkconf -p could die if "update-policy local;" diff --git a/bin/dnssec/dnssec-signzone.c b/bin/dnssec/dnssec-signzone.c index 7e325a67dbf..96b896d5075 100644 --- a/bin/dnssec/dnssec-signzone.c +++ b/bin/dnssec/dnssec-signzone.c @@ -29,7 +29,7 @@ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dnssec-signzone.c,v 1.260 2010/01/05 23:48:37 tbox Exp $ */ +/* $Id: dnssec-signzone.c,v 1.261 2010/06/03 03:13:31 marka Exp $ */ /*! \file */ @@ -1655,6 +1655,15 @@ verifyzone(void) { result = dns_dbiterator_current(dbiter, &node, name); check_dns_dbiterator_current(result); + if (!dns_name_issubdomain(name, gorigin)) { + dns_db_detachnode(gdb, &node); + result = dns_dbiterator_next(dbiter); + if (result == ISC_R_NOMORE) + done = ISC_TRUE; + else + check_result(result, "dns_dbiterator_next()"); + continue; + } if (delegation(name, node, NULL)) { zonecut = dns_fixedname_name(&fzonecut); dns_name_copy(name, zonecut, NULL); @@ -1990,6 +1999,46 @@ add_ds(dns_name_t *name, dns_dbnode_t *node, isc_uint32_t nsttl) { } } +/* + * Remove records of the given type and their signatures. + */ +static void +remove_records(dns_dbnode_t *node, dns_rdatatype_t which) { + isc_result_t result; + dns_rdatatype_t type, covers; + dns_rdatasetiter_t *rdsiter = NULL; + dns_rdataset_t rdataset; + + dns_rdataset_init(&rdataset); + + /* + * Delete any records of the given type at the apex. + */ + result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter); + check_result(result, "dns_db_allrdatasets()"); + for (result = dns_rdatasetiter_first(rdsiter); + result == ISC_R_SUCCESS; + result = dns_rdatasetiter_next(rdsiter)) { + dns_rdatasetiter_current(rdsiter, &rdataset); + type = rdataset.type; + covers = rdataset.covers; + dns_rdataset_disassociate(&rdataset); + if (type == which || covers == which) { + if (which == dns_rdatatype_nsec && !update_chain) + fatal("Zone contains NSEC records. Use -u " + "to update to NSEC3."); + if (which == dns_rdatatype_nsec3param && !update_chain) + fatal("Zone contains NSEC3 chains. Use -u " + "to update to NSEC."); + result = dns_db_deleterdataset(gdb, node, gversion, + type, covers); + check_result(result, "dns_db_deleterdataset()"); + continue; + } + } + dns_rdatasetiter_destroy(&rdsiter); +} + /*% * Generate NSEC records for the zone and remove NSEC3/NSEC3PARAM records. */ @@ -2049,36 +2098,25 @@ nsecify(void) { result = dns_dbiterator_first(dbiter); check_result(result, "dns_dbiterator_first()"); - result = dns_dbiterator_current(dbiter, &node, name); - check_dns_dbiterator_current(result); - - /* - * Delete any NSEC3PARAM records at the apex. - */ - result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter); - check_result(result, "dns_db_allrdatasets()"); - for (result = dns_rdatasetiter_first(rdsiter); - result == ISC_R_SUCCESS; - result = dns_rdatasetiter_next(rdsiter)) { - dns_rdatasetiter_current(rdsiter, &rdataset); - type = rdataset.type; - covers = rdataset.covers; - dns_rdataset_disassociate(&rdataset); - if (type == dns_rdatatype_nsec3param || - covers == dns_rdatatype_nsec3param) { - result = dns_db_deleterdataset(gdb, node, gversion, - type, covers); - check_result(result, - "dns_db_deleterdataset(nsec3param/rrsig)"); - continue; - } - } - dns_rdatasetiter_destroy(&rdsiter); - dns_db_detachnode(gdb, &node); - while (!done) { result = dns_dbiterator_current(dbiter, &node, name); check_dns_dbiterator_current(result); + /* + * Skip out-of-zone records. + */ + if (!dns_name_issubdomain(name, gorigin)) { + result = dns_dbiterator_next(dbiter); + if (result == ISC_R_NOMORE) + done = ISC_TRUE; + else + check_result(result, "dns_dbiterator_next()"); + dns_db_detachnode(gdb, &node); + continue; + } + + if (dns_name_equal(name, gorigin)) + remove_records(node, dns_rdatatype_nsec3param); + if (delegation(name, node, &nsttl)) { zonecut = dns_fixedname_name(&fzonecut); dns_name_copy(name, zonecut, NULL); @@ -2451,8 +2489,6 @@ nsec3ify(unsigned int hashalg, unsigned int iterations, dns_fixedname_t fname, fnextname, fzonecut; dns_name_t *name, *nextname, *zonecut; dns_rdataset_t rdataset; - dns_rdatasetiter_t *rdsiter = NULL; - dns_rdatatype_t type, covers; int order; isc_boolean_t active; isc_boolean_t done = ISC_FALSE; @@ -2477,40 +2513,25 @@ nsec3ify(unsigned int hashalg, unsigned int iterations, result = dns_dbiterator_first(dbiter); check_result(result, "dns_dbiterator_first()"); - result = dns_dbiterator_current(dbiter, &node, name); - check_dns_dbiterator_current(result); - - /* - * Delete any NSEC records at the apex. - */ - result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter); - check_result(result, "dns_db_allrdatasets()"); - for (result = dns_rdatasetiter_first(rdsiter); - result == ISC_R_SUCCESS; - result = dns_rdatasetiter_next(rdsiter)) { - dns_rdatasetiter_current(rdsiter, &rdataset); - type = rdataset.type; - covers = rdataset.covers; - dns_rdataset_disassociate(&rdataset); - if (type == dns_rdatatype_nsec || - covers == dns_rdatatype_nsec) { - if (!update_chain) - fatal("Zone contains NSEC records. Use -u " - "to update to NSEC3."); - - result = dns_db_deleterdataset(gdb, node, gversion, - type, covers); - check_result(result, - "dns_db_deleterdataset(nsec3param/rrsig)"); - continue; - } - } - dns_rdatasetiter_destroy(&rdsiter); - dns_db_detachnode(gdb, &node); - while (!done) { result = dns_dbiterator_current(dbiter, &node, name); check_dns_dbiterator_current(result); + /* + * Skip out-of-zone records. + */ + if (!dns_name_issubdomain(name, gorigin)) { + result = dns_dbiterator_next(dbiter); + if (result == ISC_R_NOMORE) + done = ISC_TRUE; + else + check_result(result, "dns_dbiterator_next()"); + dns_db_detachnode(gdb, &node); + continue; + } + + if (dns_name_equal(name, gorigin)) + remove_records(node, dns_rdatatype_nsec); + result = dns_dbiterator_next(dbiter); nextnode = NULL; while (result == ISC_R_SUCCESS) { @@ -2627,6 +2648,18 @@ nsec3ify(unsigned int hashalg, unsigned int iterations, while (!done) { result = dns_dbiterator_current(dbiter, &node, name); check_dns_dbiterator_current(result); + /* + * Skip out-of-zone records. + */ + if (!dns_name_issubdomain(name, gorigin)) { + result = dns_dbiterator_next(dbiter); + if (result == ISC_R_NOMORE) + done = ISC_TRUE; + else + check_result(result, "dns_dbiterator_next()"); + dns_db_detachnode(gdb, &node); + continue; + } result = dns_dbiterator_next(dbiter); nextnode = NULL; while (result == ISC_R_SUCCESS) { diff --git a/bin/tests/system/dnssec/clean.sh b/bin/tests/system/dnssec/clean.sh index 0f866b2249d..0842eeaa7de 100644 --- a/bin/tests/system/dnssec/clean.sh +++ b/bin/tests/system/dnssec/clean.sh @@ -15,7 +15,7 @@ # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. -# $Id: clean.sh,v 1.25 2009/10/27 23:47:44 tbox Exp $ +# $Id: clean.sh,v 1.26 2010/06/03 03:13:32 marka Exp $ rm -f */K* */keyset-* */dsset-* */dlvset-* */signedkey-* */*.signed */trusted.conf */tmp* */*.jnl */*.bk rm -f ns1/root.db ns2/example.db ns3/secure.example.db @@ -37,3 +37,4 @@ rm -f ns3/optout.nsec3.example.db rm -f ns3/optout.optout.example.db rm -f ns3/secure.nsec3.example.db rm -f ns3/secure.optout.example.db +rm -f signer/example.db diff --git a/bin/tests/system/dnssec/tests.sh b/bin/tests/system/dnssec/tests.sh index ad769ccd640..3156b302ee7 100644 --- a/bin/tests/system/dnssec/tests.sh +++ b/bin/tests/system/dnssec/tests.sh @@ -15,7 +15,7 @@ # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. -# $Id: tests.sh,v 1.58 2010/01/18 23:48:40 tbox Exp $ +# $Id: tests.sh,v 1.59 2010/06/03 03:13:32 marka Exp $ SYSTEMTESTTOP=.. . $SYSTEMTESTTOP/conf.sh @@ -904,6 +904,35 @@ n=`expr $n + 1` if [ $ret != 0 ]; then echo "I:failed"; fi status=`expr $status + $ret` +echo "I:checking that we can sign a zone with out-of-zone records ($n)" +ret=0 +( +cd signer +RANDFILE=../random.data +zone=example +key1=`$KEYGEN -r $RANDFILE -a NSEC3RSASHA1 -b 1024 -n zone $zone` +key2=`$KEYGEN -r $RANDFILE -f KSK -a NSEC3RSASHA1 -b 1024 -n zone $zone` +cat example.db.in $key1.key $key2.key > example.db +$SIGNER -o example -f example.db example.db > /dev/null 2>&1 +) || ret=1 +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + +echo "I:checking that we can sign a zone (NSEC3) with out-of-zone records ($n)" +ret=0 +( +cd signer +RANDFILE=../random.data +zone=example +key1=`$KEYGEN -r $RANDFILE -a NSEC3RSASHA1 -b 1024 -n zone $zone` +key2=`$KEYGEN -r $RANDFILE -f KSK -a NSEC3RSASHA1 -b 1024 -n zone $zone` +cat example.db.in $key1.key $key2.key > example.db +$SIGNER -3 - -o example -f example.db example.db > /dev/null 2>&1 +grep "JIEIDARU68SM01LPOROGNS2AUEE8ERCP.example. 0 IN NSEC3 1 0 100 - JIEIDARU68SM01LPOROGNS2AUEE8ERCP A NS SOA RRSIG DNSKEY NSEC3PARAM" example.db > /dev/null +) || ret=1 +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + # Run a minimal update test if possible. This is really just # a regression test for RT #2399; more tests should be added.