diff --git a/CHANGES b/CHANGES index dc71bd7984..274b75ee1b 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,7 @@ +4331. [func] When loading managed signed zones detect if the + RRSIG's inception time is in the future and regenerate + the RRSIG immediately. [RT #41808] + 4330. [protocol] Identify the PAD option as "PAD" when printing out a message. diff --git a/bin/tests/system/dnssec/clean.sh b/bin/tests/system/dnssec/clean.sh index 05dce05b4f..c4b3f3794e 100644 --- a/bin/tests/system/dnssec/clean.sh +++ b/bin/tests/system/dnssec/clean.sh @@ -77,6 +77,7 @@ rm -f ns3/split-smart.example.db rm -f ns3/ttlpatch.example.db ns3/ttlpatch.example.db.signed rm -f ns3/ttlpatch.example.db.patched rm -f ns3/unsecure.example.db ns3/bogus.example.db ns3/keyless.example.db +rm -f ns3/managed-future.example.db rm -f ns4/managed-keys.bind* rm -f ns4/named.conf rm -f ns4/named.conf ns5/named.conf diff --git a/bin/tests/system/dnssec/ns2/example.db.in b/bin/tests/system/dnssec/ns2/example.db.in index 4614ebf117..cd8f08d6c6 100644 --- a/bin/tests/system/dnssec/ns2/example.db.in +++ b/bin/tests/system/dnssec/ns2/example.db.in @@ -160,3 +160,6 @@ ns.expiring A 10.53.0.3 future NS ns.future ns.future A 10.53.0.3 + +managed-future NS ns.managed-future +ns.managed-future A 10.53.0.3 diff --git a/bin/tests/system/dnssec/ns2/sign.sh b/bin/tests/system/dnssec/ns2/sign.sh index d35bc93db5..18c116f8d1 100644 --- a/bin/tests/system/dnssec/ns2/sign.sh +++ b/bin/tests/system/dnssec/ns2/sign.sh @@ -30,7 +30,7 @@ for subdomain in secure badds bogus dynamic keyless nsec3 optout \ nsec3-unknown optout-unknown multiple rsasha256 rsasha512 \ kskonly update-nsec3 auto-nsec auto-nsec3 secure.below-cname \ ttlpatch split-dnssec split-smart expired expiring upper lower \ - dnskey-unknown dnskey-nsec3-unknown + dnskey-unknown dnskey-nsec3-unknown managed-future do cp ../ns3/dsset-$subdomain.example. . done diff --git a/bin/tests/system/dnssec/ns3/managed-future.example.db.in b/bin/tests/system/dnssec/ns3/managed-future.example.db.in new file mode 100644 index 0000000000..83ac20e8ea --- /dev/null +++ b/bin/tests/system/dnssec/ns3/managed-future.example.db.in @@ -0,0 +1,43 @@ +; Copyright (C) 2014 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. + +$TTL 300 ; 5 minutes +@ IN SOA mname1. . ( + 2000042407 ; serial + 20 ; refresh (20 seconds) + 20 ; retry (20 seconds) + 1814400 ; expire (3 weeks) + 3600 ; minimum (1 hour) + ) + NS ns +ns A 10.53.0.3 + +a A 10.0.0.1 +b A 10.0.0.2 +d A 10.0.0.4 +z A 10.0.0.26 +a.a.a.a A 10.0.0.3 +*.wild A 10.0.0.6 +insecure NS ns.insecure +ns.insecure A 10.53.0.3 +secure NS ns.secure +ns.secure A 10.53.0.3 +nsec3 NS ns.nsec3 +ns.nsec3 A 10.53.0.3 +optout NS ns.optout +ns.optout A 10.53.0.3 +child NS ns2.example. +insecure.empty NS ns.insecure.empty +ns.insecure.empty A 10.53.0.3 +foo.*.empty-wild NS ns diff --git a/bin/tests/system/dnssec/ns3/named.conf b/bin/tests/system/dnssec/ns3/named.conf index b7ce7e1c38..ac3dfbb951 100644 --- a/bin/tests/system/dnssec/ns3/named.conf +++ b/bin/tests/system/dnssec/ns3/named.conf @@ -292,6 +292,12 @@ zone "future.example" { file "future.example.db.signed"; }; +zone "managed-future.example" { + type master; + file "managed-future.example.db.signed"; + allow-update { any; }; +}; + include "siginterval.conf"; include "trusted.conf"; diff --git a/bin/tests/system/dnssec/ns3/sign.sh b/bin/tests/system/dnssec/ns3/sign.sh index de785bec65..1a779b78d0 100644 --- a/bin/tests/system/dnssec/ns3/sign.sh +++ b/bin/tests/system/dnssec/ns3/sign.sh @@ -520,3 +520,14 @@ 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 cp -f $kskname.key trusted-future.key + +# +# A zone with future signatures. +# +zone=managed-future.example +infile=managed-future.example.db.in +zonefile=managed-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 diff --git a/bin/tests/system/dnssec/tests.sh b/bin/tests/system/dnssec/tests.sh index 45c693ed6e..5162006bea 100644 --- a/bin/tests/system/dnssec/tests.sh +++ b/bin/tests/system/dnssec/tests.sh @@ -117,6 +117,7 @@ grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null && ret=1 n=`expr $n + 1` if [ $ret != 0 ]; then echo "I:failed"; fi status=`expr $status + $ret` + echo "I:checking for AD in authoritative answer ($n)" ret=0 $DIG $DIGOPTS a.example. @10.53.0.2 a > dig.out.ns2.test$n || ret=1 @@ -3265,5 +3266,14 @@ n=`expr $n + 1` if [ $ret != 0 ]; then echo "I:failed"; fi status=`expr $status + $ret` +echo "I:check that a named managed zone that was signed 'in-the-future' is re-signed when loaded" +ret=0 +$DIG $DIGOPTS managed-future.example. @10.53.0.4 a > dig.out.ns4.test$n || ret=1 +grep "flags:.*ad.*QUERY" dig.out.ns4.test$n > /dev/null || ret=1 +grep "status: NOERROR" dig.out.ns4.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 diff --git a/lib/dns/master.c b/lib/dns/master.c index 7fc140c9fb..317a435149 100644 --- a/lib/dns/master.c +++ b/lib/dns/master.c @@ -150,6 +150,7 @@ struct dns_loadctx { isc_uint32_t references; dns_incctx_t *inc; isc_uint32_t resign; + isc_stdtime_t now; dns_masterincludecb_t include_cb; void *include_arg; @@ -622,6 +623,7 @@ loadctx_create(dns_masterformat_t format, isc_mem_t *mctx, lctx->result = ISC_R_SUCCESS; lctx->include_cb = include_cb; lctx->include_arg = include_arg; + isc_stdtime_get(&lctx->now); dns_fixedname_init(&lctx->fixed_top); lctx->top = dns_fixedname_name(&lctx->fixed_top); @@ -1068,7 +1070,6 @@ load_text(dns_loadctx_t *lctx) { const char *source = ""; unsigned long line = 0; isc_boolean_t explicit_ttl; - isc_stdtime_t now; char classname1[DNS_RDATACLASS_FORMATSIZE]; char classname2[DNS_RDATACLASS_FORMATSIZE]; unsigned int options = 0; @@ -1081,7 +1082,6 @@ load_text(dns_loadctx_t *lctx) { ISC_LIST_INIT(glue_list); ISC_LIST_INIT(current_list); - isc_stdtime_get(&now); /* * Allocate target_size of buffer space. This is greater than twice @@ -1896,7 +1896,7 @@ load_text(dns_loadctx_t *lctx) { result = dns_rdata_tostruct(&rdata[rdcount], &sig, NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); - if (isc_serial_lt(sig.timeexpire, now)) { + if (isc_serial_lt(sig.timeexpire, lctx->now)) { (*callbacks->warn)(callbacks, "%s:%lu: " "signature has expired", @@ -3048,7 +3048,7 @@ grow_rdata(int new_len, dns_rdata_t *old, int old_len, } static isc_uint32_t -resign_fromlist(dns_rdatalist_t *this, isc_uint32_t resign) { +resign_fromlist(dns_rdatalist_t *this, dns_loadctx_t *lctx) { dns_rdata_t *rdata; dns_rdata_rrsig_t sig; isc_uint32_t when; @@ -3056,13 +3056,18 @@ resign_fromlist(dns_rdatalist_t *this, isc_uint32_t resign) { rdata = ISC_LIST_HEAD(this->rdata); INSIST(rdata != NULL); (void)dns_rdata_tostruct(rdata, &sig, NULL); - when = sig.timeexpire - resign; + if (isc_serial_gt(sig.timesigned, lctx->now)) + when = lctx->now; + else + when = sig.timeexpire - lctx->resign; rdata = ISC_LIST_NEXT(rdata, link); while (rdata != NULL) { (void)dns_rdata_tostruct(rdata, &sig, NULL); - if (sig.timeexpire - resign < when) - when = sig.timeexpire - resign; + if (isc_serial_gt(sig.timesigned, lctx->now)) + when = lctx->now; + else if (sig.timeexpire - lctx->resign < when) + when = sig.timeexpire - lctx->resign; rdata = ISC_LIST_NEXT(rdata, link); } return (when); @@ -3100,7 +3105,7 @@ commit(dns_rdatacallbacks_t *callbacks, dns_loadctx_t *lctx, if (dataset.type == dns_rdatatype_rrsig && (lctx->options & DNS_MASTER_RESIGN) != 0) { dataset.attributes |= DNS_RDATASETATTR_RESIGN; - dataset.resign = resign_fromlist(this, lctx->resign); + dataset.resign = resign_fromlist(this, lctx); } result = ((*callbacks->add)(callbacks->add_private, owner, &dataset));