diff --git a/bin/tests/system/mirror/clean.sh b/bin/tests/system/mirror/clean.sh index e856da1521..d8edbd403e 100644 --- a/bin/tests/system/mirror/clean.sh +++ b/bin/tests/system/mirror/clean.sh @@ -9,6 +9,7 @@ rm -f */*.conf rm -f */*.db +rm -f */*.jnl rm -f */*.mirror rm -f */*.prev rm -f */*.signed diff --git a/bin/tests/system/mirror/ns2/named.conf.in b/bin/tests/system/mirror/ns2/named.conf.in index 04803c27ac..01257e0853 100644 --- a/bin/tests/system/mirror/ns2/named.conf.in +++ b/bin/tests/system/mirror/ns2/named.conf.in @@ -34,6 +34,12 @@ zone "verify-axfr" { file "verify-axfr.db.signed"; }; +zone "verify-ixfr" { + type master; + file "verify-ixfr.db.signed"; + ixfr-from-differences yes; +}; + zone "verify-unsigned" { type master; file "verify.db.in"; diff --git a/bin/tests/system/mirror/ns2/sign.sh b/bin/tests/system/mirror/ns2/sign.sh index df40ab7165..b9d9c266e7 100644 --- a/bin/tests/system/mirror/ns2/sign.sh +++ b/bin/tests/system/mirror/ns2/sign.sh @@ -18,7 +18,7 @@ ORIGINAL_SERIAL=`awk '$2 == "SOA" {print $5}' verify.db.in` UPDATED_SERIAL_BAD=`expr ${ORIGINAL_SERIAL} + 1` UPDATED_SERIAL_GOOD=`expr ${ORIGINAL_SERIAL} + 2` -for variant in axfr untrusted; do +for variant in axfr ixfr untrusted; do zone=verify-$variant infile=verify.db.in zonefile=verify-$variant.db diff --git a/bin/tests/system/mirror/ns3/named.conf.in b/bin/tests/system/mirror/ns3/named.conf.in index 5452695f02..7006c4af8e 100644 --- a/bin/tests/system/mirror/ns3/named.conf.in +++ b/bin/tests/system/mirror/ns3/named.conf.in @@ -41,6 +41,13 @@ zone "verify-axfr" { file "verify-axfr.db.mirror"; }; +zone "verify-ixfr" { + type slave; + masters { 10.53.0.2; }; + mirror yes; + file "verify-ixfr.db.mirror"; +}; + zone "verify-unsigned" { type slave; masters { 10.53.0.2; }; diff --git a/bin/tests/system/mirror/setup.sh b/bin/tests/system/mirror/setup.sh index 9204787cb6..07c90da9dc 100644 --- a/bin/tests/system/mirror/setup.sh +++ b/bin/tests/system/mirror/setup.sh @@ -21,4 +21,5 @@ copy_setports ns3/named.conf.in ns3/named.conf ( cd ns2 && $SHELL -e sign.sh ) cat ns2/verify-axfr.db.bad.signed > ns2/verify-axfr.db.signed +cat ns2/verify-ixfr.db.original.signed > ns2/verify-ixfr.db.signed cat ns2/verify-untrusted.db.original.signed > ns2/verify-untrusted.db.signed diff --git a/bin/tests/system/mirror/tests.sh b/bin/tests/system/mirror/tests.sh index a6e0417a96..87d60e88f6 100644 --- a/bin/tests/system/mirror/tests.sh +++ b/bin/tests/system/mirror/tests.sh @@ -101,5 +101,49 @@ grep "${UPDATED_SERIAL_GOOD}.*; serial" dig.out.ns3.test$n > /dev/null || ret=1 if [ $ret != 0 ]; then echo_i "failed"; fi status=`expr $status + $ret` +n=`expr $n + 1` +echo_i "checking that an IXFR of an incorrectly signed mirror zone is rejected ($n)" +nextpartreset ns3/named.run +ret=0 +wait_for_transfer verify-ixfr +nextpart ns3/named.run > /dev/null +# Wait 1 second so that the zone file timestamp changes and the subsequent +# invocation of "rndc reload" triggers a zone reload. +sleep 1 +cat ns2/verify-ixfr.db.bad.signed > ns2/verify-ixfr.db.signed +reload_zone verify-ixfr ${UPDATED_SERIAL_BAD} +# Trigger IXFR. +$RNDCCMD 10.53.0.3 refresh verify-ixfr > /dev/null 2>&1 +wait_for_transfer verify-ixfr +# Ensure the transfer was incremental as expected. +if [ `nextpartpeek ns3/named.run | grep "verify-ixfr.*got incremental response" | wc -l` -eq 0 ]; then + echo_i "failed: did not get an incremental response" + ret=1 +fi +# Ensure the new, bad version of the zone was not accepted. +$DIG $DIGOPTS @10.53.0.3 +norec verify-ixfr SOA > dig.out.ns3.test$n 2>&1 || ret=1 +grep "${UPDATED_SERIAL_BAD}.*; serial" dig.out.ns3.test$n > /dev/null && ret=1 +nextpart ns3/named.run | grep "No correct RSASHA256 signature for verify-ixfr SOA" > /dev/null || ret=1 +if [ $ret != 0 ]; then echo_i "failed"; fi +status=`expr $status + $ret` + +n=`expr $n + 1` +echo_i "checking that an IXFR of an updated, correctly signed mirror zone is accepted after AXFR failover ($n)" +ret=0 +nextpart ns3/named.run > /dev/null +# Wait 1 second so that the zone file timestamp changes and the subsequent +# invocation of "rndc reload" triggers a zone reload. +sleep 1 +cat ns2/verify-ixfr.db.good.signed > ns2/verify-ixfr.db.signed +reload_zone verify-ixfr ${UPDATED_SERIAL_GOOD} +# Trigger IXFR. +$RNDCCMD 10.53.0.3 refresh verify-ixfr > /dev/null 2>&1 +wait_for_transfer verify-ixfr +# Ensure the new, good version of the zone was accepted. +$DIG $DIGOPTS @10.53.0.3 +norec verify-ixfr SOA > dig.out.ns3.test$n 2>&1 || ret=1 +grep "${UPDATED_SERIAL_GOOD}.*; serial" dig.out.ns3.test$n > /dev/null || ret=1 +if [ $ret != 0 ]; then echo_i "failed"; fi +status=`expr $status + $ret` + echo_i "exit status: $status" [ $status -eq 0 ] || exit 1 diff --git a/lib/dns/xfrin.c b/lib/dns/xfrin.c index 6fad0b8403..d67652dd0b 100644 --- a/lib/dns/xfrin.c +++ b/lib/dns/xfrin.c @@ -443,6 +443,7 @@ ixfr_commit(dns_xfrin_ctx_t *xfr) { CHECK(ixfr_apply(xfr)); if (xfr->ver != NULL) { + CHECK(dns_zone_verifydb(xfr->zone, xfr->db, xfr->ver)); /* XXX enter ready-to-commit state here */ if (xfr->ixfr.journal != NULL) CHECK(dns_journal_commit(xfr->ixfr.journal));