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