Blob Blame History Raw
commit 0f835f7eff5bbd45461b9b43276267ff3c953ece
Author: Tomas Korbar <tkorbar@redhat.com>
Date:   Fri Nov 13 10:23:42 2020 +0100

    Fix inline resigning

diff --git a/bin/tests/system/conf.sh.in b/bin/tests/system/conf.sh.in
index 564c084..5cd0b05 100644
--- a/bin/tests/system/conf.sh.in
+++ b/bin/tests/system/conf.sh.in
@@ -69,6 +69,8 @@ LWTEST=$TOP/bin/tests/system/lwresd/lwtest
 MAKEJOURNAL=$TOP/bin/tests/makejournal
 PIPEQUERIES=$TOP/bin/tests/system/pipelined/pipequeries
 SAMPLEUPDATE=$TOP/lib/samples/sample-update
+DEFAULT_ALGORITHM=ECDSAP256SHA256
+DEFAULT_BITS=256
 
 # we don't want a KRB5_CONFIG setting breaking the tests
 KRB5_CONFIG=/dev/null
@@ -364,3 +366,5 @@ export SAMPLEUPDATE
 export SIGNER
 export SUBDIRS
 export TESTSOCK6
+export DEFAULT_ALGORITHM
+export DEFAULT_BITS
diff --git a/bin/tests/system/inline/ns8/example.com.db.in b/bin/tests/system/inline/ns8/example.com.db.in
new file mode 100644
index 0000000..eb39aa7
--- /dev/null
+++ b/bin/tests/system/inline/ns8/example.com.db.in
@@ -0,0 +1,19 @@
+; Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+;
+; This Source Code Form is subject to the terms of the Mozilla Public
+; License, v. 2.0. If a copy of the MPL was not distributed with this
+; file, You can obtain one at http://mozilla.org/MPL/2.0/.
+;
+; See the COPYRIGHT file distributed with this work for additional
+; information regarding copyright ownership.
+
+$TTL 300	; 5 minutes
+@			IN SOA	ns8 . (
+				2000042407 ; serial
+				20         ; refresh (20 seconds)
+				20         ; retry (20 seconds)
+				1814400    ; expire (3 weeks)
+				3600       ; minimum (1 hour)
+				)
+			NS	ns8
+ns8			A	10.53.0.8
diff --git a/bin/tests/system/inline/ns8/named.conf.in b/bin/tests/system/inline/ns8/named.conf.in
new file mode 100644
index 0000000..ea4876b
--- /dev/null
+++ b/bin/tests/system/inline/ns8/named.conf.in
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+// NS8
+
+include "../../common/rndc.key";
+
+controls {
+	inet 10.53.0.8 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
+};
+
+options {
+	query-source address 10.53.0.8;
+	notify-source 10.53.0.8;
+	transfer-source 10.53.0.8;
+	port @PORT@;
+	pid-file "named.pid";
+	session-keyfile "session.key";
+	listen-on { 10.53.0.8; };
+	listen-on-v6 { none; };
+	recursion no;
+	notify yes;
+	try-tcp-refresh no;
+	notify-delay 0;
+	allow-new-zones yes;
+};
+
+zone "example01.com" {
+	type master;
+	inline-signing yes;
+	auto-dnssec maintain;
+	file "example01.com.db";
+};
+
+zone "example02.com" {
+	type master;
+	inline-signing yes;
+	auto-dnssec maintain;
+	file "example02.com.db";
+};
+
+zone "example03.com" {
+	type master;
+	inline-signing yes;
+	auto-dnssec maintain;
+	file "example03.com.db";
+};
+
+zone "example04.com" {
+	type master;
+	inline-signing yes;
+	auto-dnssec maintain;
+	file "example04.com.db";
+};
+
+zone "example05.com" {
+	type master;
+	inline-signing yes;
+	auto-dnssec maintain;
+	file "example05.com.db";
+};
+
+zone "example06.com" {
+	type master;
+	inline-signing yes;
+	auto-dnssec maintain;
+	file "example06.com.db";
+};
+
+zone "example07.com" {
+	type master;
+	inline-signing yes;
+	auto-dnssec maintain;
+	file "example07.com.db";
+};
+
+zone "example08.com" {
+	type master;
+	inline-signing yes;
+	auto-dnssec maintain;
+	file "example08.com.db";
+};
+
+zone "example09.com" {
+	type master;
+	inline-signing yes;
+	auto-dnssec maintain;
+	file "example09.com.db";
+};
+
+zone "example10.com" {
+	type master;
+	inline-signing yes;
+	auto-dnssec maintain;
+	file "example10.com.db";
+};
+
+zone "example11.com" {
+	type master;
+	inline-signing yes;
+	auto-dnssec maintain;
+	file "example11.com.db";
+};
+
+zone "example12.com" {
+	type master;
+	inline-signing yes;
+	auto-dnssec maintain;
+	file "example12.com.db";
+};
+
+zone "example13.com" {
+	type master;
+	inline-signing yes;
+	auto-dnssec maintain;
+	file "example13.com.db";
+};
+
+zone "example14.com" {
+	type master;
+	inline-signing yes;
+	auto-dnssec maintain;
+	file "example14.com.db";
+};
+
+zone "example15.com" {
+	type master;
+	inline-signing yes;
+	auto-dnssec maintain;
+	file "example15.com.db";
+};
+
+zone "example16.com" {
+	type master;
+	inline-signing yes;
+	auto-dnssec maintain;
+	file "example16.com.db";
+};
diff --git a/bin/tests/system/inline/ns8/sign.sh b/bin/tests/system/inline/ns8/sign.sh
new file mode 100644
index 0000000..5d36cb9
--- /dev/null
+++ b/bin/tests/system/inline/ns8/sign.sh
@@ -0,0 +1,26 @@
+#!/bin/sh -e
+#
+# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+# See the COPYRIGHT file distributed with this work for additional
+# information regarding copyright ownership.
+
+SYSTEMTESTTOP=../..
+. $SYSTEMTESTTOP/conf.sh
+
+for zone in example01.com example02.com example03.com example04.com \
+	    example05.com example06.com example07.com example08.com \
+	    example09.com example10.com example11.com example12.com \
+	    example13.com example14.com example15.com example16.com
+do
+  rm -f K${zone}.+*+*.key
+  rm -f K${zone}.+*+*.private
+  keyname=`$KEYGEN -q -a $DEFAULT_ALGORITHM -b $DEFAULT_BITS -n zone $zone`
+  keyname=`$KEYGEN -q -a $DEFAULT_ALGORITHM -b $DEFAULT_BITS -n zone -f KSK $zone`
+  cp example.com.db.in ${zone}.db
+  $SIGNER -S -T 3600 -O raw -o ${zone} ${zone}.db > /dev/null 2>&1
+done
diff --git a/bin/tests/system/inline/setup.sh b/bin/tests/system/inline/setup.sh
index 4dd4dd0..13dd6c7 100644
--- a/bin/tests/system/inline/setup.sh
+++ b/bin/tests/system/inline/setup.sh
@@ -49,7 +49,9 @@ copy_setports ns4/named.conf.in ns4/named.conf
 copy_setports ns5/named.conf.pre ns5/named.conf
 copy_setports ns6/named.conf.in ns6/named.conf
 copy_setports ns7/named.conf.in ns7/named.conf
