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