]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
3175. [bug] Fix how DNSSEC positive wildcard responses from a
authorMark Andrews <marka@isc.org>
Thu, 20 Oct 2011 21:42:11 +0000 (21:42 +0000)
committerMark Andrews <marka@isc.org>
Thu, 20 Oct 2011 21:42:11 +0000 (21:42 +0000)
                        NSEC3 signed zone are validated.  Stop sending a
                        unnecessary NSEC3 record when generating such
                        responses. [RT #26200]

CHANGES
bin/named/query.c
bin/tests/system/dnssec/tests.sh
lib/dns/validator.c

diff --git a/CHANGES b/CHANGES
index f05395176cb98a0d98db9de0cd31d83c5e14bc5e..4b5089fecf80e3f585de55611f1c466f8198e54e 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,8 @@
+3175.   [bug]           Fix how DNSSEC positive wildcard responses from a
+                       NSEC3 signed zone are validated.  Stop sending a
+                       unnecessary NSEC3 record when generating such
+                       responses. [RT #26200]
+
 3174.  [bug]           Always compute to revoked key tag from scratch.
                        [RT #24711]
 
index 2d6c91323f5676f8ce47ef83305670370e77cccb..36850fdf2f20fc0ad9afd59229f367ffdb0eac96 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: query.c,v 1.375 2011/10/13 22:48:23 tbox Exp $ */
+/* $Id: query.c,v 1.376 2011/10/20 21:42:11 marka Exp $ */
 
 /*! \file */
 
@@ -3378,8 +3378,9 @@ query_addwildcardproof(ns_client_t *client, dns_db_t *db,
                                       sigrdataset, fname, ISC_TRUE, cname);
                if (!dns_rdataset_isassociated(rdataset))
                        goto cleanup;
-               query_addrrset(client, &fname, &rdataset, &sigrdataset,
-                              dbuf, DNS_SECTION_AUTHORITY);
+               if (!ispositive)
+                       query_addrrset(client, &fname, &rdataset, &sigrdataset,
+                                      dbuf, DNS_SECTION_AUTHORITY);
 
                /*
                 * Replace resources which were consumed by query_addrrset.
index 8e7c65e4d29617119d47527cc672d472125d5998..13e1b3cd8aac7504cf54c6f934b19545fad0ce20 100644 (file)
@@ -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.98 2011/10/15 05:00:15 marka Exp $
+# $Id: tests.sh,v 1.99 2011/10/20 21:42:11 marka Exp $
 
 SYSTEMTESTTOP=..
 . $SYSTEMTESTTOP/conf.sh
@@ -133,6 +133,24 @@ n=`expr $n + 1`
 if [ $ret != 0 ]; then echo "I:failed"; fi
 status=`expr $status + $ret`
 
+echo "I:checking positive wildcard answer NSEC3 ($n)"
+ret=0
+$DIG $DIGOPTS a.wild.nsec3.example. @10.53.0.3 a > dig.out.ns3.test$n || ret=1
+grep "AUTHORITY: 4," dig.out.ns3.test$n > /dev/null || ret=1
+grep "status: NOERROR" dig.out.ns3.test$n > /dev/null || ret=1
+n=`expr $n + 1`
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+echo "I:checking positive wildcard answer NSEC3 ($n)"
+ret=0
+$DIG $DIGOPTS a.wild.nsec3.example. @10.53.0.3 a > dig.out.ns3.test$n || ret=1
+grep "AUTHORITY: 4," dig.out.ns3.test$n > /dev/null || ret=1
+grep "status: NOERROR" dig.out.ns3.test$n > /dev/null || ret=1
+n=`expr $n + 1`
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
 echo "I:checking positive wildcard validation NSEC3 ($n)"
 ret=0
 $DIG $DIGOPTS a.wild.nsec3.example. @10.53.0.3 a > dig.out.ns3.test$n || ret=1
index 4049b1ccab1ea482572cc7348a9f4ec60a98c615..0af80177e29d79ef4c877a44a63ca57d9437a58a 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: validator.c,v 1.205 2011/10/15 05:00:15 marka Exp $ */
+/* $Id: validator.c,v 1.206 2011/10/20 21:42:11 marka Exp $ */
 
 #include <config.h>
 
@@ -1922,13 +1922,14 @@ verify(dns_validator_t *val, dst_key_t *key, dns_rdata_t *rdata,
        isc_result_t result;
        dns_fixedname_t fixed;
        isc_boolean_t ignore = ISC_FALSE;
+       dns_name_t *wild;
 
        val->attributes |= VALATTR_TRIEDVERIFY;
        dns_fixedname_init(&fixed);
+       wild = dns_fixedname_name(&fixed);
  again:
        result = dns_dnssec_verify2(val->event->name, val->event->rdataset,
-                                   key, ignore, val->view->mctx, rdata,
-                                   dns_fixedname_name(&fixed));
+                                   key, ignore, val->view->mctx, rdata, wild);
        if (result == DNS_R_SIGEXPIRED && val->view->acceptexpired) {
                ignore = ISC_TRUE;
                goto again;
@@ -1943,9 +1944,20 @@ verify(dns_validator_t *val, dst_key_t *key, dns_rdata_t *rdata,
                              "verify rdataset (keyid=%u): %s",
                              keyid, isc_result_totext(result));
        if (result == DNS_R_FROMWILDCARD) {
-               if (!dns_name_equal(val->event->name,
-                                   dns_fixedname_name(&fixed)))
+               if (!dns_name_equal(val->event->name, wild)) {
+                       dns_name_t *closest;
+                       unsigned int labels;
+
+                       /*
+                        * Compute the closest encloser in case we need it
+                        * for the NSEC3 NOQNAME proof.
+                        */
+                       closest = dns_fixedname_name(&val->closest);
+                       dns_name_copy(wild, closest, NULL);
+                       labels = dns_name_countlabels(closest) - 1;
+                       dns_name_getlabelsequence(closest, 1, labels, closest);
                        val->attributes |= VALATTR_NEEDNOQNAME;
+               }
                result = ISC_R_SUCCESS;
        }
        return (result);
@@ -2873,9 +2885,9 @@ findnsec3proofs(dns_validator_t *val) {
        dns_name_t *name, tname;
        isc_result_t result;
        isc_boolean_t exists, data, optout, unknown;
-       isc_boolean_t setclosest, setnearest;
+       isc_boolean_t setclosest, setnearest, *setclosestp;
        dns_fixedname_t fclosest, fnearest, fzonename;
-       dns_name_t *closest, *nearest, *zonename;
+       dns_name_t *closest, *nearest, *zonename, *closestp;
        dns_name_t **proofs = val->event->proofs;
        dns_rdataset_t *rdataset, trdataset;
 
@@ -2922,6 +2934,25 @@ findnsec3proofs(dns_validator_t *val) {
        if (dns_name_countlabels(zonename) == 0)
                return (ISC_R_SUCCESS);
 
+       /*
+        * If the val->closest is set then we want to use it otherwise
+        * we need to discover it.
+        */
+       if (dns_name_countlabels(dns_fixedname_name(&val->closest)) != 0) {
+               char namebuf[DNS_NAME_FORMATSIZE];
+
+               dns_name_format(dns_fixedname_name(&val->closest),
+                                namebuf, sizeof(namebuf));
+               validator_log(val, ISC_LOG_DEBUG(3), "closest encloser from "
+                             "wildcard signature '%s'", namebuf);
+                dns_name_copy(dns_fixedname_name(&val->closest), closest, NULL);
+               closestp = NULL;
+               setclosestp = NULL;
+       } else {
+               closestp = closest;
+               setclosestp = &setclosest;
+       }
+
        for (result = val_rdataset_first(val, &name, &rdataset);
             result == ISC_R_SUCCESS;
             result = val_rdataset_next(val, &name, &rdataset))
@@ -2939,8 +2970,8 @@ findnsec3proofs(dns_validator_t *val) {
                unknown = ISC_FALSE;
                (void)nsec3noexistnodata(val, val->event->name, name, rdataset,
                                         zonename, &exists, &data, &optout,
-                                        &unknown, &setclosest, &setnearest,
-                                        closest, nearest);
+                                        &unknown, setclosestp, &setnearest,
+                                        closestp, nearest);
                if (setclosest)
                        proofs[DNS_VALIDATOR_CLOSESTENCLOSER] = name;
                if (unknown)