From befd429434f15b57b427f8f7ab5f3ea53c5608c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20K=C4=99pie=C5=84?= Date: Thu, 28 Jun 2018 13:38:39 +0200 Subject: [PATCH] Verify mirror zone files loaded from disk Verify data read from mirror zone files before it is used in order to prevent loading corrupt mirror zones from disk. --- bin/tests/system/mirror/ns2/sign.sh | 2 +- bin/tests/system/mirror/ns3/named.conf.in | 8 ++++++++ bin/tests/system/mirror/setup.sh | 1 + bin/tests/system/mirror/tests.sh | 24 +++++++++++++++++++++++ lib/dns/zone.c | 5 +++++ 5 files changed, 39 insertions(+), 1 deletion(-) diff --git a/bin/tests/system/mirror/ns2/sign.sh b/bin/tests/system/mirror/ns2/sign.sh index b9d9c266e7..77fbb3a894 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 ixfr untrusted; do +for variant in axfr ixfr load 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 7006c4af8e..775a7fe6b9 100644 --- a/bin/tests/system/mirror/ns3/named.conf.in +++ b/bin/tests/system/mirror/ns3/named.conf.in @@ -48,6 +48,14 @@ zone "verify-ixfr" { file "verify-ixfr.db.mirror"; }; +zone "verify-load" { + type slave; + masters { 10.53.0.2; }; + mirror yes; + file "verify-load.db.mirror"; + masterfile-format text; +}; + 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 07c90da9dc..9fb8063d44 100644 --- a/bin/tests/system/mirror/setup.sh +++ b/bin/tests/system/mirror/setup.sh @@ -22,4 +22,5 @@ copy_setports ns3/named.conf.in ns3/named.conf 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-load.db.bad.signed > ns3/verify-load.db.mirror 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 87d60e88f6..e5748328d4 100644 --- a/bin/tests/system/mirror/tests.sh +++ b/bin/tests/system/mirror/tests.sh @@ -145,5 +145,29 @@ 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 loading an incorrectly signed mirror zone from disk fails ($n)" +ret=0 +nextpartreset ns3/named.run +wait_for_load verify-load ${UPDATED_SERIAL_BAD} ns3/named.run +$DIG $DIGOPTS @10.53.0.3 +norec verify-load 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-load 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 loading a correctly signed mirror zone from disk succeeds ($n)" +ret=0 +$PERL $SYSTEMTESTTOP/stop.pl --use-rndc --port ${CONTROLPORT} . ns3 +cat ns2/verify-load.db.good.signed > ns3/verify-load.db.mirror +nextpart ns3/named.run > /dev/null +$PERL $SYSTEMTESTTOP/start.pl --noclean --restart --port ${PORT} . ns3 +wait_for_load verify-load ${UPDATED_SERIAL_GOOD} ns3/named.run +$DIG $DIGOPTS @10.53.0.3 +norec verify-load 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/zone.c b/lib/dns/zone.c index 667a83466e..0acf2e0305 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -4609,6 +4609,11 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime, goto cleanup; } + result = dns_zone_verifydb(zone, db, NULL); + if (result != ISC_R_SUCCESS) { + goto cleanup; + } + if (zone->db != NULL) { unsigned int oldsoacount;