]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
[master] remove spurious signatures from glue
authorEvan Hunt <each@isc.org>
Wed, 24 Oct 2012 22:45:48 +0000 (15:45 -0700)
committerEvan Hunt <each@isc.org>
Wed, 24 Oct 2012 22:46:59 +0000 (15:46 -0700)
3404. [bug] dnssec-signzone: When re-signing a zone, remove
RRSIG and NSEC records from nodes that used to be
in-zone but are now below a zone cut. [RT #31556]

CHANGES
bin/dnssec/dnssec-signzone.c
bin/tests/system/dnssec/clean.sh
bin/tests/system/dnssec/tests.sh

diff --git a/CHANGES b/CHANGES
index b8e6c3e771acc8af95f811f3cc5ae5484ba14cc2..7a5194465a8bcad20a5a670a20fd26522a91fa49 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,7 @@
+3404.  [bug]           dnssec-signzone: When re-signing a zone, remove
+                       RRSIG and NSEC records from nodes that used to be 
+                       in-zone but are now below a zone cut. [RT #31556]
+
 3403.  [bug]           Silence noisy OpenSSL logging. [RT #31497]
 
 3402.  [bug]           Correct interface numbers for IPv4 and IPv6 interfaces.
index 720e9a6ce24053574360ea15344fd9b2b54fd67c..4b8a0940859f76b606b60f98de23e6cdeb7ee305 100644 (file)
@@ -1602,7 +1602,9 @@ 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) {
+remove_records(dns_dbnode_t *node, dns_rdatatype_t which,
+              isc_boolean_t checknsec)
+{
        isc_result_t result;
        dns_rdatatype_t type, covers;
        dns_rdatasetiter_t *rdsiter = NULL;
@@ -1623,10 +1625,12 @@ remove_records(dns_dbnode_t *node, dns_rdatatype_t which) {
                covers = rdataset.covers;
                dns_rdataset_disassociate(&rdataset);
                if (type == which || covers == which) {
-                       if (which == dns_rdatatype_nsec && !update_chain)
+                       if (which == dns_rdatatype_nsec &&
+                           checknsec && !update_chain)
                                fatal("Zone contains NSEC records.  Use -u "
                                      "to update to NSEC3.");
-                       if (which == dns_rdatatype_nsec3param && !update_chain)
+                       if (which == dns_rdatatype_nsec3param &&
+                           checknsec && !update_chain)
                                fatal("Zone contains NSEC3 chains.  Use -u "
                                      "to update to NSEC.");
                        result = dns_db_deleterdataset(gdb, node, gversion,
@@ -1638,6 +1642,39 @@ remove_records(dns_dbnode_t *node, dns_rdatatype_t which) {
        dns_rdatasetiter_destroy(&rdsiter);
 }
 
+/*
+ * Remove signatures covering the given type (0 == all signatures).
+ */
+static void
+remove_sigs(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);
+       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_rrsig &&
+                   (covers == which || which == 0))
+               {
+                       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.
  */
@@ -1714,14 +1751,17 @@ nsecify(void) {
                }
 
                if (dns_name_equal(name, gorigin))
-                       remove_records(node, dns_rdatatype_nsec3param);
+                       remove_records(node, dns_rdatatype_nsec3param,
+                                      ISC_TRUE);
 
                if (is_delegation(gdb, gversion, gorigin, name, node, &nsttl)) {
                        zonecut = dns_fixedname_name(&fzonecut);
                        dns_name_copy(name, zonecut, NULL);
+                       remove_sigs(node, 0);
                        if (generateds)
                                add_ds(name, node, nsttl);
                }
+
                result = dns_dbiterator_next(dbiter);
                nextnode = NULL;
                while (result == ISC_R_SUCCESS) {
@@ -1739,6 +1779,9 @@ nsecify(void) {
                            (zonecut != NULL &&
                             dns_name_issubdomain(nextname, zonecut)))
                        {
+                               remove_sigs(nextnode, 0);
+                               remove_records(nextnode, dns_rdatatype_nsec,
+                                              ISC_FALSE);
                                dns_db_detachnode(gdb, &nextnode);
                                result = dns_dbiterator_next(dbiter);
                                continue;
@@ -2130,7 +2173,7 @@ nsec3ify(unsigned int hashalg, unsigned int iterations,
                }
 
                if (dns_name_equal(name, gorigin))
-                       remove_records(node, dns_rdatatype_nsec);
+                       remove_records(node, dns_rdatatype_nsec, ISC_TRUE);
 
                result = dns_dbiterator_next(dbiter);
                nextnode = NULL;
@@ -2147,6 +2190,7 @@ nsec3ify(unsigned int hashalg, unsigned int iterations,
                        if (!dns_name_issubdomain(nextname, gorigin) ||
                            (zonecut != NULL &&
                             dns_name_issubdomain(nextname, zonecut))) {
+                               remove_sigs(nextnode, 0);
                                dns_db_detachnode(gdb, &nextnode);
                                result = dns_dbiterator_next(dbiter);
                                continue;
@@ -2156,6 +2200,7 @@ nsec3ify(unsigned int hashalg, unsigned int iterations,
                        {
                                zonecut = dns_fixedname_name(&fzonecut);
                                dns_name_copy(nextname, zonecut, NULL);
+                               remove_sigs(nextnode, 0);
                                if (generateds)
                                        add_ds(nextname, nextnode, nsttl);
                                if (OPTOUT(nsec3flags) &&
index 8e21caa8711838ab26ebc5ed4d1a7ef3c9126b20..fc853c0e33facc71c36dfad9319be612be0231d9 100644 (file)
@@ -47,7 +47,7 @@ rm -f ns3/secure.nsec3.example.db
 rm -f ns3/secure.optout.example.db
 rm -f */named.secroots
 rm -f ns1/managed.key.id
-rm -f signer/example.db
+rm -f signer/*.db
 rm -f signer/signer.out.*
 rm -f ns2/algroll.db
 rm -f ns3/kskonly.example.db
index e4040ddb744abcb8f760b10e814f2241cbaab082..0de949c3ceb28d1f66fcc8b8cef6ecc8a0da77c6 100644 (file)
@@ -1123,6 +1123,75 @@ n=`expr $n + 1`
 if [ $ret != 0 ]; then echo "I:failed"; fi
 status=`expr $status + $ret`
 
+echo "I:checking dnssec-signzone purges RRSIGs from formerly-owned glue (nsec) ($n)"
+ret=0
+(
+cd signer
+# remove NSEC-only keys
+rm -f Kexample.+005*
+cp -f example.db.in example2.db
+cat << EOF >> example2.db
+sub1.example. IN A 10.53.0.1
+ns.sub2.example. IN A 10.53.0.2
+EOF
+echo '$INCLUDE "example2.db.signed"' >> example2.db
+touch example2.db.signed
+$SIGNER -DS -O full -f example2.db.signed -o example example2.db > /dev/null 2>&1
+) || ret=1
+grep "^sub1\.example\..*RRSIG[         ]A[     ]" signer/example2.db.signed > /dev/null 2>&1 || ret=1
+grep "^ns\.sub2\.example\..*RRSIG[     ]A[     ]" signer/example2.db.signed > /dev/null 2>&1 || ret=1
+(
+cd signer
+cp -f example.db.in example2.db
+cat << EOF >> example2.db
+sub1.example. IN NS sub1.example.
+sub1.example. IN A 10.53.0.1
+sub2.example. IN NS ns.sub2.example.
+ns.sub2.example. IN A 10.53.0.2
+EOF
+echo '$INCLUDE "example2.db.signed"' >> example2.db
+$SIGNER -DS -O full -f example2.db.signed -o example example2.db > /dev/null 2>&1
+) || ret=1
+grep "^sub1\.example\..*RRSIG[         ]A[     ]" signer/example2.db.signed > /dev/null 2>&1 && ret=1
+grep "^ns\.sub2\.example\..*RRSIG[     ]A[     ]" signer/example2.db.signed > /dev/null 2>&1 && ret=1
+n=`expr $n + 1`
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+echo "I:checking dnssec-signzone purges RRSIGs from formerly-owned glue (nsec3) ($n)"
+ret=0
+(
+cd signer
+rm -f example2.db.signed
+cp -f example.db.in example2.db
+cat << EOF >> example2.db
+sub1.example. IN A 10.53.0.1
+ns.sub2.example. IN A 10.53.0.2
+EOF
+echo '$INCLUDE "example2.db.signed"' >> example2.db
+touch example2.db.signed
+$SIGNER -DS -3 feedabee -O full -f example2.db.signed -o example example2.db > /dev/null 2>&1
+) || ret=1
+grep "^sub1\.example\..*RRSIG[         ]A[     ]" signer/example2.db.signed > /dev/null 2>&1 || ret=1
+grep "^ns\.sub2\.example\..*RRSIG[     ]A[     ]" signer/example2.db.signed > /dev/null 2>&1 || ret=1
+(
+cd signer
+cp -f example.db.in example2.db
+cat << EOF >> example2.db
+sub1.example. IN NS sub1.example.
+sub1.example. IN A 10.53.0.1
+sub2.example. IN NS ns.sub2.example.
+ns.sub2.example. IN A 10.53.0.2
+EOF
+echo '$INCLUDE "example2.db.signed"' >> example2.db
+$SIGNER -DS -3 feedabee -O full -f example2.db.signed -o example example2.db > /dev/null 2>&1
+) || ret=1
+grep "^sub1\.example\..*RRSIG[         ]A[     ]" signer/example2.db.signed > /dev/null 2>&1 && ret=1
+grep "^ns\.sub2\.example\..*RRSIG[     ]A[     ]" signer/example2.db.signed > /dev/null 2>&1 && ret=1
+n=`expr $n + 1`
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
 echo "I:checking dnssec-signzone output format ($n)"
 ret=0
 (