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