]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
[v9_9] 5011 fixes
authorEvan Hunt <each@isc.org>
Tue, 10 Feb 2015 21:12:55 +0000 (13:12 -0800)
committerEvan Hunt <each@isc.org>
Tue, 10 Feb 2015 21:12:55 +0000 (13:12 -0800)
4056. [bug] Fixed several small bugs in automatic trust anchor
management, including a memory leak and a possible
loss of key state information. [RT #38458]

17 files changed:
CHANGES
bin/named/main.c
bin/tests/system/dnssec/clean.sh
bin/tests/system/dnssec/ns3/sign.sh
bin/tests/system/dnssec/ns5/named1.conf [moved from bin/tests/system/dnssec/ns5/named.conf with 89% similarity]
bin/tests/system/dnssec/ns5/named2.conf [new file with mode: 0644]
bin/tests/system/dnssec/ns5/sign.sh [new file with mode: 0644]
bin/tests/system/dnssec/setup.sh
bin/tests/system/dnssec/tests.sh
doc/arm/notes.xml
lib/dns/rdata/generic/keydata_65533.c
lib/dns/zone.c
lib/isc/httpd.c
lib/isc/tests/time_test.c
lib/isc/unix/include/isc/time.h
lib/isc/unix/time.c
lib/isc/win32/include/isc/time.h

diff --git a/CHANGES b/CHANGES
index e7e62df715f82a568582e9388ec6e07587c6c58f..ef3d5bc733555079329f63ced21f0f09303b0ffd 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,7 @@
+4056.  [bug]           Fixed several small bugs in automatic trust anchor
+                       management, including a memory leak and a possible 
+                       loss of key state information. [RT #38458]
+
 4057.  [bug]           'dnssec-dsfromkey -T 0' failed to add ttl field.
                        [RT #38565]
 
index b6c92c9d7ffd6819dbe2e4aa49a9242e4e64b85f..6e340cc13c496af80d767d26b5b9bb9d95a3740a 100644 (file)
 #define BACKTRACE_MAXFRAME 128
 #endif
 
+extern unsigned int dns_zone_mkey_hour;
+extern unsigned int dns_zone_mkey_day;
+extern unsigned int dns_zone_mkey_month;
+
 static isc_boolean_t   want_stats = ISC_FALSE;
 static char            program_name[ISC_DIR_NAMEMAX] = "named";
 static char            absolute_conffile[ISC_DIR_PATHMAX];
@@ -536,7 +540,38 @@ parse_command_line(int argc, char *argv[]) {
                                ns_g_nosyslog = ISC_TRUE;
                        else if (!strcmp(isc_commandline_argument, "nonearest"))
                                ns_g_nonearest = ISC_TRUE;
-                       else if (!strcmp(isc_commandline_argument, "notcp"))
+                       else if (!strncmp(isc_commandline_argument,
+                                         "mkeytimers=", 11))
+                       {
+                               p = strtok(isc_commandline_argument + 11, "/");
+                               if (p == NULL)
+                                       ns_main_earlyfatal("bad mkeytimer");
+                               dns_zone_mkey_hour = atoi(p);
+                               if (dns_zone_mkey_hour == 0)
+                                       ns_main_earlyfatal("bad mkeytimer");
+
+                               p = strtok(NULL, "/");
+                               if (p == NULL) {
+                                       dns_zone_mkey_day =
+                                               (24 * dns_zone_mkey_hour);
+                                       dns_zone_mkey_month =
+                                               (30 * dns_zone_mkey_day);
+                                       break;
+                               }
+                               dns_zone_mkey_day = atoi(p);
+                               if (dns_zone_mkey_day < dns_zone_mkey_hour)
+                                       ns_main_earlyfatal("bad mkeytimer");
+
+                               p = strtok(NULL, "/");
+                               if (p == NULL) {
+                                       dns_zone_mkey_month =
+                                               (30 * dns_zone_mkey_day);
+                                       break;
+                               }
+                               dns_zone_mkey_month = atoi(p);
+                               if (dns_zone_mkey_month < dns_zone_mkey_day)
+                                       ns_main_earlyfatal("bad mkeytimer");
+                       } else if (!strcmp(isc_commandline_argument, "notcp"))
                                ns_g_notcp = ISC_TRUE;
                        else
                                fprintf(stderr, "unknown -T flag '%s\n",
index 713dc78f8fb28bc44e9c2a2286a0eefa56b265b0..feeef5536dfb04d8dd87352ad4ff8476fede541c 100644 (file)
@@ -16,7 +16,8 @@
 # PERFORMANCE OF THIS SOFTWARE.
 
 rm -f */K* */keyset-* */dsset-* */dlvset-* */signedkey-* */*.signed
-rm -f */trusted.conf */managed.conf */tmp* */*.jnl */*.bk
+rm -f */trusted.conf */managed.conf */revoked.conf
+rm -f */tmp* */*.jnl */*.bk */*.jbk
 rm -f ns1/root.db ns2/example.db ns3/secure.example.db
 rm -f ns3/unsecure.example.db ns3/bogus.example.db ns3/keyless.example.db
 rm -f ns3/dynamic.example.db ns3/dynamic.example.db.signed.jnl
@@ -50,7 +51,7 @@ rm -f signer/*.db
 rm -f signer/signer.out.*
 rm -f ns2/algroll.db
 rm -f ns3/kskonly.example.db
-rm -f ns4/named.conf
+rm -f ns4/named.conf ns5/named.conf
 rm -f ns4/managed-keys.bind*
 rm -f ns3/auto-nsec.example.db ns3/auto-nsec3.example.db
 rm -f ns3/secure.below-cname.example.db
@@ -79,3 +80,4 @@ rm -f ns3/dnskey-nsec3-unknown.example.db
 rm -f ns3/dnskey-nsec3-unknown.example.db.tmp
 rm -f ns3/dnskey-unknown.example.db
 rm -f ns3/dnskey-unknown.example.db.tmp
+rm -f named.secroots.test*
index 9d8108cc1a9f608ce2828673c8a944d0f7f002d7..614b3bb2fd119e7b5601fbbc0d4ba6805321bd83 100644 (file)
@@ -15,8 +15,6 @@
 # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 # PERFORMANCE OF THIS SOFTWARE.
 
-# $Id: sign.sh,v 1.43 2011/11/04 05:36:28 each Exp $
-
 SYSTEMTESTTOP=../..
 . $SYSTEMTESTTOP/conf.sh
 
@@ -505,5 +503,5 @@ zonefile=future.example.db
 kskname=`$KEYGEN -q -r $RANDFILE -f KSK $zone`
 zskname=`$KEYGEN -q -r $RANDFILE $zone`
 cat $infile $kskname.key $zskname.key >$zonefile
-$SIGNER -P -s +3600 -r $RANDFILE -o $zone $zonefile > /dev/null 2>&1
+$SIGNER -P -s +3600 -r $RANDFILE -o $zone $zonefile > /dev/null 2>&1
 cp -f $kskname.key trusted-future.key
similarity index 89%
rename from bin/tests/system/dnssec/ns5/named.conf
rename to bin/tests/system/dnssec/ns5/named1.conf
index 64892ca10fbe7b76bfdc5dac74662a3b74918aad..1a13a9f776435c25044ab33dcf0c5b9c3dd4313b 100644 (file)
@@ -15,8 +15,6 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: named.conf,v 1.25 2007/06/18 23:47:28 tbox Exp $ */
-
 // NS5
 
 controls { /* empty */ };
@@ -35,6 +33,16 @@ options {
        dnssec-validation yes;
 };
 
+key rndc_key {
+       secret "1234abcd8765";
+       algorithm hmac-sha256;
+};
+
+controls {
+       inet 10.53.0.5 port 9953 allow { any; } keys { rndc_key; };
+};
+
+
 zone "." {
        type hint;
        file "../../common/root.hint";
diff --git a/bin/tests/system/dnssec/ns5/named2.conf b/bin/tests/system/dnssec/ns5/named2.conf
new file mode 100644 (file)
index 0000000..5b60285
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2004, 2006, 2007  Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000, 2001  Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+// NS5
+
+controls { /* empty */ };
+
+key rndc_key {
+       secret "1234abcd8765";
+       algorithm hmac-sha256;
+};
+
+controls {
+       inet 10.53.0.5 port 9953 allow { any; } keys { rndc_key; };
+};
+
+options {
+       query-source address 10.53.0.5;
+       notify-source 10.53.0.5;
+       transfer-source 10.53.0.5;
+       port 5300;
+       pid-file "named.pid";
+       listen-on { 10.53.0.5; 127.0.0.1; };
+       listen-on-v6 { none; };
+       recursion yes;
+};
+
+view root {
+        match-destinations { 127.0.0.1; };
+
+        zone "." {
+                type master;
+                file "root.db.signed";
+        };
+};
+
+view other {
+include "revoked.conf";
+
+        zone "." {
+                type static-stub;
+                server-addresses { 127.0.0.1; };
+        };
+};
diff --git a/bin/tests/system/dnssec/ns5/sign.sh b/bin/tests/system/dnssec/ns5/sign.sh
new file mode 100644 (file)
index 0000000..16fe760
--- /dev/null
@@ -0,0 +1,42 @@
+#!/bin/sh -e
+#
+# Copyright (C) 2015  Internet Systems Consortium, Inc. ("ISC")
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+# AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+# PERFORMANCE OF THIS SOFTWARE.
+
+SYSTEMTESTTOP=../..
+. $SYSTEMTESTTOP/conf.sh
+
+zone=.
+infile=../ns1/root.db.in
+zonefile=root.db.signed
+
+keyname=`$KEYGEN -r $RANDFILE -qfk $zone`
+
+# copy the KSK out first, then revoke it
+cat $keyname.key | grep -v '^; ' | $PERL -n -e '
+local ($dn, $class, $type, $flags, $proto, $alg, @rest) = split;
+local $key = join("", @rest);
+print <<EOF
+managed-keys {
+    "$dn" initial-key $flags $proto $alg "$key";
+};
+EOF
+' > revoked.conf
+
+$SETTIME -R now ${keyname}.key > /dev/null
+
+# create a current set of keys, and sign the root zone
+$KEYGEN -r $RANDFILE -q $zone > /dev/null
+$KEYGEN -r $RANDFILE -qfk $zone > /dev/null
+$SIGNER -S -r $RANDFILE -o $zone -f $zonefile $infile > /dev/null 2>&1
index 797e011a063e652478218cb7ff54cf8876055653..b376ed007c54275e3bddf494dcc842cc23a449d8 100644 (file)
@@ -28,4 +28,8 @@ echo "a.bogus.example.        A       10.0.0.22" >>../ns3/bogus.example.db.signed
 
 cd ../ns3 && cp -f siginterval1.conf siginterval.conf
 cd ../ns4 && cp -f named1.conf named.conf
-cd ../ns5 && cp -f trusted.conf.bad trusted.conf
+cd ../ns5 && {
+    cp -f trusted.conf.bad trusted.conf
+    cp -f named1.conf named.conf
+    $SHELL sign.sh
+}
index 0c9ef4639bdcacb6467f0a8d39369b88d4889adc..1cf0cd8d4eb832238dea070a434bd31e9cb35225 100644 (file)
@@ -15,8 +15,6 @@
 # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 # PERFORMANCE OF THIS SOFTWARE.
 
-# $Id$
-
 SYSTEMTESTTOP=..
 . $SYSTEMTESTTOP/conf.sh
 
@@ -1530,9 +1528,10 @@ echo "I:checking rndc secroots ($n)"
 ret=0
 $RNDC -c ../common/rndc.conf -s 10.53.0.4 -p 9953 secroots 2>&1 | sed 's/^/I:ns1 /'
 keyid=`cat ns1/managed.key.id`
-linecount=`grep "./RSAMD5/$keyid ; trusted" ns4/named.secroots | wc -l`
+cp ns4/named.secroots named.secroots.test$n
+linecount=`grep "./RSAMD5/$keyid ; trusted" named.secroots.test$n | wc -l`
 [ "$linecount" -eq 1 ] || ret=1
-linecount=`cat ns4/named.secroots | wc -l`
+linecount=`cat named.secroots.test$n | wc -l`
 [ "$linecount" -eq 5 ] || ret=1
 n=`expr $n + 1`
 if [ $ret != 0 ]; then echo "I:failed"; fi
@@ -2299,10 +2298,11 @@ if [ $ret != 0 ]; then echo "I:failed"; fi
 status=`expr $status + $ret`
 
 echo "I:check KEYDATA records are printed in human readable form in key zone ($n)"
-# force the zone to be written out
+# force the managed-keys zone to be written out
 $PERL $SYSTEMTESTTOP/stop.pl --use-rndc . ns4
 ret=0
 grep KEYDATA ns4/managed-keys.bind > /dev/null || ret=1
+grep "next refresh:" ns4/managed-keys.bind > /dev/null || ret=1
 # restart the server
 $PERL $SYSTEMTESTTOP/start.pl --noclean --restart . ns4
 n=`expr $n + 1`
@@ -2504,5 +2504,16 @@ n=`expr $n + 1`
 if [ $ret != 0 ]; then echo "I:failed"; fi
 status=`expr $status + $ret`
 
+echo "I:checking initialization with a revoked managed key ($n)"
+ret=0
+cp ns5/named2.conf ns5/named.conf
+$RNDC -c ../common/rndc.conf -s 10.53.0.5 -p 9953 reconfig 2>&1 | sed 's/^/I:ns5 /'
+sleep 3
+$DIG $DIGOPTS +dnssec -p 5300 @10.53.0.5 SOA . > dig.out.ns5.test$n
+grep "status: NOERROR" dig.out.ns5.test$n > /dev/null || ret=1
+n=`expr $n + 1`
+if [ $ret != 0 ]; then echo "I:failed"; fi
+status=`expr $status + $ret`
+
 echo "I:exit status: $status"
 exit $status
index fd844907f69dad4010435b8a3161782e0e09312e..6960bda51b1dc6e607353a3320d4d8ecaedaebdf 100644 (file)
          processes to grow to very large sizes. [RT #38454]
        </para>
       </listitem>
+      <listitem>
+       <para>
+         Fixed some bugs in RFC 5011 trust anchor management,
+         including a memory leak and a possible loss of state
+         information.[RT #38458]
+       </para>
+      </listitem>
     </itemizedlist>
   </sect2>
   <sect2 id="end_of_life">
index fae2bce8dbeb750cf710a8385687dc9e4397ef54..1e5741863fa91248d56611584e35090bce944873 100644 (file)
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id$ */
-
 #ifndef GENERIC_KEYDATA_65533_C
 #define GENERIC_KEYDATA_65533_C 1
 
+#include <isc/time.h>
+#include <isc/stdtime.h>
+
 #include <dst/dst.h>
 
 #define RRTYPE_KEYDATA_ATTRIBUTES (0)
@@ -97,7 +98,7 @@ totext_keydata(ARGS_TOTEXT) {
        char buf[sizeof("64000")];
        unsigned int flags;
        unsigned char algorithm;
-       unsigned long when;
+       unsigned long refresh, add, remove;
        char algbuf[DNS_NAME_FORMATSIZE];
        const char *keyinfo;
 
@@ -109,21 +110,21 @@ totext_keydata(ARGS_TOTEXT) {
        dns_rdata_toregion(rdata, &sr);
 
        /* refresh timer */
-       when = uint32_fromregion(&sr);
+       refresh = uint32_fromregion(&sr);
        isc_region_consume(&sr, 4);
-       RETERR(dns_time32_totext(when, target));
+       RETERR(dns_time32_totext(refresh, target));
        RETERR(str_totext(" ", target));
 
        /* add hold-down */
-       when = uint32_fromregion(&sr);
+       add = uint32_fromregion(&sr);
        isc_region_consume(&sr, 4);
-       RETERR(dns_time32_totext(when, target));
+       RETERR(dns_time32_totext(add, target));
        RETERR(str_totext(" ", target));
 
        /* remove hold-down */
-       when = uint32_fromregion(&sr);
+       remove = uint32_fromregion(&sr);
        isc_region_consume(&sr, 4);
-       RETERR(dns_time32_totext(when, target));
+       RETERR(dns_time32_totext(remove, target));
        RETERR(str_totext(" ", target));
 
        /* flags */
@@ -176,6 +177,10 @@ totext_keydata(ARGS_TOTEXT) {
 
        if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0) {
                isc_region_t tmpr;
+               char rbuf[ISC_FORMATHTTPTIMESTAMP_SIZE];
+               char abuf[ISC_FORMATHTTPTIMESTAMP_SIZE];
+               char dbuf[ISC_FORMATHTTPTIMESTAMP_SIZE];
+               isc_time_t t;
 
                RETERR(str_totext(" ; ", target));
                RETERR(str_totext(keyinfo, target));
@@ -189,6 +194,47 @@ totext_keydata(ARGS_TOTEXT) {
                isc_region_consume(&tmpr, 12);
                sprintf(buf, "%u", dst_region_computeid(&tmpr, algorithm));
                RETERR(str_totext(buf, target));
+
+               if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) {
+                       isc_stdtime_t now;
+
+                       isc_stdtime_get(&now);
+
+                       RETERR(str_totext(tctx->linebreak, target)); 
+                       RETERR(str_totext("; next refresh: ", target));
+                       isc_time_set(&t, refresh, 0);
+                       isc_time_formathttptimestamp(&t, rbuf, sizeof(rbuf));
+                       RETERR(str_totext(rbuf, target));
+
+                       if (add == 0) {
+                               RETERR(str_totext(tctx->linebreak, target)); 
+                               RETERR(str_totext("; no trust", target));
+                       } else {
+                               RETERR(str_totext(tctx->linebreak, target)); 
+                               if (add < now) {
+                                       RETERR(str_totext("; trusted since: ",
+                                                         target));
+                               } else {
+                                       RETERR(str_totext("; trust pending: ",
+                                                         target));
+                               }
+                               isc_time_set(&t, add, 0);
+                               isc_time_formathttptimestamp(&t, abuf,
+                                                            sizeof(abuf));
+                               RETERR(str_totext(abuf, target));
+                       }
+
+                       if (remove != 0) {
+                               RETERR(str_totext(tctx->linebreak, target)); 
+                               RETERR(str_totext("; removal pending: ",
+                                                 target));
+                               isc_time_set(&t, remove, 0);
+                               isc_time_formathttptimestamp(&t, dbuf,
+                                                            sizeof(dbuf));
+                               RETERR(str_totext(dbuf, target));
+                       }
+               }
+
        }
        return (ISC_R_SUCCESS);
 }
index edefe8bcb00e3e18f8dd31ca6c219062778215ff..ecd424f4b822c0135e150979e15f025fef61538d 100644 (file)
@@ -661,6 +661,16 @@ struct dns_asyncload {
 #define DAY (24*HOUR)
 #define MONTH (30*DAY)
 
+/*
+ * These can be overridden by the -T mkeytimers option on the command
+ * line, so that we can test with shorter periods than specified in
+ * RFC 5011.
+ */
+unsigned int dns_zone_mkey_hour = HOUR;
+unsigned int dns_zone_mkey_day = (24 * HOUR);
+unsigned int dns_zone_mkey_month = (30 * DAY);
+
+
 #define SEND_BUFFER_SIZE 2048
 
 static void zone_settimer(dns_zone_t *, isc_time_t *);
@@ -3189,7 +3199,7 @@ check_nsec3param(dns_zone_t *zone, dns_db_t *db) {
  */
 static void
 set_refreshkeytimer(dns_zone_t *zone, dns_rdata_keydata_t *key,
-                   isc_stdtime_t now)
+                   isc_stdtime_t now, isc_boolean_t force)
 {
        const char me[] = "set_refreshkeytimer";
        isc_stdtime_t then;
@@ -3198,6 +3208,8 @@ set_refreshkeytimer(dns_zone_t *zone, dns_rdata_keydata_t *key,
 
        ENTER;
        then = key->refresh;
+       if (force)
+               then = now;
        if (key->addhd > now && key->addhd < then)
                then = key->addhd;
        if (key->removehd > now && key->removehd < then)
@@ -3277,8 +3289,9 @@ create_keydata(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
                CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD,
                                    dst_key_name(key), 0, &rdata));
                *changed = ISC_TRUE;
+
                /* Refresh new keys from the zone apex as soon as possible. */
-               set_refreshkeytimer(zone, &keydata, now);
+               set_refreshkeytimer(zone, &keydata, now, ISC_TRUE);
 
  skip:
                result = dns_keytable_nextkeynode(keytable, keynode, &nextnode);
@@ -3434,8 +3447,8 @@ load_secroots(dns_zone_t *zone, dns_name_t *name, dns_rdataset_t *rdataset) {
                        continue;
                RUNTIME_CHECK(result == ISC_R_SUCCESS);
 
-               /* Set the key refresh timer. */
-               set_refreshkeytimer(zone, &keydata, now);
+               /* Set the key refresh timer to force a fast refresh. */
+               set_refreshkeytimer(zone, &keydata, now, ISC_TRUE);
 
                /* If the removal timer is nonzero, this key was revoked. */
                if (keydata.removehd != 0) {
@@ -3703,7 +3716,8 @@ sync_keyzone(dns_zone_t *zone, dns_db_t *db) {
                result = dns_keytable_find(sr, rrname, &keynode);
                if ((result != ISC_R_SUCCESS &&
                     result != DNS_R_PARTIALMATCH) ||
-                   dns_keynode_managed(keynode) == ISC_FALSE) {
+                   dns_keynode_managed(keynode) == ISC_FALSE)
+               {
                        CHECK(delete_keydata(db, ver, &diff,
                                             rrname, rdataset));
                        changed = ISC_TRUE;
@@ -7910,7 +7924,8 @@ zone_sign(dns_zone_t *zone) {
 
 static isc_result_t
 normalize_key(dns_rdata_t *rr, dns_rdata_t *target,
-             unsigned char *data, int size) {
+             unsigned char *data, int size)
+{
        dns_rdata_dnskey_t dnskey;
        dns_rdata_keydata_t keydata;
        isc_buffer_t buf;
@@ -8007,11 +8022,11 @@ refresh_time(dns_keyfetch_t *kfetch, isc_boolean_t retry) {
        if (dns_rdataset_isassociated(&kfetch->dnskeysigset))
                rdset = &kfetch->dnskeysigset;
        else
-               return (now + HOUR);
+               return (now + dns_zone_mkey_hour);
 
        result = dns_rdataset_first(rdset);
        if (result != ISC_R_SUCCESS)
-               return (now + HOUR);
+               return (now + dns_zone_mkey_hour);
 
        dns_rdataset_current(rdset, &sigrr);
        result = dns_rdata_tostruct(&sigrr, &sig, NULL);
@@ -8026,11 +8041,11 @@ refresh_time(dns_keyfetch_t *kfetch, isc_boolean_t retry) {
                                t = exp;
                }
 
-               if (t > (15*DAY))
-                       t = (15*DAY);
+               if (t > (15 * dns_zone_mkey_day))
+                       t = (15 * dns_zone_mkey_day);
 
-               if (t < HOUR)
-                       t = HOUR;
+               if (t < dns_zone_mkey_hour)
+                       t = dns_zone_mkey_hour;
        } else {
                t = sig.originalttl / 10;
 
@@ -8040,11 +8055,11 @@ refresh_time(dns_keyfetch_t *kfetch, isc_boolean_t retry) {
                                t = exp;
                }
 
-               if (t > DAY)
-                       t = DAY;
+               if (t > dns_zone_mkey_day)
+                       t = dns_zone_mkey_day;
 
-               if (t < HOUR)
-                       t = HOUR;
+               if (t < dns_zone_mkey_hour)
+                       t = dns_zone_mkey_hour;
        }
 
        return (now + t);
@@ -8087,7 +8102,7 @@ minimal_update(dns_keyfetch_t *kfetch, dns_dbversion_t *ver, dns_diff_t *diff)
                if (result != ISC_R_SUCCESS)
                        goto failure;
                keydata.refresh = refresh_time(kfetch, ISC_TRUE);
-               set_refreshkeytimer(zone, &keydata, now);
+               set_refreshkeytimer(zone, &keydata, now, ISC_FALSE);
 
                dns_rdata_reset(&rdata);
                isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
@@ -8130,8 +8145,8 @@ revocable(dns_keyfetch_t *kfetch, dns_rdata_keydata_t *keydata) {
        /* Generate a key from keydata */
        isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
        dns_keydata_todnskey(keydata, &dnskey, NULL);
-       dns_rdata_fromstruct(&rr, keydata->common.rdclass, dns_rdatatype_dnskey,
-                                    &dnskey, &keyb);
+       dns_rdata_fromstruct(&rr, keydata->common.rdclass,
+                            dns_rdatatype_dnskey, &dnskey, &keyb);
        result = dns_dnssec_keyfromrdata(keyname, &rr, mctx, &dstkey);
        if (result != ISC_R_SUCCESS)
                return (ISC_FALSE);
@@ -8139,7 +8154,8 @@ revocable(dns_keyfetch_t *kfetch, dns_rdata_keydata_t *keydata) {
        /* See if that key generated any of the signatures */
        for (result = dns_rdataset_first(&kfetch->dnskeysigset);
             result == ISC_R_SUCCESS;
-            result = dns_rdataset_next(&kfetch->dnskeysigset)) {
+            result = dns_rdataset_next(&kfetch->dnskeysigset))
+       {
                dns_fixedname_t fixed;
                dns_fixedname_init(&fixed);
 
@@ -8149,8 +8165,8 @@ revocable(dns_keyfetch_t *kfetch, dns_rdata_keydata_t *keydata) {
                RUNTIME_CHECK(result == ISC_R_SUCCESS);
 
                if (dst_key_alg(dstkey) == sig.algorithm &&
-                   (dst_key_id(dstkey) == sig.keyid ||
-                    dst_key_rid(dstkey) == sig.keyid)) {
+                   dst_key_rid(dstkey) == sig.keyid)
+               {
                        result = dns_dnssec_verify2(keyname,
                                            &kfetch->dnskeyset,
                                            dstkey, ISC_FALSE, mctx, &sigrr,
@@ -8312,8 +8328,6 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) {
                                                dns_trust_secure;
                                        kfetch->dnskeysigset.trust =
                                                dns_trust_secure;
-                                       dns_keytable_detachkeynode(secroots,
-                                                                  &keynode);
                                        break;
                                }
                        }
@@ -8324,6 +8338,9 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) {
                        keynode = nextnode;
                }
 
+               if (keynode != NULL)
+                       dns_keytable_detachkeynode(secroots, &keynode);
+
                if (kfetch->dnskeyset.trust == dns_trust_secure)
                        break;
        }
@@ -8368,31 +8385,34 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) {
                        isc_boolean_t deletekey = ISC_FALSE;
 
                        if (!secure) {
-                               if (now > keydata.removehd)
+                               if (keydata.removehd != 0 &&
+                                   keydata.removehd <= now)
                                        deletekey = ISC_TRUE;
-                       } else if (now < keydata.addhd) {
+                       } else if (keydata.addhd == 0) {
+                               deletekey = ISC_TRUE;
+                       } else if (keydata.addhd > now) {
                                dns_zone_log(zone, ISC_LOG_WARNING,
                                             "Pending key unexpectedly missing "
                                             "from %s; restarting acceptance "
                                             "timer", namebuf);
-                               keydata.addhd = now + MONTH;
+                               if (keydata.addhd < now + dns_zone_mkey_month)
+                                       keydata.addhd =
+                                               now + dns_zone_mkey_month;
                                keydata.refresh = refresh_time(kfetch,
                                                               ISC_FALSE);
-                       } else if (keydata.addhd == 0) {
-                               keydata.addhd = now;
                        } else if (keydata.removehd == 0) {
                                dns_zone_log(zone, ISC_LOG_WARNING,
                                             "Active key unexpectedly missing "
                                             "from %s", namebuf);
-                               keydata.refresh = now + HOUR;
-                       } else if (now > keydata.removehd) {
+                               keydata.refresh = now + dns_zone_mkey_hour;
+                       } else if (keydata.removehd <= now) {
                                deletekey = ISC_TRUE;
                        } else {
                                keydata.refresh = refresh_time(kfetch,
                                                               ISC_FALSE);
                        }
 
-                       if  (secure || deletekey) {
+                       if (secure || deletekey) {
                                /* Delete old version */
                                CHECK(update_one_rr(kfetch->db, ver, &diff,
                                                    DNS_DIFFOP_DEL, keyname, 0,
@@ -8413,7 +8433,7 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) {
                                            DNS_DIFFOP_ADD, keyname, 0,
                                            &keydatarr));
 
-                       set_refreshkeytimer(zone, &keydata, now);
+                       set_refreshkeytimer(zone, &keydata, now, ISC_FALSE);
                }
        }
 
@@ -8435,7 +8455,8 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) {
         */
        for (result = dns_rdataset_first(&kfetch->dnskeyset);
             result == ISC_R_SUCCESS;
-            result = dns_rdataset_next(&kfetch->dnskeyset)) {
+            result = dns_rdataset_next(&kfetch->dnskeyset))
+       {
                isc_boolean_t revoked = ISC_FALSE;
                isc_boolean_t newkey = ISC_FALSE;
                isc_boolean_t updatekey = ISC_FALSE;
@@ -8471,34 +8492,43 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) {
                                        dns_view_untrust(zone->view, keyname,
                                                         &dnskey, mctx);
 
+                                       /* But ensure there's a null key */
+                                       fail_secure(zone, keyname);
+
                                        /* If initializing, delete now */
                                        if (keydata.addhd == 0)
                                                deletekey = ISC_TRUE;
-                                       else
-                                               keydata.removehd = now + MONTH;
+                                       else {
+                                               keydata.removehd = now +
+                                                       dns_zone_mkey_month;
+                                               keydata.flags |=
+                                                       DNS_KEYFLAG_REVOKE;
+                                       }
                                } else if (keydata.removehd < now) {
                                        /* Scheduled for removal */
                                        deletekey = ISC_TRUE;
                                }
-                       } else if (revoked) {
-                               if (secure && keydata.removehd == 0) {
-                                       dns_zone_log(zone, ISC_LOG_WARNING,
-                                                    "Active key for zone "
-                                                    "'%s' is revoked but "
-                                                    "did not self-sign; "
-                                                        "ignoring.", namebuf);
-                                               continue;
-                               }
+                       } else if (revoked && keydata.removehd == 0) {
+                               dns_zone_log(zone, ISC_LOG_WARNING,
+                                            "Active key for zone "
+                                            "'%s' is revoked but "
+                                            "did not self-sign; "
+                                            "ignoring.", namebuf);
+                                       continue;
                        } else if (secure) {
                                if (keydata.removehd != 0) {
                                        /*
                                         * Key isn't revoked--but it
                                         * seems it used to be.
                                         * Remove it now and add it
-                                        * back as if it were a fresh key.
+                                        * back as if it were a fresh key,
+                                        * with a 30 day acceptance timer.
                                         */
                                        deletekey = ISC_TRUE;
                                        newkey = ISC_TRUE;
+                                       keydata.removehd = 0;
+                                       keydata.addhd = 
+                                               now + dns_zone_mkey_month;
                                } else if (keydata.addhd > now)
                                        pending++;
                                else if (keydata.addhd == 0)
@@ -8506,6 +8536,13 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) {
 
                                if (keydata.addhd <= now)
                                        trustkey = ISC_TRUE;
+                       } else if (keydata.addhd > now) {
+                               /*
+                                * Not secure, and key is pending:
+                                * reset the acceptance timer
+                                */
+                               pending++;
+                               keydata.addhd = now + dns_zone_mkey_month;
                        }
 
                        if (!deletekey && !newkey)
@@ -8567,7 +8604,8 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) {
                        RUNTIME_CHECK(result == ISC_R_SUCCESS);
                        dns_keydata_fromdnskey(&keydata, &dnskey, 0, 0, 0,
                                               NULL);
-                       keydata.addhd = initializing ? now : now + MONTH;
+                       keydata.addhd = initializing
+                                        ? now : now + dns_zone_mkey_month;
                        keydata.refresh = refresh_time(kfetch, ISC_FALSE);
                        dns_rdata_reset(&keydatarr);
                        isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
@@ -8590,7 +8628,7 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) {
 
                if (secure && !deletekey) {
                        INSIST(newkey || updatekey);
-                       set_refreshkeytimer(zone, &keydata, now);
+                       set_refreshkeytimer(zone, &keydata, now, ISC_FALSE);
                }
        }
 
@@ -8804,7 +8842,7 @@ zone_refreshkeys(dns_zone_t *zone) {
                char timebuf[80];
 
                TIME_NOW(&timenow);
-               DNS_ZONE_TIME_ADD(&timenow, HOUR, &timethen);
+               DNS_ZONE_TIME_ADD(&timenow, dns_zone_mkey_hour, &timethen);
                zone->refreshkeytime = timethen;
                zone_settimer(zone, &timenow);
 
index 46dab296f6a1c576d19833c5ffca1bd4d9a3d192..966b6517486a8177527e8ce7b0c55d19d9894a6f 100644 (file)
@@ -648,7 +648,7 @@ isc_httpd_recvdone(isc_task_t *task, isc_event_t *ev) {
        isc_socketevent_t *sev = (isc_socketevent_t *)ev;
        isc_httpdurl_t *url;
        isc_time_t now;
-       char datebuf[32];  /* Only need 30, but safety first */
+       char datebuf[ISC_FORMATHTTPTIMESTAMP_SIZE];
 
        ENTER("recv");
 
@@ -729,7 +729,7 @@ isc_httpd_recvdone(isc_task_t *task, isc_event_t *ev) {
        isc_httpd_addheader(httpd, "Expires", datebuf);
 
        if (url != NULL && url->isstatic) {
-               char loadbuf[32];
+               char loadbuf[ISC_FORMATHTTPTIMESTAMP_SIZE];
                isc_time_formathttptimestamp(&url->loadtime,
                                             loadbuf, sizeof(loadbuf));
                isc_httpd_addheader(httpd, "Last-Modified", loadbuf);
index caddec2bec4c69a4c2af9599b8d9a60e71283640..eb56ff9fb65ebb64b974c7415964767689b87196 100644 (file)
@@ -29,7 +29,7 @@ ATF_TC_HEAD(isc_time_parsehttptimestamp, tc) {
 ATF_TC_BODY(isc_time_parsehttptimestamp, tc) {
        isc_result_t result;
        isc_time_t t, x;
-       char buf[100];
+       char buf[ISC_FORMATHTTPTIMESTAMP_SIZE];
 
        setenv("TZ", "PST8PDT", 1);
        result = isc_time_now(&t);
index 2a83f099305fb72c12c9753ceebd596ccb5375a5..ade55247a93b944918102024575b733fcfb8197c 100644 (file)
@@ -43,6 +43,13 @@ struct isc_interval {
 
 extern const isc_interval_t * const isc_interval_zero;
 
+/*
+ * ISC_FORMATHTTPTIMESTAMP_SIZE needs to be 30 in C locale and potentially
+ * more for other locales to handle longer national abbreviations when
+ * expanding strftime's %a and %b.
+ */
+#define ISC_FORMATHTTPTIMESTAMP_SIZE 50
+
 ISC_LANG_BEGINDECLS
 
 void
index 890b9192ba5add55dad81d641d883c57c7788e5e..ea1ddc0ae030b310cac98f7377cb4608edde6ee5 100644 (file)
@@ -404,6 +404,9 @@ isc_time_formathttptimestamp(const isc_time_t *t, char *buf, unsigned int len) {
 
        REQUIRE(len > 0);
 
+       /*
+        * 5 spaces, 1 comma, 3 GMT, 2 %d, 4 %Y, 8 %H:%M:%S, 3+ %a, 3+ %b (29+)
+        */
        now = (time_t)t->seconds;
        flen = strftime(buf, len, "%a, %d %b %Y %H:%M:%S GMT", gmtime(&now));
        INSIST(flen < len);
index fe842ab95bd8610fc5b9191e1fc078e7c62b9d8f..bfd5bc0d622c60b3b813cb78a2e397815d68b8ce 100644 (file)
@@ -41,6 +41,13 @@ struct isc_interval {
 
 LIBISC_EXTERNAL_DATA extern const isc_interval_t * const isc_interval_zero;
 
+/*
+ * ISC_FORMATHTTPTIMESTAMP_SIZE needs to be 30 in C locale and potentially
+ * more for other locales to handle longer national abbreviations when
+ * expanding strftime's %a and %b.
+ */
+#define ISC_FORMATHTTPTIMESTAMP_SIZE 50
+
 ISC_LANG_BEGINDECLS
 
 void