+copy_setports ns8/named.conf.in ns8/named.conf
 
 (cd ns3; $SHELL -e sign.sh)
 (cd ns1; $SHELL -e sign.sh)
 (cd ns7; $SHELL -e sign.sh)
+(cd ns8; $SHELL -e sign.sh)
diff --git a/bin/tests/system/inline/tests.sh b/bin/tests/system/inline/tests.sh
index b517138..22fc1af 100755
--- a/bin/tests/system/inline/tests.sh
+++ b/bin/tests/system/inline/tests.sh
@@ -1342,5 +1342,24 @@ grep "type: slave" rndc.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 reload of touched inline zones ($n)"
+echo_ic "pre-reload 'next key event'"
+nextpart ns8/named.run > nextpart.pre$n.out
+count=`grep "zone example[0-9][0-9].com/IN (signed): next key event:" nextpart.pre$n.out | wc -l`
+echo_ic "found: $count/16"
+[ $count -eq 16 ] || ret=1
+echo_ic "touch and reload"
+touch ns8/example??.com.db
+$RNDCCMD 10.53.0.8 reload 2>&1 | sed 's/^/ns3 /' | cat_i
+sleep 5
+echo_ic "post-reload 'next key event'"
+nextpart ns8/named.run > nextpart.post$n.out
+count=`grep "zone example[0-9][0-9].com/IN (signed): next key event:" nextpart.post$n.out | wc -l`
+echo_ic "found: $count/16"
+[ $count -eq 16 ] || 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 96c98d5..42a1811 100644
--- a/lib/dns/zone.c
+++ b/lib/dns/zone.c
@@ -3611,6 +3611,8 @@ set_resigntime(dns_zone_t *zone) {
 	isc_uint32_t nanosecs;
 	dns_db_t *db = NULL;
 
+	INSIST(LOCKED_ZONE(zone));
+
 	/* We only re-sign zones that can be dynamically updated */
 	if (zone->update_disabled)
 		return;
@@ -4958,6 +4960,14 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
 	    DNS_ZONE_FLAG(zone->secure, DNS_ZONEFLG_LOADED))
 	{
 		DNS_ZONE_CLRFLAG(zone->secure, DNS_ZONEFLG_LOADPENDING);
+		/*
+		 * Re-start zone maintenance if it had been stalled
+		 * due to DNS_ZONEFLG_LOADPENDING being set when
+		 * zone_maintenance was called.
+		 */
+		if (zone->secure->task != NULL) {
+			zone_settimer(zone->secure, &now);
+		}
 	}
 
 	return (result);
