]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
3092. [bug] Signatures for records at the zone apex could go
authorEvan Hunt <each@isc.org>
Fri, 25 Mar 2011 23:53:02 +0000 (23:53 +0000)
committerEvan Hunt <each@isc.org>
Fri, 25 Mar 2011 23:53:02 +0000 (23:53 +0000)
stale due to an incorrect timer setting. [RT #23769]

3091. [bug] Fixed a bug in which zone keys that were published
and then subsequently activated could fail to trigger
automatic signing. [RT #22991]

CHANGES
bin/named/update.c
bin/tests/system/autosign/clean.sh
bin/tests/system/autosign/ns3/keygen.sh
bin/tests/system/autosign/ns3/named.conf
bin/tests/system/autosign/tests.sh
lib/dns/diff.c
lib/dns/zone.c

diff --git a/CHANGES b/CHANGES
index 6e7aaa78bf5049ae81cb67e03fb876a708198575..304b238c6a5cc079287f13238d05b4e341fb7692 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,10 @@
+3092.  [bug]           Signatures for records at the zone apex could go
+                       stale due to an incorrect timer setting. [RT #23769]
+
+3091.  [bug]           Fixed a bug in which zone keys that were published
+                       and then subsequently activated could fail to trigger
+                       automatic signing. [RT #22991]
+
 3090.  [func]          Make --with-gssapi default [RT #23738]
 
 3089.  [func]          dnssec-dsfromkey now supports reading keys from
index 3d6ac73b386fd3da0ad2b4ad95dc65ced3b0c821..89eb4fc99291a463e94cbf288ab445aa595a1e68 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: update.c,v 1.191 2011/03/11 12:51:40 marka Exp $ */
+/* $Id: update.c,v 1.192 2011/03/25 23:53:02 each Exp $ */
 
 #include <config.h>
 
@@ -2395,7 +2395,7 @@ update_signatures(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
                                                                   name, diff));
                        }
                        CHECK(add_exposed_sigs(client, zone, db, newver, name,
-                                              cut, diff, zone_keys, nkeys,
+                                              cut, &sig_diff, zone_keys, nkeys,
                                               inception, expire, check_ksk,
                                               keyset_kskonly));
                }
@@ -2554,7 +2554,7 @@ update_signatures(ns_client_t *client, dns_zone_t *zone, dns_db_t *db,
                                                   privatetype, &nsec_diff));
                } else {
                        CHECK(add_exposed_sigs(client, zone, db, newver, name,
-                                              cut, diff, zone_keys, nkeys,
+                                              cut, &sig_diff, zone_keys, nkeys,
                                               inception, expire, check_ksk,
                                               keyset_kskonly));
                        CHECK(dns_nsec3_addnsec3sx(db, newver, name, nsecttl,
index 91c094fd21f4909f6be2bc7e41e60cd6a6848198..2e9cf7b15a2335818d46d8489d45cfb57104766e 100644 (file)
 # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 # PERFORMANCE OF THIS SOFTWARE.
 
-# $Id: clean.sh,v 1.9 2011/03/17 23:47:30 tbox Exp $
+# $Id: clean.sh,v 1.10 2011/03/25 23:53:02 each Exp $
 
 rm -f */K* */dsset-* */*.signed */trusted.conf */tmp* */*.jnl */*.bk
 rm -f active.key inact.key del.key unpub.key standby.key rev.key
 rm -f nopriv.key vanishing.key del1.key del2.key
+rm -f delayksk.key delayzsk.key
 rm -f nsupdate.out
 rm -f */core
 rm -f */example.bk
index f28df31dbdf7fd7c0e71564eedb358536ee64bde..33b23c121266540be141f4b605167a1ae5d89059 100644 (file)
@@ -14,7 +14,7 @@
 # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 # PERFORMANCE OF THIS SOFTWARE.
 
-# $Id: keygen.sh,v 1.10 2011/03/17 23:47:30 tbox Exp $
+# $Id: keygen.sh,v 1.11 2011/03/25 23:53:02 each Exp $
 
 SYSTEMTESTTOP=../..
 . $SYSTEMTESTTOP/conf.sh
@@ -238,3 +238,13 @@ zonefile="${zone}.db"
 $KEYGEN -3 -q -r $RANDFILE -L 30 -fk $zone > /dev/null
 cat ${infile} K${zone}.+*.key > $zonefile
 $KEYGEN -3 -q -r $RANDFILE -L 180 $zone > /dev/null
+
+#
+# A zone with a DNSKEY RRset that is published before it's activated
+#
+zone=delay.example
+zonefile="${zone}.db"
+ksk=`$KEYGEN -G -q -3 -r $RANDFILE -fk $zone`
+echo $ksk > ../delayksk.key
+zsk=`$KEYGEN -G -q -3 -r $RANDFILE $zone`
+echo $zsk > ../delayzsk.key
index 0036b4932c53ae45f808319f68ae4c9b2f679565..4d6598ee3de96d6fa93de33ce597678e55d3b906 100644 (file)
@@ -14,7 +14,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: named.conf,v 1.9 2011/03/17 23:47:30 tbox Exp $ */
+/* $Id: named.conf,v 1.10 2011/03/25 23:53:02 each Exp $ */
 
 // NS3
 
@@ -213,4 +213,10 @@ zone "ttl4.example" {
        auto-dnssec maintain;
 };
 
+zone "delay.example" {
+       type master;
+       file "delay.example.db";
+       allow-update { any; };
+       auto-dnssec maintain;
+};
 include "trusted.conf";
index 00abad89be86c278607cc3d25756c4d87cbeefc5..a03bdac832f7b6cc2433a345c2a85f37ce080377 100644 (file)
@@ -14,7 +14,7 @@
 # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 # PERFORMANCE OF THIS SOFTWARE.
 
-# $Id: tests.sh,v 1.19 2011/03/21 16:53:44 each Exp $
+# $Id: tests.sh,v 1.20 2011/03/25 23:53:02 each Exp $
 
 SYSTEMTESTTOP=..
 . $SYSTEMTESTTOP/conf.sh
@@ -797,10 +797,62 @@ n=`expr $n + 1`
 if [ $ret != 0 ]; then echo "I:failed"; fi
 status=`expr $status + $ret`
 
-echo "I:waiting for former active key to be removed"
-sleep 10
+echo "I:checking delayed key publication/activation ($n)"
+ret=0
+zsk=`cat delayzsk.key`
+ksk=`cat delayksk.key`
+# publication and activation times should be unset
+$SETTIME -K ns3 -pA -pP $zsk | grep -v UNSET > /dev/null 2>&1 && ret=1
+$SETTIME -K ns3 -pA -pP $ksk | grep -v UNSET > /dev/null 2>&1 && ret=1
+$DIG $DIGOPTS +noall +answer dnskey delay.example. @10.53.0.3 > dig.out.ns3.test$n || ret=1
+# DNSKEY not expected:
+awk 'BEGIN {r=1} $4=="DNSKEY" {r=0} END {exit r}' dig.out.ns3.test$n && ret=1
+n=`expr $n + 1`
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+echo "I:checking scheduled key publication, not activation ($n)"
+ret=0
+$SETTIME -K ns3 -P now+3s -A none $zsk > /dev/null 2>&1
+$SETTIME -K ns3 -P now+3s -A none $ksk > /dev/null 2>&1
+$RNDC -c ../common/rndc.conf -s 10.53.0.3 -p 9953 loadkeys delay.example. 2>&1 | sed 's/^/I:ns2 /'
+
+echo "I:waiting for changes to take effect"
+sleep 5
+
+$DIG $DIGOPTS +noall +answer dnskey delay.example. @10.53.0.3 > dig.out.ns3.test$n || ret=1
+# DNSKEY expected:
+awk 'BEGIN {r=1} $4=="DNSKEY" {r=0} END {exit r}' dig.out.ns3.test$n || ret=1
+# RRSIG not expected:
+awk 'BEGIN {r=1} $4=="RRSIG" {r=0} END {exit r}' dig.out.ns3.test$n && ret=1
+n=`expr $n + 1`
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
+echo "I:checking scheduled key activation ($n)"
+ret=0
+$SETTIME -K ns3 -A now+3s $zsk > /dev/null 2>&1
+$SETTIME -K ns3 -A now+3s $ksk > /dev/null 2>&1
+$RNDC -c ../common/rndc.conf -s 10.53.0.3 -p 9953 loadkeys delay.example. 2>&1 | sed 's/^/I:ns2 /'
+
+echo "I:waiting for changes to take effect"
+sleep 5
+
+$DIG $DIGOPTS +noall +answer dnskey delay.example. @10.53.0.3 > dig.out.ns3.1.test$n || ret=1
+# DNSKEY expected:
+awk 'BEGIN {r=1} $4=="DNSKEY" {r=0} END {exit r}' dig.out.ns3.1.test$n || ret=1
+# RRSIG expected:
+awk 'BEGIN {r=1} $4=="RRSIG" {r=0} END {exit r}' dig.out.ns3.1.test$n || ret=1
+$DIG $DIGOPTS +noall +answer a a.delay.example. @10.53.0.3 > dig.out.ns3.2.test$n || ret=1
+# A expected:
+awk 'BEGIN {r=1} $4=="A" {r=0} END {exit r}' dig.out.ns3.2.test$n || ret=1
+# RRSIG expected:
+awk 'BEGIN {r=1} $4=="RRSIG" {r=0} END {exit r}' dig.out.ns3.2.test$n || ret=1
+n=`expr $n + 1`
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
 
-echo "I:checking key was removed ($n)"
+echo "I:checking former active key was removed ($n)"
 ret=0
 $DIG $DIGOPTS +multi dnskey . @10.53.0.1 > dig.out.ns1.test$n || ret=1
 grep '; key id =.*'"$oldid"'$' dig.out.ns1.test$n > /dev/null && ret=1
index 840fa4932de423d7777d6d42ae1cc6f191498423..db665d95ccf007c809a087deaf95434473d84503 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: diff.c,v 1.25 2011/03/12 04:59:47 tbox Exp $ */
+/* $Id: diff.c,v 1.26 2011/03/25 23:53:02 each Exp $ */
 
 /*! \file */
 
@@ -373,6 +373,15 @@ diff_apply(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *ver,
                                                           diff->resign);
                                        dns_db_setsigningtime(db, modified,
                                                              resign);
+                                       if (diff->resign == 0 &&
+                                           (op == DNS_DIFFOP_ADDRESIGN ||
+                                            op == DNS_DIFFOP_DELRESIGN))
+                                               isc_log_write(
+                                                       DIFF_COMMON_LOGARGS,
+                                                       ISC_LOG_WARNING,
+                                                       "resign requested "
+                                                       "with 0 resign "
+                                                       "interval");
                                }
                        } else if (result == DNS_R_UNCHANGED) {
                                /*
index 2b114c2984940ca0fa3c8465db4315edced33866..8d8b2f429bf921a2e0dfd0a0ffb2c4dcb8455a06 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: zone.c,v 1.600 2011/03/21 18:38:40 each Exp $ */
+/* $Id: zone.c,v 1.601 2011/03/25 23:53:02 each Exp $ */
 
 /*! \file */
 
@@ -4511,6 +4511,7 @@ static void
 set_key_expiry_warning(dns_zone_t *zone, isc_stdtime_t when, isc_stdtime_t now)
 {
        unsigned int delta;
+       char timebuf[80];
 
        zone->key_expiry = when;
        if (when <= now) {
@@ -4518,19 +4519,22 @@ set_key_expiry_warning(dns_zone_t *zone, isc_stdtime_t when, isc_stdtime_t now)
                             "DNSKEY RRSIG(s) have expired");
                isc_time_settoepoch(&zone->keywarntime);
        } else if (when < now + 7 * 24 * 3600) {
+               isc_time_t t;
+               isc_time_set(&t, when, 0);
+               isc_time_formattimestamp(&t, timebuf, 80);
                dns_zone_log(zone, ISC_LOG_WARNING,
-                            "DNSKEY RRSIG(s) will expire at %u",
-                            when);     /* XXXMPA convert to date. */
+                            "DNSKEY RRSIG(s) will expire within 7 days: %s",
+                            timebuf);
                delta = when - now;
                delta--;                /* loop prevention */
                delta /= 24 * 3600;     /* to whole days */
                delta *= 24 * 3600;     /* to seconds */
                isc_time_set(&zone->keywarntime, when - delta, 0);
        }  else {
-               dns_zone_log(zone, ISC_LOG_NOTICE, /* XXMPA ISC_LOG_DEBUG(1) */
-                            "setting keywarntime to %u - 7 days",
-                            when);     /* XXXMPA convert to date. */
                isc_time_set(&zone->keywarntime, when - 7 * 24 * 3600, 0);
+               isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
+               dns_zone_log(zone, ISC_LOG_NOTICE,
+                            "setting keywarntime to %s", timebuf);
        }
 }
 
