]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
3461. [bug] Negative responses could incorrectly have AD=1
authorMark Andrews <marka@isc.org>
Thu, 10 Jan 2013 12:09:08 +0000 (23:09 +1100)
committerMark Andrews <marka@isc.org>
Thu, 10 Jan 2013 12:09:08 +0000 (23:09 +1100)
                        set. [RT #32237]

18 files changed:
CHANGES
bin/named/include/named/globals.h
bin/named/main.c
bin/named/query.c
bin/tests/system/dnssec/clean.sh
bin/tests/system/dnssec/ns1/root.db.in
bin/tests/system/dnssec/ns1/sign.sh
bin/tests/system/dnssec/ns6/named.args [new file with mode: 0644]
bin/tests/system/dnssec/ns6/named.conf
bin/tests/system/dnssec/ns6/optout-tld.db.in [new file with mode: 0644]
bin/tests/system/dnssec/ns6/sign.sh [new file with mode: 0644]
bin/tests/system/dnssec/tests.sh
lib/dns/include/dns/ncache.h
lib/dns/include/dns/validator.h
lib/dns/ncache.c
lib/dns/nsec.c
lib/dns/resolver.c
lib/dns/validator.c

diff --git a/CHANGES b/CHANGES
index 6cfb4bf34094a5a654d4d9a9327df8160e40f24d..1d660d50ffccd1f9cdaeef8dfa94a2dd4a922fdf 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,6 @@
+3461.  [bug]           Negative responses could incorrectly have AD=1
+                       set. [RT #32237]
+
 3460.  [bug]           Only link against readline where needed. [RT #29810]
 
 3459.  [func]          Added -J option to named-checkzone/named-compilezone
index 2e26a9099a50c8e5af3600c9c5fe08dbe00cf234..7ac6632e2adb1bf1017884cc5bfa2724ff65b8f4 100644 (file)
@@ -159,6 +159,7 @@ EXTERN isc_boolean_t                ns_g_noedns             INIT(ISC_FALSE);
 EXTERN isc_boolean_t           ns_g_nosoa              INIT(ISC_FALSE);
 EXTERN isc_boolean_t           ns_g_noaa               INIT(ISC_FALSE);
 EXTERN unsigned int            ns_g_delay              INIT(0);
+EXTERN isc_boolean_t           ns_g_nonearest          INIT(ISC_FALSE);
 
 #undef EXTERN
 #undef INIT
index adc394799b0cda1ccac2d8d2a7f671d1f1d0b7fc..d43510af3ed90c56655bf96801ef8fcf2516b01e 100644 (file)
@@ -537,6 +537,8 @@ parse_command_line(int argc, char *argv[]) {
                                ns_g_delay = atoi(isc_commandline_argument + 6);
                        else if (!strcmp(isc_commandline_argument, "nosyslog"))
                                ns_g_nosyslog = ISC_TRUE;
+                       else if (!strcmp(isc_commandline_argument, "nonearest"))
+                               ns_g_nonearest = ISC_TRUE;
                        else
                                fprintf(stderr, "unknown -T flag '%s\n",
                                        isc_commandline_argument);
index 36f74810bed025626f2c0b2c9b84a6e4243b4424..2f7f9600563e99255ba3b8ae58cc614f68b005cc 100644 (file)
@@ -6397,7 +6397,10 @@ query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype)
                                 * closest provable encloser.
                                 */
                                if (dns_rdataset_isassociated(rdataset) &&
-                                   !dns_name_equal(qname, found)) {
+                                   !dns_name_equal(qname, found) &&
+                                   !(ns_g_nonearest &&
+                                     qtype != dns_rdatatype_ds))
+                               {
                                        unsigned int count;
                                        unsigned int skip;
 
index 189c01188bbe99b9afa06a61c9704b1ab58d74da..1648669b40faec57e8788b35d5be15764ca6fd78 100644 (file)
@@ -63,6 +63,7 @@ rm -f ns3/ttlpatch.example.db.patched
 rm -f ns3/split-smart.example.db
 rm -f ns3/inline.example.db.signed
 rm -f ns3/lower.example.db ns3/upper.example.db ns3/upper.example.db.lower
+rm -f ns6/optout-tld.db
 rm -f nosign.before
 rm -f signing.out*
 rm -f canonical?.*
index 4ff12582bdc1b8062ece9239ad7f56285a600631..be8d55db3f8f486671633fb3ad68f9e3c512df01 100644 (file)
@@ -32,3 +32,5 @@ dlv.                  NS      ns2.dlv.
 ns2.dlv.               A       10.53.0.2
 algroll                        NS      ns2.algroll
 ns2.algroll.           A       10.53.0.2
+optout-tld             NS      ns6.optout-tld.
+ns6.optout-tld.                A       10.53.0.6
index 96fc060bd86daf10c84dd114a77de131647ab50d..0b117fb2aaec129e4f2e796c08e1c9a499608af3 100644 (file)
@@ -27,10 +27,12 @@ infile=root.db.in
 zonefile=root.db
 
 (cd ../ns2 && sh sign.sh )
+(cd ../ns6 && sh sign.sh )
 
 cp ../ns2/dsset-example. .
 cp ../ns2/dsset-dlv. .
 grep "8 [12] " ../ns2/dsset-algroll. > dsset-algroll.
+cp ../ns6/dsset-optout-tld. .
 
 keyname=`$KEYGEN -q -r $RANDFILE -a RSAMD5 -b 768 -n zone $zone`
 
diff --git a/bin/tests/system/dnssec/ns6/named.args b/bin/tests/system/dnssec/ns6/named.args
new file mode 100644 (file)
index 0000000..340fbaf
--- /dev/null
@@ -0,0 +1 @@
+-m record,size,mctx -c named.conf -d 99 -g -T nonearest -T clienttest
index eb35680ef2c9ab3cf4c5160f2510d49701d20679..54221cefbdde33b8c5c4eebbd34e19690aee6d56 100644 (file)
@@ -42,4 +42,9 @@ zone "." {
        file "../../common/root.hint";
 };
 
+zone "optout-tld" {
+       type master;
+       file "optout-tld.db.signed";
+};
+
 include "trusted.conf";
diff --git a/bin/tests/system/dnssec/ns6/optout-tld.db.in b/bin/tests/system/dnssec/ns6/optout-tld.db.in
new file mode 100644 (file)
index 0000000..8cdb0aa
--- /dev/null
@@ -0,0 +1,26 @@
+; Copyright (C) 2010  Internet Systems Consortium, Inc. ("ISC")
+;
+; Permission to use, copy, modify, and/or distribute this software for any
+; purpose with or without fee is hereby granted, provided that the above
+; copyright notice and this permission notice appear in all copies.
+;
+; THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+; REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+; AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+; INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+; LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+; OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+; PERFORMANCE OF THIS SOFTWARE.
+
+; $Id: example.db.in,v 1.2 2010/06/03 06:29:03 marka Exp $
+$TTL 60
+optout-tld. 60 IN SOA example. . 0 0 0 0 0
+optout-tld. 60 IN NS ns6.optout-tld.
+ns6.optout-tld. 60 IN A 10.53.0.6
+a 60 PTR example.
+b 60 PTR example.
+a.b.c.d 60 NS example.
+e 60 PTR example.
+f 60 PTR example.
+g 60 PTR example.
+h 60 PTR example.
diff --git a/bin/tests/system/dnssec/ns6/sign.sh b/bin/tests/system/dnssec/ns6/sign.sh
new file mode 100644 (file)
index 0000000..7c1179d
--- /dev/null
@@ -0,0 +1,33 @@
+#!/bin/sh -e
+#
+# Copyright (C) 2004, 2006-2012  Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2000-2002  Internet Software Consortium.
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+# PERFORMANCE OF THIS SOFTWARE.
+
+# $Id: sign.sh,v 1.43 2011/11/04 05:36:28 each Exp $
+
+SYSTEMTESTTOP=../..
+. $SYSTEMTESTTOP/conf.sh
+
+RANDFILE=../random.data
+
+zone=optout-tld
+infile=optout-tld.db.in
+zonefile=optout-tld.db
+
+keyname=`$KEYGEN -q -r $RANDFILE -a RSASHA256 -b 768 -n zone $zone`
+
+cat $infile $keyname.key >$zonefile
+
+$SIGNER -P -3 - -A -r $RANDFILE -o $zone $zonefile > /dev/null 2>&1
index a6cb09aff824f5f1d343229db6b9b059519724aa..735be594511d5b6d5bdb7e644d9c7a426fd14aee 100644 (file)
@@ -1965,5 +1965,25 @@ n=`expr $n + 1`
 if [ $ret != 0 ]; then echo "I:failed"; fi
 status=`expr $status + $ret`
 
+echo "I:check against against missing nearest provable proof ($n)"
+$DIG $DIGOPTS +norec b.c.d.optout-tld. \
+       @10.53.0.6 ds > dig.out.ds.ns6.test$n || ret=1
+nsec3=`grep "IN.NSEC3" dig.out.ds.ns6.test$n | wc -l`
+[ $nsec3 -eq 2 ] || ret=1
+$DIG $DIGOPTS +norec b.c.d.optout-tld. \
+       @10.53.0.6 A > dig.out.ns6.test$n || ret=1
+nsec3=`grep "IN.NSEC3" dig.out.ns6.test$n | wc -l`
+[ $nsec3 -eq 1 ] || ret=1
+$DIG $DIGOPTS optout-tld. \
+       @10.53.0.4 SOA > dig.out.soa.ns4.test$n || ret=1
+grep "flags:.*ad.*QUERY" dig.out.soa.ns4.test$n > /dev/null || ret=1
+$DIG $DIGOPTS b.c.d.optout-tld. \
+       @10.53.0.4 A > dig.out.ns4.test$n || ret=1
+grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
+grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1
+n=`expr $n + 1`
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
 echo "I:exit status: $status"
 exit $status
index 8d89879cc5e4f762480518d4aac0ae84c3582751..5064e91171d5791f40ff8ce277f94d5ddde4bb3e 100644 (file)
@@ -73,6 +73,11 @@ dns_ncache_addoptout(dns_message_t *message, dns_db_t *cache,
  * rdataset, and store it in 'cache' at 'node' with a TTL limited to
  * 'maxttl'.
  *
+ * \li dns_ncache_add produces a negative cache entry with a trust of no
+ *     more than answer
+ * \li dns_ncache_addoptout produces a negative cache entry which will have
+ *     a trust of secure if all the records that make up the entry are secure.
+ *
  * The 'covers' argument is the RR type whose nonexistence we are caching,
  * or dns_rdatatype_any when caching a NXDOMAIN response.
  *
index 7d6ea7a89d2f7539f84553263817a741f4e30906..486510a6fd65ed98bb307b0a3c11291ccc1cb4cc 100644 (file)
@@ -104,6 +104,10 @@ typedef struct dns_validatorevent {
         * Optout proof seen.
         */
        isc_boolean_t                   optout;
+       /*
+        * Answer is secure.
+        */
+       isc_boolean_t                   secure;
 } dns_validatorevent_t;
 
 #define DNS_VALIDATOR_NOQNAMEPROOF 0
index c0e99d4969d467366b48eda03c9e7870e67f4e90..7d50abc4dfffc269d2511aa5ebb7245429fb7953 100644 (file)
  *
  */
 
+static isc_result_t
+addoptout(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node,
+         dns_rdatatype_t covers, isc_stdtime_t now, dns_ttl_t maxttl,
+         isc_boolean_t optout, isc_boolean_t secure,
+         dns_rdataset_t *addedrdataset);
+
 static inline isc_result_t
 copy_rdataset(dns_rdataset_t *rdataset, isc_buffer_t *buffer) {
        isc_result_t result;
@@ -96,8 +102,8 @@ dns_ncache_add(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node,
               dns_rdatatype_t covers, isc_stdtime_t now, dns_ttl_t maxttl,
               dns_rdataset_t *addedrdataset)
 {
-       return (dns_ncache_addoptout(message, cache, node, covers, now, maxttl,
-                                   ISC_FALSE, addedrdataset));
+       return (addoptout(message, cache, node, covers, now, maxttl,
+                         ISC_FALSE, ISC_FALSE, addedrdataset));
 }
 
 isc_result_t
@@ -105,6 +111,16 @@ dns_ncache_addoptout(dns_message_t *message, dns_db_t *cache,
                     dns_dbnode_t *node, dns_rdatatype_t covers,
                     isc_stdtime_t now, dns_ttl_t maxttl,
                     isc_boolean_t optout, dns_rdataset_t *addedrdataset)
+{
+       return (addoptout(message, cache, node, covers, now, maxttl,
+                         optout, ISC_TRUE, addedrdataset));
+}
+
+static isc_result_t
+addoptout(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node,
+         dns_rdatatype_t covers, isc_stdtime_t now, dns_ttl_t maxttl,
+         isc_boolean_t optout, isc_boolean_t secure,
+         dns_rdataset_t *addedrdataset)
 {
        isc_result_t result;
        isc_buffer_t buffer;
@@ -242,6 +258,8 @@ dns_ncache_addoptout(dns_message_t *message, dns_db_t *cache,
        dns_rdataset_init(&ncrdataset);
        RUNTIME_CHECK(dns_rdatalist_tordataset(&ncrdatalist, &ncrdataset)
                      == ISC_R_SUCCESS);
+       if (!secure && trust > dns_trust_answer)
+               trust = dns_trust_answer;
        ncrdataset.trust = trust;
        ncrdataset.attributes |= DNS_RDATASETATTR_NEGATIVE;
        if (message->rcode == dns_rcode_nxdomain)
index 5ae1cf8739194029c94ac960767b53cb93a86787..bbdde55daffda3d0226f23ffa7ad3378244919b9 100644 (file)
@@ -327,7 +327,7 @@ dns_nsec_noexistnodata(dns_rdatatype_t type, dns_name_t *name,
        }
        dns_rdataset_current(nsecset, &rdata);
 
-       (*logit)(arg, ISC_LOG_DEBUG(3), "looking for relevant nsec");
+       (*logit)(arg, ISC_LOG_DEBUG(3), "looking for relevant NSEC");
        relation = dns_name_fullcompare(name, nsecname, &order, &olabels);
 
        if (order < 0) {
index 0b30a8cd8a4e0d78badac66459803100ab60493c..0e78eb11577390c8fb1c5a577ceca424f3cc3710 100644 (file)
@@ -472,6 +472,7 @@ static isc_result_t ncache_adderesult(dns_message_t *message,
                                      dns_rdatatype_t covers,
                                      isc_stdtime_t now, dns_ttl_t maxttl,
                                      isc_boolean_t optout,
+                                     isc_boolean_t secure,
                                      dns_rdataset_t *ardataset,
                                      isc_result_t *eresultp);
 static void validated(isc_task_t *task, isc_event_t *event);
@@ -4248,7 +4249,7 @@ validated(isc_task_t *task, isc_event_t *event) {
 
                result = ncache_adderesult(fctx->rmessage, fctx->cache, node,
                                           covers, now, ttl, vevent->optout,
-                                          ardataset, &eresult);
+                                          vevent->secure, ardataset, &eresult);
                if (result != ISC_R_SUCCESS)
                        goto noanswer_response;
                goto answer_response;
@@ -4990,8 +4991,8 @@ cache_message(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, isc_stdtime_t now)
 static isc_result_t
 ncache_adderesult(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node,
                  dns_rdatatype_t covers, isc_stdtime_t now, dns_ttl_t maxttl,
-                 isc_boolean_t optout, dns_rdataset_t *ardataset,
-                 isc_result_t *eresultp)
+                 isc_boolean_t optout, isc_boolean_t secure,
+                 dns_rdataset_t *ardataset, isc_result_t *eresultp)
 {
        isc_result_t result;
        dns_rdataset_t rdataset;
@@ -5000,8 +5001,12 @@ ncache_adderesult(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node,
                dns_rdataset_init(&rdataset);
                ardataset = &rdataset;
        }
-       result = dns_ncache_addoptout(message, cache, node, covers, now,
-                                    maxttl, optout, ardataset);
+       if (secure) 
+               result = dns_ncache_addoptout(message, cache, node, covers,
+                                             now, maxttl, optout, ardataset);
+       else
+               result = dns_ncache_add(message, cache, node, covers, now,
+                                       maxttl, ardataset);
        if (result == DNS_R_UNCHANGED || result == ISC_R_SUCCESS) {
                /*
                 * If the cache now contains a negative entry and we
@@ -5168,7 +5173,7 @@ ncache_message(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
 
        result = ncache_adderesult(fctx->rmessage, fctx->cache, node,
                                   covers, now, ttl, ISC_FALSE,
-                                  ardataset, &eresult);
+                                  ISC_FALSE, ardataset, &eresult);
        if (result != ISC_R_SUCCESS)
                goto unlock;
 
index 319fc2bab9d3ab4d4a9fb44345ba204072fd336e..69cee2827b0e75256a9b134366bb3e4ebbb9b267 100644 (file)
@@ -195,6 +195,7 @@ marksecure(dns_validatorevent_t *event) {
        dns_rdataset_settrust(event->rdataset, dns_trust_secure);
        if (event->sigrdataset != NULL)
                dns_rdataset_settrust(event->sigrdataset, dns_trust_secure);
+       event->secure = ISC_TRUE;
 }
 
 static void
@@ -2847,6 +2848,8 @@ nsecvalidate(dns_validator_t *val, isc_boolean_t resume) {
                              "nonexistence proof(s) found");
                if (val->event->message == NULL)
                        marksecure(val->event);
+               else
+                       val->event->secure = ISC_TRUE;
                return (ISC_R_SUCCESS);
        }
 
@@ -3734,6 +3737,7 @@ dns_validator_create(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
        event->message = message;
        memset(event->proofs, 0, sizeof(event->proofs));
        event->optout = ISC_FALSE;
+       event->secure = ISC_FALSE;
        result = isc_mutex_init(&val->lock);
        if (result != ISC_R_SUCCESS)
                goto cleanup_event;