@@ -6672,14 +6682,15 @@ zone_resigninc(dns_zone_t *zone) {
 	if (version != NULL) {
 		dns_db_closeversion(db, &version, ISC_FALSE);
 		dns_db_detach(&db);
-	} else if (db != NULL)
+	} else if (db != NULL) {
 		dns_db_detach(&db);
+	}
+
+	LOCK_ZONE(zone);
 	if (result == ISC_R_SUCCESS) {
 		set_resigntime(zone);
-		LOCK_ZONE(zone);
 		zone_needdump(zone, DNS_DUMP_DELAY);
 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
-		UNLOCK_ZONE(zone);
 	} else {
 		/*
 		 * Something failed.  Retry in 5 minutes.
@@ -6688,6 +6699,7 @@ zone_resigninc(dns_zone_t *zone) {
 		isc_interval_set(&ival, 300, 0);
 		isc_time_nowplusinterval(&zone->resigntime, &ival);
 	}
+	UNLOCK_ZONE(zone);
 
 	INSIST(version == NULL);
 }
@@ -8177,7 +8189,9 @@ zone_nsec3chain(dns_zone_t *zone) {
 		nsec3chain = ISC_LIST_HEAD(cleanup);
 	}
 
+	LOCK_ZONE(zone);
 	set_resigntime(zone);
+	UNLOCK_ZONE(zone);
 
  failure:
 	if (result != ISC_R_SUCCESS)
@@ -8841,14 +8855,14 @@ zone_sign(dns_zone_t *zone) {
 		signing = ISC_LIST_HEAD(cleanup);
 	}
 
+	LOCK_ZONE(zone);
 	set_resigntime(zone);
 
 	if (commit) {
-		LOCK_ZONE(zone);
 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
 		zone_needdump(zone, DNS_DUMP_DELAY);
-		UNLOCK_ZONE(zone);
 	}
+	UNLOCK_ZONE(zone);
 
  failure:
 	/*
@@ -8885,6 +8899,7 @@ zone_sign(dns_zone_t *zone) {
 	} else if (db != NULL)
 		dns_db_detach(&db);
 
+	LOCK_ZONE(zone);
 	if (ISC_LIST_HEAD(zone->signing) != NULL) {
 		isc_interval_t interval;
 		if (zone->update_disabled || result != ISC_R_SUCCESS)
@@ -8892,8 +8907,10 @@ zone_sign(dns_zone_t *zone) {
 		else
 			isc_interval_set(&interval, 0, 10000000); /* 10 ms */
 		isc_time_nowplusinterval(&zone->signingtime, &interval);
-	} else
+ 	} else {
 		isc_time_settoepoch(&zone->signingtime);
+	}
+	UNLOCK_ZONE(zone);
 
 	INSIST(version == NULL);
 }