@@ -7255,6 +7259,7 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) {
        INSIST(result == ISC_R_SUCCESS);
 
        dns_diff_init(mctx, &diff);
+       diff.resign = zone->sigresigninginterval;
 
        CHECK(dns_db_newversion(kfetch->db, &ver));
 
@@ -13932,6 +13937,7 @@ zone_rekey(dns_zone_t *zone) {
        mctx = zone->mctx;
        dns_diff_init(mctx, &diff);
        dns_diff_init(mctx, &sig_diff);
+       sig_diff.resign = zone->sigresigninginterval;
 
        CHECK(dns_zone_getdb(zone, &db));
        CHECK(dns_db_newversion(db, &ver));
@@ -14028,14 +14034,15 @@ zone_rekey(dns_zone_t *zone) {
 
                /*
                 * Has a new key become active?  If so, is it for
-                * a new algorithm?
+                * a new algorithm?  In that event, we need to sign the
+                * zone fully.  If there's a new key, but it's for an
+                * already-existing algorithm, then the zone signing
+                * can be handled incrementally.
                 */
-               for (tuple = ISC_LIST_HEAD(sig_diff.tuples);
-                    tuple != NULL;
-                    tuple = ISC_LIST_NEXT(tuple, link)) {
-                       dns_rdata_dnskey_t dnskey;
-
-                       if (tuple->rdata.type != dns_rdatatype_dnskey)
+               for (key = ISC_LIST_HEAD(dnskeys);
+                    key != NULL;
+                    key = ISC_LIST_NEXT(key, link)) {
+                       if (!key->first_sign)
                                continue;
 
                        newkey = ISC_TRUE;
@@ -14044,25 +14051,19 @@ zone_rekey(dns_zone_t *zone) {
                                break;
                        }
 
-                       result = dns_rdata_tostruct(&tuple->rdata,
-                                                   &dnskey, NULL);
-                       RUNTIME_CHECK(result == ISC_R_SUCCESS);
-                       if (!signed_with_alg(&keysigs,
-                                            dnskey.algorithm)) {
+                       if (signed_with_alg(&keysigs, dst_key_alg(key->key))) {
+                               /*
+                                * This isn't a new algorithm; clear
+                                * first_sign so we won't sign the
+                                * whole zone with this key later
+                                */
+                               key->first_sign = ISC_FALSE;
+                       } else {
                                newalg = ISC_TRUE;
                                break;
                        }
                }
 
-               /*
-                * If we found a new algorithm, we need to sign the
-                * zone fully.  If there's a new key, but it's for an
-                * already-existing algorithm, then the zone signing
-                * can be handled incrementally.
-                */
-               if (newkey && !newalg)
-                       set_resigntime(zone);
-
                /* Remove any signatures from removed keys.  */
                if (!ISC_LIST_EMPTY(rmkeys)) {
                        for (key = ISC_LIST_HEAD(rmkeys);
@@ -14106,30 +14107,19 @@ zone_rekey(dns_zone_t *zone) {
                        /*
                         * We haven't been told to sign fully, but a new
                         * algorithm was added to the DNSKEY.  We sign
-                        * the full zone, but only with the newly-added
+                        * the full zone, but only with newly active
                         * keys.
                         */
-                       for (tuple = ISC_LIST_HEAD(sig_diff.tuples);
-                            tuple != NULL;
-                            tuple = ISC_LIST_NEXT(tuple, link)) {
-                               dns_rdata_dnskey_t dnskey;
-                               dns_secalg_t algorithm;
-                               isc_region_t r;
-                               isc_uint16_t keyid;
-
-                               if (tuple->rdata.type != dns_rdatatype_dnskey ||
-                                   tuple->op == DNS_DIFFOP_DEL)
+                       for (key = ISC_LIST_HEAD(dnskeys);
+                            key != NULL;
+                            key = ISC_LIST_NEXT(key, link)) {
+                               if (!key->first_sign)
                                        continue;
 
-                               result = dns_rdata_tostruct(&tuple->rdata,
-                                                           &dnskey, NULL);
-                               RUNTIME_CHECK(result == ISC_R_SUCCESS);
-                               dns_rdata_toregion(&tuple->rdata, &r);
-                               algorithm = dnskey.algorithm;
-                               keyid = dst_region_computeid(&r, algorithm);
-
-                               result = zone_signwithkey(zone, algorithm,
-                                                         keyid, ISC_FALSE);
+                               result = zone_signwithkey(zone,
+                                                         dst_key_alg(key->key),
+                                                         dst_key_id(key->key),
+                                                         ISC_FALSE);
                                if (result != ISC_R_SUCCESS) {
                                        dns_zone_log(zone, ISC_LOG_ERROR,
                                             "zone_signwithkey failed: %s",
@@ -14174,6 +14164,11 @@ zone_rekey(dns_zone_t *zone) {
                                             dns_result_totext(result));
                        }
                }
+
+               /*
+                * Schedule the next resigning event
+                */
+               set_resigntime(zone);
                UNLOCK_ZONE(zone);
        }