1#!/bin/sh
2#
3# Copyright (C) 2009-2012  Internet Systems Consortium, Inc. ("ISC")
4#
5# Permission to use, copy, modify, and/or distribute this software for any
6# purpose with or without fee is hereby granted, provided that the above
7# copyright notice and this permission notice appear in all copies.
8#
9# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11# AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15# PERFORMANCE OF THIS SOFTWARE.
16
17# Id
18
19SYSTEMTESTTOP=..
20. $SYSTEMTESTTOP/conf.sh
21
22RANDFILE=random.data
23
24status=0
25n=0
26
27DIGOPTS="+tcp +noadd +nosea +nostat +nocmd +dnssec -p 5300"
28
29# convert private-type records to readable form
30showprivate () {
31    echo "-- $@ --"
32    $DIG $DIGOPTS +nodnssec +short @$2 -t type65534 $1 | cut -f3 -d' ' |
33        while read record; do
34            perl -e 'my $rdata = pack("H*", @ARGV[0]);
35                die "invalid record" unless length($rdata) == 5;
36                my ($alg, $key, $remove, $complete) = unpack("CnCC", $rdata);
37                my $action = "signing";
38                $action = "removing" if $remove;
39                my $state = " (incomplete)";
40                $state = " (complete)" if $complete;
41                print ("$action: alg: $alg, key: $key$state\n");' $record
42        done
43}
44
45# check that signing records are marked as complete
46checkprivate () {
47    ret=0
48    x=`showprivate "$@"`
49    echo $x | grep incomplete >&- 2>&- && ret=1
50    [ $ret = 1 ] && {
51        echo "$x"
52        echo "I:failed"
53    }
54    return $ret
55}
56
57#
58#  The NSEC record at the apex of the zone and its RRSIG records are
59#  added as part of the last step in signing a zone.  We wait for the
60#  NSEC records to appear before proceeding with a counter to prevent
61#  infinite loops if there is a error.
62#
63echo "I:waiting for autosign changes to take effect"
64i=0
65while [ $i -lt 30 ]
66do
67	ret=0
68	#
69	# Wait for the root DNSKEY RRset to be fully signed.
70	#
71	$DIG $DIGOPTS . @10.53.0.1 dnskey > dig.out.ns1.test$n || ret=1
72	grep "ANSWER: 10," dig.out.ns1.test$n > /dev/null || ret=1
73	for z in .
74	do
75		$DIG $DIGOPTS $z @10.53.0.1 nsec > dig.out.ns1.test$n || ret=1
76		grep "NS SOA" dig.out.ns1.test$n > /dev/null || ret=1
77	done
78	for z in bar. example. private.secure.example.
79	do
80		$DIG $DIGOPTS $z @10.53.0.2 nsec > dig.out.ns2.test$n || ret=1
81		grep "NS SOA" dig.out.ns2.test$n > /dev/null || ret=1
82	done
83	for z in bar. example.
84	do 
85		$DIG $DIGOPTS $z @10.53.0.3 nsec > dig.out.ns3.test$n || ret=1
86		grep "NS SOA" dig.out.ns3.test$n > /dev/null || ret=1
87	done
88	i=`expr $i + 1`
89	if [ $ret = 0 ]; then break; fi
90	echo "I:waiting ... ($i)"
91	sleep 2
92done
93n=`expr $n + 1`
94if [ $ret != 0 ]; then echo "I:failed"; else echo "I:done"; fi
95status=`expr $status + $ret`
96
97echo "I:checking NSEC->NSEC3 conversion prerequisites ($n)"
98ret=0
99# these commands should result in an empty file:
100$DIG $DIGOPTS +noall +answer nsec3.example. nsec3param @10.53.0.3 > dig.out.ns3.1.test$n || ret=1
101grep "NSEC3PARAM" dig.out.ns3.1.test$n > /dev/null && ret=1
102$DIG $DIGOPTS +noall +answer autonsec3.example. nsec3param @10.53.0.3 > dig.out.ns3.2.test$n || ret=1
103grep "NSEC3PARAM" dig.out.ns3.2.test$n > /dev/null && ret=1
104n=`expr $n + 1`
105if [ $ret != 0 ]; then echo "I:failed"; fi
106status=`expr $status + $ret`
107
108echo "I:checking NSEC3->NSEC conversion prerequisites ($n)"
109ret=0
110$DIG $DIGOPTS +noall +answer nsec3-to-nsec.example. nsec3param @10.53.0.3 > dig.out.ns3.test$n || ret=1
111grep "NSEC3PARAM" dig.out.ns3.test$n > /dev/null || ret=1
112n=`expr $n + 1`
113if [ $ret != 0 ]; then echo "I:failed"; fi
114status=`expr $status + $ret`
115
116echo "I:converting zones from nsec to nsec3"
117$NSUPDATE > /dev/null 2>&1 <<END	|| status=1
118server 10.53.0.3 5300
119zone nsec3.nsec3.example.
120update add nsec3.nsec3.example. 3600 NSEC3PARAM 1 0 10 BEEF
121send
122zone optout.nsec3.example.
123update add optout.nsec3.example. 3600 NSEC3PARAM 1 1 10 BEEF
124send
125zone nsec3.example.
126update add nsec3.example. 3600 NSEC3PARAM 1 0 10 BEEF
127send
128zone autonsec3.example.
129update add autonsec3.example. 3600 NSEC3PARAM 1 0 20 DEAF
130send
131zone nsec3.optout.example.
132update add nsec3.optout.example. 3600 NSEC3PARAM 1 0 10 BEEF
133send
134zone optout.optout.example.
135update add optout.optout.example. 3600 NSEC3PARAM 1 1 10 BEEF
136send
137zone optout.example.
138update add optout.example. 3600 NSEC3PARAM 1 1 10 BEEF
139send
140END
141
142# try to convert nsec.example; this should fail due to non-NSEC key
143echo "I:preset nsec3param in unsigned zone via nsupdate ($n)"
144$NSUPDATE > nsupdate.out 2>&1 <<END
145server 10.53.0.3 5300
146zone nsec.example.
147update add nsec.example. 3600 NSEC3PARAM 1 0 10 BEEF
148send
149END
150
151echo "I:checking for nsec3param in unsigned zone ($n)"
152ret=0
153$DIG $DIGOPTS +noall +answer autonsec3.example. nsec3param @10.53.0.3 > dig.out.ns3.test$n || ret=1
154grep "NSEC3PARAM" dig.out.ns3.test$n > /dev/null && ret=1
155n=`expr $n + 1`
156if [ $ret != 0 ]; then echo "I:failed"; fi
157status=`expr $status + $ret`
158
159echo "I:checking for nsec3param signing record ($n)"
160ret=0
161$RNDC -c ../common/rndc.conf -s 10.53.0.3 -p 9953 signing -list autonsec3.example. > signing.out.test$n 2>&1
162grep "Pending NSEC3 chain 1 0 20 DEAF" signing.out.test$n > /dev/null || ret=1
163n=`expr $n + 1`
164if [ $ret != 0 ]; then echo "I:failed"; fi
165status=`expr $status + $ret`
166
167echo "I:resetting nsec3param via rndc signing ($n)"
168ret=0
169$RNDC -c ../common/rndc.conf -s 10.53.0.3 -p 9953 signing -clear all autonsec3.example. > /dev/null 2>&1
170$RNDC -c ../common/rndc.conf -s 10.53.0.3 -p 9953 signing -nsec3param 1 1 10 beef autonsec3.example. > /dev/null 2>&1
171sleep 1
172$RNDC -c ../common/rndc.conf -s 10.53.0.3 -p 9953 signing -list autonsec3.example. > signing.out.test$n 2>&1
173grep "Pending NSEC3 chain 1 1 10 BEEF" signing.out.test$n > /dev/null || ret=1
174num=`grep "Pending " signing.out.test$n | wc -l`
175[ $num -eq 1 ] || ret=1
176n=`expr $n + 1`
177if [ $ret != 0 ]; then echo "I:failed"; fi
178status=`expr $status + $ret`
179
180echo "I:signing preset nsec3 zone"
181zsk=`cat autozsk.key`
182ksk=`cat autoksk.key`
183$SETTIME -K ns3 -P now -A now $zsk > /dev/null 2>&1
184$SETTIME -K ns3 -P now -A now $ksk > /dev/null 2>&1
185$RNDC -c ../common/rndc.conf -s 10.53.0.3 -p 9953 loadkeys autonsec3.example. 2>&1 | sed 's/^/I:ns3 /'
186
187echo "I:waiting for changes to take effect"
188sleep 3
189
190echo "I:converting zone from nsec3 to nsec"
191$NSUPDATE > /dev/null 2>&1 << END	|| status=1
192server 10.53.0.3 5300
193zone nsec3-to-nsec.example.
194update delete nsec3-to-nsec.example. NSEC3PARAM
195send
196END
197
198echo "I:waiting for change to take effect"
199sleep 3
200
201echo "I:checking that expired RRSIGs from missing key are not deleted ($n)"
202ret=0
203missing=`sed 's/^K.*+007+0*\([0-9]\)/\1/' < missingzsk.key`
204$JOURNALPRINT ns3/nozsk.example.db.jnl | \
205   awk '{if ($1 == "del" && $5 == "RRSIG" && $12 == id) {exit 1}} END {exit 0}' id=$missing || ret=1
206if [ $ret != 0 ]; then echo "I:failed"; fi
207status=`expr $status + $ret`
208
209echo "I:checking that expired RRSIGs from inactive key are not deleted ($n)"
210ret=0
211inactive=`sed 's/^K.*+007+0*\([0-9]\)/\1/' < inactivezsk.key`
212$JOURNALPRINT ns3/inaczsk.example.db.jnl | \
213   awk '{if ($1 == "del" && $5 == "RRSIG" && $12 == id) {exit 1}} END {exit 0}' id=$inactive || ret=1
214if [ $ret != 0 ]; then echo "I:failed"; fi
215status=`expr $status + $ret`
216
217echo "I:checking that non-replaceable RRSIGs are logged only once ($n)"
218ret=0
219loglines=`grep "Key nozsk.example/NSEC3RSASHA1/$missing .* retaining signatures" ns3/named.run | wc -l`
220[ "$loglines" -eq 1 ] || ret=1
221loglines=`grep "Key inaczsk.example/NSEC3RSASHA1/$missing .* retaining signatures" ns3/named.run | wc -l`
222[ "$loglines" -eq 1 ] || ret=1
223if [ $ret != 0 ]; then echo "I:failed"; fi
224status=`expr $status + $ret`
225
226echo "I:checking serial is not incremented when signatures are unchanged ($n)"
227ret=0
228newserial=`$DIG $DIGOPTS +short soa nozsk.example @10.53.0.3 | awk '$0 !~ /SOA/ {print $3}'`
229[ "$newserial" -eq 2 ] || ret=1
230newserial=`$DIG $DIGOPTS +short soa inaczsk.example @10.53.0.3 | awk '$0 !~ /SOA/ {print $3}'`
231[ "$newserial" -eq 2 ] || ret=1
232if [ $ret != 0 ]; then echo "I:failed"; fi
233status=`expr $status + $ret`
234
235# Send rndc sync command to ns1, ns2 and ns3, to force the dynamically
236# signed zones to be dumped to their zone files
237echo "I:dumping zone files"
238$RNDC -c ../common/rndc.conf -s 10.53.0.1 -p 9953 sync 2>&1 | sed 's/^/I:ns1 /'
239$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 sync 2>&1 | sed 's/^/I:ns2 /'
240$RNDC -c ../common/rndc.conf -s 10.53.0.3 -p 9953 sync 2>&1 | sed 's/^/I:ns3 /'
241
242echo "I:checking expired signatures were updated ($n)"
243ret=0
244$DIG $DIGOPTS +noauth a.oldsigs.example. @10.53.0.3 a > dig.out.ns3.test$n || ret=1
245$DIG $DIGOPTS +noauth a.oldsigs.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1
246$PERL ../digcomp.pl dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
247grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
248n=`expr $n + 1`
249if [ $ret != 0 ]; then echo "I:failed"; fi
250status=`expr $status + $ret`
251
252echo "I:checking NSEC->NSEC3 conversion succeeded ($n)"
253ret=0
254$DIG $DIGOPTS nsec3.example. nsec3param @10.53.0.3 > dig.out.ns3.ok.test$n || ret=1
255grep "status: NOERROR" dig.out.ns3.ok.test$n > /dev/null || ret=1
256$DIG $DIGOPTS +noauth q.nsec3.example. @10.53.0.3 a > dig.out.ns3.test$n || ret=1
257$DIG $DIGOPTS +noauth q.nsec3.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1
258$PERL ../digcomp.pl dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
259grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
260grep "status: NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1
261n=`expr $n + 1`
262if [ $ret != 0 ]; then echo "I:failed"; fi
263status=`expr $status + $ret`
264
265echo "I:checking direct NSEC3 autosigning succeeded ($n)"
266ret=0
267$DIG $DIGOPTS +noall +answer autonsec3.example. nsec3param @10.53.0.3 > dig.out.ns3.ok.test$n || ret=1
268[ -s  dig.out.ns3.ok.test$n ] || ret=1
269grep "NSEC3PARAM" dig.out.ns3.ok.test$n > /dev/null || ret=1
270$DIG $DIGOPTS +noauth q.autonsec3.example. @10.53.0.3 a > dig.out.ns3.test$n || ret=1
271$DIG $DIGOPTS +noauth q.autonsec3.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1
272$PERL ../digcomp.pl dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
273grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
274grep "status: NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1
275n=`expr $n + 1`
276if [ $ret != 0 ]; then echo "I:failed"; fi
277status=`expr $status + $ret`
278
279echo "I:checking NSEC->NSEC3 conversion failed with NSEC-only key ($n)"
280ret=0
281grep "failed: REFUSED" nsupdate.out > /dev/null || ret=1
282n=`expr $n + 1`
283if [ $ret != 0 ]; then echo "I:failed"; fi
284status=`expr $status + $ret`
285
286echo "I:checking NSEC3->NSEC conversion succeeded ($n)"
287ret=0
288# this command should result in an empty file:
289$DIG $DIGOPTS +noall +answer nsec3-to-nsec.example. nsec3param @10.53.0.3 > dig.out.ns3.nx.test$n || ret=1
290grep "NSEC3PARAM" dig.out.ns3.nx.test$n > /dev/null && ret=1
291$DIG $DIGOPTS +noauth q.nsec3-to-nsec.example. @10.53.0.3 a > dig.out.ns3.test$n || ret=1
292$DIG $DIGOPTS +noauth q.nsec3-to-nsec.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1
293$PERL ../digcomp.pl dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
294grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
295grep "status: NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1
296n=`expr $n + 1`
297if [ $ret != 0 ]; then echo "I:failed"; fi
298status=`expr $status + $ret`
299
300echo "I:checking NSEC3->NSEC conversion with 'rndc signing -nsec3param none' ($n)"
301ret=0
302$RNDC -c ../common/rndc.conf -s 10.53.0.3 -p 9953 signing -nsec3param none autonsec3.example. > /dev/null 2>&1
303sleep 2
304# this command should result in an empty file:
305$DIG $DIGOPTS +noall +answer autonsec3.example. nsec3param @10.53.0.3 > dig.out.ns3.nx.test$n || ret=1
306grep "NSEC3PARAM" dig.out.ns3.nx.test$n > /dev/null && ret=1
307$DIG $DIGOPTS +noauth q.autonsec3.example. @10.53.0.3 a > dig.out.ns3.test$n || ret=1
308$DIG $DIGOPTS +noauth q.autonsec3.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1
309$PERL ../digcomp.pl dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
310grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
311grep "status: NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1
312n=`expr $n + 1`
313if [ $ret != 0 ]; then echo "I:failed"; fi
314status=`expr $status + $ret`
315
316echo "I:checking TTLs of imported DNSKEYs (no default) ($n)"
317ret=0
318$DIG $DIGOPTS +tcp +noall +answer dnskey ttl1.example. @10.53.0.3 > dig.out.ns3.test$n || ret=1
319[ -s dig.out.ns3.test$n ] || ret=1
320awk 'BEGIN {r=0} $2 != 300 {r=1; print "I:found TTL " $2} END {exit r}' dig.out.ns3.test$n || ret=1
321n=`expr $n + 1`
322if [ $ret != 0 ]; then echo "I:failed"; fi
323status=`expr $status + $ret`
324
325echo "I:checking TTLs of imported DNSKEYs (with default) ($n)"
326ret=0
327$DIG $DIGOPTS +tcp +noall +answer dnskey ttl2.example. @10.53.0.3 > dig.out.ns3.test$n || ret=1
328[ -s dig.out.ns3.test$n ] || ret=1
329awk 'BEGIN {r=0} $2 != 60 {r=1; print "I:found TTL " $2} END {exit r}' dig.out.ns3.test$n || ret=1
330n=`expr $n + 1`
331if [ $ret != 0 ]; then echo "I:failed"; fi
332status=`expr $status + $ret`
333
334echo "I:checking TTLs of imported DNSKEYs (mismatched) ($n)"
335ret=0
336$DIG $DIGOPTS +tcp +noall +answer dnskey ttl3.example. @10.53.0.3 > dig.out.ns3.test$n || ret=1
337[ -s dig.out.ns3.test$n ] || ret=1
338awk 'BEGIN {r=0} $2 != 30 {r=1; print "I:found TTL " $2} END {exit r}' dig.out.ns3.test$n || ret=1
339n=`expr $n + 1`
340if [ $ret != 0 ]; then echo "I:failed"; fi
341status=`expr $status + $ret`
342
343echo "I:checking TTLs of imported DNSKEYs (existing RRset) ($n)"
344ret=0
345$DIG $DIGOPTS +tcp +noall +answer dnskey ttl4.example. @10.53.0.3 > dig.out.ns3.test$n || ret=1
346[ -s dig.out.ns3.test$n ] || ret=1
347awk 'BEGIN {r=0} $2 != 30 {r=1; print "I:found TTL " $2} END {exit r}' dig.out.ns3.test$n || ret=1
348n=`expr $n + 1`
349if [ $ret != 0 ]; then echo "I:failed"; fi
350status=`expr $status + $ret`
351
352echo "I:checking positive validation NSEC ($n)"
353ret=0
354$DIG $DIGOPTS +noauth a.example. @10.53.0.2 a > dig.out.ns2.test$n || ret=1
355$DIG $DIGOPTS +noauth a.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1
356$PERL ../digcomp.pl dig.out.ns2.test$n dig.out.ns4.test$n || ret=1
357grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
358n=`expr $n + 1`
359if [ $ret != 0 ]; then echo "I:failed"; fi
360status=`expr $status + $ret`
361
362echo "I:checking positive validation NSEC3 ($n)"
363ret=0
364$DIG $DIGOPTS +noauth a.nsec3.example. \
365	@10.53.0.3 a > dig.out.ns3.test$n || ret=1
366$DIG $DIGOPTS +noauth a.nsec3.example. \
367	@10.53.0.4 a > dig.out.ns4.test$n || ret=1
368$PERL ../digcomp.pl dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
369grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
370n=`expr $n + 1`
371if [ $ret != 0 ]; then echo "I:failed"; fi
372status=`expr $status + $ret`
373
374echo "I:checking positive validation OPTOUT ($n)"
375ret=0
376$DIG $DIGOPTS +noauth a.optout.example. \
377	@10.53.0.3 a > dig.out.ns3.test$n || ret=1
378$DIG $DIGOPTS +noauth a.optout.example. \
379	@10.53.0.4 a > dig.out.ns4.test$n || ret=1
380$PERL ../digcomp.pl dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
381grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
382n=`expr $n + 1`
383if [ $ret != 0 ]; then echo "I:failed"; fi
384status=`expr $status + $ret`
385
386echo "I:checking negative validation NXDOMAIN NSEC ($n)"
387ret=0
388$DIG $DIGOPTS +noauth q.example. @10.53.0.2 a > dig.out.ns2.test$n || ret=1
389$DIG $DIGOPTS +noauth q.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1
390$PERL ../digcomp.pl dig.out.ns2.test$n dig.out.ns4.test$n || ret=1
391grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
392grep "status: NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1
393n=`expr $n + 1`
394if [ $ret != 0 ]; then echo "I:failed"; fi
395status=`expr $status + $ret`
396
397echo "I:checking negative validation NXDOMAIN NSEC3 ($n)"
398ret=0
399$DIG $DIGOPTS +noauth q.nsec3.example. \
400	@10.53.0.3 a > dig.out.ns3.test$n || ret=1
401$DIG $DIGOPTS +noauth q.nsec3.example. \
402	@10.53.0.4 a > dig.out.ns4.test$n || ret=1
403$PERL ../digcomp.pl dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
404grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
405grep "status: NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1
406n=`expr $n + 1`
407if [ $ret != 0 ]; then echo "I:failed"; fi
408status=`expr $status + $ret`
409
410echo "I:checking negative validation NXDOMAIN OPTOUT ($n)"
411ret=0
412$DIG $DIGOPTS +noauth q.optout.example. \
413	@10.53.0.3 a > dig.out.ns3.test$n || ret=1
414$DIG $DIGOPTS +noauth q.optout.example. \
415	@10.53.0.4 a > dig.out.ns4.test$n || ret=1
416$PERL ../digcomp.pl dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
417grep "status: NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1
418# Note - this is looking for failure, hence the &&
419grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1
420n=`expr $n + 1`
421if [ $ret != 0 ]; then echo "I:failed"; fi
422status=`expr $status + $ret`
423
424echo "I:checking negative validation NODATA NSEC ($n)"
425ret=0
426$DIG $DIGOPTS +noauth a.example. @10.53.0.2 txt > dig.out.ns2.test$n || ret=1
427$DIG $DIGOPTS +noauth a.example. @10.53.0.4 txt > dig.out.ns4.test$n || ret=1
428$PERL ../digcomp.pl dig.out.ns2.test$n dig.out.ns4.test$n || ret=1
429grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
430grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
431grep "ANSWER: 0" dig.out.ns4.test$n > /dev/null || ret=1
432n=`expr $n + 1`
433if [ $ret != 0 ]; then echo "I:failed"; fi
434status=`expr $status + $ret`
435
436echo "I:checking negative validation NODATA NSEC3 ($n)"
437ret=0
438$DIG $DIGOPTS +noauth a.nsec3.example. \
439	@10.53.0.3 txt > dig.out.ns3.test$n || ret=1
440$DIG $DIGOPTS +noauth a.nsec3.example. \
441	@10.53.0.4 txt > dig.out.ns4.test$n || ret=1
442$PERL ../digcomp.pl dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
443grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
444grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
445grep "ANSWER: 0" dig.out.ns4.test$n > /dev/null || ret=1
446n=`expr $n + 1`
447if [ $ret != 0 ]; then echo "I:failed"; fi
448status=`expr $status + $ret`
449
450echo "I:checking negative validation NODATA OPTOUT ($n)"
451ret=0
452$DIG $DIGOPTS +noauth a.optout.example. \
453	@10.53.0.3 txt > dig.out.ns3.test$n || ret=1
454$DIG $DIGOPTS +noauth a.optout.example. \
455	@10.53.0.4 txt > dig.out.ns4.test$n || ret=1
456$PERL ../digcomp.pl dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
457grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
458grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
459grep "ANSWER: 0" dig.out.ns4.test$n > /dev/null || ret=1
460n=`expr $n + 1`
461if [ $ret != 0 ]; then echo "I:failed"; fi
462status=`expr $status + $ret`
463
464# Check the insecure.example domain
465
466echo "I:checking 1-server insecurity proof NSEC ($n)"
467ret=0
468$DIG $DIGOPTS +noauth a.insecure.example. @10.53.0.3 a > dig.out.ns3.test$n || ret=1
469$DIG $DIGOPTS +noauth a.insecure.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1
470$PERL ../digcomp.pl dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
471grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
472# Note - this is looking for failure, hence the &&
473grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1
474n=`expr $n + 1`
475if [ $ret != 0 ]; then echo "I:failed"; fi
476status=`expr $status + $ret`
477
478echo "I:checking 1-server negative insecurity proof NSEC ($n)"
479ret=0
480$DIG $DIGOPTS q.insecure.example. a @10.53.0.3 \
481	> dig.out.ns3.test$n || ret=1
482$DIG $DIGOPTS q.insecure.example. a @10.53.0.4 \
483	> dig.out.ns4.test$n || ret=1
484$PERL ../digcomp.pl dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
485grep "status: NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1
486# Note - this is looking for failure, hence the &&
487grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1
488n=`expr $n + 1`
489if [ $ret != 0 ]; then echo "I:failed"; fi
490status=`expr $status + $ret`
491
492# Check the secure.example domain
493
494echo "I:checking multi-stage positive validation NSEC/NSEC ($n)"
495ret=0
496$DIG $DIGOPTS +noauth a.secure.example. \
497	@10.53.0.3 a > dig.out.ns3.test$n || ret=1
498$DIG $DIGOPTS +noauth a.secure.example. \
499	@10.53.0.4 a > dig.out.ns4.test$n || ret=1
500$PERL ../digcomp.pl dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
501grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
502grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
503n=`expr $n + 1`
504if [ $ret != 0 ]; then echo "I:failed"; fi
505status=`expr $status + $ret`
506
507echo "I:checking multi-stage positive validation NSEC/NSEC3 ($n)"
508ret=0
509$DIG $DIGOPTS +noauth a.nsec3.example. \
510	@10.53.0.3 a > dig.out.ns3.test$n || ret=1
511$DIG $DIGOPTS +noauth a.nsec3.example. \
512	@10.53.0.4 a > dig.out.ns4.test$n || ret=1
513$PERL ../digcomp.pl dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
514grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
515grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
516n=`expr $n + 1`
517if [ $ret != 0 ]; then echo "I:failed"; fi
518status=`expr $status + $ret`
519
520echo "I:checking multi-stage positive validation NSEC/OPTOUT ($n)"
521ret=0
522$DIG $DIGOPTS +noauth a.optout.example. \
523	@10.53.0.3 a > dig.out.ns3.test$n || ret=1
524$DIG $DIGOPTS +noauth a.optout.example. \
525	@10.53.0.4 a > dig.out.ns4.test$n || ret=1
526$PERL ../digcomp.pl dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
527grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
528grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
529n=`expr $n + 1`
530if [ $ret != 0 ]; then echo "I:failed"; fi
531status=`expr $status + $ret`
532
533echo "I:checking multi-stage positive validation NSEC3/NSEC ($n)"
534ret=0
535$DIG $DIGOPTS +noauth a.secure.nsec3.example. \
536	@10.53.0.3 a > dig.out.ns3.test$n || ret=1
537$DIG $DIGOPTS +noauth a.secure.nsec3.example. \
538	@10.53.0.4 a > dig.out.ns4.test$n || ret=1
539$PERL ../digcomp.pl dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
540grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
541grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
542n=`expr $n + 1`
543if [ $ret != 0 ]; then echo "I:failed"; fi
544status=`expr $status + $ret`
545
546echo "I:checking multi-stage positive validation NSEC3/NSEC3 ($n)"
547ret=0
548$DIG $DIGOPTS +noauth a.nsec3.nsec3.example. \
549	@10.53.0.3 a > dig.out.ns3.test$n || ret=1
550$DIG $DIGOPTS +noauth a.nsec3.nsec3.example. \
551	@10.53.0.4 a > dig.out.ns4.test$n || ret=1
552$PERL ../digcomp.pl dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
553grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
554grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
555n=`expr $n + 1`
556if [ $ret != 0 ]; then echo "I:failed"; fi
557status=`expr $status + $ret`
558
559echo "I:checking multi-stage positive validation NSEC3/OPTOUT ($n)"
560ret=0
561$DIG $DIGOPTS +noauth a.optout.nsec3.example. \
562	@10.53.0.3 a > dig.out.ns3.test$n || ret=1
563$DIG $DIGOPTS +noauth a.optout.nsec3.example. \
564	@10.53.0.4 a > dig.out.ns4.test$n || ret=1
565$PERL ../digcomp.pl dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
566grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
567grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
568n=`expr $n + 1`
569if [ $ret != 0 ]; then echo "I:failed"; fi
570status=`expr $status + $ret`
571
572echo "I:checking multi-stage positive validation OPTOUT/NSEC ($n)"
573ret=0
574$DIG $DIGOPTS +noauth a.secure.optout.example. \
575	@10.53.0.3 a > dig.out.ns3.test$n || ret=1
576$DIG $DIGOPTS +noauth a.secure.optout.example. \
577	@10.53.0.4 a > dig.out.ns4.test$n || ret=1
578$PERL ../digcomp.pl dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
579grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
580grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
581n=`expr $n + 1`
582if [ $ret != 0 ]; then echo "I:failed"; fi
583status=`expr $status + $ret`
584
585echo "I:checking multi-stage positive validation OPTOUT/NSEC3 ($n)"
586ret=0
587$DIG $DIGOPTS +noauth a.nsec3.optout.example. \
588	@10.53.0.3 a > dig.out.ns3.test$n || ret=1
589$DIG $DIGOPTS +noauth a.nsec3.optout.example. \
590	@10.53.0.4 a > dig.out.ns4.test$n || ret=1
591$PERL ../digcomp.pl dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
592grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
593grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
594n=`expr $n + 1`
595if [ $ret != 0 ]; then echo "I:failed"; fi
596status=`expr $status + $ret`
597
598echo "I:checking multi-stage positive validation OPTOUT/OPTOUT ($n)"
599ret=0
600$DIG $DIGOPTS +noauth a.optout.optout.example. \
601	@10.53.0.3 a > dig.out.ns3.test$n || ret=1
602$DIG $DIGOPTS +noauth a.optout.optout.example. \
603	@10.53.0.4 a > dig.out.ns4.test$n || ret=1
604$PERL ../digcomp.pl dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
605grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
606grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
607n=`expr $n + 1`
608if [ $ret != 0 ]; then echo "I:failed"; fi
609status=`expr $status + $ret`
610
611echo "I:checking empty NODATA OPTOUT ($n)"
612ret=0
613$DIG $DIGOPTS +noauth empty.optout.example. \
614	@10.53.0.3 a > dig.out.ns3.test$n || ret=1
615$DIG $DIGOPTS +noauth empty.optout.example. \
616	@10.53.0.4 a > dig.out.ns4.test$n || ret=1
617$PERL ../digcomp.pl dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
618grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
619#grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
620n=`expr $n + 1`
621if [ $ret != 0 ]; then echo "I:failed"; fi
622status=`expr $status + $ret`
623
624# Check the insecure.secure.example domain (insecurity proof)
625
626echo "I:checking 2-server insecurity proof ($n)"
627ret=0
628$DIG $DIGOPTS +noauth a.insecure.secure.example. @10.53.0.2 a \
629	> dig.out.ns2.test$n || ret=1
630$DIG $DIGOPTS +noauth a.insecure.secure.example. @10.53.0.4 a \
631	> dig.out.ns4.test$n || ret=1
632$PERL ../digcomp.pl dig.out.ns2.test$n dig.out.ns4.test$n || ret=1
633grep "status: NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
634# Note - this is looking for failure, hence the &&
635grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1
636n=`expr $n + 1`
637if [ $ret != 0 ]; then echo "I:failed"; fi
638status=`expr $status + $ret`
639
640# Check a negative response in insecure.secure.example
641
642echo "I:checking 2-server insecurity proof with a negative answer ($n)"
643ret=0
644$DIG $DIGOPTS q.insecure.secure.example. @10.53.0.2 a > dig.out.ns2.test$n \
645	|| ret=1
646$DIG $DIGOPTS q.insecure.secure.example. @10.53.0.4 a > dig.out.ns4.test$n \
647	|| ret=1
648$PERL ../digcomp.pl dig.out.ns2.test$n dig.out.ns4.test$n || ret=1
649grep "status: NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1
650# Note - this is looking for failure, hence the &&
651grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1
652n=`expr $n + 1`
653if [ $ret != 0 ]; then echo "I:failed"; fi
654status=`expr $status + $ret`
655
656echo "I:checking security root query ($n)"
657ret=0
658$DIG $DIGOPTS . @10.53.0.4 key > dig.out.ns4.test$n || ret=1
659grep "NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
660grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
661n=`expr $n + 1`
662if [ $ret != 0 ]; then echo "I:failed"; fi
663status=`expr $status + $ret`
664
665echo "I:checking positive validation RSASHA256 NSEC ($n)"
666ret=0
667$DIG $DIGOPTS +noauth a.rsasha256.example. @10.53.0.3 a > dig.out.ns3.test$n || ret=1
668$DIG $DIGOPTS +noauth a.rsasha256.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1
669$PERL ../digcomp.pl dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
670grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
671n=`expr $n + 1`
672if [ $ret != 0 ]; then echo "I:failed"; fi
673status=`expr $status + $ret`
674
675echo "I:checking positive validation RSASHA512 NSEC ($n)"
676ret=0
677$DIG $DIGOPTS +noauth a.rsasha512.example. @10.53.0.3 a > dig.out.ns3.test$n || ret=1
678$DIG $DIGOPTS +noauth a.rsasha512.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1
679$PERL ../digcomp.pl dig.out.ns3.test$n dig.out.ns4.test$n || ret=1
680grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1
681n=`expr $n + 1`
682if [ $ret != 0 ]; then echo "I:failed"; fi
683status=`expr $status + $ret`
684
685echo "I:checking that positive validation in a privately secure zone works ($n)"
686ret=0
687$DIG $DIGOPTS +noauth a.private.secure.example. a @10.53.0.2 \
688	> dig.out.ns2.test$n || ret=1
689$DIG $DIGOPTS +noauth a.private.secure.example. a @10.53.0.4 \
690	> dig.out.ns4.test$n || ret=1
691$PERL ../digcomp.pl dig.out.ns2.test$n dig.out.ns4.test$n || ret=1
692grep "NOERROR" dig.out.ns4.test$n > /dev/null || ret=1
693# Note - this is looking for failure, hence the &&
694grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1
695n=`expr $n + 1`
696if [ $ret != 0 ]; then echo "I:failed"; fi
697status=`expr $status + $ret`
698
699echo "I:checking that negative validation in a privately secure zone works ($n)"
700ret=0
701$DIG $DIGOPTS +noauth q.private.secure.example. a @10.53.0.2 \
702	> dig.out.ns2.test$n || ret=1
703$DIG $DIGOPTS +noauth q.private.secure.example. a @10.53.0.4 \
704	> dig.out.ns4.test$n || ret=1
705$PERL ../digcomp.pl dig.out.ns2.test$n dig.out.ns4.test$n || ret=1
706grep "NXDOMAIN" dig.out.ns4.test$n > /dev/null || ret=1
707# Note - this is looking for failure, hence the &&
708grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1
709n=`expr $n + 1`
710if [ $ret != 0 ]; then echo "I:failed"; fi
711status=`expr $status + $ret`
712
713echo "I:checking privately secure to nxdomain works ($n)"
714ret=0
715$DIG $DIGOPTS +noauth private2secure-nxdomain.private.secure.example. SOA @10.53.0.2 \
716	> dig.out.ns2.test$n || ret=1
717$DIG $DIGOPTS +noauth private2secure-nxdomain.private.secure.example. SOA @10.53.0.4 \
718	> dig.out.ns4.test$n || ret=1
719$PERL ../digcomp.pl dig.out.ns2.test$n dig.out.ns4.test$n || ret=1
720# Note - this is looking for failure, hence the &&
721grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1
722n=`expr $n + 1`
723if [ $ret != 0 ]; then echo "I:failed"; fi
724status=`expr $status + $ret`
725
726# Try validating with a revoked trusted key.
727# This should fail.
728
729echo "I:checking that validation returns insecure due to revoked trusted key ($n)"
730ret=0
731$DIG $DIGOPTS example. soa @10.53.0.5 > dig.out.ns5.test$n || ret=1
732grep "flags:.*; QUERY" dig.out.ns5.test$n > /dev/null || ret=1
733grep "flags:.* ad.*; QUERY" dig.out.ns5.test$n > /dev/null && ret=1
734n=`expr $n + 1`
735if [ $ret != 0 ]; then echo "I:failed"; fi
736status=`expr $status + $ret`
737
738echo "I:checking that revoked key is present ($n)"
739ret=0
740id=`cat rev.key`
741$DIG $DIGOPTS +multi dnskey . @10.53.0.1 > dig.out.ns1.test$n || ret=1
742grep '; key id = '"$id"'$' dig.out.ns1.test$n > /dev/null || ret=1
743n=`expr $n + 1`
744if [ $ret != 0 ]; then echo "I:failed"; fi
745status=`expr $status + $ret`
746
747echo "I:checking that revoked key self-signs ($n)"
748ret=0
749id=`cat rev.key`
750$DIG $DIGOPTS dnskey . @10.53.0.1 > dig.out.ns1.test$n || ret=1
751grep 'RRSIG.*'" $id "'\. ' dig.out.ns1.test$n > /dev/null || ret=1
752n=`expr $n + 1`
753if [ $ret != 0 ]; then echo "I:failed"; fi
754status=`expr $status + $ret`
755
756echo "I:checking for unpublished key ($n)"
757ret=0
758id=`sed 's/^K.+007+0*\([0-9]\)/\1/' < unpub.key`
759$DIG $DIGOPTS +multi dnskey . @10.53.0.1 > dig.out.ns1.test$n || ret=1
760grep '; key id = '"$id"'$' dig.out.ns1.test$n > /dev/null && ret=1
761n=`expr $n + 1`
762if [ $ret != 0 ]; then echo "I:failed"; fi
763status=`expr $status + $ret`
764
765echo "I:checking that standby key does not sign records ($n)"
766ret=0
767id=`sed 's/^K.+007+0*\([0-9]\)/\1/' < standby.key`
768$DIG $DIGOPTS dnskey . @10.53.0.1 > dig.out.ns1.test$n || ret=1
769grep 'RRSIG.*'" $id "'\. ' dig.out.ns1.test$n > /dev/null && ret=1
770n=`expr $n + 1`
771if [ $ret != 0 ]; then echo "I:failed"; fi
772status=`expr $status + $ret`
773
774echo "I:checking that deactivated key does not sign records  ($n)"
775ret=0
776id=`sed 's/^K.+007+0*\([0-9]\)/\1/' < inact.key`
777$DIG $DIGOPTS dnskey . @10.53.0.1 > dig.out.ns1.test$n || ret=1
778grep 'RRSIG.*'" $id "'\. ' dig.out.ns1.test$n > /dev/null && ret=1
779n=`expr $n + 1`
780if [ $ret != 0 ]; then echo "I:failed"; fi
781status=`expr $status + $ret`
782
783echo "I:checking insertion of public-only key ($n)"
784ret=0
785id=`sed 's/^K.+007+0*\([0-9]\)/\1/' < nopriv.key`
786file="ns1/`cat nopriv.key`.key"
787keydata=`grep DNSKEY $file`
788$NSUPDATE > /dev/null 2>&1 <<END	|| status=1
789server 10.53.0.1 5300
790zone .
791ttl 3600
792update add $keydata
793send
794END
795sleep 1
796$DIG $DIGOPTS dnskey . @10.53.0.1 > dig.out.ns1.test$n || ret=1
797grep 'RRSIG.*'" $id "'\. ' dig.out.ns1.test$n > /dev/null && ret=1
798n=`expr $n + 1`
799if [ $ret != 0 ]; then echo "I:failed"; fi
800status=`expr $status + $ret`
801
802echo "I:checking key deletion ($n)"
803ret=0
804id=`sed 's/^K.+007+0*\([0-9]\)/\1/' < del.key`
805$DIG $DIGOPTS +multi dnskey . @10.53.0.1 > dig.out.ns1.test$n || ret=1
806grep '; key id = '"$id"'$' dig.out.ns1.test$n > /dev/null && ret=1
807n=`expr $n + 1`
808if [ $ret != 0 ]; then echo "I:failed"; fi
809status=`expr $status + $ret`
810
811echo "I:checking secure-to-insecure transition, nsupdate ($n)"
812$NSUPDATE > /dev/null 2>&1 <<END	|| status=1
813server 10.53.0.3 5300
814zone secure-to-insecure.example
815update delete secure-to-insecure.example dnskey
816send
817END
818sleep 2
819$DIG $DIGOPTS axfr secure-to-insecure.example @10.53.0.3 > dig.out.ns3.test$n || ret=1
820egrep '(RRSIG|DNSKEY|NSEC)' dig.out.ns3.test$n > /dev/null && ret=1
821n=`expr $n + 1`
822if [ $ret != 0 ]; then echo "I:failed"; fi
823status=`expr $status + $ret`
824
825echo "I:checking secure-to-insecure transition, scheduled ($n)"
826ret=0
827file="ns3/`cat del1.key`.key"
828$SETTIME -I now -D now $file > /dev/null
829file="ns3/`cat del2.key`.key"
830$SETTIME -I now -D now $file > /dev/null
831$RNDC -c ../common/rndc.conf -s 10.53.0.3 -p 9953 sign secure-to-insecure2.example. 2>&1 | sed 's/^/I:ns3 /'
832sleep 2
833$DIG $DIGOPTS axfr secure-to-insecure2.example @10.53.0.3 > dig.out.ns3.test$n || ret=1
834egrep '(RRSIG|DNSKEY|NSEC3)' dig.out.ns3.test$n > /dev/null && ret=1
835n=`expr $n + 1`
836if [ $ret != 0 ]; then echo "I:failed"; fi
837status=`expr $status + $ret`
838
839echo "I:checking that serial number and RRSIGs are both updated (rt21045) ($n)"
840ret=0
841oldserial=`$DIG $DIGOPTS +short soa prepub.example @10.53.0.3 | awk '$0 !~ /SOA/ {print $3}'`
842oldinception=`$DIG $DIGOPTS +short soa prepub.example @10.53.0.3 | awk '/SOA/ {print $6}' | sort -u`
843
844$KEYGEN -3 -q -r $RANDFILE -K ns3 -P 0 -A +6d -I +38d -D +45d prepub.example > /dev/null
845
846$RNDC -c ../common/rndc.conf -s 10.53.0.3 -p 9953 sign prepub.example 2>&1 | sed 's/^/I:ns1 /'
847newserial=$oldserial
848try=0
849while [ $oldserial -eq $newserial -a $try -lt 42 ]
850do
851	newserial=`$DIG $DIGOPTS +short soa prepub.example @10.53.0.3 |
852		 awk '$0 !~ /SOA/ {print $3}'`
853	sleep 1
854	try=`expr $try + 1`
855done
856newinception=`$DIG $DIGOPTS +short soa prepub.example @10.53.0.3 | awk '/SOA/ {print $6}' | sort -u`
857#echo "$oldserial : $newserial"
858#echo "$oldinception : $newinception"
859
860[ "$oldserial" = "$newserial" ] && ret=1
861[ "$oldinception" = "$newinception" ] && ret=1
862if [ $ret != 0 ]; then echo "I:failed"; fi
863status=`expr $status + $ret`
864
865echo "I:preparing to test key change corner cases"
866echo "I:removing a private key file"
867file="ns1/`cat vanishing.key`.private"
868rm -f $file
869
870echo "I:preparing ZSK roll"
871starttime=`$PERL -e 'print time(), "\n";'`
872oldfile=`cat active.key`
873oldid=`sed 's/^K.+007+0*\([0-9]\)/\1/' < active.key`
874newfile=`cat standby.key`
875newid=`sed 's/^K.+007+0*\([0-9]\)/\1/' < standby.key`
876$SETTIME -K ns1 -I now+2s -D now+25 $oldfile > /dev/null
877$SETTIME -K ns1 -i 0 -S $oldfile $newfile > /dev/null
878
879# note previous zone serial number
880oldserial=`$DIG $DIGOPTS +short soa . @10.53.0.1 | awk '{print $3}'`
881
882$RNDC -c ../common/rndc.conf -s 10.53.0.1 -p 9953 loadkeys . 2>&1 | sed 's/^/I:ns1 /'
883sleep 4
884
885echo "I:revoking key to duplicated key ID"
886$SETTIME -R now -K ns2 Kbar.+005+30676.key > /dev/null
887
888$RNDC -c ../common/rndc.conf -s 10.53.0.2 -p 9953 loadkeys bar. 2>&1 | sed 's/^/I:ns2 /'
889
890echo "I:waiting for changes to take effect"
891sleep 5
892
893echo "I:checking former standby key is now active ($n)"
894ret=0
895$DIG $DIGOPTS dnskey . @10.53.0.1 > dig.out.ns1.test$n || ret=1
896grep 'RRSIG.*'" $newid "'\. ' dig.out.ns1.test$n > /dev/null || ret=1
897n=`expr $n + 1`
898if [ $ret != 0 ]; then echo "I:failed"; fi
899status=`expr $status + $ret`
900
901echo "I:checking former standby key has only signed incrementally ($n)"
902ret=0
903$DIG $DIGOPTS txt . @10.53.0.1 > dig.out.ns1.test$n || ret=1
904grep 'RRSIG.*'" $newid "'\. ' dig.out.ns1.test$n > /dev/null && ret=1
905grep 'RRSIG.*'" $oldid "'\. ' dig.out.ns1.test$n > /dev/null || ret=1
906n=`expr $n + 1`
907if [ $ret != 0 ]; then echo "I:failed"; fi
908status=`expr $status + $ret`
909
910echo "I:checking that signing records have been marked as complete ($n)"
911ret=0
912checkprivate . 10.53.0.1 || ret=1
913checkprivate bar 10.53.0.2 || ret=1
914checkprivate example 10.53.0.2 || ret=1
915checkprivate private.secure.example 10.53.0.3 || ret=1
916checkprivate nsec3.example 10.53.0.3 || ret=1
917checkprivate nsec3.nsec3.example 10.53.0.3 || ret=1
918checkprivate nsec3.optout.example 10.53.0.3 || ret=1
919checkprivate nsec3-to-nsec.example 10.53.0.3 || ret=1
920checkprivate nsec.example 10.53.0.3 || ret=1
921checkprivate oldsigs.example 10.53.0.3 || ret=1
922checkprivate optout.example 10.53.0.3 || ret=1
923checkprivate optout.nsec3.example 10.53.0.3 || ret=1
924checkprivate optout.optout.example 10.53.0.3 || ret=1
925checkprivate prepub.example 10.53.0.3 || ret=1
926checkprivate rsasha256.example 10.53.0.3 || ret=1
927checkprivate rsasha512.example 10.53.0.3 || ret=1
928checkprivate secure.example 10.53.0.3 || ret=1
929checkprivate secure.nsec3.example 10.53.0.3 || ret=1
930checkprivate secure.optout.example 10.53.0.3 || ret=1
931checkprivate secure-to-insecure2.example 10.53.0.3 || ret=1
932checkprivate secure-to-insecure.example 10.53.0.3 || ret=1
933checkprivate ttl1.example 10.53.0.3 || ret=1
934checkprivate ttl2.example 10.53.0.3 || ret=1
935checkprivate ttl3.example 10.53.0.3 || ret=1
936checkprivate ttl4.example 10.53.0.3 || ret=1
937n=`expr $n + 1`
938status=`expr $status + $ret`
939
940echo "I:forcing full sign"
941$RNDC -c ../common/rndc.conf -s 10.53.0.1 -p 9953 sign . 2>&1 | sed 's/^/I:ns1 /'
942
943echo "I:waiting for change to take effect"
944sleep 5
945
946echo "I:checking former standby key has now signed fully ($n)"
947ret=0
948$DIG $DIGOPTS txt . @10.53.0.1 > dig.out.ns1.test$n || ret=1
949grep 'RRSIG.*'" $newid "'\. ' dig.out.ns1.test$n > /dev/null || ret=1
950n=`expr $n + 1`
951if [ $ret != 0 ]; then echo "I:failed"; fi
952status=`expr $status + $ret`
953
954echo "I:checking SOA serial number has been incremented ($n)"
955ret=0
956newserial=`$DIG $DIGOPTS +short soa . @10.53.0.1 | awk '{print $3}'`
957[ "$newserial" != "$oldserial" ] || ret=1
958n=`expr $n + 1`
959if [ $ret != 0 ]; then echo "I:failed"; fi
960status=`expr $status + $ret`
961
962echo "I:checking delayed key publication/activation ($n)"
963ret=0
964zsk=`cat delayzsk.key`
965ksk=`cat delayksk.key`
966# publication and activation times should be unset
967$SETTIME -K ns3 -pA -pP $zsk | grep -v UNSET > /dev/null 2>&1 && ret=1
968$SETTIME -K ns3 -pA -pP $ksk | grep -v UNSET > /dev/null 2>&1 && ret=1
969$DIG $DIGOPTS +noall +answer dnskey delay.example. @10.53.0.3 > dig.out.ns3.test$n || ret=1
970# DNSKEY not expected:
971awk 'BEGIN {r=1} $4=="DNSKEY" {r=0} END {exit r}' dig.out.ns3.test$n && ret=1
972n=`expr $n + 1`
973if [ $ret != 0 ]; then echo "I:failed"; fi
974status=`expr $status + $ret`
975
976echo "I:checking scheduled key publication, not activation ($n)"
977ret=0
978$SETTIME -K ns3 -P now+3s -A none $zsk > /dev/null 2>&1
979$SETTIME -K ns3 -P now+3s -A none $ksk > /dev/null 2>&1
980$RNDC -c ../common/rndc.conf -s 10.53.0.3 -p 9953 loadkeys delay.example. 2>&1 | sed 's/^/I:ns2 /'
981
982echo "I:waiting for changes to take effect"
983sleep 5
984
985$DIG $DIGOPTS +noall +answer dnskey delay.example. @10.53.0.3 > dig.out.ns3.test$n || ret=1
986# DNSKEY expected:
987awk 'BEGIN {r=1} $4=="DNSKEY" {r=0} END {exit r}' dig.out.ns3.test$n || ret=1
988# RRSIG not expected:
989awk 'BEGIN {r=1} $4=="RRSIG" {r=0} END {exit r}' dig.out.ns3.test$n && ret=1
990n=`expr $n + 1`
991if [ $ret != 0 ]; then echo "I:failed"; fi
992status=`expr $status + $ret`
993
994echo "I:checking scheduled key activation ($n)"
995ret=0
996$SETTIME -K ns3 -A now+3s $zsk > /dev/null 2>&1
997$SETTIME -K ns3 -A now+3s $ksk > /dev/null 2>&1
998$RNDC -c ../common/rndc.conf -s 10.53.0.3 -p 9953 loadkeys delay.example. 2>&1 | sed 's/^/I:ns2 /'
999
1000echo "I:waiting for changes to take effect"
1001sleep 5
1002
1003$DIG $DIGOPTS +noall +answer dnskey delay.example. @10.53.0.3 > dig.out.ns3.1.test$n || ret=1
1004# DNSKEY expected:
1005awk 'BEGIN {r=1} $4=="DNSKEY" {r=0} END {exit r}' dig.out.ns3.1.test$n || ret=1
1006# RRSIG expected:
1007awk 'BEGIN {r=1} $4=="RRSIG" {r=0} END {exit r}' dig.out.ns3.1.test$n || ret=1
1008$DIG $DIGOPTS +noall +answer a a.delay.example. @10.53.0.3 > dig.out.ns3.2.test$n || ret=1
1009# A expected:
1010awk 'BEGIN {r=1} $4=="A" {r=0} END {exit r}' dig.out.ns3.2.test$n || ret=1
1011# RRSIG expected:
1012awk 'BEGIN {r=1} $4=="RRSIG" {r=0} END {exit r}' dig.out.ns3.2.test$n || ret=1
1013n=`expr $n + 1`
1014if [ $ret != 0 ]; then echo "I:failed"; fi
1015status=`expr $status + $ret`
1016
1017echo "I:checking former active key was removed ($n)"
1018#
1019# Work out how long we need to sleep. Allow 4 seconds for the records
1020# to be removed.
1021#
1022now=`$PERL -e 'print time(), "\n";'`
1023sleep=`expr $starttime + 29 - $now`
1024case $sleep in
1025-*|0);;
1026*) echo "I:waiting for timer to have activated"; sleep $sleep;;
1027esac
1028ret=0
1029$DIG $DIGOPTS +multi dnskey . @10.53.0.1 > dig.out.ns1.test$n || ret=1
1030grep '; key id = '"$oldid"'$' dig.out.ns1.test$n > /dev/null && ret=1
1031n=`expr $n + 1`
1032if [ $ret != 0 ]; then echo "I:failed"; fi
1033status=`expr $status + $ret`
1034
1035echo "I:checking private key file removal caused no immediate harm ($n)"
1036ret=0
1037id=`sed 's/^K.+007+0*\([0-9]\)/\1/' < vanishing.key`
1038$DIG $DIGOPTS dnskey . @10.53.0.1 > dig.out.ns1.test$n || ret=1
1039grep 'RRSIG.*'" $id "'\. ' dig.out.ns1.test$n > /dev/null || ret=1
1040n=`expr $n + 1`
1041if [ $ret != 0 ]; then echo "I:failed"; fi
1042status=`expr $status + $ret`
1043
1044echo "I:checking revoked key with duplicate key ID (failure expected) ($n)"
1045lret=0
1046id=30676
1047$DIG $DIGOPTS +multi dnskey bar @10.53.0.2 > dig.out.ns2.test$n || lret=1
1048grep '; key id = '"$id"'$' dig.out.ns2.test$n > /dev/null || lret=1
1049$DIG $DIGOPTS dnskey bar @10.53.0.4 > dig.out.ns4.test$n || lret=1
1050grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || lret=1
1051n=`expr $n + 1`
1052if [ $lret != 0 ]; then echo "I:not yet implemented"; fi
1053
1054echo "I:checking key event timers are always set ($n)"
1055# this is a regression test for a bug in which the next key event could
1056# be scheduled for the present moment, and then never fire.  check for
1057# visible evidence of this error in the logs:
1058awk '/next key event/ {if ($1 == $8 && $2 == $9) exit 1}' */named.run || ret=1
1059n=`expr $n + 1`
1060if [ $ret != 0 ]; then echo "I:failed"; fi
1061status=`expr $status + $ret`
1062
1063# this confirms that key events are never scheduled more than
1064# 'dnssec-loadkeys-interval' minutes in the future, and that the 
1065# event scheduled is within 10 seconds of expected interval.
1066check_interval () {
1067        awk '/next key event/ {print $2 ":" $9}' $1/named.run |
1068	sed 's/\.//g' |
1069            awk -F: '
1070                     {
1071                       x = ($6+ $5*60000 + $4*3600000) - ($3+ $2*60000 + $1*3600000);
1072		       # abs(x) < 1000 ms treat as 'now'
1073		       if (x < 1000 && x > -1000)
1074                         x = 0;
1075		       # convert to seconds
1076		       x = x/1000;
1077		       # handle end of day roll over
1078		       if (x < 0)
1079			 x = x + 24*3600;
1080		       # handle log timestamp being a few milliseconds later
1081                       if (x != int(x))
1082                         x = int(x + 1);
1083                       if (int(x) > int(interval))
1084                         exit (1);
1085                     }
1086                     END { if (int(x) > int(interval) || int(x) < int(interval-10)) exit(1) }' interval=$2
1087        return $?
1088}
1089
1090echo "I:checking automatic key reloading interval ($n)"
1091ret=0
1092check_interval ns1 3600 || ret=1
1093check_interval ns2 1800 || ret=1
1094check_interval ns3 600 || ret=1
1095n=`expr $n + 1`
1096if [ $ret != 0 ]; then echo "I:failed"; fi
1097status=`expr $status + $ret`
1098
1099echo "I:checking for key reloading loops ($n)"
1100ret=0
1101# every key event should schedule a successor, so these should be equal
1102rekey_calls=`grep "reconfiguring zone keys" ns*/named.run | wc -l`
1103rekey_events=`grep "next key event" ns*/named.run | wc -l`
1104[ "$rekey_calls" = "$rekey_events" ] || ret=1
1105n=`expr $n + 1`
1106if [ $ret != 0 ]; then echo "I:failed"; fi
1107status=`expr $status + $ret`
1108
1109echo "I:forcing full sign with unreadable keys ($n)"
1110ret=0
1111chmod 0 ns1/K.+*+*.key ns1/K.+*+*.private || ret=1
1112$RNDC -c ../common/rndc.conf -s 10.53.0.1 -p 9953 sign . 2>&1 | sed 's/^/I:ns1 /'
1113$DIG $DIGOPTS . @10.53.0.1 dnskey > dig.out.ns1.test$n || ret=1
1114grep "status: NOERROR" dig.out.ns1.test$n > /dev/null || ret=1
1115n=`expr $n + 1`
1116if [ $ret != 0 ]; then echo "I:failed"; fi
1117status=`expr $status + $ret`
1118
1119echo "I:test turning on auto-dnssec during reconfig ($n)"
1120ret=0
1121# first create a zone that doesn't have auto-dnssec
1122rm -f ns3/*.nzf
1123$RNDC -c ../common/rndc.conf -s 10.53.0.3 -p 9953 addzone reconf.example '{ type master; file "reconf.example.db"; };' 2>&1 | sed 's/^/I:ns3 /'
1124rekey_calls=`grep "zone reconf.example.*next key event" ns3/named.run | wc -l`
1125[ "$rekey_calls" -eq 0 ] || ret=1
1126# ...then we add auto-dnssec and reconfigure
1127nzf=`ls ns3/*.nzf`
1128echo 'zone reconf.example { type master; file "reconf.example.db"; allow-update { any; }; auto-dnssec maintain; };' > $nzf
1129$RNDC -c ../common/rndc.conf -s 10.53.0.3 -p 9953 reconfig 2>&1 | sed 's/^/I:ns3 /'
1130for i in 0 1 2 3 4 5 6 7 8 9; do
1131    lret=0
1132    rekey_calls=`grep "zone reconf.example.*next key event" ns3/named.run | wc -l`
1133    [ "$rekey_calls" -gt 0 ] || lret=1
1134    if [ "$lret" = 0 ]; then break; fi
1135    sleep 1
1136done
1137n=`expr $n + 1`
1138if [ "$lret" != 0 ]; then ret=$lret; fi
1139if [ $ret != 0 ]; then echo "I:failed"; fi
1140status=`expr $status + $ret`
1141
1142echo "I:exit status: $status"
1143exit $status
1144