@@ -9983,7 +10000,7 @@ zone_maintenance(dns_zone_t *zone) {
 	const char me[] = "zone_maintenance";
 	isc_time_t now;
 	isc_result_t result;
-	isc_boolean_t dumping;
+	isc_boolean_t dumping, viewok;
 
 	REQUIRE(DNS_ZONE_VALID(zone));
 	ENTER;
@@ -10001,8 +10018,12 @@ zone_maintenance(dns_zone_t *zone) {
 	 * adb or resolver will be NULL, and we had better not try
 	 * to do further maintenance on it.
 	 */
-	if (zone->view == NULL || zone->view->adb == NULL)
+	LOCK_ZONE(zone);
+	viewok = (zone->view != NULL && zone->view->adb != NULL);
+	UNLOCK_ZONE(zone);
+	if (!viewok) {
 		return;
+	}
 
 	TIME_NOW(&now);
 
@@ -10195,8 +10216,14 @@ dns_zone_markdirty(dns_zone_t *zone) {
 		}
 
 		/* XXXMPA make separate call back */
-		if (result == ISC_R_SUCCESS)
+		if (result == ISC_R_SUCCESS) {
 			set_resigntime(zone);
+			if (zone->task != NULL) {
+				isc_time_t now;
+				TIME_NOW(&now);
+				zone_settimer(zone, &now);
+			}
+		}
 	}
 	if (secure != NULL)
 		UNLOCK_ZONE(secure);
@@ -14418,6 +14445,11 @@ receive_secure_serial(isc_task_t *task, isc_event_t *event) {
 	zone->sourceserialset = ISC_TRUE;
 	zone_needdump(zone, DNS_DUMP_DELAY);
 
+	/*
+	 * Set resign time to make sure it is set to the earliest
+	 * signature expiration.
+	 */
+	set_resigntime(zone);
 	TIME_NOW(&timenow);
 	zone_settimer(zone, &timenow);
 	UNLOCK_ZONE(zone);
@@ -14436,9 +14468,15 @@ receive_secure_serial(isc_task_t *task, isc_event_t *event) {
 
 	if (zone->rss_raw != NULL)
 		dns_zone_detach(&zone->rss_raw);
-	if (result != ISC_R_SUCCESS)
+	if (result != ISC_R_SUCCESS) {
+		LOCK_ZONE(zone);
+		set_resigntime(zone);
+		TIME_NOW(&timenow);
+		zone_settimer(zone, &timenow);
+		UNLOCK_ZONE(zone);
 		dns_zone_log(zone, ISC_LOG_ERROR, "receive_secure_serial: %s",
 			     dns_result_totext(result));
+	}
 	if (tuple != NULL)
 		dns_difftuple_free(&tuple);
 	if (soatuple != NULL)
@@ -18096,10 +18134,11 @@ zone_rekey(dns_zone_t *zone) {
 
 	dns_db_closeversion(db, &ver, ISC_TRUE);
 
+	LOCK_ZONE(zone);
+
 	if (commit) {
 		dns_difftuple_t *tuple;
 
-		LOCK_ZONE(zone);
 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
 
 		zone_needdump(zone, DNS_DUMP_DELAY);
@@ -18217,7 +18256,6 @@ zone_rekey(dns_zone_t *zone) {
 		 * Schedule the next resigning event
 		 */
 		set_resigntime(zone);
-		UNLOCK_ZONE(zone);
 	}
 
 	isc_time_settoepoch(&zone->refreshkeytime);
@@ -18231,11 +18269,9 @@ zone_rekey(dns_zone_t *zone) {
 		isc_time_t timethen;
 		isc_stdtime_t then;
 
-		LOCK_ZONE(zone);
 		DNS_ZONE_TIME_ADD(&timenow, zone->refreshkeyinterval,
 				  &timethen);
 		zone->refreshkeytime = timethen;
-		UNLOCK_ZONE(zone);
 
 		for (key = ISC_LIST_HEAD(dnskeys);
 		     key != NULL;
@@ -18246,12 +18282,10 @@ zone_rekey(dns_zone_t *zone) {
 				continue;
 
 			DNS_ZONE_TIME_ADD(&timenow, then - now, &timethen);
-			LOCK_ZONE(zone);
 			if (isc_time_compare(&timethen,
 					     &zone->refreshkeytime) < 0) {
 				zone->refreshkeytime = timethen;
 			}
-			UNLOCK_ZONE(zone);
 		}
 
 		zone_settimer(zone, &timenow);
@@ -18259,6 +18293,7 @@ zone_rekey(dns_zone_t *zone) {
 		isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
 		dns_zone_log(zone, ISC_LOG_INFO, "next key event: %s", timebuf);
 	}
+	UNLOCK_ZONE(zone);
 
  done:
 	dns_diff_clear(&diff);
@@ -18293,8 +18328,10 @@ zone_rekey(dns_zone_t *zone) {
 	 * Something went wrong; try again in ten minutes or
 	 * after a key refresh interval, whichever is shorter.
 	 */
+	LOCK_ZONE(zone);
 	isc_interval_set(&ival, ISC_MIN(zone->refreshkeyinterval, 600), 0);
 	isc_time_nowplusinterval(&zone->refreshkeytime, &ival);
+	UNLOCK_ZONE(zone);
 	goto done;
 }