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