diff --git a/CHANGES b/CHANGES index a60bba3421..69723d722b 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +4926. [func] Add root key sentinel support. To disable, add + 'root-key-sentinel no;' to named.conf. [GL #37] + 4925. [func] Several configuration options that define intervals can now take TTL value suffixes (for example, 2h or 1d) in addition to integer parameters. These include diff --git a/bin/named/config.c b/bin/named/config.c index 43269b4a3a..a2d2eb7ea7 100644 --- a/bin/named/config.c +++ b/bin/named/config.c @@ -195,6 +195,7 @@ options {\n\ resolver-nonbackoff-tries 3;\n\ resolver-retry-interval 800; /* in milliseconds */\n\ # rfc2308-type1 ;\n\ + root-key-sentinel yes;\n\ servfail-ttl 1;\n\ # sortlist \n\ stale-answer-enable false;\n\ diff --git a/bin/named/server.c b/bin/named/server.c index faf6481778..e037557f6c 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -4682,6 +4682,11 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, INSIST(result == ISC_R_SUCCESS); view->trust_anchor_telemetry = cfg_obj_asboolean(obj); + obj = NULL; + result = named_config_get(maps, "root-key-sentinel", &obj); + INSIST(result == ISC_R_SUCCESS); + view->root_key_sentinel = cfg_obj_asboolean(obj); + CHECK(configure_view_acl(vconfig, config, named_g_config, "allow-query-cache-on", NULL, actx, named_g_mctx, &view->cacheonacl)); diff --git a/bin/tests/system/Makefile.in b/bin/tests/system/Makefile.in index 1b2fccbbe0..a552f4667e 100644 --- a/bin/tests/system/Makefile.in +++ b/bin/tests/system/Makefile.in @@ -65,7 +65,7 @@ PARALLEL = rpzrecurse serve-stale dnssec \ masterfile masterformat metadata mkeys \ names notify nslookup nsupdate nzd2nzf \ padding pending pipelined \ - reclimit redirect resolver rndc rpz \ + reclimit redirect resolver rndc rootkeysentinel rpz \ rrchecker rrl rrsetorder rsabigexponent runtime \ sfcache smartsign sortlist \ spf staticstub statistics statschannel stub synthfromdnssec \ diff --git a/bin/tests/system/conf.sh.in b/bin/tests/system/conf.sh.in index ecd01d677a..7b8a4e9caa 100644 --- a/bin/tests/system/conf.sh.in +++ b/bin/tests/system/conf.sh.in @@ -96,16 +96,16 @@ PARALLELDIRS="acl additional addzone allow-query auth autosign \ fetchlimit filter-aaaa formerr forward \ geoip glue idna inline integrity ixfr keepalive \ legacy limits logfileconfig \ - masterfile masterformat metadata mkeys \ - names notify nslookup nsupdate nzd2nzf \ - padding pending pipelined \ - reclimit redirect resolver rndc rpz rpzrecurse \ - rrchecker rrl rrsetorder rsabigexponent runtime \ - serve-stale sfcache smartsign sortlist \ - spf staticstub statistics statschannel stub synthfromdnssec \ - tcp tools tsig tsiggss \ - unknown upforwd verify views wildcard \ - xfer xferquota zero zonechecks" + masterfile masterformat metadata mkeys \ + names notify nslookup nsupdate nzd2nzf \ + padding pending pipelined \ + reclimit redirect resolver rndc rootkeysentinel rpz rpzrecurse \ + rrchecker rrl rrsetorder rsabigexponent runtime \ + serve-stale sfcache smartsign sortlist \ + spf staticstub statistics statschannel stub synthfromdnssec \ + tcp tools tsig tsiggss \ + unknown upforwd verify views wildcard \ + xfer xferquota zero zonechecks" SUBDIRS="$SEQUENTIALDIRS $PARALLELDIRS" @@ -234,6 +234,12 @@ echo_i() { done } +echo_ic() { + echo "$@" | while read LINE ; do + echoinfo "I:$SYSTESTDIR: $LINE" + done +} + cat_i() { while read LINE ; do echoinfo "I:$SYSTESTDIR:$LINE" diff --git a/bin/tests/system/rootkeysentinel/clean.sh b/bin/tests/system/rootkeysentinel/clean.sh new file mode 100644 index 0000000000..702002bc4c --- /dev/null +++ b/bin/tests/system/rootkeysentinel/clean.sh @@ -0,0 +1,23 @@ +#!/bin/sh +# +# Copyright (C) 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/. +# +# See the COPYRIGHT file distributed with this work for additional +# information regarding copyright ownership. + +rm -f dig.out.ns?.test* +rm -f */dsset-* +rm -f */named.conf +rm -f */named.memstats +rm -f */named.run +rm -f */trusted.conf +rm -f ns1/K.* +rm -f ns1/root.db +rm -f ns1/root.db.signed +rm -f ns2/Kexample.* +rm -f ns2/example.db +rm -f ns2/example.db.signed diff --git a/bin/tests/system/rootkeysentinel/ns1/named.conf.in b/bin/tests/system/rootkeysentinel/ns1/named.conf.in new file mode 100644 index 0000000000..6312ca1621 --- /dev/null +++ b/bin/tests/system/rootkeysentinel/ns1/named.conf.in @@ -0,0 +1,31 @@ +/* + * Copyright (C) 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/. + * + * See the COPYRIGHT file distributed with this work for additional + * information regarding copyright ownership. + */ + +options { + query-source address 10.53.0.1; + notify-source 10.53.0.1; + transfer-source 10.53.0.1; + port @PORT@; + pid-file "named.pid"; + listen-on { 10.53.0.1; }; + listen-on-v6 { none; }; + recursion no; + notify yes; + dnssec-enable yes; + dnssec-validation yes; +}; + +zone "." { + type master; + file "root.db.signed"; +}; + +include "trusted.conf"; diff --git a/bin/tests/system/rootkeysentinel/ns1/root.db.in b/bin/tests/system/rootkeysentinel/ns1/root.db.in new file mode 100644 index 0000000000..065bc6e998 --- /dev/null +++ b/bin/tests/system/rootkeysentinel/ns1/root.db.in @@ -0,0 +1,22 @@ +; Copyright (C) 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/. +; +; See the COPYRIGHT file distributed with this work for additional +; information regarding copyright ownership. + +$TTL 300 +. IN SOA marka.isc.org. a.root.servers.nil. ( + 2018031400 ; serial + 600 ; refresh + 600 ; retry + 1200 ; expire + 600 ; minimum + ) +. NS a.root-servers.nil. +a.root-servers.nil. A 10.53.0.1 + +example. NS ns2.example. +ns2.example. A 10.53.0.2 diff --git a/bin/tests/system/rootkeysentinel/ns1/sign.sh b/bin/tests/system/rootkeysentinel/ns1/sign.sh new file mode 100644 index 0000000000..9f91928694 --- /dev/null +++ b/bin/tests/system/rootkeysentinel/ns1/sign.sh @@ -0,0 +1,43 @@ +#!/bin/sh -e +# +# Copyright (C) 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/. +# +# See the COPYRIGHT file distributed with this work for additional +# information regarding copyright ownership. + +SYSTEMTESTTOP=../.. +. $SYSTEMTESTTOP/conf.sh + +zone=. +infile=root.db.in +zonefile=root.db + +keyname=`$KEYGEN -q -r $RANDFILE -a RSASHA256 -b 1024 -n zone $zone` +keyid=`expr ${keyname} : 'K.+008+\(.*\)'` + +(cd ../ns2 && $SHELL sign.sh ${keyid:-00000} ) + +cp ../ns2/dsset-example$TP . + +cat $infile $keyname.key > $zonefile + +$SIGNER -P -g -r $RANDFILE -o $zone $zonefile > /dev/null + +# Configure the resolving server with a trusted key. +cat $keyname.key | grep -v '^; ' | $PERL -n -e ' +local ($dn, $class, $type, $flags, $proto, $alg, @rest) = split; +local $key = join("", @rest); +print < trusted.conf + +cp trusted.conf ../ns2/trusted.conf +cp trusted.conf ../ns3/trusted.conf +cp trusted.conf ../ns4/trusted.conf diff --git a/bin/tests/system/rootkeysentinel/ns2/example.db.in b/bin/tests/system/rootkeysentinel/ns2/example.db.in new file mode 100644 index 0000000000..77425b196c --- /dev/null +++ b/bin/tests/system/rootkeysentinel/ns2/example.db.in @@ -0,0 +1,19 @@ +; Copyright (C) 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/. +; +; See the COPYRIGHT file distributed with this work for additional +; information regarding copyright ownership. + +$TTL 300 ; 5 minutes +@ IN SOA mname1. . ( + 2018031400 ; serial + 20 ; refresh (20 seconds) + 20 ; retry (20 seconds) + 1814400 ; expire (3 weeks) + 3600 ; minimum (1 hour) + ) + NS ns2 +ns2 A 10.53.0.2 diff --git a/bin/tests/system/rootkeysentinel/ns2/named.conf.in b/bin/tests/system/rootkeysentinel/ns2/named.conf.in new file mode 100644 index 0000000000..2da0567cd5 --- /dev/null +++ b/bin/tests/system/rootkeysentinel/ns2/named.conf.in @@ -0,0 +1,31 @@ +/* + * Copyright (C) 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/. + * + * See the COPYRIGHT file distributed with this work for additional + * information regarding copyright ownership. + */ + +options { + query-source address 10.53.0.2; + notify-source 10.53.0.2; + transfer-source 10.53.0.2; + port @PORT@; + pid-file "named.pid"; + listen-on { 10.53.0.2; }; + listen-on-v6 { none; }; + recursion no; + notify yes; + dnssec-enable yes; + dnssec-validation yes; +}; + +zone "example" { + type master; + file "example.db.signed"; +}; + +include "trusted.conf"; diff --git a/bin/tests/system/rootkeysentinel/ns2/sign.sh b/bin/tests/system/rootkeysentinel/ns2/sign.sh new file mode 100644 index 0000000000..861337b730 --- /dev/null +++ b/bin/tests/system/rootkeysentinel/ns2/sign.sh @@ -0,0 +1,40 @@ +#!/bin/sh -e +# +# Copyright (C) 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/. +# +# See the COPYRIGHT file distributed with this work for additional +# information regarding copyright ownership. + +oldid=${1:-00000} +newid=`expr \( ${oldid} + 1000 \) % 65536` +newid=`expr "0000${newid}" : '.*\(.....\)$'` +badid=`expr \( ${oldid} + 7777 \) % 65536` +badid=`expr "0000${badid}" : '.*\(.....\)$'` + +SYSTEMTESTTOP=../.. +. $SYSTEMTESTTOP/conf.sh + +zone=example. +infile=example.db.in +zonefile=example.db + +keyname1=`$KEYGEN -q -r $RANDFILE -a DSA -b 768 -n zone $zone` +keyname2=`$KEYGEN -q -r $RANDFILE -a DSA -b 768 -n zone $zone` + +cat $infile $keyname1.key $keyname2.key >$zonefile +echo root-key-sentinel-is-ta-$oldid A 10.53.0.1 >> $zonefile +echo root-key-sentinel-not-ta-$oldid A 10.53.0.2 >> $zonefile +echo root-key-sentinel-is-ta-$newid A 10.53.0.3 >> $zonefile +echo root-key-sentinel-not-ta-$newid A 10.53.0.4 >> $zonefile +echo old-is-ta CNAME root-key-sentinel-is-ta-$oldid >> $zonefile +echo old-not-ta CNAME root-key-sentinel-not-ta-$oldid >> $zonefile +echo new-is-ta CNAME root-key-sentinel-is-ta-$newid >> $zonefile +echo new-not-ta CNAME root-key-sentinel-not-ta-$newid >> $zonefile +echo bad-is-ta CNAME root-key-sentinel-is-ta-$badid >> $zonefile +echo bad-not-ta CNAME root-key-sentinel-not-ta-$badid >> $zonefile + +$SIGNER -P -g -r $RANDFILE -o $zone -k $keyname1 $zonefile $keyname2 > /dev/null diff --git a/bin/tests/system/rootkeysentinel/ns3/hint.db b/bin/tests/system/rootkeysentinel/ns3/hint.db new file mode 100644 index 0000000000..bcd3e4b7f1 --- /dev/null +++ b/bin/tests/system/rootkeysentinel/ns3/hint.db @@ -0,0 +1,2 @@ +. NS a.root-servers.nil. +a.root-servers.nil. A 10.53.0.1 diff --git a/bin/tests/system/rootkeysentinel/ns3/named.conf.in b/bin/tests/system/rootkeysentinel/ns3/named.conf.in new file mode 100644 index 0000000000..ea118ce4e5 --- /dev/null +++ b/bin/tests/system/rootkeysentinel/ns3/named.conf.in @@ -0,0 +1,32 @@ +/* + * Copyright (C) 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/. + * + * See the COPYRIGHT file distributed with this work for additional + * information regarding copyright ownership. + */ + +options { + query-source address 10.53.0.3; + notify-source 10.53.0.3; + transfer-source 10.53.0.3; + port @PORT@; + pid-file "named.pid"; + listen-on { 10.53.0.3; }; + listen-on-v6 { none; }; + recursion yes; + notify yes; + dnssec-enable yes; + dnssec-validation yes; + root-key-sentinel yes; +}; + +zone "." { + type hint; + file "hint.db"; +}; + +include "trusted.conf"; diff --git a/bin/tests/system/rootkeysentinel/ns4/hint.db b/bin/tests/system/rootkeysentinel/ns4/hint.db new file mode 100644 index 0000000000..bcd3e4b7f1 --- /dev/null +++ b/bin/tests/system/rootkeysentinel/ns4/hint.db @@ -0,0 +1,2 @@ +. NS a.root-servers.nil. +a.root-servers.nil. A 10.53.0.1 diff --git a/bin/tests/system/rootkeysentinel/ns4/named.conf.in b/bin/tests/system/rootkeysentinel/ns4/named.conf.in new file mode 100644 index 0000000000..3a42b3f448 --- /dev/null +++ b/bin/tests/system/rootkeysentinel/ns4/named.conf.in @@ -0,0 +1,32 @@ +/* + * Copyright (C) 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/. + * + * See the COPYRIGHT file distributed with this work for additional + * information regarding copyright ownership. + */ + +options { + query-source address 10.53.0.4; + notify-source 10.53.0.4; + transfer-source 10.53.0.4; + port @PORT@; + pid-file "named.pid"; + listen-on { 10.53.0.4; }; + listen-on-v6 { none; }; + recursion yes; + notify yes; + dnssec-enable yes; + dnssec-validation yes; + root-key-sentinel no; +}; + +zone "." { + type hint; + file "hint.db"; +}; + +include "trusted.conf"; diff --git a/bin/tests/system/rootkeysentinel/setup.sh b/bin/tests/system/rootkeysentinel/setup.sh new file mode 100644 index 0000000000..130287b705 --- /dev/null +++ b/bin/tests/system/rootkeysentinel/setup.sh @@ -0,0 +1,25 @@ +#!/bin/sh -e +# +# Copyright (C) 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/. +# +# See the COPYRIGHT file distributed with this work for additional +# information regarding copyright ownership. + +SYSTEMTESTTOP=.. +. $SYSTEMTESTTOP/conf.sh + +$SHELL clean.sh + +test -r $RANDFILE || $GENRANDOM 800 $RANDFILE + +copy_setports ns1/named.conf.in ns1/named.conf +copy_setports ns2/named.conf.in ns2/named.conf +copy_setports ns3/named.conf.in ns3/named.conf +copy_setports ns4/named.conf.in ns4/named.conf + +cd ns1 +$SHELL sign.sh diff --git a/bin/tests/system/rootkeysentinel/tests.sh b/bin/tests/system/rootkeysentinel/tests.sh new file mode 100644 index 0000000000..a36ec57f7c --- /dev/null +++ b/bin/tests/system/rootkeysentinel/tests.sh @@ -0,0 +1,286 @@ +#!/bin/sh +# +# Copyright (C) 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/. +# +# See the COPYRIGHT file distributed with this work for additional +# information regarding copyright ownership. + +SYSTEMTESTTOP=.. +. $SYSTEMTESTTOP/conf.sh + +status=0 +n=0 + +rm -f dig.out.* + +DIGOPTS="+tcp +noadd +nosea +nostat +nocmd +dnssec -p ${PORT}" + +newtest() { + n=`expr $n + 1` + case $# in + 1) + echo_i "$1 ($n)" + ;; + 2) + echo_i "$1" + echo_ic "$2 ($n)" + ;; + esac + ret=0 +} + +newtest "get test ids" +$DIG $DIGOPTS . dnskey +short +rrcomm @10.53.0.1 > dig.out.ns1.test$n || ret=1 +oldid=`sed -n 's/.*key id = //p' < dig.out.ns1.test$n` +oldid=`expr "0000${oldid}" : '.*\(.....\)$'` +newid=`expr \( ${oldid} + 1000 \) % 65536` +newid=`expr "0000${newid}" : '.*\(.....\)$'` +badid=`expr \( ${oldid} + 7777 \) % 65536` +badid=`expr "0000${badid}" : '.*\(.....\)$'` +echo_i "test id: oldid=${oldid} (configured)" +echo_i "test id: newid=${newid} (not configured)" +echo_i "test id: badid=${badid}" +if [ $ret != 0 ]; then echo_i "failed"; fi +status=`expr $status + $ret` + +newtest "check authoritative server (expect NOERROR)" +$DIG $DIGOPTS @10.53.0.2 example SOA > dig.out.ns2.test$n +grep "status: NOERROR" dig.out.ns2.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo_i "failed"; fi +status=`expr $status + $ret` + +newtest "check test zone resolves with 'root-key-sentinel yes;'" " (expect NOERROR)" +$DIG $DIGOPTS @10.53.0.3 example SOA > dig.out.ns3.test$n +grep "status: NOERROR" dig.out.ns3.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo_i "failed"; fi +status=`expr $status + $ret` + +newtest "check root-key-sentinel-is-ta with old ta and" " 'root-key-sentinel yes;' (expect NOERROR)" +$DIG $DIGOPTS @10.53.0.3 root-key-sentinel-is-ta-${oldid}.example A > dig.out.ns3.test$n || ret=1 +grep "status: NOERROR" dig.out.ns3.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo_i "failed"; fi +status=`expr $status + $ret` + +newtest "check root-key-sentinel-not-ta with old ta and" " 'root-key-sentinel yes;' (expect SERVFAIL)" +$DIG $DIGOPTS @10.53.0.3 root-key-sentinel-not-ta-${oldid}.example A > dig.out.ns3.test$n || ret=1 +grep "status: SERVFAIL" dig.out.ns3.test$n > /dev/null || ret=1 +grep "ANSWER: 0," dig.out.ns3.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo_i "failed"; fi +status=`expr $status + $ret` + +newtest "check root-key-sentinel-not-ta with old ta, CD=1 and" " 'root-key-sentinel yes;' (expect NOERROR)" +$DIG $DIGOPTS @10.53.0.3 +cd root-key-sentinel-not-ta-${oldid}.example A > dig.out.ns3.test$n || ret=1 +grep "status: NOERROR" dig.out.ns3.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo_i "failed"; fi +status=`expr $status + $ret` + +newtest "check root-key-sentinel-is-ta with new ta and" " 'root-key-sentinel yes;' (expect SERVFAIL)" +$DIG $DIGOPTS @10.53.0.3 root-key-sentinel-is-ta-${newid}.example A > dig.out.ns3.test$n || ret=1 +grep "status: SERVFAIL" dig.out.ns3.test$n > /dev/null || ret=1 +grep "ANSWER: 0," dig.out.ns3.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo_i "failed"; fi +status=`expr $status + $ret` + +newtest "check root-key-sentinel-is-ta with new ta, CD=1 and" " 'root-key-sentinel yes;' (expect NOERROR)" +$DIG $DIGOPTS @10.53.0.3 +cd root-key-sentinel-is-ta-${newid}.example A > dig.out.ns3.test$n || ret=1 +grep "status: NOERROR" dig.out.ns3.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo_i "failed"; fi +status=`expr $status + $ret` + +newtest "check root-key-sentinel-not-ta with new ta and" " 'root-key-sentinel yes;' (expect NOERROR)" +$DIG $DIGOPTS @10.53.0.3 root-key-sentinel-not-ta-${newid}.example A > dig.out.ns3.test$n || ret=1 +grep "status: NOERROR" dig.out.ns3.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo_i "failed"; fi + +newtest "check root-key-sentinel-is-ta with bad ta and" " 'root-key-sentinel yes;' (expect SERVFAIL)" +$DIG $DIGOPTS @10.53.0.3 root-key-sentinel-is-ta-${badid}.example A > dig.out.ns3.test$n || ret=1 +grep "status: SERVFAIL" dig.out.ns3.test$n > /dev/null || ret=1 +grep "ANSWER: 0," dig.out.ns3.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo_i "failed"; fi +status=`expr $status + $ret` + +newtest "check root-key-sentinel-is-ta with bad ta, CD=1 and" " 'root-key-sentinel yes;' (expect NXDOMAIN)" +$DIG $DIGOPTS @10.53.0.3 +cd root-key-sentinel-is-ta-${badid}.example A > dig.out.ns3.test$n || ret=1 +grep "status: NXDOMAIN" dig.out.ns3.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo_i "failed"; fi +status=`expr $status + $ret` + +newtest "check root-key-sentinel-not-ta with bad ta and" " 'root-key-sentinel yes;' (expect NXDOMAIN)" +$DIG $DIGOPTS @10.53.0.3 root-key-sentinel-not-ta-${bad}.example A > dig.out.ns3.test$n || ret=1 +grep "status: NXDOMAIN" dig.out.ns3.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo_i "failed"; fi + +newtest "check root-key-sentinel-is-ta with out-of-range ta and" " 'root-key-sentinel yes;' (expect NXDOMAIN)" +$DIG $DIGOPTS @10.53.0.3 root-key-sentinel-is-ta-72345.example A > dig.out.ns3.test$n || ret=1 +grep "status: NXDOMAIN" dig.out.ns3.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo_i "failed"; fi +status=`expr $status + $ret` + +newtest "check root-key-sentinel-not-ta with out-of-range ta and" " 'root-key-sentinel yes;' (expect NXDOMAIN)" +$DIG $DIGOPTS @10.53.0.3 root-key-sentinel-not-ta-72345.example A > dig.out.ns3.test$n || ret=1 +grep "status: NXDOMAIN" dig.out.ns3.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo_i "failed"; fi + +newtest "check root-key-sentinel-is-ta with no-zero-pad ta and" " 'root-key-sentinel yes;' (expect NXDOMAIN)" +$DIG $DIGOPTS @10.53.0.3 root-key-sentinel-is-ta-1234.example A > dig.out.ns3.test$n || ret=1 +grep "status: NXDOMAIN" dig.out.ns3.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo_i "failed"; fi +status=`expr $status + $ret` + +newtest "check root-key-sentinel-not-ta with no-zero-pad ta and" " 'root-key-sentinel yes;' (expect NXDOMAIN)" +$DIG $DIGOPTS @10.53.0.3 root-key-sentinel-not-ta-1234.example A > dig.out.ns3.test$n || ret=1 +grep "status: NXDOMAIN" dig.out.ns3.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo_i "failed"; fi + +newtest "check CNAME to root-key-sentinel-is-ta with old ta and" " 'root-key-sentinel yes;' (expect NOERROR)" +$DIG $DIGOPTS @10.53.0.3 old-is-ta.example A > dig.out.ns3.test$n || ret=1 +grep "status: NOERROR" dig.out.ns3.test$n > /dev/null || ret=1 +grep "old-is-ta.*CNAME.root-key-sentinel-is-ta-${oldid}.example." dig.out.ns3.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo_i "failed"; fi +status=`expr $status + $ret` + +newtest "check CNAME to root-key-sentinel-not-ta with old ta and" " 'root-key-sentinel yes;' (expect NOERROR)" +$DIG $DIGOPTS @10.53.0.3 old-not-ta.example A > dig.out.ns3.test$n || ret=1 +grep "status: NOERROR" dig.out.ns3.test$n > /dev/null || ret=1 +grep "old-not-ta.*CNAME.root-key-sentinel-not-ta-${oldid}.example." dig.out.ns3.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo_i "failed"; fi +status=`expr $status + $ret` + +newtest "check CNAME to root-key-sentinel-is-ta with new ta and" " 'root-key-sentinel yes;' (expect NOERROR)" +$DIG $DIGOPTS @10.53.0.3 new-is-ta.example A > dig.out.ns3.test$n || ret=1 +grep "status: NOERROR" dig.out.ns3.test$n > /dev/null || ret=1 +grep "new-is-ta.*CNAME.root-key-sentinel-is-ta-${newid}.example." dig.out.ns3.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo_i "failed"; fi +status=`expr $status + $ret` + +newtest "check CNAME to root-key-sentinel-not-ta with new ta and" " 'root-key-sentinel yes;' (expect NOERROR)" +$DIG $DIGOPTS @10.53.0.3 new-not-ta.example A > dig.out.ns3.test$n || ret=1 +grep "status: NOERROR" dig.out.ns3.test$n > /dev/null || ret=1 +grep "new-not-ta.*CNAME.root-key-sentinel-not-ta-${newid}.example." dig.out.ns3.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo_i "failed"; fi +status=`expr $status + $ret` + +newtest "check CNAME to root-key-sentinel-is-ta with bad ta and" " 'root-key-sentinel yes;' (expect NXDOMAIN)" +$DIG $DIGOPTS @10.53.0.3 bad-is-ta.example A > dig.out.ns3.test$n || ret=1 +grep "status: NXDOMAIN" dig.out.ns3.test$n > /dev/null || ret=1 +grep "bad-is-ta.*CNAME.root-key-sentinel-is-ta-${badid}.example" dig.out.ns3.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo_i "failed"; fi +status=`expr $status + $ret` + +newtest "check CNAME to root-key-sentinel-not-ta with bad ta and" " 'root-key-sentinel yes;' (expect NXDOMAIN)" +$DIG $DIGOPTS @10.53.0.3 bad-not-ta.example A > dig.out.ns3.test$n || ret=1 +grep "status: NXDOMAIN" dig.out.ns3.test$n > /dev/null || ret=1 +grep "bad-not-ta.*CNAME.root-key-sentinel-not-ta-${badid}.example." dig.out.ns3.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo_i "failed"; fi +status=`expr $status + $ret` + +newtest "check test zone resolves with 'root-key-sentinel no;'" " (expect NOERROR)" +$DIG $DIGOPTS @10.53.0.4 example SOA > dig.out.ns4.test$n +grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo_i "failed"; fi +status=`expr $status + $ret` + +newtest "check root-key-sentinel-is-ta with old ta and" " 'root-key-sentinel no;' (expect NOERROR)" +$DIG $DIGOPTS @10.53.0.4 root-key-sentinel-is-ta-${oldid}.example A > dig.out.ns4.test$n || ret=1 +grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo_i "failed"; fi +status=`expr $status + $ret` + +newtest "check root-key-sentinel-not-ta with old ta and" " 'root-key-sentinel no;' (expect NOERROR)" +$DIG $DIGOPTS @10.53.0.4 root-key-sentinel-not-ta-${oldid}.example A > dig.out.ns4.test$n || ret=1 +grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo_i "failed"; fi +status=`expr $status + $ret` + +newtest "check root-key-sentinel-is-ta with new ta and" " 'root-key-sentinel no;' (expect NOERROR)" +$DIG $DIGOPTS @10.53.0.4 root-key-sentinel-is-ta-${newid}.example A > dig.out.ns4.test$n || ret=1 +grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo_i "failed"; fi +status=`expr $status + $ret` + +newtest "check root-key-sentinel-not-ta with new ta and" " 'root-key-sentinel no;' (expect NOERROR)" +$DIG $DIGOPTS @10.53.0.4 root-key-sentinel-not-ta-${newid}.example A > dig.out.ns4.test$n || ret=1 +grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo_i "failed"; fi + +newtest "check root-key-sentinel-is-ta with bad ta and" " 'root-key-sentinel no;' (expect NXDOMAIN)" +$DIG $DIGOPTS @10.53.0.4 root-key-sentinel-is-ta-${badid}.example A > dig.out.ns4.test$n || ret=1 +grep "status: NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo_i "failed"; fi +status=`expr $status + $ret` + +newtest "check root-key-sentinel-not-ta with bad ta and" " 'root-key-sentinel no;' (expect NXDOMAIN)" +$DIG $DIGOPTS @10.53.0.4 root-key-sentinel-not-ta-${bad}.example A > dig.out.ns4.test$n || ret=1 +grep "status: NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo_i "failed"; fi + +newtest "check root-key-sentinel-is-ta with out-of-range ta and" " 'root-key-sentinel no;' (expect NXDOMAIN)" +$DIG $DIGOPTS @10.53.0.4 root-key-sentinel-is-ta-72345.example A > dig.out.ns4.test$n || ret=1 +grep "status: NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo_i "failed"; fi +status=`expr $status + $ret` + +newtest "check root-key-sentinel-not-ta with out-of-range ta and" " 'root-key-sentinel no;' (expect NXDOMAIN)" +$DIG $DIGOPTS @10.53.0.4 root-key-sentinel-not-ta-72345.example A > dig.out.ns4.test$n || ret=1 +grep "status: NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo_i "failed"; fi + +newtest "check root-key-sentinel-is-ta with no-zero-pad ta and" " 'root-key-sentinel no;' (expect NXDOMAIN)" +$DIG $DIGOPTS @10.53.0.4 root-key-sentinel-is-ta-1234.example A > dig.out.ns4.test$n || ret=1 +grep "status: NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo_i "failed"; fi +status=`expr $status + $ret` + +newtest "check root-key-sentinel-not-ta with no-zero-pad ta and" " 'root-key-sentinel no;' (expect NXDOMAIN)" +$DIG $DIGOPTS @10.53.0.4 root-key-sentinel-not-ta-1234.example A > dig.out.ns4.test$n || ret=1 +grep "status: NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo_i "failed"; fi + +newtest "check CNAME to root-key-sentinel-is-ta with old ta and" " 'root-key-sentinel no;' (expect NOERROR)" +$DIG $DIGOPTS @10.53.0.4 old-is-ta.example A > dig.out.ns4.test$n || ret=1 +grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 +grep "old-is-ta.*CNAME.root-key-sentinel-is-ta-${oldid}.example." dig.out.ns4.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo_i "failed"; fi +status=`expr $status + $ret` + +newtest "check CNAME to root-key-sentinel-not-ta with old ta and" " 'root-key-sentinel no;' (expect NOERROR)" +$DIG $DIGOPTS @10.53.0.4 old-not-ta.example A > dig.out.ns4.test$n || ret=1 +grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 +grep "old-not-ta.*CNAME.root-key-sentinel-not-ta-${oldid}.example." dig.out.ns4.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo_i "failed"; fi +status=`expr $status + $ret` + +newtest "check CNAME to root-key-sentinel-is-ta with new ta and" " 'root-key-sentinel no;' (expect NOERROR)" +$DIG $DIGOPTS @10.53.0.4 new-is-ta.example A > dig.out.ns4.test$n || ret=1 +grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 +grep "new-is-ta.*CNAME.root-key-sentinel-is-ta-${newid}.example." dig.out.ns4.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo_i "failed"; fi +status=`expr $status + $ret` + +newtest "check CNAME to root-key-sentinel-not-ta with new ta and" " 'root-key-sentinel no;' (expect NOERROR)" +$DIG $DIGOPTS @10.53.0.4 new-not-ta.example A > dig.out.ns4.test$n || ret=1 +grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1 +grep "new-not-ta.*CNAME.root-key-sentinel-not-ta-${newid}.example." dig.out.ns4.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo_i "failed"; fi +status=`expr $status + $ret` + +newtest "check CNAME to root-key-sentinel-is-ta with bad ta and" " 'root-key-sentinel no;' (expect NXDOMAIN)" +$DIG $DIGOPTS @10.53.0.4 bad-is-ta.example A > dig.out.ns4.test$n || ret=1 +grep "status: NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1 +grep "bad-is-ta.*CNAME.root-key-sentinel-is-ta-${badid}.example" dig.out.ns4.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo_i "failed"; fi +status=`expr $status + $ret` + +newtest "check CNAME to root-key-sentinel-not-ta with bad ta and" " 'root-key-sentinel no;' (expect NXDOMAIN)" +$DIG $DIGOPTS @10.53.0.4 bad-not-ta.example A > dig.out.ns4.test$n || ret=1 +grep "status: NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1 +grep "bad-not-ta.*CNAME.root-key-sentinel-not-ta-${badid}.example." dig.out.ns4.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo_i "failed"; fi +status=`expr $status + $ret` + +echo_i "exit status: $status" +[ $status -eq 0 ] || exit 1 diff --git a/doc/arm/Bv9ARM-book.xml b/doc/arm/Bv9ARM-book.xml index d57aa019bc..d1e8a8d621 100644 --- a/doc/arm/Bv9ARM-book.xml +++ b/doc/arm/Bv9ARM-book.xml @@ -5845,6 +5845,17 @@ options { + + root-key-sentinel + + + Respond to root key sentinel probes as described in + draft-ietf-dnsop-kskroll-sentinel-08. The default is + yes. + + + + maintain-ixfr-base diff --git a/doc/arm/notes.xml b/doc/arm/notes.xml index 49c6acbd4e..574ede8c1d 100644 --- a/doc/arm/notes.xml +++ b/doc/arm/notes.xml @@ -71,6 +71,13 @@ using (now obsolete) idnkit-1 library. + + + Add root key sentinel support which enables resolvers to test + which trust anchors are configured for the root. To disable, add + 'root-key-sentinel no;' to named.conf. + + diff --git a/doc/misc/options b/doc/misc/options index 2604c6c951..6606dc93e1 100644 --- a/doc/misc/options +++ b/doc/misc/options @@ -318,6 +318,7 @@ options { } ]; rfc2308-type1 ; // not yet implemented root-delegation-only [ exclude { ; ... } ]; + root-key-sentinel ; rrset-order { [ class ] [ type ] [ name ] ; ... }; secroots-file ; @@ -643,6 +644,7 @@ view [ ] { dnsrps-enable ] [ dnsrps-options { } ]; rfc2308-type1 ; // not yet implemented + root-key-sentinel ; root-delegation-only [ exclude { ; ... } ]; rrset-order { [ class ] [ type ] [ name ] ; ... }; diff --git a/lib/dns/include/dns/view.h b/lib/dns/include/dns/view.h index df49832e5d..3fd4959506 100644 --- a/lib/dns/include/dns/view.h +++ b/lib/dns/include/dns/view.h @@ -125,6 +125,7 @@ struct dns_view { isc_boolean_t requireservercookie; isc_boolean_t synthfromdnssec; isc_boolean_t trust_anchor_telemetry; + isc_boolean_t root_key_sentinel; dns_transfer_format_t transfer_format; dns_acl_t * cacheacl; dns_acl_t * cacheonacl; diff --git a/lib/dns/view.c b/lib/dns/view.c index 049d0fd59f..8fbdd7bf85 100644 --- a/lib/dns/view.c +++ b/lib/dns/view.c @@ -242,6 +242,7 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, view->requireservercookie = ISC_FALSE; view->synthfromdnssec = ISC_TRUE; view->trust_anchor_telemetry = ISC_TRUE; + view->root_key_sentinel = ISC_TRUE; view->new_zone_dir = NULL; view->new_zone_file = NULL; view->new_zone_db = NULL; diff --git a/lib/isccfg/namedconf.c b/lib/isccfg/namedconf.c index 710dd12a05..07feeb3713 100644 --- a/lib/isccfg/namedconf.c +++ b/lib/isccfg/namedconf.c @@ -1958,6 +1958,7 @@ view_clauses[] = { { "response-policy", &cfg_type_rpz, 0 }, { "rfc2308-type1", &cfg_type_boolean, CFG_CLAUSEFLAG_NYI }, { "root-delegation-only", &cfg_type_optional_exclude, 0 }, + { "root-key-sentinel", &cfg_type_boolean, 0 }, { "rrset-order", &cfg_type_rrsetorder, 0 }, { "send-cookie", &cfg_type_boolean, 0 }, { "servfail-ttl", &cfg_type_ttlval, 0 }, diff --git a/lib/ns/include/ns/query.h b/lib/ns/include/ns/query.h index 87c0a638ed..365cb8c754 100644 --- a/lib/ns/include/ns/query.h +++ b/lib/ns/include/ns/query.h @@ -75,6 +75,10 @@ struct ns_query { isc_boolean_t authoritative; isc_boolean_t is_zone; } redirect; + + dns_keytag_t root_key_sentinel_keyid; + isc_boolean_t root_key_sentinel_is_ta; + isc_boolean_t root_key_sentinel_not_ta; }; #define NS_QUERYATTR_RECURSIONOK 0x0001 diff --git a/lib/ns/query.c b/lib/ns/query.c index b352cdbf55..790840f6d1 100644 --- a/lib/ns/query.c +++ b/lib/ns/query.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -700,6 +701,9 @@ query_reset(ns_client_t *client, isc_boolean_t everything) { client->query.isreferral = ISC_FALSE; client->query.dns64_options = 0; client->query.dns64_ttl = ISC_UINT32_MAX; + client->query.root_key_sentinel_keyid = 0; + client->query.root_key_sentinel_is_ta = ISC_FALSE; + client->query.root_key_sentinel_not_ta = ISC_FALSE; } static void @@ -5118,6 +5122,68 @@ query_setup(ns_client_t *client, dns_rdatatype_t qtype) { return (ns__query_start(&qctx)); } +static isc_boolean_t +get_root_key_sentinel_id(query_ctx_t *qctx, const char *ndata) { + unsigned int v = 0; + int i; + + for (i = 0; i < 5; i++) { + if (ndata[i] < '0' || ndata[i] > '9') { + return (ISC_FALSE); + } + v *= 10; + v += ndata[i] - '0'; + } + if (v > 65535U) { + return (ISC_FALSE); + } + qctx->client->query.root_key_sentinel_keyid = v; + return (ISC_TRUE); +} + +/*% + * Find out if the query is for a root key sentinel and if so, record the type + * of root key sentinel query and the key id that is being checked for. + * + * The code is assuming a zero padded decimal field of width 5. + */ +static void +root_key_sentinel_detect(query_ctx_t *qctx) { + const char *ndata = (const char *)qctx->client->query.qname->ndata; + + if (qctx->client->query.qname->length > 30 && ndata[0] == 29 && + strncasecmp(ndata + 1, "root-key-sentinel-is-ta-", 24) == 0) + { + if (!get_root_key_sentinel_id(qctx, ndata + 25)) { + return; + } + qctx->client->query.root_key_sentinel_is_ta = ISC_TRUE; + /* + * Simplify processing by disabling agressive + * negative caching. + */ + qctx->findcoveringnsec = ISC_FALSE; + ns_client_log(qctx->client, NS_LOGCATEGORY_TAT, + NS_LOGMODULE_QUERY, ISC_LOG_INFO, + "root-key-sentinel-is-ta query label found"); + } else if (qctx->client->query.qname->length > 31 && ndata[0] == 30 && + strncasecmp(ndata + 1, "root-key-sentinel-not-ta-", 25) == 0) + { + if (!get_root_key_sentinel_id(qctx, ndata + 26)) { + return; + } + qctx->client->query.root_key_sentinel_not_ta = ISC_TRUE; + /* + * Simplify processing by disabling agressive + * negative caching. + */ + qctx->findcoveringnsec = ISC_FALSE; + ns_client_log(qctx->client, NS_LOGCATEGORY_TAT, + NS_LOGMODULE_QUERY, ISC_LOG_INFO, + "root-key-sentinel-not-ta query label found"); + } +} + /*% * Starting point for a client query or a chaining query. * @@ -5158,6 +5224,18 @@ ns__query_start(query_ctx_t *qctx) { return (query_done(qctx)); } + /* + * Setup for root key sentinel processing. + */ + if (qctx->client->view->root_key_sentinel && + qctx->client->query.restarts == 0 && + (qctx->qtype == dns_rdatatype_a || + qctx->qtype == dns_rdatatype_aaaa) && + (qctx->client->message->flags & DNS_MESSAGEFLAG_CD) == 0) + { + root_key_sentinel_detect(qctx); + } + /* * First we must find the right database. */ @@ -6339,6 +6417,91 @@ query_rpzcname(query_ctx_t *qctx, dns_name_t *cname) { return (ISC_R_SUCCESS); } +/*% + * Check the configured trust anchors for a root zone trust anchor + * with a key id that matches qctx->client->query.root_key_sentinel_keyid. + * + * Return ISC_TRUE when found, otherwise return ISC_FALSE. + */ +static isc_boolean_t +has_ta(query_ctx_t *qctx) { + dns_keytable_t *keytable = NULL; + dns_keynode_t *keynode = NULL; + isc_result_t result; + + result = dns_view_getsecroots(qctx->client->view, &keytable); + if (result != ISC_R_SUCCESS) { + return (ISC_FALSE); + } + + result = dns_keytable_find(keytable, dns_rootname, &keynode); + while (result == ISC_R_SUCCESS) { + dns_keynode_t *nextnode = NULL; + dns_keytag_t keyid = dst_key_id(dns_keynode_key(keynode)); + if (keyid == qctx->client->query.root_key_sentinel_keyid) { + dns_keytable_detachkeynode(keytable, &keynode); + dns_keytable_detach(&keytable); + return (ISC_TRUE); + } + result = dns_keytable_nextkeynode(keytable, keynode, &nextnode); + dns_keytable_detachkeynode(keytable, &keynode); + keynode = nextnode; + } + dns_keytable_detach(&keytable); + + return (ISC_FALSE); +} + +/*% + * Check if a root key sentinel SERVFAIL should be returned. + */ +static isc_boolean_t +root_key_sentinel_return_servfail(query_ctx_t *qctx, isc_result_t result) { + /* + * Are we looking at a "root-key-sentinel" query? + */ + if (!qctx->client->query.root_key_sentinel_is_ta && + !qctx->client->query.root_key_sentinel_not_ta) + { + return (ISC_FALSE); + } + + /* + * We only care about the query if 'result' indicates we have a cached + * answer. + */ + switch (result) { + case ISC_R_SUCCESS: + case DNS_R_CNAME: + case DNS_R_DNAME: + case DNS_R_NCACHENXDOMAIN: + case DNS_R_NCACHENXRRSET: + break; + default: + return (ISC_FALSE); + } + + /* + * Do we meet the specified conditions to return SERVFAIL? + */ + if (!qctx->is_zone && + qctx->rdataset->trust == dns_trust_secure && + ((qctx->client->query.root_key_sentinel_is_ta && !has_ta(qctx)) || + (qctx->client->query.root_key_sentinel_not_ta && has_ta(qctx)))) + { + return (ISC_TRUE); + } + + /* + * As special processing may only be triggered by the original QNAME, + * disable it after following a CNAME/DNAME. + */ + qctx->client->query.root_key_sentinel_is_ta = ISC_FALSE; + qctx->client->query.root_key_sentinel_not_ta = ISC_FALSE; + + return (ISC_FALSE); +} + /*% * Continue after doing a database lookup or returning from * recursion, and call out to the next function depending on the @@ -6362,6 +6525,19 @@ query_gotanswer(query_ctx_t *qctx, isc_result_t result) { return (query_done(qctx)); } + /* + * If required, handle special "root-key-sentinel-is-ta-" and + * "root-key-sentinel-not-ta-" labels by returning SERVFAIL. + */ + if (root_key_sentinel_return_servfail(qctx, result)) { + /* + * Don't record this response in the SERVFAIL cache. + */ + qctx->client->attributes |= NS_CLIENTATTR_NOSETFC; + QUERY_ERROR(qctx, DNS_R_SERVFAIL); + return (query_done(qctx)); + } + switch (result) { case ISC_R_SUCCESS: return (query_prepresponse(qctx)); @@ -10855,7 +11031,7 @@ ns_query_start(ns_client_t *client) { client->query.attributes &= ~NS_QUERYATTR_SECURE; /* - * Set NS_CLIENTATTR_WANTDNSSEC if the client has set AD in the query. + * Set NS_CLIENTATTR_WANTAD if the client has set AD in the query. * This allows AD to be returned on queries without DO set. */ if ((message->flags & DNS_MESSAGEFLAG_AD) != 0) diff --git a/util/copyrights b/util/copyrights index 3793322183..70aa766f46 100644 --- a/util/copyrights +++ b/util/copyrights @@ -1821,6 +1821,19 @@ ./bin/tests/system/rndc/ns6/named.conf.in CONF-C 2016,2018 ./bin/tests/system/rndc/setup.sh SH 2011,2012,2013,2014,2016,2017,2018 ./bin/tests/system/rndc/tests.sh SH 2011,2012,2013,2014,2015,2016,2017,2018 +./bin/tests/system/rootkeysentinel/clean.sh SH 2018 +./bin/tests/system/rootkeysentinel/ns1/named.conf.in CONF-C 2018 +./bin/tests/system/rootkeysentinel/ns1/root.db.in ZONE 2018 +./bin/tests/system/rootkeysentinel/ns1/sign.sh SH 2018 +./bin/tests/system/rootkeysentinel/ns2/example.db.in ZONE 2018 +./bin/tests/system/rootkeysentinel/ns2/named.conf.in CONF-C 2018 +./bin/tests/system/rootkeysentinel/ns2/sign.sh SH 2018 +./bin/tests/system/rootkeysentinel/ns3/hint.db ZONE 2018 +./bin/tests/system/rootkeysentinel/ns3/named.conf.in CONF-C 2018 +./bin/tests/system/rootkeysentinel/ns4/hint.db ZONE 2018 +./bin/tests/system/rootkeysentinel/ns4/named.conf.in CONF-C 2018 +./bin/tests/system/rootkeysentinel/setup.sh SH 2018 +./bin/tests/system/rootkeysentinel/tests.sh SH 2018 ./bin/tests/system/rpz/.gitignore X 2017,2018 ./bin/tests/system/rpz/Makefile.in MAKE 2017,2018 ./bin/tests/system/rpz/ckdnsrps.sh SH 2017,2018