Home | History | Annotate | Line # | Download | only in dnssec
tests.sh revision 1.1.1.7
      1 #!/bin/sh
      2 #
      3 # Copyright (C) Internet Systems Consortium, Inc. ("ISC")
      4 #
      5 # This Source Code Form is subject to the terms of the Mozilla Public
      6 # License, v. 2.0. If a copy of the MPL was not distributed with this
      7 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
      8 #
      9 # See the COPYRIGHT file distributed with this work for additional
     10 # information regarding copyright ownership.
     11 
     12 # shellcheck source=conf.sh
     13 SYSTEMTESTTOP=..
     14 . "$SYSTEMTESTTOP/conf.sh"
     15 
     16 set -e
     17 
     18 status=0
     19 n=1
     20 
     21 rm -f dig.out.*
     22 
     23 dig_with_opts() {
     24     "$DIG" +tcp +noadd +nosea +nostat +nocmd +dnssec -p "$PORT" "$@"
     25 }
     26 
     27 dig_with_additionalopts() {
     28     "$DIG" +noall +additional +dnssec -p "$PORT" "$@"
     29 }
     30 
     31 dig_with_answeropts() {
     32     "$DIG" +noall +answer +dnssec -p "$PORT" "$@"
     33 }
     34 
     35 delv_with_opts() {
     36     "$DELV" -a ns1/trusted.conf -p "$PORT" "$@"
     37 }
     38 
     39 rndccmd() {
     40     "$RNDC" -c "$SYSTEMTESTTOP/common/rndc.conf" -p "$CONTROLPORT" -s "$@"
     41 }
     42 
     43 # TODO: Move loadkeys_on to conf.sh.common
     44 dnssec_loadkeys_on() {
     45 	nsidx=$1
     46 	zone=$2
     47 	nextpart ns${nsidx}/named.run > /dev/null
     48 	rndccmd 10.53.0.${nsidx} loadkeys ${zone} | sed "s/^/ns${nsidx} /" | cat_i
     49 	wait_for_log 20 "next key event" ns${nsidx}/named.run || return 1
     50 }
     51 
     52 # convert private-type records to readable form
     53 showprivate () {
     54     echo "-- $* --"
     55     dig_with_opts +nodnssec +short "@$2" -t type65534 "$1" | cut -f3 -d' ' |
     56         while read -r record; do
     57 	    # shellcheck disable=SC2016
     58             $PERL -e 'my $rdata = pack("H*", @ARGV[0]);
     59                 die "invalid record" unless length($rdata) == 5;
     60                 my ($alg, $key, $remove, $complete) = unpack("CnCC", $rdata);
     61                 my $action = "signing";
     62                 $action = "removing" if $remove;
     63                 my $state = " (incomplete)";
     64                 $state = " (complete)" if $complete;
     65                 print ("$action: alg: $alg, key: $key$state\n");' "$record"
     66         done
     67 }
     68 
     69 # check that signing records are marked as complete
     70 checkprivate () {
     71     for i in 1 2 3 4 5 6 7 8 9 10; do
     72         showprivate "$@" | grep -q incomplete || return 0
     73 	sleep 1
     74     done
     75     echo_d "$1 signing incomplete"
     76     return 1
     77 }
     78 
     79 # check that a zone file is raw format, version 0
     80 israw0 () {
     81     # shellcheck disable=SC2016
     82     < "$1" $PERL -e 'binmode STDIN;
     83 	             read(STDIN, $input, 8);
     84 	             ($style, $version) = unpack("NN", $input);
     85 	             exit 1 if ($style != 2 || $version != 0);'
     86     return $?
     87 }
     88 
     89 # check that a zone file is raw format, version 1
     90 israw1 () {
     91     # shellcheck disable=SC2016
     92     < "$1" $PERL -e 'binmode STDIN;
     93 		     read(STDIN, $input, 8);
     94                      ($style, $version) = unpack("NN", $input);
     95                      exit 1 if ($style != 2 || $version != 1);'
     96     return $?
     97 }
     98 
     99 # strip NS and RRSIG NS from input
    100 stripns () {
    101     awk '($4 == "NS") || ($4 == "RRSIG" && $5 == "NS") { next} { print }' "$1"
    102 }
    103 
    104 #
    105 # Ensure there is not multiple consecutive blank lines.
    106 # Ensure there is a blank line before "Start view" and
    107 # "Negative trust anchors:".
    108 # Ensure there is not a blank line before "Secure roots:".
    109 #
    110 check_secroots_layout () {
    111 	tr -d '\r' < "$1" | \
    112 	awk '$0 == "" { if (empty) exit(1); empty=1; next }
    113 	     /Start view/ { if (!empty) exit(1) }
    114 	     /Secure roots:/ { if (empty) exit(1) }
    115 	     /Negative trust anchors:/ { if (!empty) exit(1) }
    116 	     { empty=0 }'
    117 	return $?
    118 }
    119 
    120 # Check that for a query against a validating resolver where the
    121 # authoritative zone is unsigned (insecure delegation), glue is returned
    122 # in the additional section
    123 echo_i "checking that additional glue is returned for unsigned delegation ($n)"
    124 ret=0
    125 $DIG +tcp +dnssec -p "$PORT" a.insecure.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1
    126 grep "ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 2" dig.out.ns4.test$n > /dev/null || ret=1
    127 grep "ns\\.insecure\\.example\\..*A.10\\.53\\.0\\.3" dig.out.ns4.test$n > /dev/null || ret=1
    128 n=$((n+1))
    129 if [ "$ret" -ne 0 ]; then echo_i "failed"; fi
    130 status=$((status+ret))
    131 
    132 # Check the example. domain
    133 
    134 echo_i "checking that zone transfer worked ($n)"
    135 for i in 1 2 3 4 5 6 7 8 9
    136 do
    137 	ret=0
    138 	dig_with_opts a.example. @10.53.0.2 a > dig.out.ns2.test$n || ret=1
    139 	dig_with_opts a.example. @10.53.0.3 a > dig.out.ns3.test$n || ret=1
    140 	$PERL ../digcomp.pl dig.out.ns2.test$n dig.out.ns3.test$n > /dev/null || ret=1
    141 	[ "$ret" -eq 0 ] && break
    142 	sleep 1
    143 done
    144 digcomp dig.out.ns2.test$n dig.out.ns3.test$n > /dev/null || ret=1
    145 n=$((n+1))
    146 test "$ret" -eq 0 || echo_i "failed"
    147 status=$((status+ret))
    148 
    149 # test AD bit:
    150 #  - dig +adflag asks for authentication (ad in response)
    151 echo_i "checking AD bit asking for validation ($n)"
    152 ret=0
    153 dig_with_opts +noauth +noadd +nodnssec +adflag a.example. @10.53.0.2 a > dig.out.ns2.test$n || ret=1
    154 dig_with_opts +noauth +noadd +nodnssec +adflag a.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1
    155 digcomp dig.out.ns2.test$n dig.out.ns4.test$n || ret=1
    156 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
    157 n=$((n+1))
    158 test "$ret" -eq 0 || echo_i "failed"
    159 status=$((status+ret))
    160 
    161 # test AD bit:
    162 #  - dig +noadflag
    163 echo_i "checking that AD is not set without +adflag or +dnssec ($n)"
    164 ret=0
    165 dig_with_opts +noauth +noadd +nodnssec +noadflag a.example. @10.53.0.2 a > dig.out.ns2.test$n || ret=1
    166 dig_with_opts +noauth +noadd +nodnssec +noadflag a.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1
    167 digcomp dig.out.ns2.test$n dig.out.ns4.test$n || ret=1
    168 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1
    169 n=$((n+1))
    170 test "$ret" -eq 0 || echo_i "failed"
    171 status=$((status+ret))
    172 
    173 echo_i "checking for AD in authoritative answer ($n)"
    174 ret=0
    175 dig_with_opts a.example. @10.53.0.2 a > dig.out.ns2.test$n || ret=1
    176 grep "flags:.*ad.*QUERY" dig.out.ns2.test$n > /dev/null && ret=1
    177 n=$((n+1))
    178 test "$ret" -eq 0 || echo_i "failed"
    179 status=$((status+ret))
    180 
    181 echo_i "checking positive validation NSEC ($n)"
    182 ret=0
    183 dig_with_opts +noauth a.example. @10.53.0.2 a > dig.out.ns2.test$n || ret=1
    184 dig_with_opts +noauth a.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1
    185 digcomp dig.out.ns2.test$n dig.out.ns4.test$n || ret=1
    186 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
    187 n=$((n+1))
    188 test "$ret" -eq 0 || echo_i "failed"
    189 status=$((status+ret))
    190 
    191 echo_i "checking that 'example/DS' from the referral was used in previous validation ($n)"
    192 ret=0
    193 grep "query 'example/DS/IN' approved" ns1/named.run > /dev/null && ret=1
    194 grep "fetch: example/DS" ns4/named.run > /dev/null && ret=1
    195 grep "validating example/DS: starting" ns4/named.run > /dev/null || ret=1
    196 n=$((n+1))
    197 test "$ret" -eq 0 || echo_i "failed"
    198 status=$((status+ret))
    199 
    200 if [ -x ${DELV} ] ; then
    201    ret=0
    202    echo_i "checking positive validation NSEC using dns_client ($n)"
    203    delv_with_opts @10.53.0.4 a a.example > delv.out$n || ret=1
    204    grep "a.example..*10.0.0.1" delv.out$n > /dev/null || ret=1
    205    grep "a.example..*.RRSIG.A [0-9][0-9]* 2 300 .*" delv.out$n > /dev/null || ret=1
    206    n=$((n+1))
    207    test "$ret" -eq 0 || echo_i "failed"
    208    status=$((status+ret))
    209 fi
    210 
    211 echo_i "checking positive validation NSEC3 ($n)"
    212 ret=0
    213 dig_with_opts +noauth a.nsec3.example. \
    214 	@10.53.0.3 a > dig.out.ns3.test$n || ret=1
    215 dig_with_opts +noauth a.nsec3.example. \
    216 	@10.53.0.4 a > dig.out.ns4.test$n || ret=1
    217 digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
    218 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
    219 n=$((n+1))
    220 test "$ret" -eq 0 || echo_i "failed"
    221 status=$((status+ret))
    222 
    223 if [ -x ${DELV} ] ; then
    224    ret=0
    225    echo_i "checking positive validation NSEC3 using dns_client ($n)"
    226    delv_with_opts @10.53.0.4 a a.nsec3.example > delv.out$n || ret=1
    227    grep "a.nsec3.example..*10.0.0.1" delv.out$n > /dev/null || ret=1
    228    grep "a.nsec3.example..*RRSIG.A [0-9][0-9]* 3 300.*" delv.out$n > /dev/null || ret=1
    229    n=$((n+1))
    230    test "$ret" -eq 0 || echo_i "failed"
    231    status=$((status+ret))
    232 fi
    233 
    234 echo_i "checking positive validation OPTOUT ($n)"
    235 ret=0
    236 dig_with_opts +noauth a.optout.example. \
    237 	@10.53.0.3 a > dig.out.ns3.test$n || ret=1
    238 dig_with_opts +noauth a.optout.example. \
    239 	@10.53.0.4 a > dig.out.ns4.test$n || ret=1
    240 digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
    241 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
    242 n=$((n+1))
    243 test "$ret" -eq 0 || echo_i "failed"
    244 status=$((status+ret))
    245 
    246 SP="[[:space:]]+"
    247 
    248 if [ -x ${DELV} ] ; then
    249    ret=0
    250    echo_i "checking positive validation OPTOUT using dns_client ($n)"
    251    delv_with_opts @10.53.0.4 a a.optout.example > delv.out$n || ret=1
    252    grep -Eq "^a\\.optout\\.example\\.""$SP""[0-9]+""$SP""IN""$SP""A""$SP""10.0.0.1" delv.out$n || ret=1
    253    grep -Eq "^a\\.optout\\.example\\.""$SP""[0-9]+""$SP""IN""$SP""RRSIG""$SP""A""$SP""$DEFAULT_ALGORITHM_NUMBER""$SP""3""$SP""300" delv.out$n || ret=1
    254    n=$((n+1))
    255    test "$ret" -eq 0 || echo_i "failed"
    256    status=$((status+ret))
    257 fi
    258 
    259 echo_i "checking positive wildcard validation NSEC ($n)"
    260 ret=0
    261 dig_with_opts a.wild.example. @10.53.0.3 a > dig.out.ns3.test$n || ret=1
    262 dig_with_opts a.wild.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1
    263 stripns dig.out.ns3.test$n > dig.out.ns3.stripped.test$n
    264 stripns dig.out.ns4.test$n > dig.out.ns4.stripped.test$n
    265 digcomp dig.out.ns3.stripped.test$n dig.out.ns4.stripped.test$n || ret=1
    266 grep "\\*\\.wild\\.example\\..*RRSIG	NSEC" dig.out.ns4.test$n > /dev/null || ret=1
    267 grep "\\*\\.wild\\.example\\..*NSEC	z\\.example" dig.out.ns4.test$n > /dev/null || ret=1
    268 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
    269 grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
    270 n=$((n+1))
    271 test "$ret" -eq 0 || echo_i "failed"
    272 status=$((status+ret))
    273 
    274 if [ -x ${DELV} ] ; then
    275    ret=0
    276    echo_i "checking positive wildcard validation NSEC using dns_client ($n)"
    277    delv_with_opts @10.53.0.4 a a.wild.example > delv.out$n || ret=1
    278    grep "a.wild.example..*10.0.0.27" delv.out$n > /dev/null || ret=1
    279    grep -E "a.wild.example..*RRSIG.A [0-9]+ 2 300.*" delv.out$n > /dev/null || ret=1
    280    n=$((n+1))
    281    test "$ret" -eq 0 || echo_i "failed"
    282    status=$((status+ret))
    283 fi
    284 
    285 echo_i "checking positive wildcard answer NSEC3 ($n)"
    286 ret=0
    287 dig_with_opts a.wild.nsec3.example. @10.53.0.3 a > dig.out.ns3.test$n || ret=1
    288 grep "AUTHORITY: 4," dig.out.ns3.test$n > /dev/null || ret=1
    289 grep "status: NOERROR" dig.out.ns3.test$n > /dev/null || ret=1
    290 n=$((n+1))
    291 test "$ret" -eq 0 || echo_i "failed"
    292 status=$((status+ret))
    293 
    294 echo_i "checking positive wildcard answer NSEC3 ($n)"
    295 ret=0
    296 dig_with_opts a.wild.nsec3.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1
    297 grep "AUTHORITY: 4," dig.out.ns4.test$n > /dev/null || ret=1
    298 grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
    299 n=$((n+1))
    300 test "$ret" -eq 0 || echo_i "failed"
    301 status=$((status+ret))
    302 
    303 echo_i "checking positive wildcard validation NSEC3 ($n)"
    304 ret=0
    305 dig_with_opts a.wild.nsec3.example. @10.53.0.3 a > dig.out.ns3.test$n || ret=1
    306 dig_with_opts a.wild.nsec3.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1
    307 stripns dig.out.ns3.test$n > dig.out.ns3.stripped.test$n
    308 stripns dig.out.ns4.test$n > dig.out.ns4.stripped.test$n
    309 digcomp dig.out.ns3.stripped.test$n dig.out.ns4.stripped.test$n || ret=1
    310 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
    311 grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
    312 n=$((n+1))
    313 test "$ret" -eq 0 || echo_i "failed"
    314 status=$((status+ret))
    315 
    316 if [ -x ${DELV} ] ; then
    317    ret=0
    318    echo_i "checking positive wildcard validation NSEC3 using dns_client ($n)"
    319    delv_with_opts @10.53.0.4 a a.wild.nsec3.example > delv.out$n || ret=1
    320    grep -E "a.wild.nsec3.example..*10.0.0.6" delv.out$n > /dev/null || ret=1
    321    grep -E "a.wild.nsec3.example..*RRSIG.A [0-9][0-9]* 3 300.*" delv.out$n > /dev/null || ret=1
    322    n=$((n+1))
    323    test "$ret" -eq 0 || echo_i "failed"
    324    status=$((status+ret))
    325 fi
    326 
    327 echo_i "checking positive wildcard validation OPTOUT ($n)"
    328 ret=0
    329 dig_with_opts a.wild.optout.example. \
    330 	@10.53.0.3 a > dig.out.ns3.test$n || ret=1
    331 dig_with_opts a.wild.optout.example. \
    332 	@10.53.0.4 a > dig.out.ns4.test$n || ret=1
    333 stripns dig.out.ns3.test$n > dig.out.ns3.stripped.test$n
    334 stripns dig.out.ns4.test$n > dig.out.ns4.stripped.test$n
    335 digcomp dig.out.ns3.stripped.test$n dig.out.ns4.stripped.test$n || ret=1
    336 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1
    337 grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
    338 n=$((n+1))
    339 test "$ret" -eq 0 || echo_i "failed"
    340 status=$((status+ret))
    341 
    342 if [ -x ${DELV} ] ; then
    343    ret=0
    344    echo_i "checking positive wildcard validation OPTOUT using dns_client ($n)"
    345    delv_with_opts @10.53.0.4 a a.wild.optout.example > delv.out$n || ret=1
    346    grep "a.wild.optout.example..*10.0.0.6" delv.out$n > /dev/null || ret=1
    347    grep "a.wild.optout.example..*RRSIG.A [0-9][0-9]* 3 300.*" delv.out$n > /dev/null || ret=1
    348    n=$((n+1))
    349    test "$ret" -eq 0 || echo_i "failed"
    350    status=$((status+ret))
    351 fi
    352 
    353 echo_i "checking negative validation NXDOMAIN NSEC ($n)"
    354 ret=0
    355 dig_with_opts +noauth q.example. @10.53.0.2 a > dig.out.ns2.test$n || ret=1
    356 dig_with_opts +noauth q.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1
    357 digcomp dig.out.ns2.test$n dig.out.ns4.test$n || ret=1
    358 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
    359 grep "status: NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1
    360 n=$((n+1))
    361 test "$ret" -eq 0 || echo_i "failed"
    362 status=$((status+ret))
    363 
    364 if [ -x ${DELV} ] ; then
    365    ret=0
    366    echo_i "checking negative validation NXDOMAIN NSEC using dns_client ($n)"
    367    delv_with_opts @10.53.0.4 a q.example > delv.out$n 2>&1 || ret=1
    368    grep "resolution failed: ncache nxdomain" delv.out$n > /dev/null || ret=1
    369    n=$((n+1))
    370    test "$ret" -eq 0 || echo_i "failed"
    371    status=$((status+ret))
    372 fi
    373 
    374 echo_i "checking negative validation NXDOMAIN NSEC3 ($n)"
    375 ret=0
    376 dig_with_opts +noauth q.nsec3.example. \
    377 	@10.53.0.3 a > dig.out.ns3.test$n || ret=1
    378 dig_with_opts +noauth q.nsec3.example. \
    379 	@10.53.0.4 a > dig.out.ns4.test$n || ret=1
    380 digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
    381 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
    382 grep "status: NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1
    383 n=$((n+1))
    384 test "$ret" -eq 0 || echo_i "failed"
    385 status=$((status+ret))
    386 
    387 if [ -x ${DELV} ] ; then
    388    ret=0
    389    echo_i "checking negative validation NXDOMAIN NSEC3 using dns_client ($n)"
    390    delv_with_opts @10.53.0.4 a q.nsec3.example > delv.out$n 2>&1 || ret=1
    391    grep "resolution failed: ncache nxdomain" delv.out$n > /dev/null || ret=1
    392    n=$((n+1))
    393    test "$ret" -eq 0 || echo_i "failed"
    394    status=$((status+ret))
    395 fi
    396 
    397 echo_i "checking negative validation NXDOMAIN OPTOUT ($n)"
    398 ret=0
    399 dig_with_opts +noauth q.optout.example. \
    400 	@10.53.0.3 a > dig.out.ns3.test$n || ret=1
    401 dig_with_opts +noauth q.optout.example. \
    402 	@10.53.0.4 a > dig.out.ns4.test$n || ret=1
    403 digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
    404 grep "status: NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1
    405 # Note - this is looking for failure, hence the &&
    406 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1
    407 n=$((n+1))
    408 test "$ret" -eq 0 || echo_i "failed"
    409 status=$((status+ret))
    410 
    411 if [ -x ${DELV} ] ; then
    412    ret=0
    413    echo_i "checking negative validation NXDOMAIN OPTOUT using dns_client ($n)"
    414    delv_with_opts @10.53.0.4 a q.optout.example > delv.out$n 2>&1 || ret=1
    415    grep "resolution failed: ncache nxdomain" delv.out$n > /dev/null || ret=1
    416    n=$((n+1))
    417    test "$ret" -eq 0 || echo_i "failed"
    418    status=$((status+ret))
    419 fi
    420 
    421 echo_i "checking negative validation NODATA NSEC ($n)"
    422 ret=0
    423 dig_with_opts +noauth a.example. @10.53.0.2 txt > dig.out.ns2.test$n || ret=1
    424 dig_with_opts +noauth a.example. @10.53.0.4 txt > dig.out.ns4.test$n || ret=1
    425 digcomp dig.out.ns2.test$n dig.out.ns4.test$n || ret=1
    426 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
    427 grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
    428 grep "ANSWER: 0" dig.out.ns4.test$n > /dev/null || ret=1
    429 n=$((n+1))
    430 test "$ret" -eq 0 || echo_i "failed"
    431 status=$((status+ret))
    432 
    433 if [ -x ${DELV} ] ; then
    434    ret=0
    435    echo_i "checking negative validation NODATA OPTOUT using dns_client ($n)"
    436    delv_with_opts @10.53.0.4 txt a.example > delv.out$n 2>&1 || ret=1
    437    grep "resolution failed: ncache nxrrset" delv.out$n > /dev/null || ret=1
    438    n=$((n+1))
    439    test "$ret" -eq 0 || echo_i "failed"
    440    status=$((status+ret))
    441 fi
    442 
    443 echo_i "checking negative validation NODATA NSEC3 ($n)"
    444 ret=0
    445 dig_with_opts +noauth a.nsec3.example. \
    446 	@10.53.0.3 txt > dig.out.ns3.test$n || ret=1
    447 dig_with_opts +noauth a.nsec3.example. \
    448 	@10.53.0.4 txt > dig.out.ns4.test$n || ret=1
    449 digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
    450 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
    451 grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
    452 grep "ANSWER: 0" dig.out.ns4.test$n > /dev/null || ret=1
    453 n=$((n+1))
    454 test "$ret" -eq 0 || echo_i "failed"
    455 status=$((status+ret))
    456 
    457 if [ -x ${DELV} ] ; then
    458    ret=0
    459    echo_i "checking negative validation NODATA NSEC3 using dns_client ($n)"
    460    delv_with_opts @10.53.0.4 txt a.nsec3.example > delv.out$n 2>&1 || ret=1
    461    grep "resolution failed: ncache nxrrset" delv.out$n > /dev/null || ret=1
    462    n=$((n+1))
    463    test "$ret" -eq 0 || echo_i "failed"
    464    status=$((status+ret))
    465 fi
    466 
    467 echo_i "checking negative validation NODATA OPTOUT ($n)"
    468 ret=0
    469 dig_with_opts +noauth a.optout.example. \
    470 	@10.53.0.3 txt > dig.out.ns3.test$n || ret=1
    471 dig_with_opts +noauth a.optout.example. \
    472 	@10.53.0.4 txt > dig.out.ns4.test$n || ret=1
    473 digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
    474 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
    475 grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
    476 grep "ANSWER: 0" dig.out.ns4.test$n > /dev/null || ret=1
    477 n=$((n+1))
    478 test "$ret" -eq 0 || echo_i "failed"
    479 status=$((status+ret))
    480 
    481 if [ -x ${DELV} ] ; then
    482    ret=0
    483    echo_i "checking negative validation NODATA OPTOUT using dns_client ($n)"
    484    delv_with_opts @10.53.0.4 txt a.optout.example > delv.out$n 2>&1 || ret=1
    485    grep "resolution failed: ncache nxrrset" delv.out$n > /dev/null || ret=1
    486    n=$((n+1))
    487    test "$ret" -eq 0 || echo_i "failed"
    488    status=$((status+ret))
    489 fi
    490 
    491 echo_i "checking negative wildcard validation NSEC ($n)"
    492 ret=0
    493 dig_with_opts b.wild.example. @10.53.0.2 txt > dig.out.ns2.test$n || ret=1
    494 dig_with_opts b.wild.example. @10.53.0.4 txt > dig.out.ns4.test$n || ret=1
    495 digcomp dig.out.ns2.test$n dig.out.ns4.test$n || ret=1
    496 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
    497 grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
    498 n=$((n+1))
    499 test "$ret" -eq 0 || echo_i "failed"
    500 status=$((status+ret))
    501 
    502 if [ -x ${DELV} ] ; then
    503    ret=0
    504    echo_i "checking negative wildcard validation NSEC using dns_client ($n)"
    505    delv_with_opts @10.53.0.4 txt b.wild.example > delv.out$n 2>&1 || ret=1
    506    grep "resolution failed: ncache nxrrset" delv.out$n > /dev/null || ret=1
    507    n=$((n+1))
    508    test "$ret" -eq 0 || echo_i "failed"
    509    status=$((status+ret))
    510 fi
    511 
    512 echo_i "checking negative wildcard validation NSEC3 ($n)"
    513 ret=0
    514 dig_with_opts b.wild.nsec3.example. @10.53.0.3 txt > dig.out.ns3.test$n || ret=1
    515 dig_with_opts b.wild.nsec3.example. @10.53.0.4 txt > dig.out.ns4.test$n || ret=1
    516 digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
    517 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
    518 n=$((n+1))
    519 test "$ret" -eq 0 || echo_i "failed"
    520 status=$((status+ret))
    521 
    522 if [ -x ${DELV} ] ; then
    523    ret=0
    524    echo_i "checking negative wildcard validation NSEC3 using dns_client ($n)"
    525    delv_with_opts @10.53.0.4 txt b.wild.nsec3.example > delv.out$n 2>&1 || ret=1
    526    grep "resolution failed: ncache nxrrset" delv.out$n > /dev/null || ret=1
    527    n=$((n+1))
    528    test "$ret" -eq 0 || echo_i "failed"
    529    status=$((status+ret))
    530 fi
    531 
    532 echo_i "checking negative wildcard validation OPTOUT ($n)"
    533 ret=0
    534 dig_with_opts b.wild.optout.example. \
    535 	@10.53.0.3 txt > dig.out.ns3.test$n || ret=1
    536 dig_with_opts b.wild.optout.example. \
    537 	@10.53.0.4 txt > dig.out.ns4.test$n || ret=1
    538 digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
    539 grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
    540 # Note - this is looking for failure, hence the &&
    541 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1
    542 n=$((n+1))
    543 test "$ret" -eq 0 || echo_i "failed"
    544 status=$((status+ret))
    545 
    546 if [ -x ${DELV} ] ; then
    547    ret=0
    548    echo_i "checking negative wildcard validation OPTOUT using dns_client ($n)"
    549    delv_with_opts @10.53.0.4 txt b.optout.nsec3.example > delv.out$n 2>&1 || ret=1
    550    grep "resolution failed: ncache nxrrset" delv.out$n > /dev/null || ret=1
    551    n=$((n+1))
    552    test "$ret" -eq 0 || echo_i "failed"
    553    status=$((status+ret))
    554 fi
    555 
    556 # Check the insecure.example domain
    557 
    558 echo_i "checking 1-server insecurity proof NSEC ($n)"
    559 ret=0
    560 dig_with_opts +noauth a.insecure.example. @10.53.0.3 a > dig.out.ns3.test$n || ret=1
    561 dig_with_opts +noauth a.insecure.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1
    562 digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
    563 grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
    564 # Note - this is looking for failure, hence the &&
    565 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1
    566 n=$((n+1))
    567 test "$ret" -eq 0 || echo_i "failed"
    568 status=$((status+ret))
    569 
    570 if [ -x ${DELV} ] ; then
    571    ret=0
    572    echo_i "checking 1-server insecurity proof NSEC using dns_client ($n)"
    573    delv_with_opts @10.53.0.4 a a.insecure.example > delv.out$n || ret=1
    574    grep "a.insecure.example..*10.0.0.1" delv.out$n > /dev/null || ret=1
    575    n=$((n+1))
    576    test "$ret" -eq 0 || echo_i "failed"
    577    status=$((status+ret))
    578 fi
    579 
    580 echo_i "checking 1-server insecurity proof NSEC3 ($n)"
    581 ret=0
    582 dig_with_opts +noauth a.insecure.nsec3.example. @10.53.0.3 a > dig.out.ns3.test$n || ret=1
    583 dig_with_opts +noauth a.insecure.nsec3.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1
    584 digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
    585 grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
    586 # Note - this is looking for failure, hence the &&
    587 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1
    588 n=$((n+1))
    589 test "$ret" -eq 0 || echo_i "failed"
    590 status=$((status+ret))
    591 
    592 if [ -x ${DELV} ] ; then
    593    ret=0
    594    echo_i "checking 1-server insecurity proof NSEC3 using dns_client ($n)"
    595    delv_with_opts @10.53.0.4 a a.insecure.nsec3.example > delv.out$n || ret=1
    596    grep "a.insecure.nsec3.example..*10.0.0.1" delv.out$n > /dev/null || ret=1
    597    n=$((n+1))
    598    test "$ret" -eq 0 || echo_i "failed"
    599    status=$((status+ret))
    600 fi
    601 
    602 echo_i "checking 1-server insecurity proof OPTOUT ($n)"
    603 ret=0
    604 dig_with_opts +noauth a.insecure.optout.example. @10.53.0.3 a > dig.out.ns3.test$n || ret=1
    605 dig_with_opts +noauth a.insecure.optout.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1
    606 digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
    607 grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
    608 # Note - this is looking for failure, hence the &&
    609 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1
    610 n=$((n+1))
    611 test "$ret" -eq 0 || echo_i "failed"
    612 status=$((status+ret))
    613 
    614 if [ -x ${DELV} ] ; then
    615    ret=0
    616    echo_i "checking 1-server insecurity proof OPTOUT using dns_client ($n)"
    617    delv_with_opts @10.53.0.4 a a.insecure.optout.example > delv.out$n || ret=1
    618    grep "a.insecure.optout.example..*10.0.0.1" delv.out$n > /dev/null || ret=1
    619    n=$((n+1))
    620    test "$ret" -eq 0 || echo_i "failed"
    621    status=$((status+ret))
    622 fi
    623 
    624 echo_i "checking 1-server negative insecurity proof NSEC ($n)"
    625 ret=0
    626 dig_with_opts q.insecure.example. a @10.53.0.3 \
    627 	> dig.out.ns3.test$n || ret=1
    628 dig_with_opts q.insecure.example. a @10.53.0.4 \
    629 	> dig.out.ns4.test$n || ret=1
    630 digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
    631 grep "status: NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1
    632 # Note - this is looking for failure, hence the &&
    633 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1
    634 n=$((n+1))
    635 test "$ret" -eq 0 || echo_i "failed"
    636 status=$((status+ret))
    637 
    638 if [ -x ${DELV} ] ; then
    639    ret=0
    640    echo_i "checking 1-server negative insecurity proof NSEC using dns_client ($n)"
    641    delv_with_opts @10.53.0.4 a q.insecure.example > delv.out$n 2>&1 || ret=1
    642    grep "resolution failed: ncache nxdomain" delv.out$n > /dev/null || ret=1
    643    n=$((n+1))
    644    test "$ret" -eq 0 || echo_i "failed"
    645    status=$((status+ret))
    646 fi
    647 
    648 echo_i "checking 1-server negative insecurity proof NSEC3 ($n)"
    649 ret=0
    650 dig_with_opts q.insecure.nsec3.example. a @10.53.0.3 \
    651 	> dig.out.ns3.test$n || ret=1
    652 dig_with_opts q.insecure.nsec3.example. a @10.53.0.4 \
    653 	> dig.out.ns4.test$n || ret=1
    654 digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
    655 grep "status: NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1
    656 # Note - this is looking for failure, hence the &&
    657 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1
    658 n=$((n+1))
    659 test "$ret" -eq 0 || echo_i "failed"
    660 status=$((status+ret))
    661 
    662 if [ -x ${DELV} ] ; then
    663    ret=0
    664    echo_i "checking 1-server negative insecurity proof NSEC3 using dns_client ($n)"
    665    delv_with_opts @10.53.0.4 a q.insecure.nsec3.example > delv.out$n 2>&1 || ret=1
    666    grep "resolution failed: ncache nxdomain" delv.out$n > /dev/null || ret=1
    667    n=$((n+1))
    668    test "$ret" -eq 0 || echo_i "failed"
    669    status=$((status+ret))
    670 fi
    671 
    672 echo_i "checking 1-server negative insecurity proof OPTOUT ($n)"
    673 ret=0
    674 dig_with_opts q.insecure.optout.example. a @10.53.0.3 \
    675 	> dig.out.ns3.test$n || ret=1
    676 dig_with_opts q.insecure.optout.example. a @10.53.0.4 \
    677 	> dig.out.ns4.test$n || ret=1
    678 digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
    679 grep "status: NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1
    680 # Note - this is looking for failure, hence the &&
    681 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1
    682 n=$((n+1))
    683 test "$ret" -eq 0 || echo_i "failed"
    684 status=$((status+ret))
    685 
    686 if [ -x ${DELV} ] ; then
    687    ret=0
    688    echo_i "checking 1-server negative insecurity proof OPTOUT using dns_client ($n)"
    689    delv_with_opts @10.53.0.4 a q.insecure.optout.example > delv.out$n 2>&1 || ret=1
    690    grep "resolution failed: ncache nxdomain" delv.out$n > /dev/null || ret=1
    691    n=$((n+1))
    692    test "$ret" -eq 0 || echo_i "failed"
    693    status=$((status+ret))
    694 fi
    695 
    696 echo_i "checking 1-server negative insecurity proof with SOA hack NSEC ($n)"
    697 ret=0
    698 dig_with_opts r.insecure.example. soa @10.53.0.3 \
    699 	> dig.out.ns3.test$n || ret=1
    700 dig_with_opts r.insecure.example. soa @10.53.0.4 \
    701 	> dig.out.ns4.test$n || ret=1
    702 digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
    703 grep "status: NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1
    704 grep "0	IN	SOA" dig.out.ns4.test$n > /dev/null || ret=1
    705 # Note - this is looking for failure, hence the &&
    706 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1
    707 n=$((n+1))
    708 test "$ret" -eq 0 || echo_i "failed"
    709 status=$((status+ret))
    710 
    711 echo_i "checking 1-server negative insecurity proof with SOA hack NSEC3 ($n)"
    712 ret=0
    713 dig_with_opts r.insecure.nsec3.example. soa @10.53.0.3 \
    714 	> dig.out.ns3.test$n || ret=1
    715 dig_with_opts r.insecure.nsec3.example. soa @10.53.0.4 \
    716 	> dig.out.ns4.test$n || ret=1
    717 digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
    718 grep "status: NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1
    719 grep "0	IN	SOA" dig.out.ns4.test$n > /dev/null || ret=1
    720 # Note - this is looking for failure, hence the &&
    721 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1
    722 n=$((n+1))
    723 test "$ret" -eq 0 || echo_i "failed"
    724 status=$((status+ret))
    725 
    726 echo_i "checking 1-server negative insecurity proof with SOA hack OPTOUT ($n)"
    727 ret=0
    728 dig_with_opts r.insecure.optout.example. soa @10.53.0.3 \
    729 	> dig.out.ns3.test$n || ret=1
    730 dig_with_opts r.insecure.optout.example. soa @10.53.0.4 \
    731 	> dig.out.ns4.test$n || ret=1
    732 digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
    733 grep "status: NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1
    734 grep "0	IN	SOA" dig.out.ns4.test$n > /dev/null || ret=1
    735 # Note - this is looking for failure, hence the &&
    736 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1
    737 n=$((n+1))
    738 test "$ret" -eq 0 || echo_i "failed"
    739 status=$((status+ret))
    740 
    741 # Check the secure.example domain
    742 
    743 echo_i "checking multi-stage positive validation NSEC/NSEC ($n)"
    744 ret=0
    745 dig_with_opts +noauth a.secure.example. \
    746 	@10.53.0.3 a > dig.out.ns3.test$n || ret=1
    747 dig_with_opts +noauth a.secure.example. \
    748 	@10.53.0.4 a > dig.out.ns4.test$n || ret=1
    749 digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
    750 grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
    751 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
    752 n=$((n+1))
    753 test "$ret" -eq 0 || echo_i "failed"
    754 status=$((status+ret))
    755 
    756 echo_i "checking multi-stage positive validation NSEC/NSEC3 ($n)"
    757 ret=0
    758 dig_with_opts +noauth a.nsec3.example. \
    759 	@10.53.0.3 a > dig.out.ns3.test$n || ret=1
    760 dig_with_opts +noauth a.nsec3.example. \
    761 	@10.53.0.4 a > dig.out.ns4.test$n || ret=1
    762 digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
    763 grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
    764 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
    765 n=$((n+1))
    766 test "$ret" -eq 0 || echo_i "failed"
    767 status=$((status+ret))
    768 
    769 echo_i "checking multi-stage positive validation NSEC/OPTOUT ($n)"
    770 ret=0
    771 dig_with_opts +noauth a.optout.example. \
    772 	@10.53.0.3 a > dig.out.ns3.test$n || ret=1
    773 dig_with_opts +noauth a.optout.example. \
    774 	@10.53.0.4 a > dig.out.ns4.test$n || ret=1
    775 digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
    776 grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
    777 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
    778 n=$((n+1))
    779 test "$ret" -eq 0 || echo_i "failed"
    780 status=$((status+ret))
    781 
    782 echo_i "checking multi-stage positive validation NSEC3/NSEC ($n)"
    783 ret=0
    784 dig_with_opts +noauth a.secure.nsec3.example. \
    785 	@10.53.0.3 a > dig.out.ns3.test$n || ret=1
    786 dig_with_opts +noauth a.secure.nsec3.example. \
    787 	@10.53.0.4 a > dig.out.ns4.test$n || ret=1
    788 digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
    789 grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
    790 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
    791 n=$((n+1))
    792 test "$ret" -eq 0 || echo_i "failed"
    793 status=$((status+ret))
    794 
    795 echo_i "checking multi-stage positive validation NSEC3/NSEC3 ($n)"
    796 ret=0
    797 dig_with_opts +noauth a.nsec3.nsec3.example. \
    798 	@10.53.0.3 a > dig.out.ns3.test$n || ret=1
    799 dig_with_opts +noauth a.nsec3.nsec3.example. \
    800 	@10.53.0.4 a > dig.out.ns4.test$n || ret=1
    801 digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
    802 grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
    803 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
    804 n=$((n+1))
    805 test "$ret" -eq 0 || echo_i "failed"
    806 status=$((status+ret))
    807 
    808 echo_i "checking multi-stage positive validation NSEC3/OPTOUT ($n)"
    809 ret=0
    810 dig_with_opts +noauth a.optout.nsec3.example. \
    811 	@10.53.0.3 a > dig.out.ns3.test$n || ret=1
    812 dig_with_opts +noauth a.optout.nsec3.example. \
    813 	@10.53.0.4 a > dig.out.ns4.test$n || ret=1
    814 digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
    815 grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
    816 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
    817 n=$((n+1))
    818 test "$ret" -eq 0 || echo_i "failed"
    819 status=$((status+ret))
    820 
    821 echo_i "checking multi-stage positive validation OPTOUT/NSEC ($n)"
    822 ret=0
    823 dig_with_opts +noauth a.secure.optout.example. \
    824 	@10.53.0.3 a > dig.out.ns3.test$n || ret=1
    825 dig_with_opts +noauth a.secure.optout.example. \
    826 	@10.53.0.4 a > dig.out.ns4.test$n || ret=1
    827 digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
    828 grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
    829 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
    830 n=$((n+1))
    831 test "$ret" -eq 0 || echo_i "failed"
    832 status=$((status+ret))
    833 
    834 echo_i "checking multi-stage positive validation OPTOUT/NSEC3 ($n)"
    835 ret=0
    836 dig_with_opts +noauth a.nsec3.optout.example. \
    837 	@10.53.0.3 a > dig.out.ns3.test$n || ret=1
    838 dig_with_opts +noauth a.nsec3.optout.example. \
    839 	@10.53.0.4 a > dig.out.ns4.test$n || ret=1
    840 digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
    841 grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
    842 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
    843 n=$((n+1))
    844 test "$ret" -eq 0 || echo_i "failed"
    845 status=$((status+ret))
    846 
    847 echo_i "checking multi-stage positive validation OPTOUT/OPTOUT ($n)"
    848 ret=0
    849 dig_with_opts +noauth a.optout.optout.example. \
    850 	@10.53.0.3 a > dig.out.ns3.test$n || ret=1
    851 dig_with_opts +noauth a.optout.optout.example. \
    852 	@10.53.0.4 a > dig.out.ns4.test$n || ret=1
    853 digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
    854 grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
    855 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
    856 n=$((n+1))
    857 test "$ret" -eq 0 || echo_i "failed"
    858 status=$((status+ret))
    859 
    860 echo_i "checking empty NODATA OPTOUT ($n)"
    861 ret=0
    862 dig_with_opts +noauth empty.optout.example. \
    863 	@10.53.0.3 a > dig.out.ns3.test$n || ret=1
    864 dig_with_opts +noauth empty.optout.example. \
    865 	@10.53.0.4 a > dig.out.ns4.test$n || ret=1
    866 digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
    867 grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
    868 #grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
    869 n=$((n+1))
    870 test "$ret" -eq 0 || echo_i "failed"
    871 status=$((status+ret))
    872 
    873 # Check the bogus domain
    874 
    875 echo_i "checking failed validation ($n)"
    876 ret=0
    877 dig_with_opts a.bogus.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1
    878 grep "SERVFAIL" dig.out.ns4.test$n > /dev/null || ret=1
    879 n=$((n+1))
    880 test "$ret" -eq 0 || echo_i "failed"
    881 status=$((status+ret))
    882 
    883 if [ -x ${DELV} ] ; then
    884    ret=0
    885    echo_i "checking failed validation using dns_client ($n)"
    886    delv_with_opts +cd @10.53.0.4 a a.bogus.example > delv.out$n 2>&1 || ret=1
    887    grep "resolution failed: RRSIG failed to verify" delv.out$n > /dev/null || ret=1
    888    n=$((n+1))
    889    test "$ret" -eq 0 || echo_i "failed"
    890    status=$((status+ret))
    891 fi
    892 
    893 # Try validating with a bad trusted key.
    894 # This should fail.
    895 
    896 echo_i "checking that validation fails with a misconfigured trusted key ($n)"
    897 ret=0
    898 dig_with_opts example. soa @10.53.0.5 > dig.out.ns5.test$n || ret=1
    899 grep "SERVFAIL" dig.out.ns5.test$n > /dev/null || ret=1
    900 n=$((n+1))
    901 test "$ret" -eq 0 || echo_i "failed"
    902 status=$((status+ret))
    903 
    904 echo_i "checking that negative validation fails with a misconfigured trusted key ($n)"
    905 ret=0
    906 dig_with_opts example. ptr @10.53.0.5 > dig.out.ns5.test$n || ret=1
    907 grep "SERVFAIL" dig.out.ns5.test$n > /dev/null || ret=1
    908 n=$((n+1))
    909 test "$ret" -eq 0 || echo_i "failed"
    910 status=$((status+ret))
    911 
    912 echo_i "checking that insecurity proofs fail with a misconfigured trusted key ($n)"
    913 ret=0
    914 dig_with_opts a.insecure.example. a @10.53.0.5 > dig.out.ns5.test$n || ret=1
    915 grep "SERVFAIL" dig.out.ns5.test$n > /dev/null || ret=1
    916 n=$((n+1))
    917 test "$ret" -eq 0 || echo_i "failed"
    918 status=$((status+ret))
    919 
    920 echo_i "checking that validation fails when key record is missing ($n)"
    921 ret=0
    922 dig_with_opts a.b.keyless.example. a @10.53.0.4 > dig.out.ns4.test$n || ret=1
    923 grep "SERVFAIL" dig.out.ns4.test$n > /dev/null || ret=1
    924 n=$((n+1))
    925 test "$ret" -eq 0 || echo_i "failed"
    926 status=$((status+ret))
    927 
    928 if [ -x ${DELV} ] ; then
    929    ret=0
    930    echo_i "checking that validation fails when key record is missing using dns_client ($n)"
    931    delv_with_opts +cd @10.53.0.4 a a.b.keyless.example > delv.out$n 2>&1 || ret=1
    932    grep "resolution failed: broken trust chain" delv.out$n > /dev/null || ret=1
    933    n=$((n+1))
    934    test "$ret" -eq 0 || echo_i "failed"
    935    status=$((status+ret))
    936 fi
    937 
    938 echo_i "checking that validation succeeds when a revoked key is encountered ($n)"
    939 ret=0
    940 dig_with_opts revkey.example soa @10.53.0.4 > dig.out.ns4.test$n || ret=1
    941 grep "NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
    942 grep "flags: .* ad" dig.out.ns4.test$n > /dev/null || ret=1
    943 n=$((n+1))
    944 test "$ret" -eq 0 || echo_i "failed"
    945 status=$((status+ret))
    946 
    947 if [ -x ${DELV} ] ; then
    948    ret=0
    949    echo_i "checking that validation succeeds when a revoked key is encountered using dns_client ($n)"
    950    delv_with_opts +cd @10.53.0.4 soa revkey.example > delv.out$n 2>&1 || ret=1
    951    grep "fully validated" delv.out$n > /dev/null || ret=1
    952    n=$((n+1))
    953    test "$ret" -eq 0 || echo_i "failed"
    954    status=$((status+ret))
    955 fi
    956 
    957 echo_i "Checking that a bad CNAME signature is caught after a +CD query ($n)"
    958 ret=0
    959 #prime
    960 dig_with_opts +cd bad-cname.example. @10.53.0.4 > dig.out.ns4.prime$n || ret=1
    961 #check: requery with +CD.  pending data should be returned even if it's bogus
    962 expect="a.example.
    963 10.0.0.1"
    964 ans=$(dig_with_opts +cd +nodnssec +short bad-cname.example. @10.53.0.4) || ret=1
    965 test "$ans" = "$expect" || ret=1
    966 test "$ret" -eq 0 || echo_i "failed, got '$ans', expected '$expect'"
    967 #check: requery without +CD.  bogus cached data should be rejected.
    968 dig_with_opts +nodnssec bad-cname.example. @10.53.0.4 > dig.out.ns4.test$n || ret=1
    969 grep "SERVFAIL" dig.out.ns4.test$n > /dev/null || ret=1
    970 n=$((n+1))
    971 test "$ret" -eq 0 || echo_i "failed"
    972 status=$((status+ret))
    973 
    974 echo_i "Checking that a bad DNAME signature is caught after a +CD query ($n)"
    975 ret=0
    976 #prime
    977 dig_with_opts +cd a.bad-dname.example. @10.53.0.4 > dig.out.ns4.prime$n || ret=1
    978 #check: requery with +CD.  pending data should be returned even if it's bogus
    979 expect="example.
    980 a.example.
    981 10.0.0.1"
    982 ans=$(dig_with_opts +cd +nodnssec +short a.bad-dname.example. @10.53.0.4) || ret=1
    983 test "$ans" = "$expect" || ret=1
    984 test "$ret" -eq 0 || echo_i "failed, got '$ans', expected '$expect'"
    985 #check: requery without +CD.  bogus cached data should be rejected.
    986 dig_with_opts +nodnssec a.bad-dname.example. @10.53.0.4 > dig.out.ns4.test$n || ret=1
    987 grep "SERVFAIL" dig.out.ns4.test$n > /dev/null || ret=1
    988 n=$((n+1))
    989 test "$ret" -eq 0 || echo_i "failed"
    990 status=$((status+ret))
    991 
    992 # Check the insecure.secure.example domain (insecurity proof)
    993 
    994 echo_i "checking 2-server insecurity proof ($n)"
    995 ret=0
    996 dig_with_opts +noauth a.insecure.secure.example. @10.53.0.2 a \
    997 	> dig.out.ns2.test$n || ret=1
    998 dig_with_opts +noauth a.insecure.secure.example. @10.53.0.4 a \
    999 	> dig.out.ns4.test$n || ret=1
   1000 digcomp dig.out.ns2.test$n dig.out.ns4.test$n || ret=1
   1001 grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
   1002 # Note - this is looking for failure, hence the &&
   1003 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1
   1004 n=$((n+1))
   1005 test "$ret" -eq 0 || echo_i "failed"
   1006 status=$((status+ret))
   1007 
   1008 # Check a negative response in insecure.secure.example
   1009 
   1010 echo_i "checking 2-server insecurity proof with a negative answer ($n)"
   1011 ret=0
   1012 dig_with_opts q.insecure.secure.example. @10.53.0.2 a > dig.out.ns2.test$n \
   1013 	|| ret=1
   1014 dig_with_opts q.insecure.secure.example. @10.53.0.4 a > dig.out.ns4.test$n \
   1015 	|| ret=1
   1016 digcomp dig.out.ns2.test$n dig.out.ns4.test$n || ret=1
   1017 grep "status: NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1
   1018 # Note - this is looking for failure, hence the &&
   1019 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1
   1020 n=$((n+1))
   1021 test "$ret" -eq 0 || echo_i "failed"
   1022 status=$((status+ret))
   1023 
   1024 echo_i "checking 2-server insecurity proof with a negative answer and SOA hack ($n)"
   1025 ret=0
   1026 dig_with_opts r.insecure.secure.example. @10.53.0.2 soa > dig.out.ns2.test$n \
   1027 	|| ret=1
   1028 dig_with_opts r.insecure.secure.example. @10.53.0.4 soa > dig.out.ns4.test$n \
   1029 	|| ret=1
   1030 digcomp dig.out.ns2.test$n dig.out.ns4.test$n || ret=1
   1031 grep "status: NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1
   1032 # Note - this is looking for failure, hence the &&
   1033 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1
   1034 n=$((n+1))
   1035 test "$ret" -eq 0 || echo_i "failed"
   1036 status=$((status+ret))
   1037 
   1038 # Check that the query for a security root is successful and has ad set
   1039 
   1040 echo_i "checking security root query ($n)"
   1041 ret=0
   1042 dig_with_opts . @10.53.0.4 key > dig.out.ns4.test$n || ret=1
   1043 grep "NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
   1044 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
   1045 n=$((n+1))
   1046 test "$ret" -eq 0 || echo_i "failed"
   1047 status=$((status+ret))
   1048 
   1049 # Check that the setting the cd bit works
   1050 
   1051 echo_i "checking cd bit on a positive answer ($n)"
   1052 ret=0
   1053 dig_with_opts +noauth example. soa @10.53.0.4 \
   1054 	> dig.out.ns4.test$n || ret=1
   1055 dig_with_opts +noauth +cdflag example. soa @10.53.0.5 \
   1056 	> dig.out.ns5.test$n || ret=1
   1057 digcomp dig.out.ns4.test$n dig.out.ns5.test$n || ret=1
   1058 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
   1059 # Note - this is looking for failure, hence the &&
   1060 grep "flags:.*ad.*QUERY" dig.out.ns5.test$n > /dev/null && ret=1
   1061 n=$((n+1))
   1062 test "$ret" -eq 0 || echo_i "failed"
   1063 status=$((status+ret))
   1064 
   1065 echo_i "checking cd bit on a negative answer ($n)"
   1066 ret=0
   1067 dig_with_opts q.example. soa @10.53.0.4 > dig.out.ns4.test$n || ret=1
   1068 dig_with_opts +cdflag q.example. soa @10.53.0.5 > dig.out.ns5.test$n || ret=1
   1069 digcomp dig.out.ns4.test$n dig.out.ns5.test$n || ret=1
   1070 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
   1071 # Note - this is looking for failure, hence the &&
   1072 grep "flags:.*ad.*QUERY" dig.out.ns5.test$n > /dev/null && ret=1
   1073 n=$((n+1))
   1074 test "$ret" -eq 0 || echo_i "failed"
   1075 status=$((status+ret))
   1076 
   1077 echo_i "checking insecurity proof works using negative cache ($n)"
   1078 ret=0
   1079 rndccmd 10.53.0.4 flush 2>&1 | sed 's/^/ns4 /' | cat_i
   1080 dig_with_opts +cd @10.53.0.4 insecure.example. ds > dig.out.ns4.test$n.1 || ret=1
   1081 for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
   1082 do
   1083         dig_with_opts @10.53.0.4 nonexistent.insecure.example. > dig.out.ns4.test$n.2 || ret=1
   1084 	if grep "status: NXDOMAIN" dig.out.ns4.test$n.2 >/dev/null; then
   1085 		break
   1086 	fi
   1087 	sleep 1
   1088 done
   1089 grep "status: NXDOMAIN" dig.out.ns4.test$n.2 >/dev/null || ret=1
   1090 n=$((n+1))
   1091 test "$ret" -eq 0 || echo_i "failed"
   1092 status=$((status+ret))
   1093 
   1094 echo_i "checking positive validation RSASHA256 NSEC ($n)"
   1095 ret=0
   1096 dig_with_opts +noauth a.rsasha256.example. @10.53.0.3 a > dig.out.ns3.test$n || ret=1
   1097 dig_with_opts +noauth a.rsasha256.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1
   1098 digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
   1099 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
   1100 n=$((n+1))
   1101 test "$ret" -eq 0 || echo_i "failed"
   1102 status=$((status+ret))
   1103 
   1104 echo_i "checking positive validation RSASHA512 NSEC ($n)"
   1105 ret=0
   1106 dig_with_opts +noauth a.rsasha512.example. @10.53.0.3 a > dig.out.ns3.test$n || ret=1
   1107 dig_with_opts +noauth a.rsasha512.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1
   1108 digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
   1109 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
   1110 n=$((n+1))
   1111 test "$ret" -eq 0 || echo_i "failed"
   1112 status=$((status+ret))
   1113 
   1114 echo_i "checking positive validation with KSK-only DNSKEY signature ($n)"
   1115 ret=0
   1116 dig_with_opts +noauth a.kskonly.example. @10.53.0.3 a > dig.out.ns3.test$n || ret=1
   1117 dig_with_opts +noauth a.kskonly.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1
   1118 digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
   1119 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
   1120 n=$((n+1))
   1121 test "$ret" -eq 0 || echo_i "failed"
   1122 status=$((status+ret))
   1123 
   1124 echo_i "checking cd bit on a query that should fail ($n)"
   1125 ret=0
   1126 dig_with_opts a.bogus.example. soa @10.53.0.4 \
   1127 	> dig.out.ns4.test$n || ret=1
   1128 dig_with_opts +cdflag a.bogus.example. soa @10.53.0.5 \
   1129 	> dig.out.ns5.test$n || ret=1
   1130 digcomp dig.out.ns4.test$n dig.out.ns5.test$n || ret=1
   1131 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
   1132 # Note - this is looking for failure, hence the &&
   1133 grep "flags:.*ad.*QUERY" dig.out.ns5.test$n > /dev/null && ret=1
   1134 n=$((n+1))
   1135 test "$ret" -eq 0 || echo_i "failed"
   1136 status=$((status+ret))
   1137 
   1138 echo_i "checking cd bit on an insecurity proof ($n)"
   1139 ret=0
   1140 dig_with_opts +noauth a.insecure.example. soa @10.53.0.4 \
   1141 	> dig.out.ns4.test$n || ret=1
   1142 dig_with_opts +noauth +cdflag a.insecure.example. soa @10.53.0.5 \
   1143 	> dig.out.ns5.test$n || ret=1
   1144 digcomp dig.out.ns4.test$n dig.out.ns5.test$n || ret=1
   1145 grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
   1146 # Note - these are looking for failure, hence the &&
   1147 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1
   1148 grep "flags:.*ad.*QUERY" dig.out.ns5.test$n > /dev/null && ret=1
   1149 n=$((n+1))
   1150 test "$ret" -eq 0 || echo_i "failed"
   1151 status=$((status+ret))
   1152 
   1153 echo_i "checking cd bit on a negative insecurity proof ($n)"
   1154 ret=0
   1155 dig_with_opts q.insecure.example. a @10.53.0.4 \
   1156 	> dig.out.ns4.test$n || ret=1
   1157 dig_with_opts +cdflag q.insecure.example. a @10.53.0.5 \
   1158 	> dig.out.ns5.test$n || ret=1
   1159 digcomp dig.out.ns4.test$n dig.out.ns5.test$n || ret=1
   1160 grep "status: NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1
   1161 # Note - these are looking for failure, hence the &&
   1162 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1
   1163 grep "flags:.*ad.*QUERY" dig.out.ns5.test$n > /dev/null && ret=1
   1164 n=$((n+1))
   1165 test "$ret" -eq 0 || echo_i "failed"
   1166 status=$((status+ret))
   1167 
   1168 echo_i "checking that validation of an ANY query works ($n)"
   1169 ret=0
   1170 dig_with_opts +noauth foo.example. any @10.53.0.2 > dig.out.ns2.test$n || ret=1
   1171 dig_with_opts +noauth foo.example. any @10.53.0.4 > dig.out.ns4.test$n || ret=1
   1172 digcomp dig.out.ns2.test$n dig.out.ns4.test$n || ret=1
   1173 grep "NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
   1174 # 2 records in the zone, 1 NXT, 3 SIGs
   1175 grep "ANSWER: 6" dig.out.ns4.test$n > /dev/null || ret=1
   1176 n=$((n+1))
   1177 test "$ret" -eq 0 || echo_i "failed"
   1178 status=$((status+ret))
   1179 
   1180 echo_i "checking that validation of a query returning a CNAME works ($n)"
   1181 ret=0
   1182 dig_with_opts +noauth cname1.example. txt @10.53.0.2 \
   1183 	> dig.out.ns2.test$n || ret=1
   1184 dig_with_opts +noauth cname1.example. txt @10.53.0.4 \
   1185 	> dig.out.ns4.test$n || ret=1
   1186 digcomp dig.out.ns2.test$n dig.out.ns4.test$n || ret=1
   1187 grep "NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
   1188 # the CNAME & its sig, the TXT and its SIG
   1189 grep "ANSWER: 4" dig.out.ns4.test$n > /dev/null || ret=1
   1190 n=$((n+1))
   1191 test "$ret" -eq 0 || echo_i "failed"
   1192 status=$((status+ret))
   1193 
   1194 echo_i "checking that validation of a query returning a DNAME works ($n)"
   1195 ret=0
   1196 dig_with_opts +noauth foo.dname1.example. txt @10.53.0.2 \
   1197 	> dig.out.ns2.test$n || ret=1
   1198 dig_with_opts +noauth foo.dname1.example. txt @10.53.0.4 \
   1199 	> dig.out.ns4.test$n || ret=1
   1200 digcomp dig.out.ns2.test$n dig.out.ns4.test$n || ret=1
   1201 grep "NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
   1202 # The DNAME & its sig, the TXT and its SIG, and the synthesized CNAME.
   1203 # It would be nice to test that the CNAME is being synthesized by the
   1204 # recursive server and not cached, but I don't know how.
   1205 grep "ANSWER: 5" dig.out.ns4.test$n > /dev/null || ret=1
   1206 n=$((n+1))
   1207 test "$ret" -eq 0 || echo_i "failed"
   1208 status=$((status+ret))
   1209 
   1210 echo_i "checking that validation of an ANY query returning a CNAME works ($n)"
   1211 ret=0
   1212 dig_with_opts +noauth cname2.example. any @10.53.0.2 \
   1213 	> dig.out.ns2.test$n || ret=1
   1214 dig_with_opts +noauth cname2.example. any @10.53.0.4 \
   1215 	> dig.out.ns4.test$n || ret=1
   1216 digcomp dig.out.ns2.test$n dig.out.ns4.test$n || ret=1
   1217 grep "NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
   1218 # The CNAME, NXT, and their SIGs
   1219 grep "ANSWER: 4" dig.out.ns4.test$n > /dev/null || ret=1
   1220 n=$((n+1))
   1221 test "$ret" -eq 0 || echo_i "failed"
   1222 status=$((status+ret))
   1223 
   1224 echo_i "checking that validation of an ANY query returning a DNAME works ($n)"
   1225 ret=0
   1226 dig_with_opts +noauth foo.dname2.example. any @10.53.0.2 \
   1227 	> dig.out.ns2.test$n || ret=1
   1228 dig_with_opts +noauth foo.dname2.example. any @10.53.0.4 \
   1229 	> dig.out.ns4.test$n || ret=1
   1230 digcomp dig.out.ns2.test$n dig.out.ns4.test$n || ret=1
   1231 grep "NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
   1232 n=$((n+1))
   1233 test "$ret" -eq 0 || echo_i "failed"
   1234 status=$((status+ret))
   1235 
   1236 echo_i "checking that lookups succeed after disabling an algorithm ($n)"
   1237 ret=0
   1238 dig_with_opts +noauth example. SOA @10.53.0.2 \
   1239 	> dig.out.ns2.test$n || ret=1
   1240 dig_with_opts +noauth example. SOA @10.53.0.6 \
   1241 	> dig.out.ns6.test$n || ret=1
   1242 digcomp dig.out.ns2.test$n dig.out.ns6.test$n || ret=1
   1243 # Note - this is looking for failure, hence the &&
   1244 grep "flags:.*ad.*QUERY" dig.out.ns6.test$n > /dev/null && ret=1
   1245 n=$((n+1))
   1246 test "$ret" -eq 0 || echo_i "failed"
   1247 status=$((status+ret))
   1248 
   1249 echo_i "checking a non-cachable NODATA works ($n)"
   1250 ret=0
   1251 dig_with_opts +noauth a.nosoa.secure.example. txt @10.53.0.7 \
   1252 	> dig.out.ns7.test$n || ret=1
   1253 grep "AUTHORITY: 0" dig.out.ns7.test$n > /dev/null || ret=1
   1254 dig_with_opts +noauth a.nosoa.secure.example. txt @10.53.0.4 \
   1255 	> dig.out.ns4.test$n || ret=1
   1256 grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
   1257 n=$((n+1))
   1258 test "$ret" -eq 0 || echo_i "failed"
   1259 status=$((status+ret))
   1260 
   1261 echo_i "checking a non-cachable NXDOMAIN works ($n)"
   1262 ret=0
   1263 dig_with_opts +noauth b.nosoa.secure.example. txt @10.53.0.7 \
   1264 	> dig.out.ns7.test$n || ret=1
   1265 grep "AUTHORITY: 0" dig.out.ns7.test$n > /dev/null || ret=1
   1266 dig_with_opts +noauth b.nosoa.secure.example. txt @10.53.0.4 \
   1267 	> dig.out.ns4.test$n || ret=1
   1268 grep "status: NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1
   1269 n=$((n+1))
   1270 test "$ret" -eq 0 || echo_i "failed"
   1271 status=$((status+ret))
   1272 
   1273 echo_i "checking that we can load a rfc2535 signed zone ($n)"
   1274 ret=0
   1275 dig_with_opts rfc2535.example. SOA @10.53.0.2 \
   1276 	> dig.out.ns2.test$n || ret=1
   1277 grep "status: NOERROR" dig.out.ns2.test$n > /dev/null || ret=1
   1278 n=$((n+1))
   1279 test "$ret" -eq 0 || echo_i "failed"
   1280 status=$((status+ret))
   1281 
   1282 echo_i "checking that we can transfer a rfc2535 signed zone ($n)"
   1283 ret=0
   1284 dig_with_opts rfc2535.example. SOA @10.53.0.3 \
   1285 	> dig.out.ns3.test$n || ret=1
   1286 grep "status: NOERROR" dig.out.ns3.test$n > /dev/null || ret=1
   1287 n=$((n+1))
   1288 test "$ret" -eq 0 || echo_i "failed"
   1289 status=$((status+ret))
   1290 
   1291 echo_i "basic dnssec-signzone checks:"
   1292 echo_ic "two DNSKEYs ($n)"
   1293 ret=0
   1294 (
   1295 cd signer/general || exit 1
   1296 rm -f signed.zone
   1297 $SIGNER -f signed.zone -o example.com. test1.zone > signer.out.$n
   1298 test -f signed.zone
   1299 ) || ret=1
   1300 n=$((n+1))
   1301 test "$ret" -eq 0 || echo_i "failed"
   1302 status=$((status+ret))
   1303 
   1304 echo_ic "one non-KSK DNSKEY ($n)"
   1305 ret=0
   1306 (
   1307 cd signer/general || exit 1
   1308 rm -f signed.zone
   1309 $SIGNER -f signed.zone -o example.com. test2.zone > signer.out.$n
   1310 test -f signed.zone
   1311 ) && ret=1
   1312 n=$((n+1))
   1313 test "$ret" -eq 0 || echo_i "failed"
   1314 status=$((status+ret))
   1315 
   1316 echo_ic "one KSK DNSKEY ($n)"
   1317 ret=0
   1318 (
   1319 cd signer/general || exit 1
   1320 rm -f signed.zone
   1321 $SIGNER -f signed.zone -o example.com. test3.zone > signer.out.$n
   1322 test -f signed.zone
   1323 ) && ret=1
   1324 n=$((n+1))
   1325 test "$ret" -eq 0 || echo_i "failed"
   1326 status=$((status+ret))
   1327 
   1328 echo_ic "three DNSKEY ($n)"
   1329 ret=0
   1330 (
   1331 cd signer/general || exit 1
   1332 rm -f signed.zone
   1333 $SIGNER -f signed.zone -o example.com. test4.zone > signer.out.$n
   1334 test -f signed.zone
   1335 ) || ret=1
   1336 n=$((n+1))
   1337 test "$ret" -eq 0 || echo_i "failed"
   1338 status=$((status+ret))
   1339 
   1340 echo_ic "three DNSKEY, one private key missing ($n)"
   1341 ret=0
   1342 (
   1343 cd signer/general || exit 1
   1344 rm -f signed.zone
   1345 $SIGNER -f signed.zone -o example.com. test5.zone > signer.out.$n
   1346 test -f signed.zone
   1347 ) || ret=1
   1348 n=$((n+1))
   1349 test "$ret" -eq 0 || echo_i "failed"
   1350 status=$((status+ret))
   1351 
   1352 echo_ic "four DNSKEY ($n)"
   1353 ret=0
   1354 (
   1355 cd signer/general || exit 1
   1356 rm -f signed.zone
   1357 $SIGNER -f signed.zone -o example.com. test6.zone > signer.out.$n
   1358 test -f signed.zone
   1359 ) || ret=1
   1360 n=$((n+1))
   1361 test "$ret" -eq 0 || echo_i "failed"
   1362 status=$((status+ret))
   1363 
   1364 echo_ic "two DNSKEY, both private keys missing ($n)"
   1365 ret=0
   1366 (
   1367 cd signer/general || exit 1
   1368 rm -f signed.zone
   1369 $SIGNER -f signed.zone -o example.com. test7.zone > signer.out.$n
   1370 test -f signed.zone
   1371 ) && ret=1
   1372 n=$((n+1))
   1373 test "$ret" -eq 0 || echo_i "failed"
   1374 status=$((status+ret))
   1375 
   1376 echo_ic "two DNSKEY, one private key missing ($n)"
   1377 ret=0
   1378 (
   1379 cd signer/general || exit 1
   1380 rm -f signed.zone
   1381 $SIGNER -f signed.zone -o example.com. test8.zone > signer.out.$n
   1382 test -f signed.zone
   1383 ) && ret=1
   1384 n=$((n+1))
   1385 test "$ret" -eq 0 || echo_i "failed"
   1386 status=$((status+ret))
   1387 
   1388 echo_i "checking that a key using an unsupported algorithm cannot be generated ($n)"
   1389 ret=0
   1390 zone=example
   1391 # If dnssec-keygen fails, the test script will exit immediately.  Prevent that
   1392 # from happening, and also trigger a test failure if dnssec-keygen unexpectedly
   1393 # succeeds, by using "&& ret=1".
   1394 $KEYGEN -a 255 $zone > dnssectools.out.test$n 2>&1 && ret=1
   1395 grep -q "unsupported algorithm: 255" dnssectools.out.test$n || ret=1
   1396 n=$((n+1))
   1397 test "$ret" -eq 0 || echo_i "failed"
   1398 status=$((status+ret))
   1399 
   1400 echo_i "checking that a DS record cannot be generated for a key using an unsupported algorithm ($n)"
   1401 ret=0
   1402 zone=example
   1403 # Fake an unsupported algorithm key
   1404 unsupportedkey=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -n zone "$zone")
   1405 awk '$3 == "DNSKEY" { $6 = 255 } { print }' ${unsupportedkey}.key > ${unsupportedkey}.tmp
   1406 mv ${unsupportedkey}.tmp ${unsupportedkey}.key
   1407 # If dnssec-dsfromkey fails, the test script will exit immediately.  Prevent
   1408 # that from happening, and also trigger a test failure if dnssec-dsfromkey
   1409 # unexpectedly succeeds, by using "&& ret=1".
   1410 $DSFROMKEY ${unsupportedkey} > dnssectools.out.test$n 2>&1 && ret=1
   1411 grep -q "algorithm is unsupported" dnssectools.out.test$n || ret=1
   1412 n=$((n+1))
   1413 test "$ret" -eq 0 || echo_i "failed"
   1414 status=$((status+ret))
   1415 
   1416 echo_i "checking that a zone cannot be signed with a key using an unsupported algorithm ($n)"
   1417 ret=0
   1418 ret=0
   1419 cat signer/example.db.in "${unsupportedkey}.key" > signer/example.db
   1420 # If dnssec-signzone fails, the test script will exit immediately.  Prevent that
   1421 # from happening, and also trigger a test failure if dnssec-signzone
   1422 # unexpectedly succeeds, by using "&& ret=1".
   1423 $SIGNER -o example signer/example.db ${unsupportedkey} > dnssectools.out.test$n 2>&1 && ret=1
   1424 grep -q "algorithm is unsupported" dnssectools.out.test$n || ret=1
   1425 n=$((n+1))
   1426 test "$ret" -eq 0 || echo_i "failed"
   1427 status=$((status+ret))
   1428 
   1429 get_rsasha1_key_ids_from_sigs() {
   1430 	tr -d '\r' < signer/example.db.signed | \
   1431 	awk '
   1432 		NF < 8 { next }
   1433 		$(NF-5) != "RRSIG" { next }
   1434 		$(NF-3) != "5" { next }
   1435 		$NF != "(" { next }
   1436 		{
   1437 			getline;
   1438 			print $3;
   1439 		}
   1440 	' | \
   1441 	sort -u
   1442 }
   1443 
   1444 echo_i "checking that we can sign a zone with out-of-zone records ($n)"
   1445 ret=0
   1446 zone=example
   1447 key1=$($KEYGEN -K signer -q -a NSEC3RSASHA1 -b 1024 -n zone $zone)
   1448 key2=$($KEYGEN -K signer -q -f KSK -a NSEC3RSASHA1 -b 1024 -n zone $zone)
   1449 (
   1450 cd signer || exit 1
   1451 cat example.db.in "$key1.key" "$key2.key" > example.db
   1452 $SIGNER -o example -f example.db example.db > /dev/null
   1453 ) || ret=1
   1454 n=$((n+1))
   1455 test "$ret" -eq 0 || echo_i "failed"
   1456 status=$((status+ret))
   1457 
   1458 echo_i "checking that we can sign a zone (NSEC3) with out-of-zone records ($n)"
   1459 ret=0
   1460 zone=example
   1461 key1=$($KEYGEN -K signer -q -a NSEC3RSASHA1 -b 1024 -n zone $zone)
   1462 key2=$($KEYGEN -K signer -q -f KSK -a NSEC3RSASHA1 -b 1024 -n zone $zone)
   1463 (
   1464 cd signer || exit 1
   1465 cat example.db.in "$key1.key" "$key2.key" > example.db
   1466 $SIGNER -3 - -H 10 -o example -f example.db example.db > /dev/null
   1467 awk '/^IQF9LQTLK/ {
   1468 		printf("%s", $0);
   1469 		while (!index($0, ")")) {
   1470 			if (getline <= 0)
   1471 				break;
   1472 			printf (" %s", $0);
   1473 		}
   1474 		printf("\n");
   1475 	}' example.db | sed 's/[ 	][ 	]*/ /g' > nsec3param.out
   1476 
   1477 grep "IQF9LQTLKKNFK0KVIFELRAK4IC4QLTMG.example. 0 IN NSEC3 1 0 10 - ( IQF9LQTLKKNFK0KVIFELRAK4IC4QLTMG A NS SOA RRSIG DNSKEY NSEC3PARAM )" nsec3param.out > /dev/null
   1478 ) || ret=1
   1479 n=$((n+1))
   1480 test "$ret" -eq 0 || echo_i "failed"
   1481 status=$((status+ret))
   1482 
   1483 echo_i "checking NSEC3 signing with empty nonterminals above a delegation ($n)"
   1484 ret=0
   1485 zone=example
   1486 key1=$($KEYGEN -K signer -q -a NSEC3RSASHA1 -b 1024 -n zone $zone)
   1487 key2=$($KEYGEN -K signer -q -f KSK -a NSEC3RSASHA1 -b 1024 -n zone $zone)
   1488 (
   1489 cd signer || exit 1
   1490 cat example.db.in "$key1.key" "$key2.key" > example3.db
   1491 echo "some.empty.nonterminal.nodes.example 60 IN NS ns.example.tld" >> example3.db
   1492 $SIGNER -3 - -A -H 10 -o example -f example3.db example3.db > /dev/null
   1493 awk '/^IQF9LQTLK/ {
   1494 		printf("%s", $0);
   1495 		while (!index($0, ")")) {
   1496 			if (getline <= 0)
   1497 				break;
   1498 			printf (" %s", $0);
   1499 		}
   1500 		printf("\n");
   1501 	}' example.db | sed 's/[ 	][ 	]*/ /g' > nsec3param.out
   1502 
   1503 grep "IQF9LQTLKKNFK0KVIFELRAK4IC4QLTMG.example. 0 IN NSEC3 1 0 10 - ( IQF9LQTLKKNFK0KVIFELRAK4IC4QLTMG A NS SOA RRSIG DNSKEY NSEC3PARAM )" nsec3param.out > /dev/null
   1504 ) || ret=1
   1505 n=$((n+1))
   1506 test "$ret" -eq 0 || echo_i "failed"
   1507 status=$((status+ret))
   1508 
   1509 echo_i "checking that dnssec-signzone updates originalttl on ttl changes ($n)"
   1510 ret=0
   1511 zone=example
   1512 key1=$($KEYGEN -K signer -q -a RSASHA1 -b 1024 -n zone $zone)
   1513 key2=$($KEYGEN -K signer -q -f KSK -a RSASHA1 -b 1024 -n zone $zone)
   1514 (
   1515 cd signer || exit 1
   1516 cat example.db.in "$key1.key" "$key2.key" > example.db
   1517 $SIGNER -o example -f example.db.before example.db > /dev/null
   1518 sed 's/60.IN.SOA./50 IN SOA /' example.db.before > example.db.changed
   1519 $SIGNER -o example -f example.db.after example.db.changed > /dev/null
   1520 )
   1521 grep "SOA 5 1 50" signer/example.db.after > /dev/null || ret=1
   1522 n=$((n+1))
   1523 test "$ret" -eq 0 || echo_i "failed"
   1524 status=$((status+ret))
   1525 
   1526 echo_i "checking dnssec-signzone keeps valid signatures from removed keys ($n)"
   1527 ret=0
   1528 zone=example
   1529 key1=$($KEYGEN -K signer -q -f KSK -a RSASHA1 -b 1024 -n zone $zone)
   1530 key2=$($KEYGEN -K signer -q -a RSASHA1 -b 1024 -n zone $zone)
   1531 keyid2=$(keyfile_to_key_id "$key2")
   1532 key3=$($KEYGEN -K signer -q -a RSASHA1 -b 1024 -n zone $zone)
   1533 keyid3=$(keyfile_to_key_id "$key3")
   1534 (
   1535 cd signer || exit 1
   1536 cat example.db.in "$key1.key" "$key2.key" > example.db
   1537 $SIGNER -D -o example example.db > /dev/null
   1538 
   1539 # now switch out key2 for key3 and resign the zone
   1540 cat example.db.in "$key1.key" "$key3.key" > example.db
   1541 echo "\$INCLUDE \"example.db.signed\"" >> example.db
   1542 $SIGNER -D -o example example.db > /dev/null
   1543 ) || ret=1
   1544 get_rsasha1_key_ids_from_sigs | grep "^$keyid2$" > /dev/null || ret=1
   1545 get_rsasha1_key_ids_from_sigs | grep "^$keyid3$" > /dev/null || ret=1
   1546 n=$((n+1))
   1547 test "$ret" -eq 0 || echo_i "failed"
   1548 status=$((status+ret))
   1549 
   1550 echo_i "checking dnssec-signzone -R purges signatures from removed keys ($n)"
   1551 ret=0
   1552 (
   1553 cd signer || exit 1
   1554 $SIGNER -RD -o example example.db > /dev/null
   1555 ) || ret=1
   1556 get_rsasha1_key_ids_from_sigs | grep "^$keyid2$" > /dev/null && ret=1
   1557 get_rsasha1_key_ids_from_sigs | grep "^$keyid3$" > /dev/null || ret=1
   1558 n=$((n+1))
   1559 test "$ret" -eq 0 || echo_i "failed"
   1560 status=$((status+ret))
   1561 
   1562 echo_i "checking dnssec-signzone keeps valid signatures from inactive keys ($n)"
   1563 ret=0
   1564 zone=example
   1565 (
   1566 cd signer || exit 1
   1567 cp -f example.db.in example.db
   1568 $SIGNER -SD -o example example.db > /dev/null
   1569 echo "\$INCLUDE \"example.db.signed\"" >> example.db
   1570 # now retire key2 and resign the zone
   1571 $SETTIME -I now "$key2" > /dev/null 2>&1
   1572 $SIGNER -SD -o example example.db > /dev/null
   1573 ) || ret=1
   1574 get_rsasha1_key_ids_from_sigs | grep "^$keyid2$" > /dev/null || ret=1
   1575 get_rsasha1_key_ids_from_sigs | grep "^$keyid3$" > /dev/null || ret=1
   1576 n=$((n+1))
   1577 test "$ret" -eq 0 || echo_i "failed"
   1578 status=$((status+ret))
   1579 
   1580 echo_i "checking dnssec-signzone -Q purges signatures from inactive keys ($n)"
   1581 ret=0
   1582 (
   1583 cd signer || exit 1
   1584 $SIGNER -SDQ -o example example.db > /dev/null
   1585 ) || ret=1
   1586 get_rsasha1_key_ids_from_sigs | grep "^$keyid2$" > /dev/null && ret=1
   1587 get_rsasha1_key_ids_from_sigs | grep "^$keyid3$" > /dev/null || ret=1
   1588 n=$((n+1))
   1589 test "$ret" -eq 0 || echo_i "failed"
   1590 status=$((status+ret))
   1591 
   1592 echo_i "checking dnssec-signzone retains unexpired signatures ($n)"
   1593 ret=0
   1594 (
   1595 cd signer || exit 1
   1596 $SIGNER -Sxt -o example example.db > signer.out.1
   1597 $SIGNER -Sxt -o example -f example.db.signed example.db.signed > signer.out.2
   1598 ) || ret=1
   1599 gen1=$(awk '/generated/ {print $3}' signer/signer.out.1)
   1600 retain1=$(awk '/retained/ {print $3}' signer/signer.out.1)
   1601 gen2=$(awk '/generated/ {print $3}' signer/signer.out.2)
   1602 retain2=$(awk '/retained/ {print $3}' signer/signer.out.2)
   1603 drop2=$(awk '/dropped/ {print $3}' signer/signer.out.2)
   1604 [ "$retain2" -eq $((gen1+retain1)) ] || ret=1
   1605 [ "$gen2" -eq 0 ] || ret=1
   1606 [ "$drop2" -eq 0 ] || ret=1
   1607 n=$((n+1))
   1608 test "$ret" -eq 0 || echo_i "failed"
   1609 status=$((status+ret))
   1610 
   1611 echo_i "checking dnssec-signzone purges RRSIGs from formerly-owned glue (nsec) ($n)"
   1612 ret=0
   1613 (
   1614 cd signer || exit 1
   1615 # remove NSEC-only keys
   1616 rm -f Kexample.+005*
   1617 cp -f example.db.in example2.db
   1618 cat << EOF >> example2.db
   1619 sub1.example. IN A 10.53.0.1
   1620 ns.sub2.example. IN A 10.53.0.2
   1621 EOF
   1622 echo "\$INCLUDE \"example2.db.signed\"" >> example2.db
   1623 touch example2.db.signed
   1624 $SIGNER -DS -O full -f example2.db.signed -o example example2.db > /dev/null
   1625 ) || ret=1
   1626 grep "^sub1\\.example\\..*RRSIG[ 	]A[ 	]" signer/example2.db.signed > /dev/null 2>&1 || ret=1
   1627 grep "^ns\\.sub2\\.example\\..*RRSIG[ 	]A[ 	]" signer/example2.db.signed > /dev/null 2>&1 || ret=1
   1628 (
   1629 cd signer || exit 1
   1630 cp -f example.db.in example2.db
   1631 cat << EOF >> example2.db
   1632 sub1.example. IN NS sub1.example.
   1633 sub1.example. IN A 10.53.0.1
   1634 sub2.example. IN NS ns.sub2.example.
   1635 ns.sub2.example. IN A 10.53.0.2
   1636 EOF
   1637 echo "\$INCLUDE \"example2.db.signed\"" >> example2.db
   1638 $SIGNER -DS -O full -f example2.db.signed -o example example2.db > /dev/null
   1639 ) || ret=1
   1640 grep "^sub1\\.example\\..*RRSIG[ 	]A[ 	]" signer/example2.db.signed > /dev/null 2>&1 && ret=1
   1641 grep "^ns\\.sub2\\.example\\..*RRSIG[ 	]A[ 	]" signer/example2.db.signed > /dev/null 2>&1 && ret=1
   1642 n=$((n+1))
   1643 test "$ret" -eq 0 || echo_i "failed"
   1644 status=$((status+ret))
   1645 
   1646 echo_i "checking dnssec-signzone purges RRSIGs from formerly-owned glue (nsec3) ($n)"
   1647 ret=0
   1648 (
   1649 cd signer || exit 1
   1650 rm -f example2.db.signed
   1651 cp -f example.db.in example2.db
   1652 cat << EOF >> example2.db
   1653 sub1.example. IN A 10.53.0.1
   1654 ns.sub2.example. IN A 10.53.0.2
   1655 EOF
   1656 echo "\$INCLUDE \"example2.db.signed\"" >> example2.db
   1657 touch example2.db.signed
   1658 $SIGNER -DS -3 feedabee -O full -f example2.db.signed -o example example2.db > /dev/null
   1659 ) || ret=1
   1660 grep "^sub1\\.example\\..*RRSIG[ 	]A[ 	]" signer/example2.db.signed > /dev/null 2>&1 || ret=1
   1661 grep "^ns\\.sub2\\.example\\..*RRSIG[ 	]A[ 	]" signer/example2.db.signed > /dev/null 2>&1 || ret=1
   1662 (
   1663 cd signer || exit 1
   1664 cp -f example.db.in example2.db
   1665 cat << EOF >> example2.db
   1666 sub1.example. IN NS sub1.example.
   1667 sub1.example. IN A 10.53.0.1
   1668 sub2.example. IN NS ns.sub2.example.
   1669 ns.sub2.example. IN A 10.53.0.2
   1670 EOF
   1671 echo "\$INCLUDE \"example2.db.signed\"" >> example2.db
   1672 $SIGNER -DS -3 feedabee -O full -f example2.db.signed -o example example2.db > /dev/null
   1673 ) || ret=1
   1674 grep "^sub1\\.example\\..*RRSIG[ 	]A[ 	]" signer/example2.db.signed > /dev/null 2>&1 && ret=1
   1675 grep "^ns\\.sub2\\.example\\..*RRSIG[ 	]A[ 	]" signer/example2.db.signed > /dev/null 2>&1 && ret=1
   1676 n=$((n+1))
   1677 test "$ret" -eq 0 || echo_i "failed"
   1678 status=$((status+ret))
   1679 
   1680 echo_i "checking dnssec-signzone output format ($n)"
   1681 ret=0
   1682 (
   1683 cd signer || exit 1
   1684 $SIGNER -O full -f - -Sxt -o example example.db > signer.out.3 2> /dev/null
   1685 $SIGNER -O text -f - -Sxt -o example example.db > signer.out.4 2> /dev/null
   1686 $SIGNER -O raw -f signer.out.5 -Sxt -o example example.db > /dev/null
   1687 $SIGNER -O raw=0 -f signer.out.6 -Sxt -o example example.db > /dev/null
   1688 $SIGNER -O raw -f - -Sxt -o example example.db > signer.out.7 2> /dev/null
   1689 ) || ret=1
   1690 awk '/IN *SOA/ {if (NF != 11) exit(1)}' signer/signer.out.3 || ret=1
   1691 awk '/IN *SOA/ {if (NF != 7) exit(1)}' signer/signer.out.4 || ret=1
   1692 israw1 signer/signer.out.5 || ret=1
   1693 israw0 signer/signer.out.6 || ret=1
   1694 israw1 signer/signer.out.7 || ret=1
   1695 n=$((n+1))
   1696 test "$ret" -eq 0 || echo_i "failed"
   1697 status=$((status+ret))
   1698 
   1699 echo_i "checking TTLs are capped by dnssec-signzone -M ($n)"
   1700 ret=0
   1701 (
   1702 cd signer || exit 1
   1703 $SIGNER -O full -f signer.out.8 -S -M 30 -o example example.db > /dev/null
   1704 ) || ret=1
   1705 awk '/^;/ { next; } $2 > 30 { exit 1; }' signer/signer.out.8 || ret=1
   1706 n=$((n+1))
   1707 test "$ret" -eq 0 || echo_i "failed"
   1708 status=$((status+ret))
   1709 
   1710 echo_i "checking dnssec-signzone -N date ($n)"
   1711 ret=0
   1712 (
   1713 cd signer || exit 1
   1714 TZ=UTC $SIGNER -O full -f signer.out.9 -S -N date -o example example2.db > /dev/null
   1715 ) || ret=1
   1716 # shellcheck disable=SC2016
   1717 now=$(TZ=UTC $PERL -e '@lt=localtime(); printf "%.4d%0.2d%0.2d00\n",$lt[5]+1900,$lt[4]+1,$lt[3];')
   1718 serial=$(awk '/^;/ { next; } $4 == "SOA" { print $7 }' signer/signer.out.9)
   1719 [ "$now" -eq "$serial" ] || ret=1
   1720 n=$((n+1))
   1721 test "$ret" -eq 0 || echo_i "failed"
   1722 status=$((status+ret))
   1723 
   1724 echo_i "checking validated data are not cached longer than originalttl ($n)"
   1725 ret=0
   1726 dig_with_opts +ttl +noauth a.ttlpatch.example. @10.53.0.3 a > dig.out.ns3.test$n || ret=1
   1727 dig_with_opts +ttl +noauth a.ttlpatch.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1
   1728 grep "3600.IN" dig.out.ns3.test$n > /dev/null || ret=1
   1729 grep "300.IN" dig.out.ns3.test$n > /dev/null && ret=1
   1730 grep "300.IN" dig.out.ns4.test$n > /dev/null || ret=1
   1731 grep "3600.IN" dig.out.ns4.test$n > /dev/null && ret=1
   1732 n=$((n+1))
   1733 test "$ret" -eq 0 || echo_i "failed"
   1734 status=$((status+ret))
   1735 
   1736 # Test that "rndc secroots" is able to dump trusted keys
   1737 echo_i "checking rndc secroots ($n)"
   1738 ret=0
   1739 keyid=$(cat ns1/managed.key.id)
   1740 rndccmd 10.53.0.4 secroots 2>&1 | sed 's/^/ns4 /' | cat_i
   1741 cp ns4/named.secroots named.secroots.test$n
   1742 check_secroots_layout named.secroots.test$n || ret=1
   1743 linecount=$(grep -c "./${DEFAULT_ALGORITHM}/$keyid ; static" named.secroots.test$n || true)
   1744 [ "$linecount" -eq 1 ] || ret=1
   1745 linecount=$(< named.secroots.test$n wc -l)
   1746 [ "$linecount" -eq 9 ] || ret=1
   1747 n=$((n+1))
   1748 test "$ret" -eq 0 || echo_i "failed"
   1749 status=$((status+ret))
   1750 
   1751 # Check direct query for RRSIG.  If we first ask for normal (non RRSIG)
   1752 # record, the corresponding RRSIG should be cached and subsequent query
   1753 # for RRSIG will be returned with the cached record.
   1754 echo_i "checking RRSIG query from cache ($n)"
   1755 ret=0
   1756 dig_with_opts normalthenrrsig.secure.example. @10.53.0.4 a > /dev/null || ret=1
   1757 ans=$(dig_with_opts +short normalthenrrsig.secure.example. @10.53.0.4 rrsig) || ret=1
   1758 expect=$(dig_with_opts +short normalthenrrsig.secure.example. @10.53.0.3 rrsig | grep '^A' ) || ret=1
   1759 test "$ans" = "$expect" || ret=1
   1760 # also check that RA is set
   1761 dig_with_opts normalthenrrsig.secure.example. @10.53.0.4 rrsig > dig.out.ns4.test$n || ret=1
   1762 grep "flags:.*ra.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
   1763 n=$((n+1))
   1764 test "$ret" -eq 0 || echo_i "failed"
   1765 status=$((status+ret))
   1766 
   1767 # Check direct query for RRSIG: If it's not cached with other records,
   1768 # it should result in an empty response.
   1769 echo_i "checking RRSIG query not in cache ($n)"
   1770 ret=0
   1771 ans=$(dig_with_opts +short rrsigonly.secure.example. @10.53.0.4 rrsig) || ret=1
   1772 test -z "$ans" || ret=1
   1773 # also check that RA is cleared
   1774 dig_with_opts rrsigonly.secure.example. @10.53.0.4 rrsig > dig.out.ns4.test$n || ret=1
   1775 grep "flags:.*ra.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1
   1776 n=$((n+1))
   1777 test "$ret" -eq 0 || echo_i "failed"
   1778 status=$((status+ret))
   1779 
   1780 #
   1781 # RT21868 regression test.
   1782 #
   1783 echo_i "checking NSEC3 zone with mismatched NSEC3PARAM / NSEC parameters ($n)"
   1784 ret=0
   1785 dig_with_opts non-exist.badparam. @10.53.0.2 a > dig.out.ns2.test$n || ret=1
   1786 grep "status: NXDOMAIN" dig.out.ns2.test$n > /dev/null || ret=1
   1787 n=$((n+1))
   1788 test "$ret" -eq 0 || echo_i "failed"
   1789 status=$((status+ret))
   1790 
   1791 #
   1792 # RT22007 regression test.
   1793 #
   1794 echo_i "checking optout NSEC3 referral with only insecure delegations ($n)"
   1795 ret=0
   1796 dig_with_opts +norec delegation.single-nsec3. @10.53.0.2 a > dig.out.ns2.test$n || ret=1
   1797 grep "status: NOERROR" dig.out.ns2.test$n > /dev/null || ret=1
   1798 grep "3KL3NK1HKQ4IUEEHBEF12VGFKUETNBAN.*NSEC3 1 1 1 - 3KL3NK1HKQ4IUEEHBEF12VGFKUETNBAN" dig.out.ns2.test$n > /dev/null || ret=1
   1799 n=$((n+1))
   1800 test "$ret" -eq 0 || echo_i "failed"
   1801 status=$((status+ret))
   1802 
   1803 echo_i "checking optout NSEC3 NXDOMAIN with only insecure delegations ($n)"
   1804 ret=0
   1805 dig_with_opts +norec nonexist.single-nsec3. @10.53.0.2 a > dig.out.ns2.test$n || ret=1
   1806 grep "status: NXDOMAIN" dig.out.ns2.test$n > /dev/null || ret=1
   1807 grep "3KL3NK1HKQ4IUEEHBEF12VGFKUETNBAN.*NSEC3 1 1 1 - 3KL3NK1HKQ4IUEEHBEF12VGFKUETNBAN" dig.out.ns2.test$n > /dev/null || ret=1
   1808 n=$((n+1))
   1809 test "$ret" -eq 0 || echo_i "failed"
   1810 
   1811 status=$((status+ret))
   1812 echo_i "checking optout NSEC3 nodata with only insecure delegations ($n)"
   1813 ret=0
   1814 dig_with_opts +norec single-nsec3. @10.53.0.2 a > dig.out.ns2.test$n || ret=1
   1815 grep "status: NOERROR" dig.out.ns2.test$n > /dev/null || ret=1
   1816 grep "3KL3NK1HKQ4IUEEHBEF12VGFKUETNBAN.*NSEC3 1 1 1 - 3KL3NK1HKQ4IUEEHBEF12VGFKUETNBAN" dig.out.ns2.test$n > /dev/null || ret=1
   1817 n=$((n+1))
   1818 test "$ret" -eq 0 || echo_i "failed"
   1819 status=$((status+ret))
   1820 
   1821 echo_i "checking that a zone finishing the transition from $ALTERNATIVE_ALGORITHM to $DEFAULT_ALGORITHM validates secure ($n)"
   1822 ret=0
   1823 dig_with_opts ns algroll. @10.53.0.4 > dig.out.ns4.test$n || ret=1
   1824 grep "NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
   1825 grep "flags:[^;]* ad[^;]*;" dig.out.ns4.test$n > /dev/null || ret=1
   1826 n=$((n+1))
   1827 test "$ret" -eq 0 || echo_i "failed"
   1828 status=$((status+ret))
   1829 
   1830 echo_i "checking validate-except in an insecure local domain ($n)"
   1831 ret=0
   1832 dig_with_opts ns www.corp @10.53.0.4 > dig.out.ns4.test$n || ret=1
   1833 grep "NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
   1834 grep "flags:[^;]* ad[^;]*;" dig.out.ns4.test$n > /dev/null && ret=1
   1835 n=$((n+1))
   1836 test "$ret" -eq 0 || echo_i "failed"
   1837 status=$((status+ret))
   1838 
   1839 echo_i "checking positive and negative validation with negative trust anchors ($n)"
   1840 ret=0
   1841 
   1842 #
   1843 # check correct initial behavior
   1844 #
   1845 dig_with_opts a.bogus.example. a @10.53.0.4 > dig.out.ns4.test$n.1 || ret=1
   1846 grep "status: SERVFAIL" dig.out.ns4.test$n.1 > /dev/null || ret=1
   1847 dig_with_opts badds.example. soa @10.53.0.4 > dig.out.ns4.test$n.2 || ret=1
   1848 grep "status: SERVFAIL" dig.out.ns4.test$n.2 > /dev/null || ret=1
   1849 dig_with_opts a.secure.example. a @10.53.0.4 > dig.out.ns4.test$n.3 || ret=1
   1850 grep "status: SERVFAIL" dig.out.ns4.test$n.3 > /dev/null && ret=1
   1851 grep "flags:[^;]* ad[^;]*;" dig.out.ns4.test$n.3 > /dev/null || ret=1
   1852 
   1853 if [ "$ret" -ne 0 ]; then echo_i "failed - checking initial state"; fi
   1854 status=$((status+ret))
   1855 ret=0
   1856 
   1857 #
   1858 # add negative trust anchors
   1859 #
   1860 rndccmd 10.53.0.4 nta -f -l 20s bogus.example 2>&1 | sed 's/^/ns4 /' | cat_i
   1861 rndccmd 10.53.0.4 nta badds.example 2>&1 | sed 's/^/ns4 /' | cat_i
   1862 # reconfig should maintain NTAs
   1863 rndccmd 10.53.0.4 reconfig 2>&1 | sed 's/^/ns4 /' | cat_i
   1864 rndccmd 10.53.0.4 nta -d > rndc.out.ns4.test$n.1
   1865 lines=$(wc -l < rndc.out.ns4.test$n.1)
   1866 [ "$lines" -eq 2 ] || ret=1
   1867 rndccmd 10.53.0.4 nta secure.example 2>&1 | sed 's/^/ns4 /' | cat_i
   1868 rndccmd 10.53.0.4 nta fakenode.secure.example 2>&1 | sed 's/^/ns4 /' | cat_i
   1869 # reload should maintain NTAs
   1870 rndc_reload ns4 10.53.0.4
   1871 rndccmd 10.53.0.4 nta -d > rndc.out.ns4.test$n.2
   1872 lines=$(wc -l < rndc.out.ns4.test$n.2)
   1873 [ "$lines" -eq 4 ] || ret=1
   1874 # shellcheck disable=SC2016
   1875 start=$($PERL -e 'print time()."\n";')
   1876 
   1877 if [ "$ret" -ne 0 ]; then echo_i "failed - adding NTA's failed"; fi
   1878 status=$((status+ret))
   1879 ret=0
   1880 
   1881 #
   1882 # check behavior with NTA's in place
   1883 #
   1884 dig_with_opts a.bogus.example. a @10.53.0.4 > dig.out.ns4.test$n.4 || ret=1
   1885 grep "status: SERVFAIL" dig.out.ns4.test$n.4 > /dev/null && ret=1
   1886 grep "flags:[^;]* ad[^;]*;" dig.out.ns4.test$n.4 > /dev/null && ret=1
   1887 dig_with_opts badds.example. soa @10.53.0.4 > dig.out.ns4.test$n.5 || ret=1
   1888 grep "status: SERVFAIL" dig.out.ns4.test$n.5 > /dev/null && ret=1
   1889 grep "flags:[^;]* ad[^;]*;" dig.out.ns4.test$n.5 > /dev/null && ret=1
   1890 dig_with_opts a.secure.example. a @10.53.0.4 > dig.out.ns4.test$n.6 || ret=1
   1891 grep "status: SERVFAIL" dig.out.ns4.test$n.6 > /dev/null && ret=1
   1892 grep "flags:[^;]* ad[^;]*;" dig.out.ns4.test$n.6 > /dev/null && ret=1
   1893 dig_with_opts a.fakenode.secure.example. a @10.53.0.4 > dig.out.ns4.test$n.7 || ret=1
   1894 grep "flags:[^;]* ad[^;]*;" dig.out.ns4.test$n.7 > /dev/null && ret=1
   1895 echo_i "dumping secroots"
   1896 rndccmd 10.53.0.4 secroots | sed 's/^/ns4 /' | cat_i
   1897 cp ns4/named.secroots named.secroots.test$n
   1898 check_secroots_layout named.secroots.test$n || ret=1
   1899 grep "bogus.example: expiry" named.secroots.test$n > /dev/null || ret=1
   1900 grep "badds.example: expiry" named.secroots.test$n > /dev/null || ret=1
   1901 grep "secure.example: expiry" named.secroots.test$n > /dev/null || ret=1
   1902 grep "fakenode.secure.example: expiry" named.secroots.test$n > /dev/null || ret=1
   1903 
   1904 if [ "$ret" -ne 0 ]; then echo_i "failed - with NTA's in place failed"; fi
   1905 status=$((status+ret))
   1906 ret=0
   1907 
   1908 echo_i "waiting for NTA rechecks/expirations"
   1909 
   1910 #
   1911 # secure.example and badds.example used default nta-duration
   1912 # (configured as 12s in ns4/named1.conf), but nta recheck interval
   1913 # is configured to 9s, so at t=10 the NTAs for secure.example and
   1914 # fakenode.secure.example should both be lifted, but badds.example
   1915 # should still be going.
   1916 #
   1917 # shellcheck disable=SC2016
   1918 $PERL -e 'my $delay =  '"$start"' + 10 - time(); select(undef, undef, undef, $delay) if ($delay > 0);'
   1919 dig_with_opts b.secure.example. a @10.53.0.4 > dig.out.ns4.test$n.8 || ret=1
   1920 grep "status: SERVFAIL" dig.out.ns4.test$n.8 > /dev/null && ret=1
   1921 grep "flags:[^;]* ad[^;]*;" dig.out.ns4.test$n.8 > /dev/null || ret=1
   1922 dig_with_opts b.fakenode.secure.example. a @10.53.0.4 > dig.out.ns4.test$n.9 || ret=1
   1923 grep "flags:[^;]* ad[^;]*;" dig.out.ns4.test$n.9 > /dev/null || ret=1
   1924 grep "status: NXDOMAIN" dig.out.ns4.test$n.9 > /dev/null || ret=1
   1925 dig_with_opts badds.example. soa @10.53.0.4 > dig.out.ns4.test$n.10 || ret=1
   1926 grep "status: SERVFAIL" dig.out.ns4.test$n.10 > /dev/null && ret=1
   1927 grep "flags:[^;]* ad[^;]*;" dig.out.ns4.test$n.10 > /dev/null && ret=1
   1928 
   1929 if [ "$ret" -ne 0 ]; then echo_i "failed - checking that default nta's were lifted due to recheck"; fi
   1930 status=$((status+ret))
   1931 ret=0
   1932 
   1933 #
   1934 # bogus.example was set to expire in 20s, so at t=13
   1935 # it should still be NTA'd, but badds.example used the default
   1936 # lifetime of 12s, so it should revert to SERVFAIL now.
   1937 #
   1938 # shellcheck disable=SC2016
   1939 $PERL -e 'my $delay = '"$start"' + 13 - time(); select(undef, undef, undef, $delay) if ($delay > 0);'
   1940 # check nta table
   1941 rndccmd 10.53.0.4 nta -d > rndc.out.ns4.test$n._11
   1942 lines=$(grep -c " expiry " rndc.out.ns4.test$n._11 || true)
   1943 [ "$lines" -le 2 ] || ret=1
   1944 grep "bogus.example/_default: expiry" rndc.out.ns4.test$n._11 > /dev/null || ret=1
   1945 grep "badds.example/_default: expiry" rndc.out.ns4.test$n._11 > /dev/null && ret=1
   1946 dig_with_opts b.bogus.example. a @10.53.0.4 > dig.out.ns4.test$n.11 || ret=1
   1947 grep "status: SERVFAIL" dig.out.ns4.test$n.11 > /dev/null && ret=1
   1948 dig_with_opts a.badds.example. a @10.53.0.4 > dig.out.ns4.test$n.12 || ret=1
   1949 grep "status: SERVFAIL" dig.out.ns4.test$n.12 > /dev/null || ret=1
   1950 grep "flags:[^;]* ad[^;]*;" dig.out.ns4.test$n.12 > /dev/null && ret=1
   1951 dig_with_opts c.secure.example. a @10.53.0.4 > dig.out.ns4.test$n.13 || ret=1
   1952 grep "status: SERVFAIL" dig.out.ns4.test$n.13 > /dev/null && ret=1
   1953 grep "flags:[^;]* ad[^;]*;" dig.out.ns4.test$n.13 > /dev/null || ret=1
   1954 
   1955 if [ "$ret" -ne 0 ]; then echo_i "failed - checking that default nta's were lifted due to lifetime"; fi
   1956 status=$((status+ret))
   1957 ret=0
   1958 
   1959 #
   1960 # at t=21, all the NTAs should have expired.
   1961 #
   1962 # shellcheck disable=SC2016
   1963 $PERL -e 'my $delay = '"$start"' + 21 - time(); select(undef, undef, undef, $delay) if ($delay > 0);'
   1964 # check correct behavior after bogus.example expiry
   1965 dig_with_opts d.secure.example. a @10.53.0.4 > dig.out.ns4.test$n.14 || ret=1
   1966 grep "status: SERVFAIL" dig.out.ns4.test$n.14 > /dev/null && ret=1
   1967 grep "flags:[^;]* ad[^;]*;" dig.out.ns4.test$n.14 > /dev/null || ret=1
   1968 dig_with_opts c.bogus.example. a @10.53.0.4 > dig.out.ns4.test$n.15 || ret=1
   1969 grep "status: SERVFAIL" dig.out.ns4.test$n.15 > /dev/null || ret=1
   1970 # check nta table has been cleaned up now
   1971 rndccmd 10.53.0.4 nta -d > rndc.out.ns4.test$n.3
   1972 lines=$(grep -c " expiry " rndc.out.ns4.test$n.3 || true)
   1973 [ "$lines" -eq 0 ] || ret=1
   1974 n=$((n+1))
   1975 if [ "$ret" -ne 0 ]; then echo_i "failed - checking that all nta's have been lifted"; fi
   1976 status=$((status+ret))
   1977 ret=0
   1978 
   1979 echo_i "testing NTA removals ($n)"
   1980 rndccmd 10.53.0.4 nta badds.example 2>&1 | sed 's/^/ns4 /' | cat_i
   1981 rndccmd 10.53.0.4 nta -d > rndc.out.ns4.test$n.1
   1982 grep "badds.example/_default: expiry" rndc.out.ns4.test$n.1 > /dev/null || ret=1
   1983 dig_with_opts a.badds.example. a @10.53.0.4 > dig.out.ns4.test$n.1 || ret=1
   1984 grep "status: SERVFAIL" dig.out.ns4.test$n.1 > /dev/null && ret=1
   1985 grep "^a.badds.example." dig.out.ns4.test$n.1 > /dev/null || ret=1
   1986 rndccmd 10.53.0.4 nta -remove badds.example > rndc.out.ns4.test$n.2
   1987 grep "Negative trust anchor removed: badds.example/_default" rndc.out.ns4.test$n.2 > /dev/null || ret=1
   1988 rndccmd 10.53.0.4 nta -d > rndc.out.ns4.test$n.3
   1989 grep "badds.example/_default: expiry" rndc.out.ns4.test$n.3 > /dev/null && ret=1
   1990 dig_with_opts a.badds.example. a @10.53.0.4 > dig.out.ns4.test$n.2 || ret=1
   1991 grep "status: SERVFAIL" dig.out.ns4.test$n.2 > /dev/null || ret=1
   1992 test "$ret" -eq 0 || echo_i "failed"
   1993 status=$((status+ret))
   1994 ret=0
   1995 
   1996 echo_i "remove non-existent NTA three times"
   1997 rndccmd 10.53.0.4 nta -r foo > rndc.out.ns4.test$n.4 2>&1
   1998 rndccmd 10.53.0.4 nta -remove foo > rndc.out.ns4.test$n.5 2>&1
   1999 rndccmd 10.53.0.4 nta -r foo > rndc.out.ns4.test$n.6 2>&1
   2000 grep "not found" rndc.out.ns4.test$n.6 > /dev/null || ret=1
   2001 test "$ret" -eq 0 || echo_i "failed"
   2002 status=$((status+ret))
   2003 ret=0
   2004 
   2005 n=$((n+1))
   2006 echo_i "testing NTA with bogus lifetimes ($n)"
   2007 echo_i "check with no nta lifetime specified"
   2008 rndccmd 10.53.0.4 nta -l "" foo > rndc.out.ns4.test$n.1 2>&1 || true
   2009 grep "'nta' failed: bad ttl" rndc.out.ns4.test$n.1 > /dev/null || ret=1
   2010 test "$ret" -eq 0 || echo_i "failed"
   2011 status=$((status+ret))
   2012 ret=0
   2013 
   2014 echo_i "check with bad nta lifetime"
   2015 rndccmd 10.53.0.4 nta -l garbage foo > rndc.out.ns4.test$n.2 2>&1 || true
   2016 grep "'nta' failed: bad ttl" rndc.out.ns4.test$n.2 > /dev/null || ret=1
   2017 test "$ret" -eq 0 || echo_i "failed"
   2018 status=$((status+ret))
   2019 ret=0
   2020 
   2021 echo_i "check with too long nta lifetime"
   2022 rndccmd 10.53.0.4 nta -l 7d1h foo > rndc.out.ns4.test$n.3 2>&1 || true
   2023 grep "'nta' failed: out of range" rndc.out.ns4.test$n.3 > /dev/null || ret=1
   2024 test "$ret" -eq 0 || echo_i "failed"
   2025 status=$((status+ret))
   2026 ret=0
   2027 
   2028 #
   2029 # check NTA persistence across restarts
   2030 #
   2031 n=$((n+1))
   2032 echo_i "testing NTA persistence across restarts ($n)"
   2033 rndccmd 10.53.0.4 nta -d > rndc.out.ns4.test$n.1
   2034 lines=$(grep -c " expiry " rndc.out.ns4.test$n.1 || true)
   2035 [ "$lines" -eq 0 ] || ret=1
   2036 rndccmd 10.53.0.4 nta -f -l 30s bogus.example 2>&1 | sed 's/^/ns4 /' | cat_i
   2037 rndccmd 10.53.0.4 nta -f -l 10s badds.example 2>&1 | sed 's/^/ns4 /' | cat_i
   2038 rndccmd 10.53.0.4 nta -d > rndc.out.ns4.test$n.2
   2039 lines=$(grep -c " expiry " rndc.out.ns4.test$n.2 || true)
   2040 [ "$lines" -eq 2 ] || ret=1
   2041 # shellcheck disable=SC2016
   2042 start=$($PERL -e 'print time()."\n";')
   2043 
   2044 if [ "$ret" -ne 0 ]; then echo_i "failed - NTA persistence: adding NTA's failed"; fi
   2045 status=$((status+ret))
   2046 ret=0
   2047 
   2048 echo_i "killing ns4 with SIGTERM"
   2049 $KILL -TERM "$(cat ns4/named.pid)"
   2050 rm -f ns4/named.pid
   2051 
   2052 #
   2053 # ns4 has now shutdown. wait until t=14 when badds.example's NTA
   2054 # (lifetime=10s) would have expired, and then restart ns4.
   2055 #
   2056 echo_i "waiting till 14s have passed since NTAs were added before restarting ns4"
   2057 # shellcheck disable=SC2016
   2058 $PERL -e 'my $delay = '"$start"' + 14 - time(); select(undef, undef, undef, $delay) if ($delay > 0);'
   2059 
   2060 if
   2061     $PERL "$SYSTEMTESTTOP/start.pl" --noclean --restart --port "$PORT" dnssec ns4
   2062 then
   2063     echo_i "restarted server ns4"
   2064 else
   2065     echo_i "could not restart server ns4"
   2066     exit 1
   2067 fi
   2068 
   2069 echo_i "sleeping for an additional 4 seconds for ns4 to fully startup"
   2070 sleep 4
   2071 
   2072 #
   2073 # ns4 should be back up now. The NTA for bogus.example should still be
   2074 # valid, whereas badds.example should not have been added during named
   2075 # startup (as it had already expired), the fact that it's ignored should
   2076 # be logged.
   2077 #
   2078 rndccmd 10.53.0.4 nta -d > rndc.out.ns4.test$n.3
   2079 lines=$(wc -l < rndc.out.ns4.test$n.3)
   2080 [ "$lines" -eq 1 ] || ret=1
   2081 grep "bogus.example/_default: expiry" rndc.out.ns4.test$n.3 > /dev/null || ret=1
   2082 dig_with_opts b.bogus.example. a @10.53.0.4 > dig.out.ns4.test$n.4 || ret=1
   2083 grep "status: SERVFAIL" dig.out.ns4.test$n.4 > /dev/null && ret=1
   2084 grep "flags:[^;]* ad[^;]*;" dig.out.ns4.test$n.4 > /dev/null && ret=1
   2085 dig_with_opts a.badds.example. a @10.53.0.4 > dig.out.ns4.test$n.5 || ret=1
   2086 grep "status: SERVFAIL" dig.out.ns4.test$n.5 > /dev/null || ret=1
   2087 grep "ignoring expired NTA at badds.example" ns4/named.run > /dev/null || ret=1
   2088 
   2089 # cleanup
   2090 rndccmd 10.53.0.4 nta -remove bogus.example > rndc.out.ns4.test$n.6
   2091 
   2092 if [ "$ret" -ne 0 ]; then echo_i "failed - NTA persistence: restoring NTA failed"; fi
   2093 status=$((status+ret))
   2094 ret=0
   2095 
   2096 #
   2097 # check "regular" attribute in NTA file works as expected at named
   2098 # startup.
   2099 #
   2100 n=$((n+1))
   2101 echo_i "testing loading regular attribute from NTA file ($n)"
   2102 rndccmd 10.53.0.4 nta -d > rndc.out.ns4.test$n.1 2>/dev/null
   2103 lines=$(wc -l < rndc.out.ns4.test$n.1)
   2104 [ "$lines" -eq 0 ] || ret=1
   2105 # initially, secure.example. validates with AD=1
   2106 dig_with_opts a.secure.example. a @10.53.0.4 > dig.out.ns4.test$n.2 || ret=1
   2107 grep "status: SERVFAIL" dig.out.ns4.test$n.2 > /dev/null && ret=1
   2108 grep "flags:[^;]* ad[^;]*;" dig.out.ns4.test$n.2 > /dev/null || ret=1
   2109 
   2110 echo_i "killing ns4 with SIGTERM"
   2111 $KILL -TERM "$(cat ns4/named.pid)"
   2112 rm -f ns4/named.pid
   2113 
   2114 echo_i "sleeping for an additional 4 seconds for ns4 to fully shutdown"
   2115 sleep 4
   2116 
   2117 #
   2118 # ns4 has now shutdown. add NTA for secure.example. directly into the
   2119 # _default.nta file with the regular attribute and some future timestamp.
   2120 #
   2121 future="$(($(date +%Y)+20))0101010000"
   2122 echo "secure.example. regular $future" > ns4/_default.nta
   2123 # shellcheck disable=SC2016
   2124 start=$($PERL -e 'print time()."\n";')
   2125 
   2126 if
   2127     $PERL "$SYSTEMTESTTOP/start.pl" --noclean --restart --port "$PORT" dnssec ns4
   2128 then
   2129     echo_i "restarted server ns4"
   2130 else
   2131     echo_i "could not restart server ns4"
   2132     exit 1
   2133 fi
   2134 
   2135 # nta-recheck is configured as 9s, so at t=12 the NTAs for
   2136 # secure.example. should be lifted as it is not a forced NTA.
   2137 echo_i "waiting till 12s have passed after ns4 was restarted"
   2138 # shellcheck disable=SC2016
   2139 $PERL -e 'my $delay = '"$start"' + 12 - time(); select(undef, undef, undef, $delay) if ($delay > 0);'
   2140 
   2141 # secure.example. should now return an AD=1 answer (still validates) as
   2142 # the NTA has been lifted.
   2143 dig_with_opts a.secure.example. a @10.53.0.4 > dig.out.ns4.test$n.3 || ret=1
   2144 grep "status: SERVFAIL" dig.out.ns4.test$n.3 > /dev/null && ret=1
   2145 grep "flags:[^;]* ad[^;]*;" dig.out.ns4.test$n.3 > /dev/null || ret=1
   2146 
   2147 # cleanup
   2148 rndccmd 10.53.0.4 nta -remove secure.example > rndc.out.ns4.test$n.4 2>/dev/null
   2149 
   2150 if [ "$ret" -ne 0 ]; then echo_i "failed - NTA persistence: loading regular NTAs failed"; fi
   2151 status=$((status+ret))
   2152 ret=0
   2153 
   2154 #
   2155 # check "forced" attribute in NTA file works as expected at named
   2156 # startup.
   2157 #
   2158 n=$((n+1))
   2159 echo_i "testing loading forced attribute from NTA file ($n)"
   2160 rndccmd 10.53.0.4 nta -d > rndc.out.ns4.test$n.1 2>/dev/null
   2161 lines=$(wc -l < rndc.out.ns4.test$n.1)
   2162 [ "$lines" -eq 0 ] || ret=1
   2163 # initially, secure.example. validates with AD=1
   2164 dig_with_opts a.secure.example. a @10.53.0.4 > dig.out.ns4.test$n.2 || ret=1
   2165 grep "status: SERVFAIL" dig.out.ns4.test$n.2 > /dev/null && ret=1
   2166 grep "flags:[^;]* ad[^;]*;" dig.out.ns4.test$n.2 > /dev/null || ret=1
   2167 
   2168 echo_i "killing ns4 with SIGTERM"
   2169 $KILL -TERM "$(cat ns4/named.pid)"
   2170 rm -f named.pid
   2171 
   2172 echo_i "sleeping for an additional 4 seconds for ns4 to fully shutdown"
   2173 sleep 4
   2174 
   2175 #
   2176 # ns4 has now shutdown. add NTA for secure.example. directly into the
   2177 # _default.nta file with the forced attribute and some future timestamp.
   2178 #
   2179 echo "secure.example. forced $future" > ns4/_default.nta
   2180 start=$($PERL -e 'print time()."\n";')
   2181 
   2182 if
   2183     $PERL "$SYSTEMTESTTOP/start.pl" --noclean --restart --port "$PORT" dnssec ns4
   2184 then
   2185     echo_i "restarted server ns4"
   2186 else
   2187     echo_i "could not restart server ns4"
   2188     exit 1
   2189 fi
   2190 
   2191 # nta-recheck is configured as 9s, but even at t=12 the NTAs for
   2192 # secure.example. should not be lifted as it is a forced NTA.
   2193 echo_i "waiting till 12s have passed after ns4 was restarted"
   2194 # shellcheck disable=SC2016
   2195 $PERL -e 'my $delay = '"$start"' + 12 - time(); select(undef, undef, undef, $delay) if ($delay > 0);'
   2196 
   2197 # secure.example. should now return an AD=0 answer (non-authenticated)
   2198 # as the NTA is still there.
   2199 dig_with_opts a.secure.example. a @10.53.0.4 > dig.out.ns4.test$n.3 || ret=1
   2200 grep "status: SERVFAIL" dig.out.ns4.test$n.3 > /dev/null && ret=1
   2201 grep "flags:[^;]* ad[^;]*;" dig.out.ns4.test$n.3 > /dev/null && ret=1
   2202 
   2203 # cleanup
   2204 rndccmd 10.53.0.4 nta -remove secure.example > rndc.out.ns4.test$n.4 2>/dev/null
   2205 
   2206 if [ "$ret" -ne 0 ]; then echo_i "failed - NTA persistence: loading forced NTAs failed"; fi
   2207 status=$((status+ret))
   2208 ret=0
   2209 
   2210 #
   2211 # check that NTA lifetime read from file is clamped to 1 week.
   2212 #
   2213 n=$((n+1))
   2214 echo_i "testing loading out of bounds lifetime from NTA file ($n)"
   2215 
   2216 echo_i "killing ns4 with SIGTERM"
   2217 $KILL -TERM "$(cat ns4/named.pid)"
   2218 rm -f ns4/named.pid
   2219 
   2220 echo_i "sleeping for an additional 4 seconds for ns4 to fully shutdown"
   2221 sleep 4
   2222 
   2223 #
   2224 # ns4 has now shutdown. add NTA for secure.example. directly into the
   2225 # _default.nta file with a lifetime well into the future.
   2226 #
   2227 echo "secure.example. forced $future" > ns4/_default.nta
   2228 added=$($PERL -e 'print time()."\n";')
   2229 
   2230 if
   2231     $PERL "$SYSTEMTESTTOP/start.pl" --noclean --restart --port "$PORT" dnssec ns4
   2232 then
   2233     echo_i "restarted server ns4"
   2234 else
   2235     echo_i "could not restart server ns4"
   2236     exit 1
   2237 fi
   2238 
   2239 echo_i "sleeping for an additional 4 seconds for ns4 to fully startup"
   2240 sleep 4
   2241 
   2242 # dump the NTA to a file (omit validate-except entries)
   2243 echo_i "testing 'rndc nta'"
   2244 rndccmd 10.53.0.4 nta -d > rndc.out.ns4.test$n.1 2>/dev/null
   2245 # "corp" is configured as a validate-except domain and thus should be
   2246 # omitted. only "secure.example" should be in the dump at this point.
   2247 lines=$(wc -l < rndc.out.ns4.test$n.1)
   2248 [ "$lines" -eq 1 ] || ret=1
   2249 grep 'secure.example' rndc.out.ns4.test$n.1 > /dev/null || ret=1
   2250 ts=$(awk '{print $3" "$4}' < rndc.out.ns4.test$n.1)
   2251 # rndc nta outputs localtime, so append the timezone
   2252 ts_with_zone="$ts $(date +%z)"
   2253 echo "ts=$ts" > rndc.out.ns4.test$n.2
   2254 echo "ts_with_zone=$ts_with_zone" >> rndc.out.ns4.test$n.2
   2255 echo "added=$added" >> rndc.out.ns4.test$n.2
   2256 if $PERL -e 'use Time::Piece; use Time::Seconds;' 2>/dev/null
   2257 then
   2258     # ntadiff.pl computes $ts_with_zone - ($added + 1week)
   2259     d=$($PERL ./ntadiff.pl "$ts_with_zone" "$added")
   2260     echo "d=$d" >> rndc.out.ns4.test$n.2
   2261     # diff from $added(now) + 1week to the clamped NTA lifetime should be
   2262     # less than a few seconds (handle daylight saving changes by adding 3600).
   2263     [ "$d" -lt 3610 ] || ret=1
   2264 else
   2265     echo_i "skipped ntadiff test; install PERL module Time::Piece"
   2266 fi
   2267 
   2268 # cleanup
   2269 rndccmd 10.53.0.4 nta -remove secure.example > rndc.out.ns4.test$n.3 2>/dev/null
   2270 
   2271 n=$((n+1))
   2272 if [ "$ret" -ne 0 ]; then echo_i "failed - NTA lifetime clamping failed"; fi
   2273 status=$((status+ret))
   2274 
   2275 echo_i "checking that NTAs work with 'forward only;' to a validating resolver ($n)"
   2276 ret=0
   2277 # Sanity check behavior without an NTA in place.
   2278 dig_with_opts @10.53.0.9 badds.example. SOA > dig.out.ns9.test$n.1 || ret=1
   2279 grep "SERVFAIL" dig.out.ns9.test$n.1 > /dev/null || ret=1
   2280 grep "ANSWER: 0" dig.out.ns9.test$n.1 > /dev/null || ret=1
   2281 grep "flags:[^;]* ad[ ;].*QUERY" dig.out.ns9.test$n.1 > /dev/null && ret=1
   2282 # Add an NTA, expecting that to cause resolution to succeed.
   2283 rndccmd 10.53.0.9 nta badds.example > rndc.out.ns9.test$n.1 2>&1 || ret=1
   2284 dig_with_opts @10.53.0.9 badds.example. SOA > dig.out.ns9.test$n.2 || ret=1
   2285 grep "NOERROR" dig.out.ns9.test$n.2 > /dev/null || ret=1
   2286 grep "ANSWER: 2" dig.out.ns9.test$n.2 > /dev/null || ret=1
   2287 grep "flags:[^;]* ad[ ;].*QUERY" dig.out.ns9.test$n.2 > /dev/null && ret=1
   2288 # Remove the NTA, expecting that to cause resolution to fail again.
   2289 rndccmd 10.53.0.9 nta -remove badds.example > rndc.out.ns9.test$n.2 2>&1 || ret=1
   2290 dig_with_opts @10.53.0.9 badds.example. SOA > dig.out.ns9.test$n.3 || ret=1
   2291 grep "SERVFAIL" dig.out.ns9.test$n.3 > /dev/null || ret=1
   2292 grep "ANSWER: 0" dig.out.ns9.test$n.3 > /dev/null || ret=1
   2293 grep "flags:[^;]* ad[ ;].*QUERY" dig.out.ns9.test$n.3 > /dev/null && ret=1
   2294 if [ "$ret" -ne 0 ]; then echo_i "failed"; fi
   2295 status=$((status+ret))
   2296 
   2297 echo_i "completed NTA tests"
   2298 
   2299 # Run a minimal update test if possible.  This is really just
   2300 # a regression test for RT #2399; more tests should be added.
   2301 
   2302 if $PERL -e 'use Net::DNS;' 2>/dev/null
   2303 then
   2304     echo_i "running DNSSEC update test"
   2305     ret=0
   2306     output=$($PERL dnssec_update_test.pl -s 10.53.0.3 -p "$PORT" dynamic.example.)
   2307     test "$?" -eq 0 || ret=1
   2308     echo "$output" | cat_i
   2309     [ $ret -eq 1 ] && status=1
   2310 else
   2311     echo_i "The DNSSEC update test requires the Net::DNS library." >&2
   2312 fi
   2313 
   2314 n=$((n+1))
   2315 echo_i "checking managed key maintenance has not started yet ($n)"
   2316 ret=0
   2317 [ -f "ns4/managed-keys.bind.jnl" ] && ret=1
   2318 n=$((n+1))
   2319 test "$ret" -eq 0 || echo_i "failed"
   2320 status=$((status+ret))
   2321 
   2322 # Reconfigure caching server to use "dnssec-validation auto", and repeat
   2323 # some of the DNSSEC validation tests to ensure that it works correctly.
   2324 echo_i "switching to automatic root key configuration"
   2325 copy_setports ns4/named2.conf.in ns4/named.conf
   2326 rndccmd 10.53.0.4 reconfig 2>&1 | sed 's/^/ns4 /' | cat_i
   2327 sleep 5
   2328 
   2329 echo_i "checking managed key maintenance timer has now started ($n)"
   2330 ret=0
   2331 [ -f "ns4/managed-keys.bind.jnl" ] || ret=1
   2332 n=$((n+1))
   2333 test "$ret" -eq 0 || echo_i "failed"
   2334 status=$((status+ret))
   2335 
   2336 echo_i "checking positive validation NSEC ($n)"
   2337 ret=0
   2338 dig_with_opts +noauth a.example. @10.53.0.2 a > dig.out.ns2.test$n || ret=1
   2339 dig_with_opts +noauth a.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1
   2340 digcomp dig.out.ns2.test$n dig.out.ns4.test$n || ret=1
   2341 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
   2342 n=$((n+1))
   2343 test "$ret" -eq 0 || echo_i "failed"
   2344 status=$((status+ret))
   2345 
   2346 echo_i "checking positive validation NSEC3 ($n)"
   2347 ret=0
   2348 dig_with_opts +noauth a.nsec3.example. \
   2349 	@10.53.0.3 a > dig.out.ns3.test$n || ret=1
   2350 dig_with_opts +noauth a.nsec3.example. \
   2351 	@10.53.0.4 a > dig.out.ns4.test$n || ret=1
   2352 digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
   2353 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
   2354 n=$((n+1))
   2355 test "$ret" -eq 0 || echo_i "failed"
   2356 status=$((status+ret))
   2357 
   2358 echo_i "checking positive validation OPTOUT ($n)"
   2359 ret=0
   2360 dig_with_opts +noauth a.optout.example. \
   2361 	@10.53.0.3 a > dig.out.ns3.test$n || ret=1
   2362 dig_with_opts +noauth a.optout.example. \
   2363 	@10.53.0.4 a > dig.out.ns4.test$n || ret=1
   2364 digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
   2365 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
   2366 n=$((n+1))
   2367 test "$ret" -eq 0 || echo_i "failed"
   2368 status=$((status+ret))
   2369 
   2370 echo_i "checking negative validation ($n)"
   2371 ret=0
   2372 dig_with_opts +noauth q.example. @10.53.0.2 a > dig.out.ns2.test$n || ret=1
   2373 dig_with_opts +noauth q.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1
   2374 digcomp dig.out.ns2.test$n dig.out.ns4.test$n || ret=1
   2375 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
   2376 grep "status: NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1
   2377 n=$((n+1))
   2378 test "$ret" -eq 0 || echo_i "failed"
   2379 status=$((status+ret))
   2380 
   2381 echo_i "checking that root DS queries validate ($n)"
   2382 ret=0
   2383 dig_with_opts +noauth . @10.53.0.1 ds > dig.out.ns1.test$n || ret=1
   2384 dig_with_opts +noauth . @10.53.0.4 ds > dig.out.ns4.test$n || ret=1
   2385 digcomp dig.out.ns1.test$n dig.out.ns4.test$n || ret=1
   2386 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
   2387 grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
   2388 n=$((n+1))
   2389 test "$ret" -eq 0 || echo_i "failed"
   2390 status=$((status+ret))
   2391 
   2392 echo_i "checking that DS at a RFC 1918 empty zone lookup succeeds ($n)"
   2393 ret=0
   2394 dig_with_opts +noauth 10.in-addr.arpa ds @10.53.0.2 >dig.out.ns2.test$n || ret=1
   2395 dig_with_opts +noauth 10.in-addr.arpa ds @10.53.0.4 >dig.out.ns6.test$n || ret=1
   2396 digcomp dig.out.ns2.test$n dig.out.ns6.test$n || ret=1
   2397 grep "status: NOERROR" dig.out.ns6.test$n > /dev/null || ret=1
   2398 n=$((n+1))
   2399 test "$ret" -eq 0 || echo_i "failed"
   2400 status=$((status+ret))
   2401 
   2402 echo_i "checking expired signatures remain with "'"allow-update { none; };"'" and no keys available ($n)"
   2403 ret=0
   2404 dig_with_opts +noauth expired.example. +dnssec @10.53.0.3 soa > dig.out.ns3.test$n || ret=1
   2405 grep "RRSIG.SOA" dig.out.ns3.test$n > /dev/null || ret=1
   2406 n=$((n+1))
   2407 test "$ret" -eq 0 || echo_i "failed"
   2408 
   2409 status=$((status+ret))
   2410 echo_i "checking expired signatures do not validate ($n)"
   2411 ret=0
   2412 dig_with_opts +noauth expired.example. +dnssec @10.53.0.4 soa > dig.out.ns4.test$n || ret=1
   2413 grep "SERVFAIL" dig.out.ns4.test$n > /dev/null || ret=1
   2414 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1
   2415 grep "expired.example/.*: RRSIG has expired" ns4/named.run > /dev/null || ret=1
   2416 n=$((n+1))
   2417 test "$ret" -eq 0 || echo_i "failed"
   2418 status=$((status+ret))
   2419 
   2420 echo_i "checking that the NSEC3 record for the apex is properly signed when a DNSKEY is added via UPDATE ($n)"
   2421 ret=0
   2422 (
   2423 cd ns3 || exit 1
   2424 kskname=$($KEYGEN -q -3 -a RSASHA1 -fk update-nsec3.example)
   2425 (
   2426 echo zone update-nsec3.example
   2427 echo server 10.53.0.3 "$PORT"
   2428 grep DNSKEY "${kskname}.key" | sed -e 's/^/update add /' -e 's/IN/300 IN/'
   2429 echo send
   2430 ) | $NSUPDATE
   2431 )
   2432 dig_with_opts +dnssec a update-nsec3.example. @10.53.0.4 > dig.out.ns4.test$n || ret=1
   2433 grep "NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
   2434 grep "flags:.* ad[ ;]" dig.out.ns4.test$n > /dev/null || ret=1
   2435 grep "NSEC3 .* TYPE65534" dig.out.ns4.test$n > /dev/null || ret=1
   2436 n=$((n+1))
   2437 test "$ret" -eq 0 || echo_i "failed"
   2438 status=$((status+ret))
   2439 
   2440 echo_i "checking that the NSEC record is properly generated when DNSKEY are added via auto-dnssec ($n)"
   2441 ret=0
   2442 dig_with_opts +dnssec a auto-nsec.example. @10.53.0.4 > dig.out.ns4.test$n || ret=1
   2443 grep "NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
   2444 grep "flags:.* ad[ ;]" dig.out.ns4.test$n > /dev/null || ret=1
   2445 grep "IN.NSEC[^3].* DNSKEY" dig.out.ns4.test$n > /dev/null || ret=1
   2446 n=$((n+1))
   2447 test "$ret" -eq 0 || echo_i "failed"
   2448 status=$((status+ret))
   2449 
   2450 echo_i "checking that the NSEC3 record is properly generated when DNSKEY are added via auto-dnssec ($n)"
   2451 ret=0
   2452 dig_with_opts +dnssec a auto-nsec3.example. @10.53.0.4 > dig.out.ns4.test$n || ret=1
   2453 grep "NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
   2454 grep "flags:.* ad[ ;]" dig.out.ns4.test$n > /dev/null || ret=1
   2455 grep "IN.NSEC3 .* DNSKEY" dig.out.ns4.test$n > /dev/null || ret=1
   2456 n=$((n+1))
   2457 test "$ret" -eq 0 || echo_i "failed"
   2458 status=$((status+ret))
   2459 
   2460 echo_i "checking that signing records have been marked as complete ($n)"
   2461 ret=0
   2462 checkprivate dynamic.example 10.53.0.3 || ret=1
   2463 checkprivate update-nsec3.example 10.53.0.3 || ret=1
   2464 checkprivate auto-nsec3.example 10.53.0.3 || ret=1
   2465 checkprivate expiring.example 10.53.0.3 || ret=1
   2466 checkprivate auto-nsec.example 10.53.0.3 || ret=1
   2467 n=$((n+1))
   2468 test "$ret" -eq 0 || echo_i "failed"
   2469 status=$((status+ret))
   2470 
   2471 echo_i "check that 'rndc signing' without arguments is handled ($n)"
   2472 ret=0
   2473 rndccmd 10.53.0.3 signing > /dev/null 2>&1 && ret=1
   2474 rndccmd 10.53.0.3 status > /dev/null || ret=1
   2475 n=$((n+1))
   2476 test "$ret" -eq 0 || echo_i "failed"
   2477 status=$((status+ret))
   2478 
   2479 echo_i "check that 'rndc signing -list' without zone is handled ($n)"
   2480 ret=0
   2481 rndccmd 10.53.0.3 signing -list > /dev/null 2>&1 && ret=1
   2482 rndccmd 10.53.0.3 status > /dev/null || ret=1
   2483 n=$((n+1))
   2484 test "$ret" -eq 0 || echo_i "failed"
   2485 status=$((status+ret))
   2486 
   2487 echo_i "check that 'rndc signing -clear' without additional arguments is handled ($n)"
   2488 ret=0
   2489 rndccmd 10.53.0.3 signing -clear > /dev/null 2>&1 && ret=1
   2490 rndccmd 10.53.0.3 status > /dev/null || ret=1
   2491 n=$((n+1))
   2492 test "$ret" -eq 0 || echo_i "failed"
   2493 status=$((status+ret))
   2494 
   2495 echo_i "check that 'rndc signing -clear all' without zone is handled ($n)"
   2496 ret=0
   2497 rndccmd 10.53.0.3 signing -clear all > /dev/null 2>&1 && ret=1
   2498 rndccmd 10.53.0.3 status > /dev/null || ret=1
   2499 n=$((n+1))
   2500 test "$ret" -eq 0 || echo_i "failed"
   2501 status=$((status+ret))
   2502 
   2503 echo_i "check that 'rndc signing -nsec3param' without additional arguments is handled ($n)"
   2504 ret=0
   2505 rndccmd 10.53.0.3 signing -nsec3param > /dev/null 2>&1 && ret=1
   2506 rndccmd 10.53.0.3 status > /dev/null || ret=1
   2507 n=$((n+1))
   2508 test "$ret" -eq 0 || echo_i "failed"
   2509 status=$((status+ret))
   2510 
   2511 echo_i "check that 'rndc signing -nsec3param none' without zone is handled ($n)"
   2512 ret=0
   2513 rndccmd 10.53.0.3 signing -nsec3param none > /dev/null 2>&1 && ret=1
   2514 rndccmd 10.53.0.3 status > /dev/null || ret=1
   2515 n=$((n+1))
   2516 test "$ret" -eq 0 || echo_i "failed"
   2517 status=$((status+ret))
   2518 
   2519 echo_i "check that 'rndc signing -nsec3param 1' without additional arguments is handled ($n)"
   2520 ret=0
   2521 rndccmd 10.53.0.3 signing -nsec3param 1 > /dev/null 2>&1 && ret=1
   2522 rndccmd 10.53.0.3 status > /dev/null || ret=1
   2523 n=$((n+1))
   2524 test "$ret" -eq 0 || echo_i "failed"
   2525 status=$((status+ret))
   2526 
   2527 echo_i "check that 'rndc signing -nsec3param 1 0' without additional arguments is handled ($n)"
   2528 ret=0
   2529 rndccmd 10.53.0.3 signing -nsec3param 1 0 > /dev/null 2>&1 && ret=1
   2530 rndccmd 10.53.0.3 status > /dev/null || ret=1
   2531 n=$((n+1))
   2532 test "$ret" -eq 0 || echo_i "failed"
   2533 status=$((status+ret))
   2534 
   2535 echo_i "check that 'rndc signing -nsec3param 1 0 0' without additional arguments is handled ($n)"
   2536 ret=0
   2537 rndccmd 10.53.0.3 signing -nsec3param 1 0 0 > /dev/null 2>&1 && ret=1
   2538 rndccmd 10.53.0.3 status > /dev/null || ret=1
   2539 n=$((n+1))
   2540 test "$ret" -eq 0 || echo_i "failed"
   2541 status=$((status+ret))
   2542 
   2543 echo_i "check that 'rndc signing -nsec3param 1 0 0 -' without zone is handled ($n)"
   2544 ret=0
   2545 rndccmd 10.53.0.3 signing -nsec3param 1 0 0 - > /dev/null 2>&1 && ret=1
   2546 rndccmd 10.53.0.3 status > /dev/null || ret=1
   2547 n=$((n+1))
   2548 test "$ret" -eq 0 || echo_i "failed"
   2549 status=$((status+ret))
   2550 
   2551 echo_i "check that 'rndc signing -nsec3param' works with salt ($n)"
   2552 ret=0
   2553 rndccmd 10.53.0.3 signing -nsec3param 1 0 0 ffff inline.example > /dev/null 2>&1 || ret=1
   2554 rndccmd 10.53.0.3 status > /dev/null || ret=1
   2555 for i in 1 2 3 4 5 6 7 8 9 10 ; do
   2556         salt=$(dig_with_opts +nodnssec +short nsec3param inline.example. @10.53.0.3 | awk '{print $4}')
   2557 	if [ "$salt" = "FFFF" ]; then
   2558 		break;
   2559 	fi
   2560 	echo_i "sleeping ...."
   2561 	sleep 1
   2562 done;
   2563 [ "$salt" = "FFFF" ] || ret=1
   2564 n=$((n+1))
   2565 test "$ret" -eq 0 || echo_i "failed"
   2566 status=$((status+ret))
   2567 
   2568 echo_i "check that 'rndc signing -nsec3param' works without salt ($n)"
   2569 ret=0
   2570 rndccmd 10.53.0.3 signing -nsec3param 1 0 0 - inline.example > /dev/null 2>&1 || ret=1
   2571 rndccmd 10.53.0.3 status > /dev/null || ret=1
   2572 for i in 1 2 3 4 5 6 7 8 9 10 ; do
   2573 	salt=$(dig_with_opts +nodnssec +short nsec3param inline.example. @10.53.0.3 | awk '{print $4}')
   2574 	if [ "$salt" = "-" ]; then
   2575 		break;
   2576 	fi
   2577 	echo_i "sleeping ...."
   2578 	sleep 1
   2579 done;
   2580 [ "$salt" = "-" ] || ret=1
   2581 n=$((n+1))
   2582 test "$ret" -eq 0 || echo_i "failed"
   2583 status=$((status+ret))
   2584 
   2585 echo_i "check that 'rndc signing -nsec3param' works with 'auto' as salt ($n)"
   2586 ret=0
   2587 rndccmd 10.53.0.3 signing -nsec3param 1 0 0 auto inline.example > /dev/null 2>&1 || ret=1
   2588 rndccmd 10.53.0.3 status > /dev/null || ret=1
   2589 for i in 1 2 3 4 5 6 7 8 9 10 ; do
   2590 	salt=$(dig_with_opts +nodnssec +short nsec3param inline.example. @10.53.0.3 | awk '{print $4}')
   2591 	[ -n "$salt" ] && [ "$salt" != "-" ] && break
   2592 	echo_i "sleeping ...."
   2593 	sleep 1
   2594 done;
   2595 [ "$salt" != "-" ] || ret=1
   2596 [ "${#salt}" -eq 16 ] || ret=1
   2597 n=$((n+1))
   2598 test "$ret" -eq 0 || echo_i "failed"
   2599 status=$((status+ret))
   2600 
   2601 echo_i "check that 'rndc signing -nsec3param' with 'auto' as salt again generates a different salt ($n)"
   2602 ret=0
   2603 oldsalt=$salt
   2604 rndccmd 10.53.0.3 signing -nsec3param 1 0 0 auto inline.example > /dev/null 2>&1 || ret=1
   2605 rndccmd 10.53.0.3 status > /dev/null || ret=1
   2606 for i in 1 2 3 4 5 6 7 8 9 10 ; do
   2607 	salt=$(dig_with_opts +nodnssec +short nsec3param inline.example. @10.53.0.3 | awk '{print $4}')
   2608 	[ -n "$salt" ] && [ "$salt" != "$oldsalt" ] && break
   2609 	echo_i "sleeping ...."
   2610 	sleep 1
   2611 done;
   2612 [ "$salt" != "$oldsalt" ] || ret=1
   2613 [ "${#salt}" -eq 16 ] || ret=1
   2614 n=$((n+1))
   2615 test "$ret" -eq 0 || echo_i "failed"
   2616 status=$((status+ret))
   2617 
   2618 echo_i "check rndc signing -list output ($n)"
   2619 ret=0
   2620 { rndccmd 10.53.0.3 signing -list dynamic.example > signing.out; } 2>&1
   2621 grep -q "No signing records found" signing.out || {
   2622         ret=1
   2623         sed 's/^/ns3 /' signing.out | cat_i
   2624 }
   2625 { rndccmd 10.53.0.3 signing -list update-nsec3.example > signing.out; } 2>&1
   2626 grep -q "Done signing with key .*/NSEC3RSASHA1" signing.out || {
   2627         ret=1
   2628         sed 's/^/ns3 /' signing.out | cat_i
   2629 }
   2630 n=$((n+1))
   2631 test "$ret" -eq 0 || echo_i "failed"
   2632 status=$((status+ret))
   2633 
   2634 echo_i "clear signing records ($n)"
   2635 { rndccmd 10.53.0.3 signing -clear all update-nsec3.example > /dev/null; } 2>&1 || ret=1
   2636 sleep 1
   2637 { rndccmd 10.53.0.3 signing -list update-nsec3.example > signing.out; } 2>&1
   2638 grep -q "No signing records found" signing.out || {
   2639         ret=1
   2640         sed 's/^/ns3 /' signing.out | cat_i
   2641 }
   2642 n=$((n+1))
   2643 test "$ret" -eq 0 || echo_i "failed"
   2644 status=$((status+ret))
   2645 
   2646 echo_i "checking that a insecure zone beneath a cname resolves ($n)"
   2647 ret=0
   2648 dig_with_opts soa insecure.below-cname.example. @10.53.0.4 > dig.out.ns4.test$n || ret=1
   2649 grep "NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
   2650 grep "ANSWER: 1," dig.out.ns4.test$n > /dev/null || ret=1
   2651 n=$((n+1))
   2652 test "$ret" -eq 0 || echo_i "failed"
   2653 status=$((status+ret))
   2654 
   2655 echo_i "checking that a secure zone beneath a cname resolves ($n)"
   2656 ret=0
   2657 dig_with_opts soa secure.below-cname.example. @10.53.0.4 > dig.out.ns4.test$n || ret=1
   2658 grep "NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
   2659 grep "ANSWER: 2," dig.out.ns4.test$n > /dev/null || ret=1
   2660 grep "flags:.* ad[ ;]" dig.out.ns4.test$n > /dev/null || ret=1
   2661 n=$((n+1))
   2662 test "$ret" -eq 0 || echo_i "failed"
   2663 status=$((status+ret))
   2664 
   2665 my_dig() {
   2666     "$DIG" +noadd +nosea +nostat +noquest +nocomm +nocmd -p "$PORT" @10.53.0.4 "$@"
   2667 }
   2668 
   2669 echo_i "checking DNSKEY query with no data still gets put in cache ($n)"
   2670 ret=0
   2671 firstVal=$(my_dig insecure.example. dnskey| awk '$1 != ";;" { print $2 }')
   2672 sleep 1
   2673 secondVal=$(my_dig insecure.example. dnskey| awk '$1 != ";;" { print $2 }')
   2674 if [ "${firstVal:-0}" -eq "${secondVal:-0}" ]
   2675 then
   2676 	sleep 1
   2677 	thirdVal=$(my_dig insecure.example. dnskey|awk '$1 != ";;" { print $2 }')
   2678 	if [ "${firstVal:-0}" -eq "${thirdVal:-0}" ]
   2679 	then
   2680 		echo_i "cannot confirm query answer still in cache"
   2681 		ret=1
   2682 	fi
   2683 fi
   2684 n=$((n+1))
   2685 test "$ret" -eq 0 || echo_i "failed"
   2686 status=$((status+ret))
   2687 
   2688 echo_i "check that a split dnssec dnssec-signzone work ($n)"
   2689 ret=0
   2690 dig_with_opts soa split-dnssec.example. @10.53.0.4 > dig.out.ns4.test$n || ret=1
   2691 grep "NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
   2692 grep "ANSWER: 2," dig.out.ns4.test$n > /dev/null || ret=1
   2693 grep "flags:.* ad[ ;]" dig.out.ns4.test$n > /dev/null || ret=1
   2694 n=$((n+1))
   2695 test "$ret" -eq 0 || echo_i "failed"
   2696 status=$((status+ret))
   2697 
   2698 echo_i "check that a smart split dnssec dnssec-signzone work ($n)"
   2699 ret=0
   2700 dig_with_opts soa split-smart.example. @10.53.0.4 > dig.out.ns4.test$n || ret=1
   2701 grep "NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
   2702 grep "ANSWER: 2," dig.out.ns4.test$n > /dev/null || ret=1
   2703 grep "flags:.* ad[ ;]" dig.out.ns4.test$n > /dev/null || ret=1
   2704 n=$((n+1))
   2705 test "$ret" -eq 0 || echo_i "failed"
   2706 status=$((status+ret))
   2707 
   2708 echo_i "check that NOTIFY is sent at the end of NSEC3 chain generation ($n)"
   2709 ret=0
   2710 (
   2711 echo zone nsec3chain-test
   2712 echo server 10.53.0.2 "$PORT"
   2713 echo update add nsec3chain-test. 0 nsec3param 1 0 1 123456
   2714 echo send
   2715 ) | $NSUPDATE
   2716 for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
   2717 do
   2718 	dig_with_opts nsec3param nsec3chain-test @10.53.0.2 > dig.out.ns2.test$n || ret=1
   2719 	if grep "ANSWER: 3," dig.out.ns2.test$n >/dev/null
   2720 	then
   2721 		break;
   2722 	fi
   2723 	echo_i "sleeping ...."
   2724 	sleep 3
   2725 done
   2726 grep "ANSWER: 3," dig.out.ns2.test$n > /dev/null || ret=1
   2727 if [ "$ret" -ne 0 ]; then echo_i "nsec3 chain generation not complete"; fi
   2728 dig_with_opts +noauth +nodnssec soa nsec3chain-test @10.53.0.2 > dig.out.ns2.test$n || ret=1
   2729 s2=$(awk '$4 == "SOA" { print $7}' dig.out.ns2.test$n)
   2730 for i in 1 2 3 4 5 6 7 8 9 10
   2731 do
   2732 	dig_with_opts +noauth +nodnssec soa nsec3chain-test @10.53.0.3 > dig.out.ns3.test$n || ret=1
   2733 	s3=$(awk '$4 == "SOA" { print $7}' dig.out.ns3.test$n)
   2734 	test "$s2" = "$s3" && break
   2735 	sleep 1
   2736 done
   2737 digcomp dig.out.ns2.test$n dig.out.ns3.test$n || ret=1
   2738 n=$((n+1))
   2739 test "$ret" -eq 0 || echo_i "failed"
   2740 status=$((status+ret))
   2741 
   2742 echo_i "check dnssec-dsfromkey from stdin ($n)"
   2743 ret=0
   2744 dig_with_opts dnskey algroll. @10.53.0.2 | \
   2745         $DSFROMKEY -f - algroll. > dig.out.ns2.test$n || ret=1
   2746 NF=$(awk '{print NF}' dig.out.ns2.test$n | sort -u)
   2747 [ "${NF}" = 7 ] || ret=1
   2748 # make canonical
   2749 awk '{
   2750 	for (i=1;i<7;i++) printf("%s ", $i);
   2751 	for (i=7;i<=NF;i++) printf("%s", $i);
   2752 	printf("\n");
   2753 }' < dig.out.ns2.test$n > canonical1.$n || ret=1
   2754 awk '{
   2755 	for (i=1;i<7;i++) printf("%s ", $i);
   2756 	for (i=7;i<=NF;i++) printf("%s", $i);
   2757 	printf("\n");
   2758 }' < ns1/dsset-algroll$TP > canonical2.$n || ret=1
   2759 $DIFF -b canonical1.$n canonical2.$n > /dev/null 2>&1 || ret=1
   2760 n=$((n+1))
   2761 test "$ret" -eq 0 || echo_i "failed"
   2762 status=$((status+ret))
   2763 
   2764 # Intentionally strip ".key" from keyfile name to ensure the error message
   2765 # includes it anyway to avoid confusion (RT #21731)
   2766 echo_i "check dnssec-dsfromkey error message when keyfile is not found ($n)"
   2767 ret=0
   2768 key=$($KEYGEN -a RSASHA1 -q example.) || ret=1
   2769 mv "$key.key" "$key"
   2770 $DSFROMKEY "$key" > dsfromkey.out.$n 2>&1 && ret=1
   2771 grep "$key.key: file not found" dsfromkey.out.$n > /dev/null || ret=1
   2772 n=$((n+1))
   2773 test "$ret" -eq 0 || echo_i "failed"
   2774 status=$((status+ret))
   2775 
   2776 echo_i "testing soon-to-expire RRSIGs without a replacement private key ($n)"
   2777 ret=0
   2778 dig_with_answeropts +nottlid expiring.example ns @10.53.0.3 | grep RRSIG > dig.out.ns3.test$n 2>&1
   2779 # there must be a signature here
   2780 [ -s dig.out.ns3.test$n ] || ret=1
   2781 n=$((n+1))
   2782 test "$ret" -eq 0 || echo_i "failed"
   2783 status=$((status+ret))
   2784 
   2785 echo_i "testing new records are signed with 'no-resign' ($n)"
   2786 ret=0
   2787 (
   2788 echo zone nosign.example
   2789 echo server 10.53.0.3 "$PORT"
   2790 echo update add new.nosign.example 300 in txt "hi there"
   2791 echo send
   2792 ) | $NSUPDATE
   2793 sleep 1
   2794 dig_with_answeropts +nottlid txt new.nosign.example @10.53.0.3 \
   2795         > dig.out.ns3.test$n 2>&1
   2796 grep RRSIG dig.out.ns3.test$n > /dev/null 2>&1 || ret=1
   2797 n=$((n+1))
   2798 test "$ret" -eq 0 || echo_i "failed"
   2799 status=$((status+ret))
   2800 
   2801 echo_i "testing expiring records aren't resigned with 'no-resign' ($n)"
   2802 ret=0
   2803 dig_with_answeropts +nottlid nosign.example ns @10.53.0.3 | \
   2804         grep RRSIG | sed 's/[ 	][ 	]*/ /g' > dig.out.ns3.test$n 2>&1
   2805 # the NS RRSIG should not be changed
   2806 $DIFF nosign.before dig.out.ns3.test$n > /dev/null|| ret=1
   2807 n=$((n+1))
   2808 test "$ret" -eq 0 || echo_i "failed"
   2809 status=$((status+ret))
   2810 
   2811 echo_i "testing updates fail with no private key ($n)"
   2812 ret=0
   2813 rm -f ns3/Knosign.example.*.private
   2814 (
   2815 echo zone nosign.example
   2816 echo server 10.53.0.3 "$PORT"
   2817 echo update add fail.nosign.example 300 in txt "reject me"
   2818 echo send
   2819 ) | $NSUPDATE > /dev/null 2>&1 && ret=1
   2820 dig_with_answeropts +nottlid fail.nosign.example txt @10.53.0.3 \
   2821         > dig.out.ns3.test$n 2>&1
   2822 [ -s dig.out.ns3.test$n ] && ret=1
   2823 n=$((n+1))
   2824 test "$ret" -eq 0 || echo_i "failed"
   2825 status=$((status+ret))
   2826 
   2827 echo_i "testing legacy upper case signer name validation ($n)"
   2828 ret=0
   2829 $DIG +tcp +noadd +noauth +dnssec -p "$PORT" soa upper.example @10.53.0.4 \
   2830         > dig.out.ns4.test$n 2>&1
   2831 grep "flags:.* ad;" dig.out.ns4.test$n > /dev/null || ret=1
   2832 grep "RRSIG.*SOA.* UPPER\\.EXAMPLE\\. " dig.out.ns4.test$n > /dev/null || ret=1
   2833 n=$((n+1))
   2834 test "$ret" -eq 0 || echo_i "failed"
   2835 status=$((status+ret))
   2836 
   2837 echo_i "testing that we lower case signer name ($n)"
   2838 ret=0
   2839 $DIG +tcp +noadd +noauth +dnssec -p "$PORT" soa LOWER.EXAMPLE @10.53.0.4 \
   2840         > dig.out.ns4.test$n 2>&1
   2841 grep "flags:.* ad;" dig.out.ns4.test$n > /dev/null || ret=1
   2842 grep "RRSIG.*SOA.* lower\\.example\\. " dig.out.ns4.test$n > /dev/null || ret=1
   2843 n=$((n+1))
   2844 test "$ret" -eq 0 || echo_i "failed"
   2845 status=$((status+ret))
   2846 
   2847 echo_i "testing TTL is capped at RRSIG expiry time ($n)"
   2848 ret=0
   2849 rndccmd 10.53.0.3 freeze expiring.example 2>&1 | sed 's/^/ns3 /' | cat_i
   2850 (
   2851 cd ns3 || exit 1
   2852 for file in K*.moved; do
   2853   mv "$file" "$(basename "$file" .moved)"
   2854 done
   2855 $SIGNER -S -N increment -e now+1mi -o expiring.example expiring.example.db > /dev/null
   2856 ) || ret=1
   2857 rndc_reload ns3 10.53.0.3 expiring.example
   2858 
   2859 rndccmd 10.53.0.4 flush 2>&1 | sed 's/^/ns4 /' | cat_i
   2860 dig_with_answeropts +cd expiring.example soa @10.53.0.4 > dig.out.ns4.1.$n
   2861 dig_with_answeropts expiring.example soa @10.53.0.4 > dig.out.ns4.2.$n
   2862 ttls=$(awk '$1 != ";;" {print $2}' dig.out.ns4.1.$n)
   2863 ttls2=$(awk '$1 != ";;" {print $2}' dig.out.ns4.2.$n)
   2864 for ttl in ${ttls:-0}; do
   2865     [ "${ttl}" -eq 300 ] || ret=1
   2866 done
   2867 for ttl in ${ttls2:-0}; do
   2868     [ "${ttl}" -le 60 ] || ret=1
   2869 done
   2870 n=$((n+1))
   2871 test "$ret" -eq 0 || echo_i "failed"
   2872 status=$((status+ret))
   2873 
   2874 echo_i "testing TTL is capped at RRSIG expiry time for records in the additional section (NS) ($n)"
   2875 ret=0
   2876 rndccmd 10.53.0.4 flush 2>&1 | sed 's/^/ns4 /' | cat_i
   2877 sleep 1
   2878 dig_with_additionalopts +cd expiring.example ns @10.53.0.4 > dig.out.ns4.1.$n
   2879 dig_with_additionalopts expiring.example ns @10.53.0.4 > dig.out.ns4.2.$n
   2880 ttls=$(awk '$1 != ";;" {print $2}' dig.out.ns4.1.$n)
   2881 ttls2=$(awk '$1 != ";;" {print $2}' dig.out.ns4.2.$n)
   2882 for ttl in ${ttls:-300}; do
   2883     [ "$ttl" -le 300 ] && [ "$ttl" -gt 240 ] || ret=1
   2884 done
   2885 for ttl in ${ttls2:-0}; do
   2886     [ "$ttl" -le 60 ] || ret=1
   2887 done
   2888 n=$((n+1))
   2889 test "$ret" -eq 0 || echo_i "failed"
   2890 status=$((status+ret))
   2891 
   2892 echo_i "testing TTL is capped at RRSIG expiry time for records in the additional section (MX) ($n)"
   2893 ret=0
   2894 rndccmd 10.53.0.4 flush 2>&1 | sed 's/^/ns4 /' | cat_i
   2895 sleep 1
   2896 dig_with_additionalopts +cd expiring.example mx @10.53.0.4 > dig.out.ns4.1.$n
   2897 dig_with_additionalopts expiring.example mx @10.53.0.4 > dig.out.ns4.2.$n
   2898 ttls=$(awk '$1 != ";;" {print $2}' dig.out.ns4.1.$n)
   2899 ttls2=$(awk '$1 != ";;" {print $2}' dig.out.ns4.2.$n)
   2900 for ttl in ${ttls:-300}; do
   2901     [ "$ttl" -le 300 ] && [ "$ttl" -gt 240 ] || ret=1
   2902 done
   2903 for ttl in ${ttls2:-0}; do
   2904     [ "$ttl" -le 60 ] || ret=1
   2905 done
   2906 n=$((n+1))
   2907 test "$ret" -eq 0 || echo_i "failed"
   2908 status=$((status+ret))
   2909 
   2910 copy_setports ns4/named3.conf.in ns4/named.conf
   2911 rndccmd 10.53.0.4 reconfig 2>&1 | sed 's/^/ns4 /' | cat_i
   2912 sleep 3
   2913 
   2914 echo_i "testing TTL of about to expire RRsets with dnssec-accept-expired yes; ($n)"
   2915 ret=0
   2916 rndccmd 10.53.0.4 flush 2>&1 | sed 's/^/ns4 /' | cat_i
   2917 dig_with_answeropts +cd expiring.example soa @10.53.0.4 > dig.out.ns4.1.$n
   2918 dig_with_answeropts expiring.example soa @10.53.0.4 > dig.out.ns4.2.$n
   2919 ttls=$(awk '$1 != ";;" {print $2}' dig.out.ns4.1.$n)
   2920 ttls2=$(awk '$1 != ";;" {print $2}' dig.out.ns4.2.$n)
   2921 for ttl in ${ttls:-0}; do
   2922     [ "$ttl" -eq 300 ] || ret=1
   2923 done
   2924 for ttl in ${ttls2:-0}; do
   2925     [ "$ttl" -eq 120 ] || ret=1
   2926 done
   2927 n=$((n+1))
   2928 test "$ret" -eq 0 || echo_i "failed"
   2929 status=$((status+ret))
   2930 
   2931 echo_i "testing TTL of expired RRsets with dnssec-accept-expired yes; ($n)"
   2932 ret=0
   2933 dig_with_answeropts +cd expired.example soa @10.53.0.4 > dig.out.ns4.1.$n
   2934 dig_with_answeropts expired.example soa @10.53.0.4 > dig.out.ns4.2.$n
   2935 ttls=$(awk '$1 != ";;" {print $2}' dig.out.ns4.1.$n)
   2936 ttls2=$(awk '$1 != ";;" {print $2}' dig.out.ns4.2.$n)
   2937 for ttl in ${ttls:-0}; do
   2938     [ "$ttl" -eq 300 ] || ret=1
   2939 done
   2940 for ttl in ${ttls2:-0}; do
   2941     [ "$ttl" -eq 120 ] || ret=1
   2942 done
   2943 n=$((n+1))
   2944 test "$ret" -eq 0 || echo_i "failed"
   2945 status=$((status+ret))
   2946 
   2947 echo_i "testing TTL is capped at RRSIG expiry time for records in the additional section with dnssec-accept-expired yes; ($n)"
   2948 ret=0
   2949 rndccmd 10.53.0.4 flush 2>&1 | sed 's/^/ns4 /' | cat_i
   2950 dig_with_additionalopts +cd expiring.example mx @10.53.0.4 > dig.out.ns4.1.$n
   2951 dig_with_additionalopts expiring.example mx @10.53.0.4 > dig.out.ns4.2.$n
   2952 ttls=$(awk '$1 != ";;" {print $2}' dig.out.ns4.1.$n)
   2953 ttls2=$(awk '$1 != ";;" {print $2}' dig.out.ns4.2.$n)
   2954 for ttl in ${ttls:-300}; do
   2955     [ "$ttl" -le 300 ] && [ "$ttl" -gt 240 ] || ret=1
   2956 done
   2957 for ttl in ${ttls2:-0}; do
   2958     [ "$ttl" -le 120 ] && [ "$ttl" -gt 60 ] || ret=1
   2959 done
   2960 n=$((n+1))
   2961 test "$ret" -eq 0 || echo_i "failed"
   2962 status=$((status+ret))
   2963 
   2964 echo_i "testing DNSKEY lookup via CNAME ($n)"
   2965 ret=0
   2966 dig_with_opts +noauth cnameandkey.secure.example. \
   2967 	@10.53.0.3 dnskey > dig.out.ns3.test$n || ret=1
   2968 dig_with_opts +noauth cnameandkey.secure.example. \
   2969 	@10.53.0.4 dnskey > dig.out.ns4.test$n || ret=1
   2970 digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
   2971 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
   2972 grep "CNAME" dig.out.ns4.test$n > /dev/null || ret=1
   2973 n=$((n+1))
   2974 test "$ret" -eq 0 || echo_i "failed"
   2975 status=$((status+ret))
   2976 
   2977 echo_i "testing KEY lookup at CNAME (present) ($n)"
   2978 ret=0
   2979 dig_with_opts +noauth cnameandkey.secure.example. \
   2980 	@10.53.0.3 key > dig.out.ns3.test$n || ret=1
   2981 dig_with_opts +noauth cnameandkey.secure.example. \
   2982 	@10.53.0.4 key > dig.out.ns4.test$n || ret=1
   2983 digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
   2984 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
   2985 grep "CNAME" dig.out.ns4.test$n > /dev/null && ret=1
   2986 n=$((n+1))
   2987 test "$ret" -eq 0 || echo_i "failed"
   2988 status=$((status+ret))
   2989 
   2990 echo_i "testing KEY lookup at CNAME (not present) ($n)"
   2991 ret=0
   2992 dig_with_opts +noauth cnamenokey.secure.example. \
   2993 	@10.53.0.3 key > dig.out.ns3.test$n || ret=1
   2994 dig_with_opts +noauth cnamenokey.secure.example. \
   2995 	@10.53.0.4 key > dig.out.ns4.test$n || ret=1
   2996 digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
   2997 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
   2998 grep "CNAME" dig.out.ns4.test$n > /dev/null && ret=1
   2999 n=$((n+1))
   3000 test "$ret" -eq 0 || echo_i "failed"
   3001 status=$((status+ret))
   3002 
   3003 echo_i "testing DNSKEY lookup via DNAME ($n)"
   3004 ret=0
   3005 dig_with_opts a.dnameandkey.secure.example. \
   3006 	@10.53.0.3 dnskey > dig.out.ns3.test$n || ret=1
   3007 dig_with_opts a.dnameandkey.secure.example. \
   3008 	@10.53.0.4 dnskey > dig.out.ns4.test$n || ret=1
   3009 digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
   3010 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
   3011 grep "CNAME" dig.out.ns4.test$n > /dev/null || ret=1
   3012 grep "DNAME" dig.out.ns4.test$n > /dev/null || ret=1
   3013 n=$((n+1))
   3014 test "$ret" -eq 0 || echo_i "failed"
   3015 status=$((status+ret))
   3016 
   3017 echo_i "testing KEY lookup via DNAME ($n)"
   3018 ret=0
   3019 dig_with_opts b.dnameandkey.secure.example. \
   3020 	@10.53.0.3 key > dig.out.ns3.test$n || ret=1
   3021 dig_with_opts b.dnameandkey.secure.example. \
   3022 	@10.53.0.4 key > dig.out.ns4.test$n || ret=1
   3023 digcomp dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
   3024 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
   3025 grep "DNAME" dig.out.ns4.test$n > /dev/null || ret=1
   3026 n=$((n+1))
   3027 test "$ret" -eq 0 || echo_i "failed"
   3028 status=$((status+ret))
   3029 
   3030 echo_i "check that named doesn't loop when all private keys are not available ($n)"
   3031 ret=0
   3032 lines=$(grep -c "reading private key file expiring.example" ns3/named.run || true)
   3033 test "${lines:-1000}" -lt 15 || ret=1
   3034 n=$((n+1))
   3035 test "$ret" -eq 0 || echo_i "failed"
   3036 status=$((status+ret))
   3037 
   3038 echo_i "check against against missing nearest provable proof ($n)"
   3039 dig_with_opts +norec b.c.d.optout-tld. \
   3040 	@10.53.0.6 ds > dig.out.ds.ns6.test$n || ret=1
   3041 nsec3=$(grep -c "IN.NSEC3" dig.out.ds.ns6.test$n || true)
   3042 [ "$nsec3" -eq 2 ] || ret=1
   3043 dig_with_opts +norec b.c.d.optout-tld. \
   3044 	@10.53.0.6 A > dig.out.ns6.test$n || ret=1
   3045 nsec3=$(grep -c "IN.NSEC3" dig.out.ns6.test$n || true)
   3046 [ "$nsec3" -eq 1 ] || ret=1
   3047 dig_with_opts optout-tld. \
   3048 	@10.53.0.4 SOA > dig.out.soa.ns4.test$n || ret=1
   3049 grep "flags:.*ad.*QUERY" dig.out.soa.ns4.test$n > /dev/null || ret=1
   3050 dig_with_opts b.c.d.optout-tld. \
   3051 	@10.53.0.4 A > dig.out.ns4.test$n || ret=1
   3052 grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
   3053 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1
   3054 n=$((n+1))
   3055 test "$ret" -eq 0 || echo_i "failed"
   3056 status=$((status+ret))
   3057 
   3058 echo_i "check that key id are logged when dumping the cache ($n)"
   3059 ret=0
   3060 rndc_dumpdb ns4
   3061 grep "; key id = " ns4/named_dump.db.test$n > /dev/null || ret=1
   3062 n=$((n+1))
   3063 test "$ret" -eq 0 || echo_i "failed"
   3064 status=$((status+ret))
   3065 
   3066 echo_i "check KEYDATA records are printed in human readable form in key zone ($n)"
   3067 # force the managed-keys zone to be written out
   3068 rndccmd 10.53.0.4 managed-keys sync 2>&1 | sed 's/^/ns4 /' | cat_i
   3069 for i in 1 2 3 4 5 6 7 8 9
   3070 do
   3071     ret=0
   3072     if test -f ns4/managed-keys.bind
   3073     then
   3074 	grep KEYDATA ns4/managed-keys.bind > /dev/null &&
   3075 	grep "next refresh:" ns4/managed-keys.bind > /dev/null &&
   3076 	break
   3077     fi
   3078     ret=1
   3079     sleep 1
   3080 done
   3081 n=$((n+1))
   3082 test "$ret" -eq 0 || echo_i "failed"
   3083 status=$((status+ret))
   3084 
   3085 echo_i "check dig's +nocrypto flag ($n)"
   3086 ret=0
   3087 dig_with_opts +norec +nocrypto DNSKEY . \
   3088 	@10.53.0.1 > dig.out.dnskey.ns1.test$n || ret=1
   3089 grep -E "256 [0-9]+ $DEFAULT_ALGORITHM_NUMBER \\[key id = [1-9][0-9]*]" dig.out.dnskey.ns1.test$n > /dev/null || ret=1
   3090 grep -E "RRSIG.* \\[omitted]" dig.out.dnskey.ns1.test$n > /dev/null || ret=1
   3091 dig_with_opts +norec +nocrypto DS example \
   3092 	@10.53.0.1 > dig.out.ds.ns1.test$n || ret=1
   3093 grep -E "DS.* [0-9]+ [12] \[omitted]" dig.out.ds.ns1.test$n > /dev/null || ret=1
   3094 n=$((n+1))
   3095 test "$ret" -eq 0 || echo_i "failed"
   3096 status=$((status+ret))
   3097 
   3098 echo_i "check simultaneous inactivation and publishing of dnskeys removes inactive signature ($n)"
   3099 ret=0
   3100 cnt=0
   3101 while :
   3102 do
   3103 dig_with_opts publish-inactive.example @10.53.0.3 dnskey > dig.out.ns3.test$n
   3104 keys=$(awk '$5 == 257 { print; }' dig.out.ns3.test$n | wc -l)
   3105 test "$keys" -gt 2 && break
   3106 cnt=$((cnt+1))
   3107 test "$cnt" -gt 120 && break
   3108 sleep 1
   3109 done
   3110 test "$keys" -gt 2 || ret=1
   3111 sigs=$(grep -c RRSIG dig.out.ns3.test$n || true)
   3112 n=$((n+1))
   3113 test "$sigs" -eq 2 || ret=1
   3114 if test "$ret" -ne 0 ; then echo_i "failed"; fi
   3115 status=$((status+ret))
   3116 
   3117 echo_i "check that increasing the sig-validity-interval resigning triggers re-signing ($n)"
   3118 ret=0
   3119 before=$($DIG axfr siginterval.example -p "$PORT" @10.53.0.3 | grep RRSIG.SOA)
   3120 cp ns3/siginterval2.conf ns3/siginterval.conf
   3121 rndccmd 10.53.0.3 reconfig 2>&1 | sed 's/^/ns3 /' | cat_i
   3122 i=10
   3123 while [ "$i" -ge 0 ]; do
   3124 after=$($DIG axfr siginterval.example -p "$PORT" @10.53.0.3 | grep RRSIG.SOA)
   3125 test "$before" != "$after" && break
   3126 sleep 1
   3127 i=$((i-1))
   3128 done
   3129 n=$((n+1))
   3130 if test "$before" = "$after" ; then echo_i "failed"; ret=1; fi
   3131 status=$((status+ret))
   3132 
   3133 if [ -x "$PYTHON" ]; then
   3134     echo_i "check dnskey-sig-validity sets longer expiry for DNSKEY ($n)"
   3135     ret=0
   3136     rndccmd 10.53.0.3 sign siginterval.example 2>&1 | sed 's/^/ns3 /' | cat_i
   3137     # convert expiry date to a comma-separated list of integers python can
   3138     # use as input to date(). strip leading 0s in months and days so
   3139     # python3 will recognize them as integers.
   3140     $DIG +dnssec +short -p "$PORT" @10.53.0.3 soa siginterval.example > dig.out.soa.test$n
   3141     soaexpire=$(awk '$1 ~ /SOA/ { print $5 }' dig.out.soa.test$n |
   3142 	       sed 's/\(....\)\(..\)\(..\).*/\1, \2, \3/' |
   3143 	       sed 's/ 0/ /g')
   3144     $DIG +dnssec +short -p "$PORT" @10.53.0.3 dnskey siginterval.example > dig.out.dnskey.test$n
   3145     dnskeyexpire=$(awk '$1 ~ /DNSKEY/ { print $5; exit 0 }' dig.out.dnskey.test$n |
   3146 		  sed 's/\(....\)\(..\)\(..\).*/\1, \2, \3/' |
   3147 		  sed 's/ 0/ /g')
   3148     $PYTHON > python.out.$n <<EOF
   3149 from datetime import date;
   3150 ke=date($dnskeyexpire)
   3151 se=date($soaexpire)
   3152 print((ke-se).days);
   3153 EOF
   3154     diff=$(cat python.out.$n)
   3155     [ "$diff" -ge 55 ] || ret=1
   3156     n=$((n+1))
   3157     test "$ret" -eq 0 || echo_i "failed"
   3158     status=$((status+ret))
   3159 fi
   3160 
   3161 copy_setports ns4/named4.conf.in ns4/named.conf
   3162 rndccmd 10.53.0.4 reconfig 2>&1 | sed 's/^/ns4 /' | cat_i
   3163 sleep 3
   3164 
   3165 echo_i "check insecure delegation between static-stub zones ($n)"
   3166 ret=0
   3167 dig_with_opts ns insecure.secure.example \
   3168 	@10.53.0.4 > dig.out.ns4.1.test$n || ret=1
   3169 grep "SERVFAIL" dig.out.ns4.1.test$n > /dev/null && ret=1
   3170 dig_with_opts ns secure.example \
   3171 	@10.53.0.4 > dig.out.ns4.2.test$n || ret=1
   3172 grep "SERVFAIL" dig.out.ns4.2.test$n > /dev/null && ret=1
   3173 n=$((n+1))
   3174 test "$ret" -eq 0 || echo_i "failed"
   3175 status=$((status+ret))
   3176 
   3177 echo_i "check the acceptance of seconds as inception and expiration times ($n)"
   3178 ret=0
   3179 in="NSEC 8 0 86400 1390003200 1389394800 33655 . NYWjZYBV1b+h4j0yu/SmPOOylR8P4IXKDzHX3NwEmU1SUp27aJ91dP+i+UBcnPmBib0hck4DrFVvpflCEpCnVQd2DexcN0GX+3PM7XobxhtDlmnU X1L47zJlbdHNwTqHuPaMM6Xy9HGMXps7O5JVyfggVhTz2C+G5OVxBdb2rOo="
   3180 
   3181 exp="NSEC 8 0 86400 20140118000000 20140110230000 33655 . NYWjZYBV1b+h4j0yu/SmPOOylR8P4IXKDzHX3NwEmU1SUp27aJ91dP+i +UBcnPmBib0hck4DrFVvpflCEpCnVQd2DexcN0GX+3PM7XobxhtDlmnU X1L47zJlbdHNwTqHuPaMM6Xy9HGMXps7O5JVyfggVhTz2C+G5OVxBdb2 rOo="
   3182 
   3183 out=$(echo "IN RRSIG $in" | $RRCHECKER -p | sed 's/^IN.RRSIG.//')
   3184 [ "$out" = "$exp" ] || ret=1
   3185 n=$((n+1))
   3186 test "$ret" -eq 0 || echo_i "failed"
   3187 status=$((status+ret))
   3188 
   3189 echo_i "check the correct resigning time is reported in zonestatus ($n)"
   3190 ret=0
   3191 rndccmd 10.53.0.3 \
   3192 		zonestatus secure.example > rndc.out.ns3.test$n
   3193 # next resign node: secure.example/DNSKEY
   3194 qname=$(awk '/next resign node:/ { print $4 }' rndc.out.ns3.test$n | sed 's,/.*,,')
   3195 qtype=$(awk '/next resign node:/ { print $4 }' rndc.out.ns3.test$n | sed 's,.*/,,')
   3196 # next resign time: Thu, 24 Apr 2014 10:38:16 GMT
   3197 time=$(awk 'BEGIN { m["Jan"] = "01"; m["Feb"] = "02"; m["Mar"] = "03";
   3198 		   m["Apr"] = "04"; m["May"] = "05"; m["Jun"] = "06";
   3199 		   m["Jul"] = "07"; m["Aug"] = "08"; m["Sep"] = "09";
   3200 		   m["Oct"] = "10"; m["Nov"] = "11"; m["Dec"] = "12";}
   3201 	 /next resign time:/ { printf "%d%s%02d%s\n", $7, m[$6], $5, $8 }' rndc.out.ns3.test$n | sed 's/://g')
   3202 dig_with_opts +noall +answer "$qname" "$qtype" @10.53.0.3 > dig.out.test$n
   3203 expire=$(awk '$4 == "RRSIG" { print $9 }' dig.out.test$n)
   3204 inception=$(awk '$4 == "RRSIG" { print $10 }' dig.out.test$n)
   3205 $PERL -e 'exit(0) if ("'"$time"'" lt "'"$expire"'" && "'"$time"'" gt "'"$inception"'"); exit(1);' || ret=1
   3206 n=$((n+1))
   3207 test "$ret" -eq 0 || echo_i "failed"
   3208 status=$((status+ret))
   3209 
   3210 echo_i "check that split rrsigs are handled ($n)"
   3211 ret=0
   3212 dig_with_opts split-rrsig soa @10.53.0.7 > dig.out.test$n || ret=1
   3213 awk 'BEGIN { ok=0; } $4 == "SOA" { if ($7 > 1) ok=1; } END { if (!ok) exit(1); }' dig.out.test$n || ret=1
   3214 n=$((n+1))
   3215 test "$ret" -eq 0 || echo_i "failed"
   3216 status=$((status+ret))
   3217 
   3218 echo_i "check that 'dnssec-keygen -S' works for all supported algorithms ($n)"
   3219 ret=0
   3220 alg=1
   3221 until test $alg -eq 256
   3222 do
   3223     zone="keygen-$alg."
   3224     case $alg in
   3225 	2) # Diffie Helman
   3226 	    alg=$((alg+1))
   3227 	    continue;;
   3228 	157|160|161|162|163|164|165) # private - non standard
   3229 	    alg=$((alg+1))
   3230 	    continue;;
   3231 	1|5|7|8|10) # RSA algorithms
   3232 	    key1=$($KEYGEN -a "$alg" -b "1024" -n zone "$zone" 2> "keygen-$alg.err" || true)
   3233 	    ;;
   3234 	15|16)
   3235 	    key1=$($KEYGEN -a "$alg" -n zone "$zone" 2> "keygen-$alg.err" || true)
   3236 	    # Soft-fail	in case HSM doesn't support Edwards curves
   3237 	    if grep "not found" "keygen-$alg.err" > /dev/null && [ "$CRYPTO" = "pkcs11" ]; then
   3238 		echo_i "Algorithm $alg not supported by HSM: skipping"
   3239 		alg=$((alg+1))
   3240 		continue
   3241 	    fi
   3242 	    ;;
   3243 	*)
   3244 	    key1=$($KEYGEN -a "$alg" -n zone "$zone" 2> "keygen-$alg.err" || true)
   3245     esac
   3246     if grep "unsupported algorithm" "keygen-$alg.err" > /dev/null
   3247     then
   3248 	alg=$((alg+1))
   3249 	continue
   3250     fi
   3251     if test -z "$key1"
   3252     then
   3253 	echo_i "'$KEYGEN -a $alg': failed"
   3254 	cat "keygen-$alg.err"
   3255 	ret=1
   3256 	alg=$((alg+1))
   3257 	continue
   3258     fi
   3259     $SETTIME -I now+4d "$key1.private" > /dev/null
   3260     key2=$($KEYGEN -v 10 -i 3d -S "$key1.private" 2> /dev/null)
   3261     test -f "$key2.key" -a -f "$key2.private" || {
   3262 	ret=1
   3263 	echo_i "'dnssec-keygen -S' failed for algorithm: $alg"
   3264     }
   3265     alg=$((alg+1))
   3266 done
   3267 n=$((n+1))
   3268 test "$ret" -eq 0 || echo_i "failed"
   3269 status=$((status+ret))
   3270 
   3271 echo_i "check that CDS records are signed using KSK by dnssec-signzone ($n)"
   3272 ret=0
   3273 dig_with_opts +noall +answer @10.53.0.2 cds cds.secure > dig.out.test$n
   3274 lines=$(awk '$4 == "RRSIG" && $5 == "CDS" {print}' dig.out.test$n | wc -l)
   3275 test "$lines" -eq 2 || ret=1
   3276 n=$((n+1))
   3277 test "$ret" -eq 0 || echo_i "failed"
   3278 status=$((status+ret))
   3279 
   3280 echo_i "check that CDS records are not signed using ZSK by dnssec-signzone -x ($n)"
   3281 ret=0
   3282 dig_with_opts +noall +answer @10.53.0.2 cds cds-x.secure > dig.out.test$n
   3283 lines=$(awk '$4 == "RRSIG" && $5 == "CDS" {print}' dig.out.test$n | wc -l)
   3284 test "$lines" -eq 2 || ret=1
   3285 n=$((n+1))
   3286 test "$ret" -eq 0 || echo_i "failed"
   3287 status=$((status+ret))
   3288 
   3289 echo_i "checking that positive unknown NSEC3 hash algorithm does validate ($n)"
   3290 ret=0
   3291 dig_with_opts +noauth +noadd +nodnssec +adflag @10.53.0.3 nsec3-unknown.example SOA > dig.out.ns3.test$n
   3292 dig_with_opts +noauth +noadd +nodnssec +adflag @10.53.0.4 nsec3-unknown.example SOA > dig.out.ns4.test$n
   3293 grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1
   3294 grep "status: NOERROR," dig.out.ns4.test$n > /dev/null || ret=1
   3295 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
   3296 grep "ANSWER: 1," dig.out.ns4.test$n > /dev/null || ret=1
   3297 n=$((n+1))
   3298 test "$ret" -eq 0 || echo_i "failed"
   3299 status=$((status+ret))
   3300 
   3301 echo_i "check that CDS records are signed using KSK by with dnssec-auto ($n)"
   3302 ret=0
   3303 dig_with_opts +noall +answer @10.53.0.2 cds cds-auto.secure > dig.out.test$n
   3304 lines=$(awk '$4 == "RRSIG" && $5 == "CDS" {print}' dig.out.test$n | wc -l)
   3305 test "$lines" -eq 2 || ret=1
   3306 n=$((n+1))
   3307 test "$ret" -eq 0 || echo_i "failed"
   3308 status=$((status+ret))
   3309 
   3310 echo_i "check that a lone non matching CDS record is rejected ($n)"
   3311 ret=0
   3312 (
   3313 echo zone cds-update.secure
   3314 echo server 10.53.0.2 "$PORT"
   3315 echo update delete cds-update.secure CDS
   3316 dig_with_opts +noall +answer @10.53.0.2 dnskey cds-update.secure |
   3317 grep "DNSKEY.257" | sed 's/DNSKEY.257/DNSKEY 258/' |
   3318 $DSFROMKEY -C -A -f - -T 1 cds-update.secure |
   3319 sed "s/^/update add /"
   3320 echo send
   3321 ) | $NSUPDATE > nsupdate.out.test$n 2>&1 || true
   3322 grep "update failed: REFUSED" nsupdate.out.test$n > /dev/null || ret=1
   3323 dig_with_opts +noall +answer @10.53.0.2 cds cds-update.secure > dig.out.test$n
   3324 lines=$(awk '$4 == "CDS" {print}' dig.out.test$n | wc -l)
   3325 test "${lines:-10}" -eq 0 || ret=1
   3326 n=$((n+1))
   3327 test "$ret" -eq 0 || echo_i "failed"
   3328 status=$((status+ret))
   3329 
   3330 echo_i "check that a CDS deletion record is accepted ($n)"
   3331 ret=0
   3332 (
   3333 echo zone cds-update.secure
   3334 echo server 10.53.0.2 "$PORT"
   3335 echo update delete cds-update.secure CDS
   3336 echo update add cds-update.secure 0 CDS 0 0 0 00
   3337 echo send
   3338 ) | $NSUPDATE > nsupdate.out.test$n 2>&1
   3339 dig_with_opts +noall +answer @10.53.0.2 cds cds-update.secure > dig.out.test$n
   3340 lines=$(awk '$4 == "CDS" {print}' dig.out.test$n | wc -l)
   3341 test "${lines:-10}" -eq 1 || ret=1
   3342 lines=$(tr -d '\r' < dig.out.test$n | awk '$4 == "CDS" && $5 == "0" && $6 == "0" && $7 == "0" && $8 == "00" {print}' | wc -l)
   3343 test "$lines" -eq 1 || ret=1
   3344 n=$((n+1))
   3345 test "$ret" -eq 0 || echo_i "failed"
   3346 status=$((status+ret))
   3347 
   3348 echo_i "check that CDS records are signed using KSK when added by nsupdate ($n)"
   3349 ret=0
   3350 (
   3351 echo zone cds-update.secure
   3352 echo server 10.53.0.2 "$PORT"
   3353 echo update delete cds-update.secure CDS
   3354 echo send
   3355 dig_with_opts +noall +answer @10.53.0.2 dnskey cds-update.secure |
   3356 grep "DNSKEY.257" |
   3357 $DSFROMKEY -12 -C -f - -T 1 cds-update.secure |
   3358 sed "s/^/update add /"
   3359 echo send
   3360 ) | $NSUPDATE
   3361 dig_with_opts +noall +answer @10.53.0.2 cds cds-update.secure > dig.out.test$n
   3362 lines=$(awk '$4 == "RRSIG" && $5 == "CDS" {print}' dig.out.test$n | wc -l)
   3363 test "$lines" -eq 2 || ret=1
   3364 lines=$(awk '$4 == "CDS" {print}' dig.out.test$n | wc -l)
   3365 test "$lines" -eq 2 || ret=1
   3366 n=$((n+1))
   3367 test "$ret" -eq 0 || echo_i "failed"
   3368 status=$((status+ret))
   3369 
   3370 echo_i "check that CDS records are signed only using KSK when added by"
   3371 echo_ic "nsupdate when dnssec-dnskey-kskonly is yes ($n)"
   3372 ret=0
   3373 keyid=$(cat ns2/cds-kskonly.secure.id)
   3374 (
   3375 echo zone cds-kskonly.secure
   3376 echo server 10.53.0.2 "$PORT"
   3377 echo update delete cds-kskonly.secure CDS
   3378 echo send
   3379 dig_with_opts +noall +answer @10.53.0.2 dnskey cds-kskonly.secure |
   3380 grep "DNSKEY.257" |
   3381 $DSFROMKEY -12 -C -f - -T 1 cds-kskonly.secure |
   3382 sed "s/^/update add /"
   3383 echo send
   3384 ) | $NSUPDATE
   3385 dig_with_opts +noall +answer @10.53.0.2 cds cds-kskonly.secure > dig.out.test$n
   3386 lines=$(awk '$4 == "RRSIG" && $5 == "CDS" {print}' dig.out.test$n | wc -l)
   3387 test "$lines" -eq 1 || ret=1
   3388 lines=$(awk -v id="${keyid}" '$4 == "RRSIG" && $5 == "CDS" && $11 == id {print}' dig.out.test$n | wc -l)
   3389 test "$lines" -eq 1 || ret=1
   3390 lines=$(awk '$4 == "CDS" {print}' dig.out.test$n | wc -l)
   3391 test "$lines" -eq 2 || ret=1
   3392 n=$((n+1))
   3393 test "$ret" -eq 0 || echo_i "failed"
   3394 status=$((status+ret))
   3395 
   3396 echo_i "check that CDS deletion records are signed only using KSK when added by"
   3397 echo_ic "nsupdate when dnssec-dnskey-kskonly is yes ($n)"
   3398 ret=0
   3399 keyid=$(cat ns2/cds-kskonly.secure.id)
   3400 (
   3401 echo zone cds-kskonly.secure
   3402 echo server 10.53.0.2 "$PORT"
   3403 echo update delete cds-kskonly.secure CDS
   3404 echo update add cds-kskonly.secure 0 CDS 0 0 0 00
   3405 echo send
   3406 ) | $NSUPDATE
   3407 dig_with_opts +noall +answer @10.53.0.2 cds cds-kskonly.secure > dig.out.test$n
   3408 lines=$(awk '$4 == "RRSIG" && $5 == "CDS" {print}' dig.out.test$n | wc -l)
   3409 test "$lines" -eq 1 || ret=1
   3410 lines=$(awk -v id="${keyid}" '$4 == "RRSIG" && $5 == "CDS" && $11 == id {print}' dig.out.test$n | wc -l)
   3411 test "$lines" -eq 1 || ret=1
   3412 lines=$(awk '$4 == "CDS" {print}' dig.out.test$n | wc -l)
   3413 test "$lines" -eq 1 || ret=1
   3414 lines=$(tr -d '\r' < dig.out.test$n | awk '$4 == "CDS" && $5 == "0" && $6 == "0" && $7 == "0" && $8 == "00" {print}' | wc -l)
   3415 test "$lines" -eq 1 || ret=1
   3416 n=$((n+1))
   3417 test "$ret" -eq 0 || echo_i "failed"
   3418 status=$((status+ret))
   3419 
   3420 echo_i "checking that positive unknown NSEC3 hash algorithm with OPTOUT does validate ($n)"
   3421 ret=0
   3422 dig_with_opts +noauth +noadd +nodnssec +adflag @10.53.0.3 optout-unknown.example SOA > dig.out.ns3.test$n
   3423 dig_with_opts +noauth +noadd +nodnssec +adflag @10.53.0.4 optout-unknown.example SOA > dig.out.ns4.test$n
   3424 grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1
   3425 grep "status: NOERROR," dig.out.ns4.test$n > /dev/null || ret=1
   3426 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
   3427 grep "ANSWER: 1," dig.out.ns4.test$n > /dev/null || ret=1
   3428 n=$((n+1))
   3429 test "$ret" -eq 0 || echo_i "failed"
   3430 status=$((status+ret))
   3431 
   3432 echo_i "check that a non matching CDS record is accepted with a matching CDS record ($n)"
   3433 ret=0
   3434 (
   3435 echo zone cds-update.secure
   3436 echo server 10.53.0.2 "$PORT"
   3437 echo update delete cds-update.secure CDS
   3438 echo send
   3439 dig_with_opts +noall +answer @10.53.0.2 dnskey cds-update.secure |
   3440 grep "DNSKEY.257" |
   3441 $DSFROMKEY -12 -C -f - -T 1 cds-update.secure |
   3442 sed "s/^/update add /"
   3443 dig_with_opts +noall +answer @10.53.0.2 dnskey cds-update.secure |
   3444 grep "DNSKEY.257" | sed 's/DNSKEY.257/DNSKEY 258/' |
   3445 $DSFROMKEY -12 -C -A -f - -T 1 cds-update.secure |
   3446 sed "s/^/update add /"
   3447 echo send
   3448 ) | $NSUPDATE
   3449 dig_with_opts +noall +answer @10.53.0.2 cds cds-update.secure > dig.out.test$n
   3450 lines=$(awk '$4 == "RRSIG" && $5 == "CDS" {print}' dig.out.test$n | wc -l)
   3451 test "$lines" -eq 2 || ret=1
   3452 lines=$(awk '$4 == "CDS" {print}' dig.out.test$n | wc -l)
   3453 test "$lines" -eq 4 || ret=1
   3454 n=$((n+1))
   3455 test "$ret" -eq 0 || echo_i "failed"
   3456 status=$((status+ret))
   3457 
   3458 echo_i "checking that negative unknown NSEC3 hash algorithm does not validate ($n)"
   3459 ret=0
   3460 dig_with_opts +noauth +noadd +nodnssec +adflag @10.53.0.3 nsec3-unknown.example A > dig.out.ns3.test$n
   3461 dig_with_opts +noauth +noadd +nodnssec +adflag @10.53.0.4 nsec3-unknown.example A > dig.out.ns4.test$n
   3462 grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1
   3463 grep "status: SERVFAIL," dig.out.ns4.test$n > /dev/null || ret=1
   3464 n=$((n+1))
   3465 test "$ret" -eq 0 || echo_i "failed"
   3466 status=$((status+ret))
   3467 
   3468 echo_i "check that CDNSKEY records are signed using KSK by dnssec-signzone ($n)"
   3469 ret=0
   3470 dig_with_opts +noall +answer @10.53.0.2 cdnskey cdnskey.secure > dig.out.test$n
   3471 lines=$(awk '$4 == "RRSIG" && $5 == "CDNSKEY" {print}' dig.out.test$n | wc -l)
   3472 test "$lines" -eq 2 || ret=1
   3473 n=$((n+1))
   3474 test "$ret" -eq 0 || echo_i "failed"
   3475 status=$((status+ret))
   3476 
   3477 echo_i "check that CDNSKEY records are not signed using ZSK by dnssec-signzone -x ($n)"
   3478 ret=0
   3479 dig_with_opts +noall +answer @10.53.0.2 cdnskey cdnskey-x.secure > dig.out.test$n
   3480 lines=$(awk '$4 == "RRSIG" && $5 == "CDNSKEY" {print}' dig.out.test$n | wc -l)
   3481 test "$lines" -eq 2 || ret=1
   3482 n=$((n+1))
   3483 test "$ret" -eq 0 || echo_i "failed"
   3484 status=$((status+ret))
   3485 
   3486 echo_i "checking that negative unknown NSEC3 hash algorithm with OPTOUT does not validate ($n)"
   3487 ret=0
   3488 dig_with_opts +noauth +noadd +nodnssec +adflag @10.53.0.3 optout-unknown.example A > dig.out.ns3.test$n
   3489 dig_with_opts +noauth +noadd +nodnssec +adflag @10.53.0.4 optout-unknown.example A > dig.out.ns4.test$n
   3490 grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1
   3491 grep "status: SERVFAIL," dig.out.ns4.test$n > /dev/null || ret=1
   3492 n=$((n+1))
   3493 test "$ret" -eq 0 || echo_i "failed"
   3494 status=$((status+ret))
   3495 
   3496 echo_i "check that CDNSKEY records are signed using KSK by with dnssec-auto ($n)"
   3497 ret=0
   3498 dig_with_opts +noall +answer @10.53.0.2 cdnskey cdnskey-auto.secure > dig.out.test$n
   3499 lines=$(awk '$4 == "RRSIG" && $5 == "CDNSKEY" {print}' dig.out.test$n | wc -l)
   3500 test "$lines" -eq 2 || ret=1
   3501 n=$((n+1))
   3502 test "$ret" -eq 0 || echo_i "failed"
   3503 status=$((status+ret))
   3504 
   3505 echo_i "checking that unknown DNSKEY algorithm validates as insecure ($n)"
   3506 ret=0
   3507 dig_with_opts +noauth +noadd +nodnssec +adflag @10.53.0.3 dnskey-unknown.example A > dig.out.ns3.test$n
   3508 dig_with_opts +noauth +noadd +nodnssec +adflag @10.53.0.4 dnskey-unknown.example A > dig.out.ns4.test$n
   3509 grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1
   3510 grep "status: NOERROR," dig.out.ns4.test$n > /dev/null || ret=1
   3511 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1
   3512 n=$((n+1))
   3513 test "$ret" -eq 0 || echo_i "failed"
   3514 status=$((status+ret))
   3515 
   3516 echo_i "checking that unsupported DNSKEY algorithm validates as insecure ($n)"
   3517 ret=0
   3518 dig_with_opts +noauth +noadd +nodnssec +adflag @10.53.0.3 dnskey-unsupported.example A > dig.out.ns3.test$n
   3519 dig_with_opts +noauth +noadd +nodnssec +adflag @10.53.0.4 dnskey-unsupported.example A > dig.out.ns4.test$n
   3520 grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1
   3521 grep "status: NOERROR," dig.out.ns4.test$n > /dev/null || ret=1
   3522 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1
   3523 n=$((n+1))
   3524 test "$ret" -eq 0 || echo_i "failed"
   3525 status=$((status+ret))
   3526 
   3527 echo_i "checking that unsupported DNSKEY algorithm is in DNSKEY RRset ($n)"
   3528 ret=0
   3529 dig_with_opts +noauth +noadd +nodnssec +adflag @10.53.0.3 dnskey-unsupported-2.example DNSKEY > dig.out.test$n
   3530 grep "status: NOERROR," dig.out.test$n > /dev/null || ret=1
   3531 grep "dnskey-unsupported-2\.example\..*IN.*DNSKEY.*257 3 255" dig.out.test$n > /dev/null || ret=1
   3532 n=$((n+1))
   3533 test "$ret" -eq 0 || echo_i "failed"
   3534 status=$((status+ret))
   3535 
   3536 echo_i "check that a lone non matching CDNSKEY record is rejected ($n)"
   3537 ret=0
   3538 (
   3539 echo zone cdnskey-update.secure
   3540 echo server 10.53.0.2 "$PORT"
   3541 echo update delete cdnskey-update.secure CDNSKEY
   3542 echo send
   3543 dig_with_opts +noall +answer @10.53.0.2 dnskey cdnskey-update.secure |
   3544 sed -n -e "s/^/update add /" -e 's/DNSKEY.257/CDNSKEY 258/p'
   3545 echo send
   3546 ) | $NSUPDATE > nsupdate.out.test$n 2>&1 || true
   3547 grep "update failed: REFUSED" nsupdate.out.test$n > /dev/null || ret=1
   3548 dig_with_opts +noall +answer @10.53.0.2 cdnskey cdnskey-update.secure > dig.out.test$n
   3549 lines=$(awk '$4 == "CDNSKEY" {print}' dig.out.test$n | wc -l)
   3550 test "${lines:-10}" -eq 0 || ret=1
   3551 n=$((n+1))
   3552 test "$ret" -eq 0 || echo_i "failed"
   3553 status=$((status+ret))
   3554 
   3555 echo_i "check that a CDNSKEY deletion record is accepted ($n)"
   3556 ret=0
   3557 (
   3558 echo zone cdnskey-update.secure
   3559 echo server 10.53.0.2 "$PORT"
   3560 echo update delete cdnskey-update.secure CDNSKEY
   3561 echo update add cdnskey-update.secure 0 CDNSKEY 0 3 0 AA==
   3562 echo send
   3563 ) | $NSUPDATE > nsupdate.out.test$n 2>&1
   3564 dig_with_opts +noall +answer @10.53.0.2 cdnskey cdnskey-update.secure > dig.out.test$n
   3565 lines=$(awk '$4 == "CDNSKEY" {print}' dig.out.test$n | wc -l)
   3566 test "${lines:-10}" -eq 1 || ret=1
   3567 lines=$(tr -d '\r' < dig.out.test$n | awk '$4 == "CDNSKEY" && $5 == "0" && $6 == "3" && $7 == "0" && $8 == "AA==" {print}' | wc -l)
   3568 test "${lines:-10}" -eq 1 || ret=1
   3569 n=$((n+1))
   3570 test "$ret" -eq 0 || echo_i "failed"
   3571 status=$((status+ret))
   3572 
   3573 echo_i "checking that unknown DNSKEY algorithm + unknown NSEC3 has algorithm validates as insecure ($n)"
   3574 ret=0
   3575 dig_with_opts +noauth +noadd +nodnssec +adflag @10.53.0.3 dnskey-nsec3-unknown.example A > dig.out.ns3.test$n
   3576 dig_with_opts +noauth +noadd +nodnssec +adflag @10.53.0.4 dnskey-nsec3-unknown.example A > dig.out.ns4.test$n
   3577 grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1
   3578 grep "status: NOERROR," dig.out.ns4.test$n > /dev/null || ret=1
   3579 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1
   3580 n=$((n+1))
   3581 test "$ret" -eq 0 || echo_i "failed"
   3582 status=$((status+ret))
   3583 
   3584 echo_i "check that CDNSKEY records are signed using KSK when added by nsupdate ($n)"
   3585 ret=0
   3586 (
   3587 echo zone cdnskey-update.secure
   3588 echo server 10.53.0.2 "$PORT"
   3589 echo update delete cdnskey-update.secure CDNSKEY
   3590 dig_with_opts +noall +answer @10.53.0.2 dnskey cdnskey-update.secure |
   3591 sed -n -e "s/^/update add /" -e 's/DNSKEY.257/CDNSKEY 257/p'
   3592 echo send
   3593 ) | $NSUPDATE
   3594 dig_with_opts +noall +answer @10.53.0.2 cdnskey cdnskey-update.secure > dig.out.test$n
   3595 lines=$(awk '$4 == "RRSIG" && $5 == "CDNSKEY" {print}' dig.out.test$n | wc -l)
   3596 test "$lines" -eq 2 || ret=1
   3597 lines=$(awk '$4 == "CDNSKEY" {print}' dig.out.test$n | wc -l)
   3598 test "$lines" -eq 1 || ret=1
   3599 n=$((n+1))
   3600 test "$ret" -eq 0 || echo_i "failed"
   3601 status=$((status+ret))
   3602 
   3603 echo_i "check that CDNSKEY records are signed only using KSK when added by"
   3604 echo_ic "nsupdate when dnssec-dnskey-kskonly is yes ($n)"
   3605 ret=0
   3606 keyid=$(cat ns2/cdnskey-kskonly.secure.id)
   3607 (
   3608 echo zone cdnskey-kskonly.secure
   3609 echo server 10.53.0.2 "$PORT"
   3610 echo update delete cdnskey-kskonly.secure CDNSKEY
   3611 dig_with_opts +noall +answer @10.53.0.2 dnskey cdnskey-kskonly.secure |
   3612 sed -n -e "s/^/update add /" -e 's/DNSKEY.257/CDNSKEY 257/p'
   3613 echo send
   3614 ) | $NSUPDATE
   3615 dig_with_opts +noall +answer @10.53.0.2 cdnskey cdnskey-kskonly.secure > dig.out.test$n
   3616 lines=$(awk '$4 == "RRSIG" && $5 == "CDNSKEY" {print}' dig.out.test$n | wc -l)
   3617 test "$lines" -eq 1 || ret=1
   3618 lines=$(awk -v id="${keyid}" '$4 == "RRSIG" && $5 == "CDNSKEY" && $11 == id {print}' dig.out.test$n | wc -l)
   3619 test "$lines" -eq 1 || ret=1
   3620 lines=$(awk '$4 == "CDNSKEY" {print}' dig.out.test$n | wc -l)
   3621 test "$lines" -eq 1 || ret=1
   3622 n=$((n+1))
   3623 test "$ret" -eq 0 || echo_i "failed"
   3624 status=$((status+ret))
   3625 
   3626 echo_i "check that CDNSKEY deletion records are signed only using KSK when added by"
   3627 echo_ic "nsupdate when dnssec-dnskey-kskonly is yes ($n)"
   3628 ret=0
   3629 keyid=$(cat ns2/cdnskey-kskonly.secure.id)
   3630 (
   3631 echo zone cdnskey-kskonly.secure
   3632 echo server 10.53.0.2 "$PORT"
   3633 echo update delete cdnskey-kskonly.secure CDNSKEY
   3634 echo update add cdnskey-kskonly.secure 0 CDNSKEY 0 3 0 AA==
   3635 echo send
   3636 ) | $NSUPDATE
   3637 dig_with_opts +noall +answer @10.53.0.2 cdnskey cdnskey-kskonly.secure > dig.out.test$n
   3638 lines=$(awk '$4 == "RRSIG" && $5 == "CDNSKEY" {print}' dig.out.test$n | wc -l)
   3639 test "$lines" -eq 1 || ret=1
   3640 lines=$(awk -v id="${keyid}" '$4 == "RRSIG" && $5 == "CDNSKEY" && $11 == id {print}' dig.out.test$n | wc -l)
   3641 test "$lines" -eq 1 || ret=1
   3642 lines=$(awk '$4 == "CDNSKEY" {print}' dig.out.test$n | wc -l)
   3643 test "$lines" -eq 1 || ret=1
   3644 lines=$(tr -d '\r' < dig.out.test$n | awk '$4 == "CDNSKEY" && $5 == "0" && $6 == "3" && $7 == "0" && $8 == "AA==" {print}' | wc -l)
   3645 test "${lines:-10}" -eq 1 || ret=1
   3646 n=$((n+1))
   3647 test "$ret" -eq 0 || echo_i "failed"
   3648 status=$((status+ret))
   3649 
   3650 echo_i "checking initialization with a revoked managed key ($n)"
   3651 ret=0
   3652 copy_setports ns5/named2.conf.in ns5/named.conf
   3653 rndccmd 10.53.0.5 reconfig 2>&1 | sed 's/^/ns5 /' | cat_i
   3654 sleep 3
   3655 dig_with_opts +dnssec @10.53.0.5 SOA . > dig.out.ns5.test$n
   3656 grep "status: SERVFAIL" dig.out.ns5.test$n > /dev/null || ret=1
   3657 n=$((n+1))
   3658 test "$ret" -eq 0 || echo_i "failed"
   3659 status=$((status+ret))
   3660 
   3661 echo_i "check that a non matching CDNSKEY record is accepted with a matching CDNSKEY record ($n)"
   3662 ret=0
   3663 (
   3664 echo zone cdnskey-update.secure
   3665 echo server 10.53.0.2 "$PORT"
   3666 echo update delete cdnskey-update.secure CDNSKEY
   3667 dig_with_opts +noall +answer @10.53.0.2 dnskey cdnskey-update.secure |
   3668 sed -n -e "s/^/update add /" -e 's/DNSKEY.257/CDNSKEY 257/p'
   3669 dig_with_opts +noall +answer @10.53.0.2 dnskey cdnskey-update.secure |
   3670 sed -n -e "s/^/update add /" -e 's/DNSKEY.257/CDNSKEY 258/p'
   3671 echo send
   3672 ) | $NSUPDATE
   3673 dig_with_opts +noall +answer @10.53.0.2 cdnskey cdnskey-update.secure > dig.out.test$n
   3674 lines=$(awk '$4 == "RRSIG" && $5 == "CDNSKEY" {print}' dig.out.test$n | wc -l)
   3675 test "$lines" -eq 2 || ret=1
   3676 lines=$(awk '$4 == "CDNSKEY" {print}' dig.out.test$n | wc -l)
   3677 test "$lines" -eq 2 || ret=1
   3678 n=$((n+1))
   3679 test "$ret" -eq 0 || echo_i "failed"
   3680 status=$((status+ret))
   3681 
   3682 echo_i "check that RRSIGs are correctly removed from apex when RRset is removed  NSEC ($n)"
   3683 ret=0
   3684 # generate signed zone with MX and AAAA records at apex.
   3685 (
   3686 cd signer || exit 1
   3687 $KEYGEN -q -a RSASHA1 -3 -fK remove > /dev/null
   3688 $KEYGEN -q -a RSASHA1 -33 remove > /dev/null
   3689 echo > remove.db.signed
   3690 $SIGNER -S -o remove -D -f remove.db.signed remove.db.in > signer.out.1.$n
   3691 )
   3692 grep "RRSIG MX" signer/remove.db.signed > /dev/null || {
   3693 	ret=1 ; cp signer/remove.db.signed signer/remove.db.signed.pre$n;
   3694 }
   3695 # re-generate signed zone without MX and AAAA records at apex.
   3696 (
   3697 cd signer || exit 1
   3698 $SIGNER -S -o remove -D -f remove.db.signed remove2.db.in > signer.out.2.$n
   3699 )
   3700 grep "RRSIG MX" signer/remove.db.signed > /dev/null &&  {
   3701 	ret=1 ; cp signer/remove.db.signed signer/remove.db.signed.post$n;
   3702 }
   3703 n=$((n+1))
   3704 test "$ret" -eq 0 || echo_i "failed"
   3705 status=$((status+ret))
   3706 
   3707 echo_i "check that RRSIGs are correctly removed from apex when RRset is removed  NSEC3 ($n)"
   3708 ret=0
   3709 # generate signed zone with MX and AAAA records at apex.
   3710 (
   3711 cd signer || exit 1
   3712 echo > remove.db.signed
   3713 $SIGNER -3 - -S -o remove -D -f remove.db.signed remove.db.in > signer.out.1.$n
   3714 )
   3715 grep "RRSIG MX" signer/remove.db.signed > /dev/null || {
   3716 	ret=1 ; cp signer/remove.db.signed signer/remove.db.signed.pre$n;
   3717 }
   3718 # re-generate signed zone without MX and AAAA records at apex.
   3719 (
   3720 cd signer || exit 1
   3721 $SIGNER -3 - -S -o remove -D -f remove.db.signed remove2.db.in > signer.out.2.$n
   3722 )
   3723 grep "RRSIG MX" signer/remove.db.signed > /dev/null &&  {
   3724 	ret=1 ; cp signer/remove.db.signed signer/remove.db.signed.post$n;
   3725 }
   3726 n=$((n+1))
   3727 test "$ret" -eq 0 || echo_i "failed"
   3728 status=$((status+ret))
   3729 
   3730 echo_i "check that a named managed zone that was signed 'in-the-future' is re-signed when loaded ($n)"
   3731 ret=0
   3732 dig_with_opts managed-future.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1
   3733 grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
   3734 grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
   3735 n=$((n+1))
   3736 test "$ret" -eq 0 || echo_i "failed"
   3737 status=$((status+ret))
   3738 
   3739 echo_i "check that trust-anchor-telemetry queries are logged ($n)"
   3740 ret=0
   3741 grep "sending trust-anchor-telemetry query '_ta-[0-9a-f]*/NULL" ns6/named.run > /dev/null || ret=1
   3742 n=$((n+1))
   3743 test "$ret" -eq 0 || echo_i "failed"
   3744 status=$((status+ret))
   3745 
   3746 echo_i "check that _ta-XXXX trust-anchor-telemetry queries are logged ($n)"
   3747 ret=0
   3748 grep "trust-anchor-telemetry '_ta-[0-9a-f]*/IN' from" ns1/named.run > /dev/null || ret=1
   3749 n=$((n+1))
   3750 test "$ret" -eq 0 || echo_i "failed"
   3751 status=$((status+ret))
   3752 
   3753 echo_i "check that _ta-AAAA trust-anchor-telemetry are not sent when disabled ($n)"
   3754 ret=0
   3755 grep "sending trust-anchor-telemetry query '_ta-[0-9a-f]*/IN" ns1/named.run > /dev/null && ret=1
   3756 n=$((n+1))
   3757 test "$ret" -eq 0 || echo_i "failed"
   3758 status=$((status+ret))
   3759 
   3760 echo_i "check that KEY-TAG trust-anchor-telemetry queries are logged ($n)"
   3761 ret=0
   3762 dig_with_opts . dnskey +ednsopt=KEY-TAG:ffff @10.53.0.1 > dig.out.ns1.test$n || ret=1
   3763 grep "trust-anchor-telemetry './IN' from .* 65535" ns1/named.run > /dev/null || ret=1
   3764 n=$((n+1))
   3765 test "$ret" -eq 0 || echo_i "failed"
   3766 status=$((status+ret))
   3767 
   3768 echo_i "check that multiple KEY-TAG trust-anchor-telemetry options don't leak memory ($n)"
   3769 ret=0
   3770 dig_with_opts . dnskey +ednsopt=KEY-TAG:fffe +ednsopt=KEY-TAG:fffd @10.53.0.1 > dig.out.ns1.test$n || ret=1
   3771 grep "trust-anchor-telemetry './IN' from .* 65534" ns1/named.run > /dev/null || ret=1
   3772 grep "trust-anchor-telemetry './IN' from .* 65533" ns1/named.run > /dev/null && ret=1
   3773 $PERL $SYSTEMTESTTOP/stop.pl dnssec ns1 || ret=1
   3774 nextpart ns1/named.run > /dev/null
   3775 $PERL $SYSTEMTESTTOP/start.pl --noclean --restart --port ${PORT} dnssec ns1 || ret=1
   3776 n=$(($n+1))
   3777 test "$ret" -eq 0 || echo_i "failed"
   3778 status=$((status+ret))
   3779 
   3780 echo_i "waiting for root server to finish reloading ($n)"
   3781 ret=0
   3782 wait_for_log 20 "all zones loaded" ns1/named.run || ret=1
   3783 n=$(($n+1))
   3784 test "$ret" -eq 0 || echo_i "failed"
   3785 status=$((status+ret))
   3786 
   3787 echo_i "check that the view is logged in messages from the validator when using views ($n)"
   3788 ret=0
   3789 grep "view rec: *validat" ns4/named.run > /dev/null || ret=1
   3790 n=$((n+1))
   3791 test "$ret" -eq 0 || echo_i "failed"
   3792 status=$((status+ret))
   3793 
   3794 echo_i "check that DNAME at apex with NSEC3 is correctly signed (dnssec-signzone) ($n)"
   3795 ret=0
   3796 dig_with_opts txt dname-at-apex-nsec3.example @10.53.0.3 > dig.out.ns3.test$n || ret=1
   3797 grep "RRSIG.NSEC3 ${DEFAULT_ALGORITHM_NUMBER} 3 3600" dig.out.ns3.test$n > /dev/null || ret=1
   3798 n=$((n+1))
   3799 test "$ret" -eq 0 || echo_i "failed"
   3800 status=$((status+ret))
   3801 
   3802 echo_i "check that DNSKEY and other occluded data are excluded from the delegating bitmap ($n)"
   3803 ret=0
   3804 dig_with_opts axfr occluded.example @10.53.0.3 > dig.out.ns3.test$n || ret=1
   3805 grep "^delegation.occluded.example..*NSEC.*NS KEY DS RRSIG NSEC$" dig.out.ns3.test$n > /dev/null || ret=1
   3806 grep "^delegation.occluded.example..*DNSKEY.*" dig.out.ns3.test$n > /dev/null || ret=1
   3807 grep "^delegation.occluded.example..*AAAA.*" dig.out.ns3.test$n > /dev/null || ret=1
   3808 n=$((n+1))
   3809 test "$ret" -eq 0 || echo_i "failed"
   3810 status=$((status+ret))
   3811 
   3812 echo_i "checking DNSSEC records are occluded from ANY in an insecure zone ($n)"
   3813 ret=0
   3814 dig_with_opts any x.insecure.example. @10.53.0.3 > dig.out.ns3.1.test$n || ret=1
   3815 grep "status: NOERROR" dig.out.ns3.1.test$n > /dev/null || ret=1
   3816 grep "ANSWER: 0," dig.out.ns3.1.test$n > /dev/null || ret=1
   3817 dig_with_opts any zz.secure.example. @10.53.0.3 > dig.out.ns3.2.test$n || ret=1
   3818 grep "status: NOERROR" dig.out.ns3.2.test$n > /dev/null || ret=1
   3819 # DNSKEY+RRSIG, NSEC+RRSIG
   3820 grep "ANSWER: 4," dig.out.ns3.2.test$n > /dev/null || ret=1
   3821 n=$((n+1))
   3822 test "$ret" -eq 0 || echo_i "failed"
   3823 status=$((status+ret))
   3824 
   3825 #
   3826 # DNSSEC tests related to unsupported, disabled and revoked trust anchors.
   3827 #
   3828 
   3829 # This nameserver (ns8) is loaded with a bunch of trust anchors.  Some of
   3830 # them are good (enabled.managed, enabled.trusted, secure.managed,
   3831 # secure.trusted), and some of them are bad (disabled.managed,
   3832 # revoked.managed, unsupported.managed, disabled.trusted, revoked.trusted,
   3833 # unsupported.trusted).  Make sure that the bad trust anchors are ignored.
   3834 # This is tested by looking for the corresponding lines in the logfile.
   3835 echo_i "checking that keys with unsupported algorithms and disabled algorithms are ignored ($n)"
   3836 ret=0
   3837 grep -q "ignoring static-key for 'disabled\.trusted\.': algorithm is disabled" ns8/named.run || ret=1
   3838 grep -q "ignoring static-key for 'unsupported\.trusted\.': algorithm is unsupported" ns8/named.run || ret=1
   3839 grep -q "ignoring static-key for 'revoked\.trusted\.': bad key type" ns8/named.run || ret=1
   3840 grep -q "ignoring initial-key for 'disabled\.managed\.': algorithm is disabled" ns8/named.run || ret=1
   3841 grep -q "ignoring initial-key for 'unsupported\.managed\.': algorithm is unsupported" ns8/named.run || ret=1
   3842 grep -q "ignoring initial-key for 'revoked\.managed\.': bad key type" ns8/named.run || ret=1
   3843 n=$((n+1))
   3844 test "$ret" -eq 0 || echo_i "failed"
   3845 status=$((status+ret))
   3846 
   3847 # The next two tests are fairly normal DNSSEC queries to signed zones with a
   3848 # default algorithm.  First, a query is made against the server that is
   3849 # authoritative for the given zone (ns3).  Second, a query is made against a
   3850 # resolver with trust anchors for the given zone (ns8).  Both are expected to
   3851 # return an authentic data positive response.
   3852 echo_i "checking that a trusted key using a supported algorithm validates as secure ($n)"
   3853 ret=0
   3854 dig_with_opts @10.53.0.3 a.secure.trusted A > dig.out.ns3.test$n
   3855 dig_with_opts @10.53.0.8 a.secure.trusted A > dig.out.ns8.test$n
   3856 grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1
   3857 grep "status: NOERROR," dig.out.ns8.test$n > /dev/null || ret=1
   3858 grep "flags:.*ad.*QUERY" dig.out.ns8.test$n > /dev/null || ret=1
   3859 n=$((n+1))
   3860 test "$ret" -eq 0 || echo_i "failed"
   3861 status=$((status+ret))
   3862 
   3863 echo_i "checking that a managed key using a supported algorithm validates as secure ($n)"
   3864 ret=0
   3865 dig_with_opts @10.53.0.3 a.secure.managed A > dig.out.ns3.test$n
   3866 dig_with_opts @10.53.0.8 a.secure.managed A > dig.out.ns8.test$n
   3867 grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1
   3868 grep "status: NOERROR," dig.out.ns8.test$n > /dev/null || ret=1
   3869 grep "flags:.*ad.*QUERY" dig.out.ns8.test$n > /dev/null || ret=1
   3870 n=$((n+1))
   3871 test "$ret" -eq 0 || echo_i "failed"
   3872 status=$((status+ret))
   3873 
   3874 # The next two queries ensure that a zone signed with a DNSKEY with an unsupported
   3875 # algorithm will yield insecure positive responses.  These trust anchors in ns8 are
   3876 # ignored and so this domain is treated as insecure.  The AD bit should not be set
   3877 # in the response.
   3878 echo_i "checking that a trusted key using an unsupported algorithm validates as insecure ($n)"
   3879 ret=0
   3880 dig_with_opts @10.53.0.3 a.unsupported.trusted A > dig.out.ns3.test$n
   3881 dig_with_opts @10.53.0.8 a.unsupported.trusted A > dig.out.ns8.test$n
   3882 grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1
   3883 grep "status: NOERROR," dig.out.ns8.test$n > /dev/null || ret=1
   3884 grep "flags:.*ad.*QUERY" dig.out.ns8.test$n > /dev/null && ret=1
   3885 n=$((n+1))
   3886 test "$ret" -eq 0 || echo_i "failed"
   3887 status=$((status+ret))
   3888 
   3889 echo_i "checking that a managed key using an unsupported algorithm validates as insecure ($n)"
   3890 ret=0
   3891 dig_with_opts @10.53.0.3 a.unsupported.managed A > dig.out.ns3.test$n
   3892 dig_with_opts @10.53.0.8 a.unsupported.managed A > dig.out.ns8.test$n
   3893 grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1
   3894 grep "status: NOERROR," dig.out.ns8.test$n > /dev/null || ret=1
   3895 grep "flags:.*ad.*QUERY" dig.out.ns8.test$n > /dev/null && ret=1
   3896 n=$((n+1))
   3897 test "$ret" -eq 0 || echo_i "failed"
   3898 status=$((status+ret))
   3899 
   3900 # The next two queries ensure that a zone signed with a DNSKEY that the nameserver
   3901 # has a disabled algorithm match for will yield insecure positive responses.
   3902 # These trust anchors in ns8 are ignored and so this domain is treated as insecure.
   3903 # The AD bit should not be set in the response.
   3904 echo_i "checking that a trusted key using a disabled algorithm validates as insecure ($n)"
   3905 ret=0
   3906 dig_with_opts @10.53.0.3 a.disabled.trusted A > dig.out.ns3.test$n
   3907 dig_with_opts @10.53.0.8 a.disabled.trusted A > dig.out.ns8.test$n
   3908 grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1
   3909 grep "status: NOERROR," dig.out.ns8.test$n > /dev/null || ret=1
   3910 grep "flags:.*ad.*QUERY" dig.out.ns8.test$n > /dev/null && ret=1
   3911 n=$((n+1))
   3912 test "$ret" -eq 0 || echo_i "failed"
   3913 status=$((status+ret))
   3914 
   3915 echo_i "checking that a managed key using a disabled algorithm validates as insecure ($n)"
   3916 ret=0
   3917 dig_with_opts @10.53.0.3 a.disabled.managed A > dig.out.ns3.test$n
   3918 dig_with_opts @10.53.0.8 a.disabled.managed A > dig.out.ns8.test$n
   3919 grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1
   3920 grep "status: NOERROR," dig.out.ns8.test$n > /dev/null || ret=1
   3921 grep "flags:.*ad.*QUERY" dig.out.ns8.test$n > /dev/null && ret=1
   3922 n=$((n+1))
   3923 test "$ret" -eq 0 || echo_i "failed"
   3924 status=$((status+ret))
   3925 
   3926 # The next two queries ensure that a zone signed with a DNSKEY that the
   3927 # nameserver has a disabled algorithm for, but for a different domain, will
   3928 # yield secure positive responses.  Since "enabled.trusted." and
   3929 # "enabled.managed." do not match the "disable-algorithms" option, no
   3930 # special rules apply and these zones should validate as secure, with the AD
   3931 # bit set.
   3932 echo_i "checking that a trusted key using an algorithm disabled for another domain validates as secure ($n)"
   3933 ret=0
   3934 dig_with_opts @10.53.0.3 a.enabled.trusted A > dig.out.ns3.test$n
   3935 dig_with_opts @10.53.0.8 a.enabled.trusted A > dig.out.ns8.test$n
   3936 grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1
   3937 grep "status: NOERROR," dig.out.ns8.test$n > /dev/null || ret=1
   3938 grep "flags:.*ad.*QUERY" dig.out.ns8.test$n > /dev/null || ret=1
   3939 n=$((n+1))
   3940 test "$ret" -eq 0 || echo_i "failed"
   3941 status=$((status+ret))
   3942 
   3943 echo_i "checking that a managed key using an algorithm disabled for another domain validates as secure ($n)"
   3944 ret=0
   3945 dig_with_opts @10.53.0.3 a.enabled.managed A > dig.out.ns3.test$n
   3946 dig_with_opts @10.53.0.8 a.enabled.managed A > dig.out.ns8.test$n
   3947 grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1
   3948 grep "status: NOERROR," dig.out.ns8.test$n > /dev/null || ret=1
   3949 grep "flags:.*ad.*QUERY" dig.out.ns8.test$n > /dev/null || ret=1
   3950 n=$((n+1))
   3951 test "$ret" -eq 0 || echo_i "failed"
   3952 status=$((status+ret))
   3953 
   3954 # A configured revoked trust anchor is ignored and thus the two queries below
   3955 # should result in insecure responses, since no trust points for the
   3956 # "revoked.trusted." and "revoked.managed." zones are created.
   3957 echo_i "checking that a trusted key that is revoked validates as insecure ($n)"
   3958 ret=0
   3959 dig_with_opts @10.53.0.3 a.revoked.trusted A > dig.out.ns3.test$n
   3960 dig_with_opts @10.53.0.8 a.revoked.trusted A > dig.out.ns8.test$n
   3961 grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1
   3962 grep "status: NOERROR," dig.out.ns8.test$n > /dev/null || ret=1
   3963 grep "flags:.*ad.*QUERY" dig.out.ns8.test$n > /dev/null && ret=1
   3964 n=$((n+1))
   3965 test "$ret" -eq 0 || echo_i "failed"
   3966 status=$((status+ret))
   3967 
   3968 echo_i "checking that a managed key that is revoked validates as insecure ($n)"
   3969 ret=0
   3970 dig_with_opts @10.53.0.3 a.revoked.managed A > dig.out.ns3.test$n
   3971 dig_with_opts @10.53.0.8 a.revoked.managed A > dig.out.ns8.test$n
   3972 grep "status: NOERROR," dig.out.ns3.test$n > /dev/null || ret=1
   3973 grep "status: NOERROR," dig.out.ns8.test$n > /dev/null || ret=1
   3974 grep "flags:.*ad.*QUERY" dig.out.ns8.test$n > /dev/null && ret=1
   3975 n=$((n+1))
   3976 test "$ret" -eq 0 || echo_i "failed"
   3977 status=$((status+ret))
   3978 
   3979 ###
   3980 ### Additional checks for when the KSK is offline.
   3981 ###
   3982 
   3983 # Save some useful information
   3984 zone="updatecheck-kskonly.secure"
   3985 KSK=`cat ns2/${zone}.ksk.key`
   3986 ZSK=`cat ns2/${zone}.zsk.key`
   3987 KSK_ID=`cat ns2/${zone}.ksk.id`
   3988 ZSK_ID=`cat ns2/${zone}.zsk.id`
   3989 SECTIONS="+answer +noauthority +noadditional"
   3990 echo_i "testing zone $zone KSK=$KSK_ID ZSK=$ZSK_ID"
   3991 
   3992 # Print IDs of keys used for generating RRSIG records for RRsets of type $1
   3993 # found in dig output file $2.
   3994 get_keys_which_signed() {
   3995 	qtype=$1
   3996 	output=$2
   3997 	# The key ID is the 11th column of the RRSIG record line.
   3998 	awk -v qt="$qtype" '$4 == "RRSIG" && $5 == qt {print $11}' < "$output"
   3999 }
   4000 
   4001 # Basic checks to make sure everything is fine before the KSK is made offline.
   4002 for qtype in "DNSKEY" "CDNSKEY" "CDS"
   4003 do
   4004   echo_i "checking $qtype RRset is signed with KSK only (update-check-ksk, dnssec-ksk-only) ($n)"
   4005   ret=0
   4006   dig_with_opts $SECTIONS @10.53.0.2 $qtype $zone > dig.out.test$n
   4007   lines=$(get_keys_which_signed $qtype dig.out.test$n | wc -l)
   4008   test "$lines" -eq 1 || ret=1
   4009   get_keys_which_signed $qtype dig.out.test$n | grep "^$KSK_ID$" > /dev/null || ret=1
   4010   get_keys_which_signed $qtype dig.out.test$n | grep "^$ZSK_ID$" > /dev/null && ret=1
   4011   n=$((n+1))
   4012   test "$ret" -eq 0 || echo_i "failed"
   4013   status=$((status+ret))
   4014 done
   4015 
   4016 echo_i "checking SOA RRset is signed with ZSK only (update-check-ksk and dnssec-ksk-only) ($n)"
   4017 ret=0
   4018 dig_with_opts $SECTIONS @10.53.0.2 soa $zone > dig.out.test$n
   4019 lines=$(get_keys_which_signed "SOA" dig.out.test$n | wc -l)
   4020 test "$lines" -eq 1 || ret=1
   4021 get_keys_which_signed "SOA" dig.out.test$n | grep "^$KSK_ID$" > /dev/null && ret=1
   4022 get_keys_which_signed "SOA" dig.out.test$n | grep "^$ZSK_ID$" > /dev/null || ret=1
   4023 n=$((n+1))
   4024 test "$ret" -eq 0 || echo_i "failed"
   4025 status=$((status+ret))
   4026 
   4027 # Roll the ZSK.
   4028 zsk2=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -K ns2 -n zone "$zone")
   4029 keyfile_to_key_id "$zsk2" > ns2/$zone.zsk.id2
   4030 ZSK_ID2=`cat ns2/$zone.zsk.id2`
   4031 
   4032 echo_i "load new ZSK $ZSK_ID2 for $zone ($n)"
   4033 ret=0
   4034 dnssec_loadkeys_on 2 $zone || ret=1
   4035 n=$((n+1))
   4036 test "$ret" -eq 0 || echo_i "failed"
   4037 status=$((status+ret))
   4038 
   4039 # Make new ZSK active.
   4040 echo_i "make ZSK $ZSK_ID inactive and make new ZSK $ZSK_ID2 active for zone $zone ($n)"
   4041 ret=0
   4042 $SETTIME -I now -K ns2 $ZSK > /dev/null
   4043 $SETTIME -A now -K ns2 $zsk2 > /dev/null
   4044 dnssec_loadkeys_on 2 $zone || ret=1
   4045 n=$((n+1))
   4046 test "$ret" -eq 0 || echo_i "failed"
   4047 status=$((status+ret))
   4048 
   4049 # Remove the KSK from disk.
   4050 echo_i "remove the KSK $KSK_ID for zone $zone from disk"
   4051 mv ns2/$KSK.key ns2/$KSK.key.bak
   4052 mv ns2/$KSK.private ns2/$KSK.private.bak
   4053 
   4054 # Update the zone that requires a resign of the SOA RRset.
   4055 echo_i "update the zone with $zone IN TXT nsupdate added me"
   4056 (
   4057 echo zone $zone
   4058 echo server 10.53.0.2 "$PORT"
   4059 echo update add $zone. 300 in txt "nsupdate added me"
   4060 echo send
   4061 ) | $NSUPDATE
   4062 
   4063 # Redo the tests now that the zone is updated and the KSK is offline.
   4064 for qtype in "DNSKEY" "CDNSKEY" "CDS"
   4065 do
   4066   echo_i "checking $qtype RRset is signed with KSK only, KSK offline (update-check-ksk, dnssec-ksk-only) ($n)"
   4067   ret=0
   4068   dig_with_opts $SECTIONS @10.53.0.2 $qtype $zone > dig.out.test$n
   4069   lines=$(get_keys_which_signed $qtype dig.out.test$n | wc -l)
   4070   test "$lines" -eq 1 || ret=1
   4071   get_keys_which_signed $qtype dig.out.test$n | grep "^$KSK_ID$" > /dev/null || ret=1
   4072   get_keys_which_signed $qtype dig.out.test$n | grep "^$ZSK_ID$" > /dev/null && ret=1
   4073   get_keys_which_signed $qtype dig.out.test$n | grep "^$ZSK_ID2$" > /dev/null && ret=1
   4074   n=$((n+1))
   4075   test "$ret" -eq 0 || echo_i "failed"
   4076   status=$((status+ret))
   4077 done
   4078 
   4079 for qtype in "SOA" "TXT"
   4080 do
   4081   echo_i "checking $qtype RRset is signed with ZSK only, KSK offline (update-check-ksk and dnssec-ksk-only) ($n)"
   4082   ret=0
   4083   dig_with_opts $SECTIONS @10.53.0.2 $qtype $zone > dig.out.test$n
   4084   lines=$(get_keys_which_signed $qtype dig.out.test$n | wc -l)
   4085   test "$lines" -eq 1 || ret=1
   4086   get_keys_which_signed $qtype dig.out.test$n | grep "^$KSK_ID$" > /dev/null && ret=1
   4087   get_keys_which_signed $qtype dig.out.test$n | grep "^$ZSK_ID$" > /dev/null && ret=1
   4088   get_keys_which_signed $qtype dig.out.test$n | grep "^$ZSK_ID2$" > /dev/null || ret=1
   4089   n=$((n+1))
   4090   test "$ret" -eq 0 || echo_i "failed"
   4091   status=$((status+ret))
   4092 done
   4093 
   4094 # Put back the KSK.
   4095 echo_i "put back the KSK $KSK_ID for zone $zone from disk"
   4096 mv ns2/$KSK.key.bak ns2/$KSK.key
   4097 mv ns2/$KSK.private.bak ns2/$KSK.private
   4098 
   4099 # Roll the ZSK again.
   4100 zsk3=$("$KEYGEN" -q -a "$DEFAULT_ALGORITHM" -b "$DEFAULT_BITS" -K ns2 -n zone "$zone")
   4101 keyfile_to_key_id "$zsk3" > ns2/$zone.zsk.id3
   4102 ZSK_ID3=`cat ns2/$zone.zsk.id3`
   4103 
   4104 # Schedule the new ZSK (ZSK3) to become active.
   4105 echo_i "delete old ZSK $ZSK_ID schedule ZSK $ZSK_ID2 inactive and new ZSK $ZSK_ID3 active for zone $zone ($n)"
   4106 $SETTIME -D now -K ns2 $ZSK > /dev/null
   4107 $SETTIME -I +3600 -K ns2 $zsk2 > /dev/null
   4108 $SETTIME -A +3600 -K ns2 $zsk3 > /dev/null
   4109 dnssec_loadkeys_on 2 $zone || ret=1
   4110 n=$((n+1))
   4111 test "$ret" -eq 0 || echo_i "failed"
   4112 status=$((status+ret))
   4113 
   4114 # Remove the KSK from disk.
   4115 echo_i "remove the KSK $KSK_ID for zone $zone from disk"
   4116 mv ns2/$KSK.key ns2/$KSK.key.bak
   4117 mv ns2/$KSK.private ns2/$KSK.private.bak
   4118 
   4119 # Update the zone that requires a resign of the SOA RRset.
   4120 echo_i "update the zone with $zone IN TXT nsupdate added me again"
   4121 (
   4122 echo zone $zone
   4123 echo server 10.53.0.2 "$PORT"
   4124 echo update add $zone. 300 in txt "nsupdate added me again"
   4125 echo send
   4126 ) | $NSUPDATE
   4127 
   4128 # Redo the tests now that the ZSK roll has deleted the old key.
   4129 for qtype in "DNSKEY" "CDNSKEY" "CDS"
   4130 do
   4131   echo_i "checking $qtype RRset is signed with KSK only, old ZSK deleted (update-check-ksk, dnssec-ksk-only) ($n)"
   4132   ret=0
   4133   dig_with_opts $SECTIONS @10.53.0.2 $qtype $zone > dig.out.test$n
   4134   lines=$(get_keys_which_signed $qtype dig.out.test$n | wc -l)
   4135   test "$lines" -eq 1 || ret=1
   4136   get_keys_which_signed $qtype dig.out.test$n | grep "^$KSK_ID$" > /dev/null || ret=1
   4137   get_keys_which_signed $qtype dig.out.test$n | grep "^$ZSK_ID$" > /dev/null && ret=1
   4138   get_keys_which_signed $qtype dig.out.test$n | grep "^$ZSK_ID2$" > /dev/null && ret=1
   4139   get_keys_which_signed $qtype dig.out.test$n | grep "^$ZSK_ID3$" > /dev/null && ret=1
   4140   n=$((n+1))
   4141   test "$ret" -eq 0 || echo_i "failed"
   4142   status=$((status+ret))
   4143 done
   4144 
   4145 for qtype in "SOA" "TXT"
   4146 do
   4147   echo_i "checking $qtype RRset is signed with ZSK only, old ZSK deleted (update-check-ksk and dnssec-ksk-only) ($n)"
   4148   ret=0
   4149   dig_with_opts $SECTIONS @10.53.0.2 $qtype $zone > dig.out.test$n
   4150   lines=$(get_keys_which_signed $qtype dig.out.test$n | wc -l)
   4151   test "$lines" -eq 1 || ret=1
   4152   get_keys_which_signed $qtype dig.out.test$n | grep "^$KSK_ID$" > /dev/null && ret=1
   4153   get_keys_which_signed $qtype dig.out.test$n | grep "^$ZSK_ID$" > /dev/null && ret=1
   4154   get_keys_which_signed $qtype dig.out.test$n | grep "^$ZSK_ID2$" > /dev/null || ret=1
   4155   get_keys_which_signed $qtype dig.out.test$n | grep "^$ZSK_ID3$" > /dev/null && ret=1
   4156   n=$((n+1))
   4157   test "$ret" -eq 0 || echo_i "failed"
   4158   status=$((status+ret))
   4159 done
   4160 
   4161 # Make the new ZSK (ZSK3) active.
   4162 echo_i "make new ZSK $ZSK_ID3 active for zone $zone ($n)"
   4163 $SETTIME -I +1 -K ns2 $zsk2 > /dev/null
   4164 $SETTIME -A +1 -K ns2 $zsk3 > /dev/null
   4165 dnssec_loadkeys_on 2 $zone || ret=1
   4166 n=$((n+1))
   4167 test "$ret" -eq 0 || echo_i "failed"
   4168 status=$((status+ret))
   4169 
   4170 # Wait for newest ZSK to become active.
   4171 echo_i "wait until new ZSK $ZSK_ID3 active and ZSK $ZSK_ID2 inactive"
   4172 for i in 1 2 3 4 5 6 7 8 9 10; do
   4173     ret=0
   4174     grep "DNSKEY $zone/$DEFAULT_ALGORITHM/$ZSK_ID3 (ZSK) is now active" ns2/named.run > /dev/null || ret=1
   4175     grep "DNSKEY $zone/$DEFAULT_ALGORITHM/$ZSK_ID2 (ZSK) is now inactive" ns2/named.run > /dev/null || ret=1
   4176     [ "$ret" -eq 0 ] && break
   4177     sleep 1
   4178 done
   4179 n=$((n+1))
   4180 test "$ret" -eq 0 || echo_i "failed"
   4181 status=$((status+ret))
   4182 
   4183 # Update the zone that requires a resign of the SOA RRset.
   4184 echo_i "update the zone with $zone IN TXT nsupdate added me one more time"
   4185 (
   4186 echo zone $zone
   4187 echo server 10.53.0.2 "$PORT"
   4188 echo update add $zone. 300 in txt "nsupdate added me one more time"
   4189 echo send
   4190 ) | $NSUPDATE
   4191 n=$((n+1))
   4192 test "$ret" -eq 0 || echo_i "failed"
   4193 status=$((status+ret))
   4194 
   4195 # Redo the tests one more time.
   4196 for qtype in "DNSKEY" "CDNSKEY" "CDS"
   4197 do
   4198   echo_i "checking $qtype RRset is signed with KSK only, new ZSK active (update-check-ksk, dnssec-ksk-only) ($n)"
   4199   ret=0
   4200   dig_with_opts $SECTIONS @10.53.0.2 $qtype $zone > dig.out.test$n
   4201   lines=$(get_keys_which_signed $qtype dig.out.test$n | wc -l)
   4202   test "$lines" -eq 1 || ret=1
   4203   get_keys_which_signed $qtype dig.out.test$n | grep "^$KSK_ID$" > /dev/null || ret=1
   4204   get_keys_which_signed $qtype dig.out.test$n | grep "^$ZSK_ID$" > /dev/null && ret=1
   4205   get_keys_which_signed $qtype dig.out.test$n | grep "^$ZSK_ID2$" > /dev/null && ret=1
   4206   get_keys_which_signed $qtype dig.out.test$n | grep "^$ZSK_ID3$" > /dev/null && ret=1
   4207   n=$((n+1))
   4208   test "$ret" -eq 0 || echo_i "failed"
   4209   status=$((status+ret))
   4210 done
   4211 
   4212 for qtype in "SOA" "TXT"
   4213 do
   4214   echo_i "checking $qtype RRset is signed with ZSK only, new ZSK active (update-check-ksk and dnssec-ksk-only) ($n)"
   4215   ret=0
   4216   dig_with_opts $SECTIONS @10.53.0.2 $qtype $zone > dig.out.test$n
   4217   lines=$(get_keys_which_signed $qtype dig.out.test$n | wc -l)
   4218   test "$lines" -eq 1 || ret=1
   4219   get_keys_which_signed $qtype dig.out.test$n | grep "^$KSK_ID$" > /dev/null && ret=1
   4220   get_keys_which_signed $qtype dig.out.test$n | grep "^$ZSK_ID$" > /dev/null && ret=1
   4221   get_keys_which_signed $qtype dig.out.test$n | grep "^$ZSK_ID2$" > /dev/null && ret=1
   4222   get_keys_which_signed $qtype dig.out.test$n | grep "^$ZSK_ID3$" > /dev/null || ret=1
   4223   n=$((n+1))
   4224   test "$ret" -eq 0 || echo_i "failed"
   4225   status=$((status+ret))
   4226 done
   4227 
   4228 echo_i "checking secroots output with multiple views ($n)"
   4229 ret=0
   4230 rndccmd 10.53.0.4 secroots 2>&1 | sed 's/^/ns4 /' | cat_i
   4231 cp ns4/named.secroots named.secroots.test$n
   4232 check_secroots_layout named.secroots.test$n || ret=1
   4233 n=$((n+1))
   4234 test "$ret" -eq 0 || echo_i "failed"
   4235 status=$((status+ret))
   4236 
   4237 echo_i "exit status: $status"
   4238 [ $status -eq 0 ] || exit 1
   4239