From b0dbcba2d25dfa49a2e705e4481298729334605a Mon Sep 17 00:00:00 2001 From: Mukund Sivaraman Date: Fri, 21 Apr 2017 14:51:24 +0530 Subject: [PATCH] Validate glue before adding it to the additional section (#45062) --- CHANGES | 5 ++ bin/named/query.c | 35 +++++++++--- bin/tests/system/dnssec/ns4/named4.conf | 54 ++++-------------- bin/tests/system/dnssec/ns4/named5.conf | 75 +++++++++++++++++++++++++ bin/tests/system/dnssec/tests.sh | 27 ++++++++- 5 files changed, 144 insertions(+), 52 deletions(-) create mode 100644 bin/tests/system/dnssec/ns4/named5.conf diff --git a/CHANGES b/CHANGES index 8aee60fc87..0e281f5bb6 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,8 @@ +4596. [bug] Validate glue before adding it to the additional + section. This also fixes incorrect TTL capping + when the RRSIG expired earlier than the TTL. + [RT #45062] + 4595. [func] dnssec-keygen will no longer generate RSA keys less than 1024 bits in length. dnssec-keymgr was similarly updated. [RT #36895] diff --git a/bin/named/query.c b/bin/named/query.c index 5fd52f2b29..a8ceba16ea 100644 --- a/bin/named/query.c +++ b/bin/named/query.c @@ -1586,6 +1586,7 @@ query_addadditional(void *arg, const dns_name_t *name, dns_rdatatype_t qtype) { dns_rdatatype_t type; dns_clientinfomethods_t cm; dns_clientinfo_t ci; + dns_rdatasetadditional_t additionaltype; REQUIRE(NS_CLIENT_VALID(client)); REQUIRE(qtype != dns_rdatatype_any); @@ -1609,6 +1610,7 @@ query_addadditional(void *arg, const dns_name_t *name, dns_rdatatype_t qtype) { added_something = ISC_FALSE; need_addname = ISC_FALSE; zone = NULL; + additionaltype = dns_rdatasetadditional_fromauth; dns_clientinfomethods_init(&cm, ns_client_sourceip); dns_clientinfo_init(&ci, client, NULL); @@ -1682,6 +1684,7 @@ query_addadditional(void *arg, const dns_name_t *name, dns_rdatatype_t qtype) { */ try_cache: + additionaltype = dns_rdatasetadditional_fromcache; result = query_getcachedb(client, name, qtype, &db, DNS_GETDB_NOLOG); if (result != ISC_R_SUCCESS) /* @@ -1698,20 +1701,16 @@ query_addadditional(void *arg, const dns_name_t *name, dns_rdatatype_t qtype) { } result = dns_db_findext(db, name, version, type, client->query.dboptions | - DNS_DBFIND_GLUEOK | DNS_DBFIND_ADDITIONALOK, + DNS_DBFIND_GLUEOK | DNS_DBFIND_ADDITIONALOK, client->now, &node, fname, &cm, &ci, rdataset, sigrdataset); dns_cache_updatestats(client->view->cache, result); - if (result == DNS_R_GLUE && - validate(client, db, fname, rdataset, sigrdataset)) - result = ISC_R_SUCCESS; if (!WANTDNSSEC(client)) query_putrdataset(client, &sigrdataset); if (result == ISC_R_SUCCESS) goto found; - if (dns_rdataset_isassociated(rdataset)) dns_rdataset_disassociate(rdataset); if (sigrdataset != NULL && dns_rdataset_isassociated(sigrdataset)) @@ -1746,6 +1745,8 @@ query_addadditional(void *arg, const dns_name_t *name, dns_rdatatype_t qtype) { goto cleanup; dns_db_attach(client->query.gluedb, &db); + + additionaltype = dns_rdatasetadditional_fromglue; result = dns_db_findext(db, name, version, type, client->query.dboptions | DNS_DBFIND_GLUEOK, client->now, &node, fname, &cm, &ci, @@ -1838,7 +1839,17 @@ query_addadditional(void *arg, const dns_name_t *name, dns_rdatatype_t qtype) { #ifdef ALLOW_FILTER_AAAA have_a = ISC_TRUE; #endif - if (!query_isduplicate(client, fname, + if (additionaltype == dns_rdatasetadditional_fromcache && + (DNS_TRUST_PENDING(rdataset->trust) || + DNS_TRUST_GLUE(rdataset->trust)) && + !validate(client, db, fname, rdataset, sigrdataset)) + { + dns_rdataset_disassociate(rdataset); + if (sigrdataset != NULL && + dns_rdataset_isassociated(sigrdataset)) + dns_rdataset_disassociate(sigrdataset); + result = ISC_R_NOTFOUND; + } else if (!query_isduplicate(client, fname, dns_rdatatype_a, &mname)) { if (mname != fname) { if (mname != NULL) { @@ -1897,7 +1908,17 @@ query_addadditional(void *arg, const dns_name_t *name, dns_rdatatype_t qtype) { !dns_rdataset_isassociated(sigrdataset))))) goto addname; #endif - if (!query_isduplicate(client, fname, + if (additionaltype == dns_rdatasetadditional_fromcache && + (DNS_TRUST_PENDING(rdataset->trust) || + DNS_TRUST_GLUE(rdataset->trust)) && + !validate(client, db, fname, rdataset, sigrdataset)) + { + dns_rdataset_disassociate(rdataset); + if (sigrdataset != NULL && + dns_rdataset_isassociated(sigrdataset)) + dns_rdataset_disassociate(sigrdataset); + result = ISC_R_NOTFOUND; + } else if (!query_isduplicate(client, fname, dns_rdatatype_aaaa, &mname)) { if (mname != fname) { if (mname != NULL) { diff --git a/bin/tests/system/dnssec/ns4/named4.conf b/bin/tests/system/dnssec/ns4/named4.conf index af9f26273e..745de5558f 100644 --- a/bin/tests/system/dnssec/ns4/named4.conf +++ b/bin/tests/system/dnssec/ns4/named4.conf @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013, 2016 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2012, 2013, 2016 Internet Systems Consortium, Inc. ("ISC") * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this @@ -18,6 +18,12 @@ options { pid-file "named.pid"; listen-on { 10.53.0.4; }; listen-on-v6 { none; }; + recursion yes; + acache-enable no; + dnssec-enable yes; + dnssec-validation auto; + bindkeys-file "managed.conf"; + dnssec-accept-expired yes; }; key rndc_key { @@ -29,47 +35,7 @@ controls { inet 10.53.0.4 port 9953 allow { any; } keys { rndc_key; }; }; -key auth { - secret "1234abcd8765"; - algorithm hmac-sha256; -}; - -include "trusted.conf"; - -view rec { - match-recursive-only yes; - recursion yes; - acache-enable yes; - dnssec-validation yes; - dnssec-accept-expired yes; - - zone "." { - type hint; - file "../../common/root.hint"; - }; - - zone secure.example { - type static-stub; - server-addresses { 10.53.0.4; }; - }; - - zone insecure.secure.example { - type static-stub; - server-addresses { 10.53.0.4; }; - }; -}; - -view auth { - recursion no; - allow-recursion { none; }; - - zone secure.example { - type slave; - masters { 10.53.0.3; }; - }; - - zone insecure.secure.example { - type slave; - masters { 10.53.0.2; }; - }; +zone "." { + type hint; + file "../../common/root.hint"; }; diff --git a/bin/tests/system/dnssec/ns4/named5.conf b/bin/tests/system/dnssec/ns4/named5.conf new file mode 100644 index 0000000000..af9f26273e --- /dev/null +++ b/bin/tests/system/dnssec/ns4/named5.conf @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2013, 2016 Internet Systems Consortium, Inc. ("ISC") + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +// NS4 + +controls { /* empty */ }; + +options { + query-source address 10.53.0.4; + notify-source 10.53.0.4; + transfer-source 10.53.0.4; + port 5300; + pid-file "named.pid"; + listen-on { 10.53.0.4; }; + listen-on-v6 { none; }; +}; + +key rndc_key { + secret "1234abcd8765"; + algorithm hmac-sha256; +}; + +controls { + inet 10.53.0.4 port 9953 allow { any; } keys { rndc_key; }; +}; + +key auth { + secret "1234abcd8765"; + algorithm hmac-sha256; +}; + +include "trusted.conf"; + +view rec { + match-recursive-only yes; + recursion yes; + acache-enable yes; + dnssec-validation yes; + dnssec-accept-expired yes; + + zone "." { + type hint; + file "../../common/root.hint"; + }; + + zone secure.example { + type static-stub; + server-addresses { 10.53.0.4; }; + }; + + zone insecure.secure.example { + type static-stub; + server-addresses { 10.53.0.4; }; + }; +}; + +view auth { + recursion no; + allow-recursion { none; }; + + zone secure.example { + type slave; + masters { 10.53.0.3; }; + }; + + zone insecure.secure.example { + type slave; + masters { 10.53.0.2; }; + }; +}; diff --git a/bin/tests/system/dnssec/tests.sh b/bin/tests/system/dnssec/tests.sh index 040f67c50d..9f6d6703be 100644 --- a/bin/tests/system/dnssec/tests.sh +++ b/bin/tests/system/dnssec/tests.sh @@ -2697,6 +2697,10 @@ n=`expr $n + 1` if [ $ret != 0 ]; then echo "I:failed"; fi status=`expr $status + $ret` +cp ns4/named4.conf ns4/named.conf +$RNDC -c ../common/rndc.conf -s 10.53.0.4 -p 9953 reconfig 2>&1 | sed 's/^/I:ns4 /' +sleep 3 + echo "I:testing TTL is capped at RRSIG expiry time for records in the additional section with dnssec-accept-expired yes; ($n)" ret=0 $RNDC -c ../common/rndc.conf -s 10.53.0.4 -p 9953 flush @@ -2714,6 +2718,27 @@ n=`expr $n + 1` if [ $ret != 0 ]; then echo "I:failed"; fi status=`expr $status + $ret` +cp ns4/named4.conf ns4/named.conf +$RNDC -c ../common/rndc.conf -s 10.53.0.4 -p 9953 reconfig 2>&1 | sed 's/^/I:ns4 /' +sleep 3 + +echo "I:testing TTL is capped at RRSIG expiry time for records in the additional section with acache off; ($n)" +ret=0 +$RNDC -c ../common/rndc.conf -s 10.53.0.4 -p 9953 flush +$DIG +noall +additional +dnssec +cd -p 5300 expiring.example mx @10.53.0.4 > dig.out.ns4.1.$n +$DIG +noall +additional +dnssec -p 5300 expiring.example mx @10.53.0.4 > dig.out.ns4.2.$n +ttls=`awk '$1 != ";;" {print $2}' dig.out.ns4.1.$n` +ttls2=`awk '$1 != ";;" {print $2}' dig.out.ns4.2.$n` +for ttl in ${ttls:-300}; do + [ $ttl -eq 300 ] || ret=1 +done +for ttl in ${ttls2:-0}; do + [ $ttl -le 120 -a $ttl -gt 60 ] || ret=1 +done +n=`expr $n + 1` +if [ $ret != 0 ]; then echo "I:failed"; fi +status=`expr $status + $ret` + echo "I:testing DNSKEY lookup via CNAME ($n)" ret=0 $DIG $DIGOPTS +noauth cnameandkey.secure.example. \ @@ -2875,7 +2900,7 @@ n=`expr $n + 1` if test "$before" = "$after" ; then echo "I:failed"; ret=1; fi status=`expr $status + $ret` -cp ns4/named4.conf ns4/named.conf +cp ns4/named5.conf ns4/named.conf $RNDC -c ../common/rndc.conf -s 10.53.0.4 -p 9953 reconfig 2>&1 | sed 's/^/I:ns4 /' sleep 3 -- GitLab