diff --git a/CHANGES b/CHANGES index dac0ca6cc8..4a3278cebe 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,5 @@ +4778. [test] Improve synth-from-dnssec testing. [RT #46352] + 4777. [cleanup] Removed a redundant call to configure_view_acl(). [RT #46369] diff --git a/bin/tests/system/synthfromdnssec/ns4/named.conf b/bin/tests/system/synthfromdnssec/ns4/named.conf new file mode 100644 index 0000000000..514a3b1b1f --- /dev/null +++ b/bin/tests/system/synthfromdnssec/ns4/named.conf @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2017 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; }; + recursion yes; + notify no; + dnssec-enable yes; + dnssec-validation yes; + synth-from-dnssec no; +}; + +zone "." { + type hint; + file "root.hints"; +}; + +include "../ns1/trusted.conf"; +// include "../../common/controls.conf"; diff --git a/bin/tests/system/synthfromdnssec/ns4/root.hints b/bin/tests/system/synthfromdnssec/ns4/root.hints new file mode 100644 index 0000000000..42f5ffda45 --- /dev/null +++ b/bin/tests/system/synthfromdnssec/ns4/root.hints @@ -0,0 +1,8 @@ +; Copyright (C) 2017 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/. + +. NS ns1 +ns1 A 10.53.0.1 diff --git a/bin/tests/system/synthfromdnssec/ns5/named.conf b/bin/tests/system/synthfromdnssec/ns5/named.conf new file mode 100644 index 0000000000..7c8bc4b5c6 --- /dev/null +++ b/bin/tests/system/synthfromdnssec/ns5/named.conf @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2017 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/. + */ + +// NS5 + +controls { /* empty */ }; + +options { + query-source address 10.53.0.5; + notify-source 10.53.0.5; + transfer-source 10.53.0.5; + port 5300; + pid-file "named.pid"; + listen-on { 10.53.0.5; }; + listen-on-v6 { none; }; + recursion yes; + notify no; + dnssec-enable yes; + dnssec-validation yes; + synth-from-dnssec yes; +}; + +zone "." { + type hint; + file "root.hints"; +}; + +include "../ns1/trusted.conf"; diff --git a/bin/tests/system/synthfromdnssec/ns5/root.hints b/bin/tests/system/synthfromdnssec/ns5/root.hints new file mode 100644 index 0000000000..42f5ffda45 --- /dev/null +++ b/bin/tests/system/synthfromdnssec/ns5/root.hints @@ -0,0 +1,8 @@ +; Copyright (C) 2017 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/. + +. NS ns1 +ns1 A 10.53.0.1 diff --git a/bin/tests/system/synthfromdnssec/tests.sh b/bin/tests/system/synthfromdnssec/tests.sh index a80d21bc3a..47b956be7d 100644 --- a/bin/tests/system/synthfromdnssec/tests.sh +++ b/bin/tests/system/synthfromdnssec/tests.sh @@ -17,49 +17,58 @@ rm -f dig.out.* DIGOPTS="+tcp +noadd +nosea +nostat +nocmd +dnssec -p 5300" DELVOPTS="-a ns1/trusted.conf -p 5300" -echo "I:prime negative NXDOMAIN response ($n)" -ret=0 -$DIG $DIGOPTS a.example. @10.53.0.2 a > dig.out.ns2.test$n || ret=1 -grep "flags:[^;]* ad[ ;]" dig.out.ns2.test$n > /dev/null || ret=1 -grep "status: NXDOMAIN," dig.out.ns2.test$n > /dev/null || ret=1 -grep "example.*3600.IN.SOA" dig.out.ns2.test$n > /dev/null || ret=1 -nxdomain=dig.out.ns2.test$n -n=`expr $n + 1` -if [ $ret != 0 ]; then echo "I:failed"; fi -status=`expr $status + $ret` +for ns in 2 4 5 +do + case $ns in + 2) description="";; + 4) description="no";; + 5) description="yes";; + *) exit 1;; + esac + echo "I:prime negative NXDOMAIN response (synth-from-dnssec ${description};) ($n)" + ret=0 + $DIG $DIGOPTS a.example. @10.53.0.${ns} a > dig.out.ns${ns}.test$n || ret=1 + grep "flags:[^;]* ad[ ;]" dig.out.ns${ns}.test$n > /dev/null || ret=1 + grep "status: NXDOMAIN," dig.out.ns${ns}.test$n > /dev/null || ret=1 + grep "example.*3600.IN.SOA" dig.out.ns${ns}.test$n > /dev/null || ret=1 + [ $ns -eq ${ns} ] && nxdomain=dig.out.ns${ns}.test$n + n=`expr $n + 1` + if [ $ret != 0 ]; then echo "I:failed"; fi + status=`expr $status + $ret` -echo "I:prime negative NODATA response ($n)" -ret=0 -$DIG $DIGOPTS nodata.example. @10.53.0.2 a > dig.out.ns2.test$n || ret=1 -grep "flags:[^;]* ad[ ;]" dig.out.ns2.test$n > /dev/null || ret=1 -grep "status: NOERROR," dig.out.ns2.test$n > /dev/null || ret=1 -grep "example.*3600.IN.SOA" dig.out.ns2.test$n > /dev/null || ret=1 -nodata=dig.out.ns2.test$n -n=`expr $n + 1` -if [ $ret != 0 ]; then echo "I:failed"; fi -status=`expr $status + $ret` + echo "I:prime negative NODATA response (synth-from-dnssec ${description};) ($n)" + ret=0 + $DIG $DIGOPTS nodata.example. @10.53.0.${ns} a > dig.out.ns${ns}.test$n || ret=1 + grep "flags:[^;]* ad[ ;]" dig.out.ns${ns}.test$n > /dev/null || ret=1 + grep "status: NOERROR," dig.out.ns${ns}.test$n > /dev/null || ret=1 + grep "example.*3600.IN.SOA" dig.out.ns${ns}.test$n > /dev/null || ret=1 + [ $ns -eq 2 ] && nodata=dig.out.ns${ns}.test$n + n=`expr $n + 1` + if [ $ret != 0 ]; then echo "I:failed"; fi + status=`expr $status + $ret` -echo "I:prime wildcard response ($n)" -ret=0 -$DIG $DIGOPTS a.wild-a.example. @10.53.0.2 a > dig.out.ns2.test$n || ret=1 -grep "flags:[^;]* ad[ ;]" dig.out.ns2.test$n > /dev/null || ret=1 -grep "status: NOERROR," dig.out.ns2.test$n > /dev/null || ret=1 -grep "a.wild-a.example.*3600.IN.A" dig.out.ns2.test$n > /dev/null || ret=1 -n=`expr $n + 1` -if [ $ret != 0 ]; then echo "I:failed"; fi -status=`expr $status + $ret` + echo "I:prime wildcard response (synth-from-dnssec ${description};) ($n)" + ret=0 + $DIG $DIGOPTS a.wild-a.example. @10.53.0.${ns} a > dig.out.ns${ns}.test$n || ret=1 + grep "flags:[^;]* ad[ ;]" dig.out.ns${ns}.test$n > /dev/null || ret=1 + grep "status: NOERROR," dig.out.ns${ns}.test$n > /dev/null || ret=1 + grep "a.wild-a.example.*3600.IN.A" dig.out.ns${ns}.test$n > /dev/null || ret=1 + n=`expr $n + 1` + if [ $ret != 0 ]; then echo "I:failed"; fi + status=`expr $status + $ret` -echo "I:prime wildcard CNAME response ($n)" -ret=0 -$DIG $DIGOPTS a.wild-cname.example. @10.53.0.2 a > dig.out.ns2.test$n || ret=1 -grep "flags:[^;]* ad[ ;]" dig.out.ns2.test$n > /dev/null || ret=1 -grep "status: NOERROR," dig.out.ns2.test$n > /dev/null || ret=1 -grep "a.wild-cname.example.*3600.IN.CNAME" dig.out.ns2.test$n > /dev/null || ret=1 -n=`expr $n + 1` -if [ $ret != 0 ]; then echo "I:failed"; fi -status=`expr $status + $ret` + echo "I:prime wildcard CNAME response (synth-from-dnssec ${description};) ($n)" + ret=0 + $DIG $DIGOPTS a.wild-cname.example. @10.53.0.${ns} a > dig.out.ns${ns}.test$n || ret=1 + grep "flags:[^;]* ad[ ;]" dig.out.ns${ns}.test$n > /dev/null || ret=1 + grep "status: NOERROR," dig.out.ns${ns}.test$n > /dev/null || ret=1 + grep "a.wild-cname.example.*3600.IN.CNAME" dig.out.ns${ns}.test$n > /dev/null || ret=1 + n=`expr $n + 1` + if [ $ret != 0 ]; then echo "I:failed"; fi + status=`expr $status + $ret` +done -echo "I:prime redirect response (+nodnssec) ($n)" +echo "I:prime redirect response (+nodnssec) (synth-from-dnssec ;) ($n)" ret=0 $DIG $DIGOPTS +nodnssec a.redirect. @10.53.0.3 a > dig.out.ns2.test$n || ret=1 grep "flags:[^;]* ad[ ;]" dig.out.ns2.test$n > /dev/null && ret=1 @@ -69,54 +78,88 @@ n=`expr $n + 1` if [ $ret != 0 ]; then echo "I:failed"; fi status=`expr $status + $ret` +# +# ensure TTL of synthesised answers differs from direct answers. +# sleep 1 -$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 dumpdb +for ns in 2 4 5 +do + case $ns in + 2) synth=yes description="";; + 4) synth=no description="no";; + 5) synth=yes description="yes";; + *) exit 1;; + esac + echo "I:check synthesized NXDOMAIN response (synth-from-dnssec ${description};) ($n)" + ret=0 + $DIG $DIGOPTS b.example. @10.53.0.${ns} a > dig.out.ns${ns}.test$n || ret=1 + grep "flags:[^;]* ad[ ;]" dig.out.ns${ns}.test$n > /dev/null || ret=1 + grep "status: NXDOMAIN," dig.out.ns${ns}.test$n > /dev/null || ret=1 + if [ ${synth} = yes ] + then + grep "example.*IN.SOA" dig.out.ns${ns}.test$n > /dev/null || ret=1 + grep "example.*3600.IN.SOA" dig.out.ns${ns}.test$n > /dev/null && ret=1 + else + grep "example.*3600.IN.SOA" dig.out.ns${ns}.test$n > /dev/null || ret=1 + fi + $PERL ../digcomp.pl $nxdomain dig.out.ns${ns}.test$n || ret=1 + n=`expr $n + 1` + if [ $ret != 0 ]; then echo "I:failed"; fi + status=`expr $status + $ret` -echo "I:check synthesized NXDOMAIN response ($n)" -ret=0 -$DIG $DIGOPTS b.example. @10.53.0.2 a > dig.out.ns2.test$n || ret=1 -grep "flags:[^;]* ad[ ;]" dig.out.ns2.test$n > /dev/null || ret=1 -grep "status: NXDOMAIN," dig.out.ns2.test$n > /dev/null || ret=1 -grep "example.*3600.IN.SOA" dig.out.ns2.test$n > /dev/null && ret=1 -$PERL ../digcomp.pl $nxdomain dig.out.ns2.test$n || ret=1 -n=`expr $n + 1` -if [ $ret != 0 ]; then echo "I:failed"; fi -status=`expr $status + $ret` + echo "I:check synthesized NODATA response (synth-from-dnssec ${description};) ($n)" + ret=0 + $DIG $DIGOPTS nodata.example. @10.53.0.${ns} aaaa > dig.out.ns${ns}.test$n || ret=1 + grep "flags:[^;]* ad[ ;]" dig.out.ns${ns}.test$n > /dev/null || ret=1 + grep "status: NOERROR," dig.out.ns${ns}.test$n > /dev/null || ret=1 + if [ ${synth} = yes ] + then + grep "example.*IN.SOA" dig.out.ns${ns}.test$n > /dev/null || ret=1 + grep "example.*3600.IN.SOA" dig.out.ns${ns}.test$n > /dev/null && ret=1 + else + grep "example.*3600.IN.SOA" dig.out.ns${ns}.test$n > /dev/null || ret=1 + fi + $PERL ../digcomp.pl $nodata dig.out.ns${ns}.test$n || ret=1 + n=`expr $n + 1` + if [ $ret != 0 ]; then echo "I:failed"; fi + status=`expr $status + $ret` -echo "I:check synthesized NODATA response ($n)" -ret=0 -$DIG $DIGOPTS nodata.example. @10.53.0.2 aaaa > dig.out.ns2.test$n || ret=1 -grep "flags:[^;]* ad[ ;]" dig.out.ns2.test$n > /dev/null || ret=1 -grep "status: NOERROR," dig.out.ns2.test$n > /dev/null || ret=1 -grep "example.*3600.IN.SOA" dig.out.ns2.test$n > /dev/null && ret=1 -$PERL ../digcomp.pl $nodata dig.out.ns2.test$n || ret=1 -n=`expr $n + 1` -if [ $ret != 0 ]; then echo "I:failed"; fi -status=`expr $status + $ret` + echo "I:check synthesized wildcard response (synth-from-dnssec ${description};) ($n)" + ret=0 + $DIG $DIGOPTS b.wild-a.example. @10.53.0.${ns} a > dig.out.ns${ns}.test$n || ret=1 + grep "flags:[^;]* ad[ ;]" dig.out.ns${ns}.test$n > /dev/null || ret=1 + grep "status: NOERROR," dig.out.ns${ns}.test$n > /dev/null || ret=1 + if [ ${synth} = yes ] + then + grep "b\.wild-a\.example\..*IN.A" dig.out.ns${ns}.test$n > /dev/null || ret=1 + grep "b\.wild-a\.example\..*3600.IN.A" dig.out.ns${ns}.test$n > /dev/null && ret=1 + else + grep "b\.wild-a\.example\..*3600.IN.A" dig.out.ns${ns}.test$n > /dev/null || ret=1 + fi + n=`expr $n + 1` + if [ $ret != 0 ]; then echo "I:failed"; fi + status=`expr $status + $ret` -echo "I:check synthesized wildcard response ($n)" -ret=0 -$DIG $DIGOPTS b.wild-a.example. @10.53.0.2 a > dig.out.ns2.test$n || ret=1 -grep "flags:[^;]* ad[ ;]" dig.out.ns2.test$n > /dev/null || ret=1 -grep "status: NOERROR," dig.out.ns2.test$n > /dev/null || ret=1 -grep "b\.wild-a\.example\..*3600.IN.A" dig.out.ns2.test$n > /dev/null && ret=1 -n=`expr $n + 1` -if [ $ret != 0 ]; then echo "I:failed"; fi -status=`expr $status + $ret` + echo "I:check synthesized wildcard CNAME response (synth-from-dnssec ${description};) ($n)" + ret=0 + $DIG $DIGOPTS b.wild-cname.example. @10.53.0.${ns} a > dig.out.ns${ns}.test$n || ret=1 + grep "flags:[^;]* ad[ ;]" dig.out.ns${ns}.test$n > /dev/null || ret=1 + grep "status: NOERROR," dig.out.ns${ns}.test$n > /dev/null || ret=1 + if [ ${synth} = yes ] + then + grep "b.wild-cname.example.*IN.CNAME" dig.out.ns${ns}.test$n > /dev/null || ret=1 + grep "b.wild-cname.example.*3600.IN.CNAME" dig.out.ns${ns}.test$n > /dev/null && ret=1 + else + grep "b.wild-cname.example.*3600.IN.CNAME" dig.out.ns${ns}.test$n > /dev/null || ret=1 + fi + grep "ns1.example.*.IN.A" dig.out.ns${ns}.test$n > /dev/null || ret=1 + n=`expr $n + 1` + if [ $ret != 0 ]; then echo "I:failed"; fi + status=`expr $status + $ret` +done -echo "I:check synthesized wildcard CNAME response ($n)" -ret=0 -$DIG $DIGOPTS b.wild-cname.example. @10.53.0.2 a > dig.out.ns2.test$n || ret=1 -grep "flags:[^;]* ad[ ;]" dig.out.ns2.test$n > /dev/null || ret=1 -grep "status: NOERROR," dig.out.ns2.test$n > /dev/null || ret=1 -grep "b.wild-cname.example.*3600.IN.CNAME" dig.out.ns2.test$n > /dev/null && ret=1 -grep "ns1.example.*.IN.A" dig.out.ns2.test$n > /dev/null || ret=1 -n=`expr $n + 1` -if [ $ret != 0 ]; then echo "I:failed"; fi -status=`expr $status + $ret` - -echo "I:check redirect response (+dnssec) ($n)" +echo "I:check redirect response (+dnssec) (synth-from-dnssec ;) ($n)" ret=0 $DIG $DIGOPTS b.redirect. @10.53.0.3 a > dig.out.ns2.test$n || ret=1 grep "flags:[^;]* ad[ ;]" dig.out.ns2.test$n > /dev/null || ret=1 @@ -126,7 +169,7 @@ n=`expr $n + 1` if [ $ret != 0 ]; then echo "I:failed"; fi status=`expr $status + $ret` -echo "I:check redirect response (+nodnssec) ($n)" +echo "I:check redirect response (+nodnssec) (synth-from-dnssec ;) ($n)" ret=0 $DIG $DIGOPTS +nodnssec b.redirect. @10.53.0.3 a > dig.out.ns2.test$n || ret=1 grep "flags:[^;]* ad[ ;]" dig.out.ns2.test$n > /dev/null && ret=1 diff --git a/lib/ns/query.c b/lib/ns/query.c index fdd2d7aad2..fb9fb23057 100644 --- a/lib/ns/query.c +++ b/lib/ns/query.c @@ -8338,6 +8338,38 @@ log_noexistnodata(void *val, int level, const char *fmt, ...) { va_end(ap); } +static dns_ttl_t +query_synthttl(dns_rdataset_t *soardataset, dns_rdataset_t *sigsoardataset, + dns_rdataset_t *p1rdataset, dns_rdataset_t *sigp1rdataset, + dns_rdataset_t *p2rdataset, dns_rdataset_t *sigp2rdataset) +{ + dns_rdata_soa_t soa; + dns_rdata_t rdata = DNS_RDATA_INIT; + dns_ttl_t ttl; + isc_result_t result; + + REQUIRE(soardataset != NULL); + REQUIRE(sigsoardataset != NULL); + REQUIRE(p1rdataset != NULL); + REQUIRE(sigp1rdataset != NULL); + + result = dns_rdataset_first(soardataset); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + dns_rdataset_current(soardataset, &rdata); + dns_rdata_tostruct(&rdata, &soa, NULL); + + ttl = ISC_MIN(soa.minimum, soardataset->ttl); + ttl = ISC_MIN(ttl, sigsoardataset->ttl); + ttl = ISC_MIN(ttl, p1rdataset->ttl); + ttl = ISC_MIN(ttl, sigp1rdataset->ttl); + if (p2rdataset != NULL) + ttl = ISC_MIN(ttl, p2rdataset->ttl); + if (sigp2rdataset != NULL) + ttl = ISC_MIN(ttl, sigp2rdataset->ttl); + + return (ttl); +} + /* * Synthesize a NODATA response from the SOA and covering NSEC in cache. */ @@ -8354,10 +8386,9 @@ query_synthnodata(query_ctx_t *qctx, const dns_name_t *signer, /* * Detemine the correct TTL to use for the SOA and RRSIG */ - ttl = ISC_MIN(qctx->rdataset->ttl, qctx->sigrdataset->ttl); - ttl = ISC_MIN(ttl, (*soardatasetp)->ttl); - ttl = ISC_MIN(ttl, (*sigsoardatasetp)->ttl); - + ttl = query_synthttl(*soardatasetp, *sigsoardatasetp, + qctx->rdataset, qctx->sigrdataset, + NULL, NULL); (*soardatasetp)->ttl = (*sigsoardatasetp)->ttl = ttl; /* @@ -8559,15 +8590,15 @@ query_synthcnamewildcard(query_ctx_t *qctx, dns_rdataset_t *rdataset, /* * Synthesize a NXDOMAIN response from qctx (which contains the - * NODATA proof), nowild + rdataset + sigrdataset (which contains - * the NOWILDCARD proof) and signer + soardatasetp + sigsoardatasetp + * NODATA proof), nowild + nowildrdataset + signowildrdataset (which + * contains the NOWILDCARD proof) and signer + soardatasetp + sigsoardatasetp * which contain the SOA record + RRSIG for the negative answer. */ static isc_result_t query_synthnxdomain(query_ctx_t *qctx, dns_name_t *nowild, - dns_rdataset_t *rdataset, - dns_rdataset_t *sigrdataset, + dns_rdataset_t *nowildrdataset, + dns_rdataset_t *signowildrdataset, dns_name_t *signer, dns_rdataset_t **soardatasetp, dns_rdataset_t **sigsoardatasetp) @@ -8581,12 +8612,9 @@ query_synthnxdomain(query_ctx_t *qctx, /* * Detemine the correct TTL to use for the SOA and RRSIG */ - ttl = ISC_MIN(qctx->rdataset->ttl, qctx->sigrdataset->ttl); - ttl = ISC_MIN(ttl, rdataset->ttl); - ttl = ISC_MIN(ttl, sigrdataset->ttl); - ttl = ISC_MIN(ttl, (*soardatasetp)->ttl); - ttl = ISC_MIN(ttl, (*sigsoardatasetp)->ttl); - + ttl = query_synthttl(*soardatasetp, *sigsoardatasetp, + qctx->rdataset, qctx->sigrdataset, + nowildrdataset, signowildrdataset); (*soardatasetp)->ttl = (*sigsoardatasetp)->ttl = ttl; /* @@ -8651,8 +8679,8 @@ query_synthnxdomain(query_ctx_t *qctx, goto cleanup; } - dns_rdataset_clone(rdataset, clone); - dns_rdataset_clone(sigrdataset, sigclone); + dns_rdataset_clone(nowildrdataset, clone); + dns_rdataset_clone(signowildrdataset, sigclone); /* * Add NOWILDCARD proof.