diff options
author | Internet Software Consortium, Inc <@isc.org> | 2013-10-29 14:54:54 -0600 |
---|---|---|
committer | Internet Software Consortium, Inc <@isc.org> | 2013-10-29 14:55:01 -0600 |
commit | 66e6eb1d4417635aa5431ab6e66ada4ff33ecc98 (patch) | |
tree | 79b7e8f2232da09558fd63abad4f237614b1f638 /lib | |
parent | 816cb5580f04b5989e0f952510d64201a16d0494 (diff) | |
download | bind9-66e6eb1d4417635aa5431ab6e66ada4ff33ecc98.tar.gz |
9.9.4rc2
Diffstat (limited to 'lib')
-rw-r--r-- | lib/dns/api | 4 | ||||
-rw-r--r-- | lib/dns/dnssec.c | 3 | ||||
-rw-r--r-- | lib/dns/dst_api.c | 17 | ||||
-rw-r--r-- | lib/dns/dst_internal.h | 4 | ||||
-rw-r--r-- | lib/dns/include/dns/zone.h | 6 | ||||
-rw-r--r-- | lib/dns/include/dst/dst.h | 19 | ||||
-rw-r--r-- | lib/dns/rdata/generic/dnskey_48.c | 22 | ||||
-rw-r--r-- | lib/dns/rdata/generic/key_25.c | 22 | ||||
-rw-r--r-- | lib/dns/rdata/generic/keydata_65533.c | 21 | ||||
-rw-r--r-- | lib/dns/resolver.c | 4 | ||||
-rw-r--r-- | lib/dns/update.c | 6 | ||||
-rw-r--r-- | lib/dns/win32/libdns.def | 3 | ||||
-rw-r--r-- | lib/dns/xfrin.c | 19 | ||||
-rw-r--r-- | lib/dns/zone.c | 74 | ||||
-rw-r--r-- | lib/isccfg/api | 2 | ||||
-rw-r--r-- | lib/isccfg/namedconf.c | 1 |
16 files changed, 184 insertions, 43 deletions
diff --git a/lib/dns/api b/lib/dns/api index 60d0c931..a0eb7b21 100644 --- a/lib/dns/api +++ b/lib/dns/api @@ -4,6 +4,6 @@ # 9.8: 80-89, 120-129 # 9.9: 90-109 # 9.9-sub: 130-139 -LIBINTERFACE = 100 +LIBINTERFACE = 101 LIBREVISION = 1 -LIBAGE = 0 +LIBAGE = 1 diff --git a/lib/dns/dnssec.c b/lib/dns/dnssec.c index d00c99b4..a1c5c691 100644 --- a/lib/dns/dnssec.c +++ b/lib/dns/dnssec.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -764,6 +764,7 @@ dns_dnssec_findzonekeys2(dns_db_t *db, dns_dbversion_t *ver, * If a key is marked inactive, skip it */ if (!key_active(keys[count], now)) { + dst_key_setinactive(pubkey, ISC_TRUE); dst_key_free(&keys[count]); keys[count] = pubkey; pubkey = NULL; diff --git a/lib/dns/dst_api.c b/lib/dns/dst_api.c index 98607246..93dda089 100644 --- a/lib/dns/dst_api.c +++ b/lib/dns/dst_api.c @@ -1349,10 +1349,27 @@ get_key_struct(dns_name_t *name, unsigned int alg, key->times[i] = 0; key->timeset[i] = ISC_FALSE; } + key->inactive = ISC_FALSE; key->magic = KEY_MAGIC; return (key); } +isc_boolean_t +dst_key_inactive(const dst_key_t *key) { + + REQUIRE(VALID_KEY(key)); + + return (key->inactive); +} + +void +dst_key_setinactive(dst_key_t *key, isc_boolean_t inactive) { + + REQUIRE(VALID_KEY(key)); + + key->inactive = inactive; +} + /*% * Reads a public key from disk */ diff --git a/lib/dns/dst_internal.h b/lib/dns/dst_internal.h index c3e8e29a..48ce9b85 100644 --- a/lib/dns/dst_internal.h +++ b/lib/dns/dst_internal.h @@ -1,5 +1,5 @@ /* - * Portions Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC") + * Portions Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 2000-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -126,6 +126,8 @@ struct dst_key { isc_boolean_t timeset[DST_MAX_TIMES + 1]; /*%< data set? */ isc_stdtime_t nums[DST_MAX_NUMERIC + 1]; /*%< numeric metadata */ isc_boolean_t numset[DST_MAX_NUMERIC + 1]; /*%< data set? */ + isc_boolean_t inactive; /*%< private key not present as it is + inactive */ int fmt_major; /*%< private key format, major version */ int fmt_minor; /*%< private key format, minor version */ diff --git a/lib/dns/include/dns/zone.h b/lib/dns/include/dns/zone.h index f91801f6..9efa1e72 100644 --- a/lib/dns/include/dns/zone.h +++ b/lib/dns/include/dns/zone.h @@ -2086,6 +2086,12 @@ dns_zone_rpz_enable(dns_zone_t *zone); * Set the response policy associated with a zone. */ +isc_result_t +dns_zone_rpz_enable_db(dns_zone_t *zone, dns_db_t *db); +/*% + * If a zone is a response policy zone, mark its new database. + */ + isc_boolean_t dns_zone_get_rpz(dns_zone_t *zone); diff --git a/lib/dns/include/dst/dst.h b/lib/dns/include/dst/dst.h index 4724fc64..a59ed121 100644 --- a/lib/dns/include/dst/dst.h +++ b/lib/dns/include/dst/dst.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -923,6 +923,23 @@ dst_key_restore(dns_name_t *name, unsigned int alg, unsigned int flags, unsigned int protocol, dns_rdataclass_t rdclass, isc_mem_t *mctx, const char *keystr, dst_key_t **keyp); +isc_boolean_t +dst_key_inactive(const dst_key_t *key); +/*%< + * Determines if the private key is missing due the key being deemed inactive. + * + * Requires: + * 'key' to be valid. + */ + +void +dst_key_setinactive(dst_key_t *key, isc_boolean_t inactive); +/*%< + * Set key inactive state. + * + * Requires: + * 'key' to be valid. + */ ISC_LANG_ENDDECLS diff --git a/lib/dns/rdata/generic/dnskey_48.c b/lib/dns/rdata/generic/dnskey_48.c index 688e7ac5..aa705cab 100644 --- a/lib/dns/rdata/generic/dnskey_48.c +++ b/lib/dns/rdata/generic/dnskey_48.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007, 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007, 2009, 2011-2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -32,6 +32,7 @@ static inline isc_result_t fromtext_dnskey(ARGS_FROMTEXT) { + isc_result_t result; isc_token_t token; dns_secalg_t alg; dns_secproto_t proto; @@ -67,7 +68,15 @@ fromtext_dnskey(ARGS_FROMTEXT) { if ((flags & 0xc000) == 0xc000) return (ISC_R_SUCCESS); - return (isc_base64_tobuffer(lexer, target, -1)); + result = isc_base64_tobuffer(lexer, target, -1); + if (result != ISC_R_SUCCESS) + return (result); + + /* Ensure there's at least enough data to compute a key ID for MD5 */ + if (alg == DST_ALG_RSAMD5 && isc_buffer_usedlength(target) < 7) + return (ISC_R_UNEXPECTEDEND); + + return (ISC_R_SUCCESS); } static inline isc_result_t @@ -185,6 +194,15 @@ fromwire_dnskey(ARGS_FROMWIRE) { dns_name_init(&name, NULL); RETERR(dns_name_fromwire(&name, source, dctx, options, target)); } + + /* + * RSAMD5 computes key ID differently from other + * algorithms: we need to ensure there's enough data + * present for the computation + */ + if (algorithm == DST_ALG_RSAMD5 && sr.length < 3) + return (ISC_R_UNEXPECTEDEND); + isc_buffer_activeregion(source, &sr); isc_buffer_forward(source, sr.length); return (mem_tobuffer(target, sr.base, sr.length)); diff --git a/lib/dns/rdata/generic/key_25.c b/lib/dns/rdata/generic/key_25.c index 1d0ba83a..f55401e1 100644 --- a/lib/dns/rdata/generic/key_25.c +++ b/lib/dns/rdata/generic/key_25.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007, 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007, 2009, 2011-2013 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -32,6 +32,7 @@ static inline isc_result_t fromtext_key(ARGS_FROMTEXT) { + isc_result_t result; isc_token_t token; dns_secalg_t alg; dns_secproto_t proto; @@ -67,7 +68,15 @@ fromtext_key(ARGS_FROMTEXT) { if ((flags & 0xc000) == 0xc000) return (ISC_R_SUCCESS); - return (isc_base64_tobuffer(lexer, target, -1)); + result = isc_base64_tobuffer(lexer, target, -1); + if (result != ISC_R_SUCCESS) + return (result); + + /* Ensure there's at least enough data to compute a key ID for MD5 */ + if (alg == DST_ALG_RSAMD5 && isc_buffer_usedlength(target) < 7) + return (ISC_R_UNEXPECTEDEND); + + return (ISC_R_SUCCESS); } static inline isc_result_t @@ -176,6 +185,15 @@ fromwire_key(ARGS_FROMWIRE) { dns_name_init(&name, NULL); RETERR(dns_name_fromwire(&name, source, dctx, options, target)); } + + /* + * RSAMD5 computes key ID differently from other + * algorithms: we need to ensure there's enough data + * present for the computation + */ + if (algorithm == DST_ALG_RSAMD5 && sr.length < 3) + return (ISC_R_UNEXPECTEDEND); + isc_buffer_activeregion(source, &sr); isc_buffer_forward(source, sr.length); return (mem_tobuffer(target, sr.base, sr.length)); diff --git a/lib/dns/rdata/generic/keydata_65533.c b/lib/dns/rdata/generic/keydata_65533.c index f1fe45e4..03ad1ed7 100644 --- a/lib/dns/rdata/generic/keydata_65533.c +++ b/lib/dns/rdata/generic/keydata_65533.c @@ -25,6 +25,7 @@ static inline isc_result_t fromtext_keydata(ARGS_FROMTEXT) { + isc_result_t result; isc_token_t token; dns_secalg_t alg; dns_secproto_t proto; @@ -79,7 +80,15 @@ fromtext_keydata(ARGS_FROMTEXT) { if ((flags & 0xc000) == 0xc000) return (ISC_R_SUCCESS); - return (isc_base64_tobuffer(lexer, target, -1)); + result = isc_base64_tobuffer(lexer, target, -1); + if (result != ISC_R_SUCCESS) + return (result); + + /* Ensure there's at least enough data to compute a key ID for MD5 */ + if (alg == DST_ALG_RSAMD5 && isc_buffer_usedlength(target) < 19) + return (ISC_R_UNEXPECTEDEND); + + return (ISC_R_SUCCESS); } static inline isc_result_t @@ -185,6 +194,7 @@ totext_keydata(ARGS_TOTEXT) { static inline isc_result_t fromwire_keydata(ARGS_FROMWIRE) { isc_region_t sr; + unsigned char algorithm; REQUIRE(type == 65533); @@ -197,6 +207,15 @@ fromwire_keydata(ARGS_FROMWIRE) { if (sr.length < 16) return (ISC_R_UNEXPECTEDEND); + /* + * RSAMD5 computes key ID differently from other + * algorithms: we need to ensure there's enough data + * present for the computation + */ + algorithm = sr.base[15]; + if (algorithm == DST_ALG_RSAMD5 && sr.length < 19) + return (ISC_R_UNEXPECTEDEND); + isc_buffer_forward(source, sr.length); return (mem_tobuffer(target, sr.base, sr.length)); } diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c index 27d15b93..afc588c6 100644 --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -1132,6 +1132,10 @@ log_edns(fetchctx_t *fctx) { if (fctx->reason == NULL) return; + /* + * We do not know if fctx->domain is the actual domain the record + * lives in or a parent domain so we have a '?' after it. + */ dns_name_format(&fctx->domain, domainbuf, sizeof(domainbuf)); isc_log_write(dns_lctx, DNS_LOGCATEGORY_EDNS_DISABLED, DNS_LOGMODULE_RESOLVER, ISC_LOG_INFO, diff --git a/lib/dns/update.c b/lib/dns/update.c index 14ffcc22..713fa87f 100644 --- a/lib/dns/update.c +++ b/lib/dns/update.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011, 2012 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2011-2013 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 @@ -1211,7 +1211,9 @@ del_keysigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, for (i = 0; i < nkeys; i++) { if (rrsig.keyid == dst_key_id(keys[i])) { found = ISC_TRUE; - if (!dst_key_isprivate(keys[i])) { + if (!dst_key_isprivate(keys[i]) && + !dst_key_inactive(keys[i])) + { /* * The re-signing code in zone.c * will mark this as offline. diff --git a/lib/dns/win32/libdns.def b/lib/dns/win32/libdns.def index 46327635..7661f807 100644 --- a/lib/dns/win32/libdns.def +++ b/lib/dns/win32/libdns.def @@ -677,6 +677,7 @@ dns_secalg_fromtext dns_secalg_totext dns_secproto_fromtext dns_secproto_totext +dns_soa_buildrdata dns_soa_getminimum dns_soa_getserial dns_soa_setserial @@ -1006,6 +1007,7 @@ dst_key_getprivateformat dst_key_gettime dst_key_getttl dst_key_id +dst_key_inactive dst_key_isnullkey dst_key_isprivate dst_key_iszonekey @@ -1018,6 +1020,7 @@ dst_key_rid dst_key_secretsize dst_key_setbits dst_key_setflags +dst_key_setinactive dst_key_setprivateformat dst_key_settime dst_key_setttl diff --git a/lib/dns/xfrin.c b/lib/dns/xfrin.c index 813f616e..9ad8960a 100644 --- a/lib/dns/xfrin.c +++ b/lib/dns/xfrin.c @@ -270,13 +270,18 @@ axfr_init(dns_xfrin_ctx_t *xfr) { static isc_result_t axfr_makedb(dns_xfrin_ctx_t *xfr, dns_db_t **dbp) { - return (dns_db_create(xfr->mctx, /* XXX */ - "rbt", /* XXX guess */ - &xfr->name, - dns_dbtype_zone, - xfr->rdclass, - 0, NULL, /* XXX guess */ - dbp)); + isc_result_t result; + + result = dns_db_create(xfr->mctx, /* XXX */ + "rbt", /* XXX guess */ + &xfr->name, + dns_dbtype_zone, + xfr->rdclass, + 0, NULL, /* XXX guess */ + dbp); + if (result == ISC_R_SUCCESS) + result = dns_zone_rpz_enable_db(xfr->zone, *dbp); + return (result); } static isc_result_t diff --git a/lib/dns/zone.c b/lib/dns/zone.c index 6e9f49af..3bdbc3e0 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -729,8 +729,6 @@ static isc_result_t delete_nsec(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node, dns_name_t *name, dns_diff_t *diff); static void zone_rekey(dns_zone_t *zone); -static isc_boolean_t delsig_ok(dns_rdata_rrsig_t *rrsig_ptr, - dst_key_t **keys, unsigned int nkeys); static isc_result_t zone_send_securedb(dns_zone_t *zone, isc_boolean_t locked, dns_db_t *db); @@ -1534,6 +1532,18 @@ dns_zone_get_rpz(dns_zone_t *zone) { return (zone->is_rpz); } +/* + * If a zone is a response policy zone, mark its new database. + */ +isc_result_t +dns_zone_rpz_enable_db(dns_zone_t *zone, dns_db_t *db) { +#ifdef BIND9 + if (zone->is_rpz) + return (dns_db_rpz_enabled(db, NULL)); +#endif + return (ISC_R_SUCCESS); +} + static isc_result_t zone_load(dns_zone_t *zone, unsigned int flags) { isc_result_t result; @@ -1987,14 +1997,9 @@ zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime) { isc_result_t tresult; unsigned int options; -#ifdef BIND9 - if (zone->is_rpz) { - result = dns_db_rpz_enabled(db, NULL); - if (result != ISC_R_SUCCESS) - return (result); - } -#endif - + result = dns_zone_rpz_enable_db(zone, db); + if (result != ISC_R_SUCCESS) + return (result); options = get_master_options(zone); if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MANYERRORS)) options |= DNS_MASTER_MANYERRORS; @@ -5271,19 +5276,39 @@ set_key_expiry_warning(dns_zone_t *zone, isc_stdtime_t when, isc_stdtime_t now) * have no new key. */ static isc_boolean_t -delsig_ok(dns_rdata_rrsig_t *rrsig_ptr, dst_key_t **keys, unsigned int nkeys) { +delsig_ok(dns_rdata_rrsig_t *rrsig_ptr, dst_key_t **keys, unsigned int nkeys, + isc_boolean_t *warn) +{ unsigned int i = 0; + isc_boolean_t have_ksk = ISC_FALSE, have_zsk = ISC_FALSE; + isc_boolean_t have_pksk = ISC_FALSE, have_pzsk = ISC_FALSE; - /* - * It's okay to delete a signature if there is an active ZSK - * with the same algorithm - */ for (i = 0; i < nkeys; i++) { - if (rrsig_ptr->algorithm == dst_key_alg(keys[i]) && - (dst_key_isprivate(keys[i])) && !KSK(keys[i])) - return (ISC_TRUE); + if (rrsig_ptr->algorithm != dst_key_alg(keys[i])) + continue; + if (dst_key_isprivate(keys[i])) { + if (KSK(keys[i])) + have_ksk = have_pksk = ISC_TRUE; + else + have_zsk = have_pzsk = ISC_TRUE; + } else { + if (KSK(keys[i])) + have_ksk = ISC_TRUE; + else + have_zsk = ISC_TRUE; + } } + if (have_zsk && have_ksk && !have_pzsk) + *warn = ISC_TRUE; + + /* + * It's okay to delete a signature if there is an active key + * with the same algorithm to replace it. + */ + if (have_pksk || have_pzsk) + return (ISC_TRUE); + /* * Failing that, it is *not* okay to delete a signature * if the associated public key is still in the DNSKEY RRset @@ -5351,7 +5376,8 @@ del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, RUNTIME_CHECK(result == ISC_R_SUCCESS); if (type != dns_rdatatype_dnskey) { - if (delsig_ok(&rrsig, keys, nkeys)) { + isc_boolean_t warn = ISC_FALSE, deleted = ISC_FALSE; + if (delsig_ok(&rrsig, keys, nkeys, &warn)) { result = update_one_rr(db, ver, zonediff->diff, DNS_DIFFOP_DELRESIGN, name, rdataset.ttl, &rdata); @@ -5359,7 +5385,9 @@ del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, changed = ISC_TRUE; if (result != ISC_R_SUCCESS) break; - } else { + deleted = ISC_TRUE; + } + if (warn) { /* * At this point, we've got an RRSIG, * which is signed by an inactive key. @@ -5369,7 +5397,7 @@ del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, * offline will prevent us spinning waiting * for the private part. */ - if (incremental) { + if (incremental && !deleted) { result = offline(db, ver, zonediff, name, rdataset.ttl, &rdata); @@ -5417,7 +5445,9 @@ del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, * We want the earliest offline expire time * iff there is a new offline signature. */ - if (!dst_key_isprivate(keys[i])) { + if (!dst_key_inactive(keys[i]) && + !dst_key_isprivate(keys[i])) + { isc_int64_t timeexpire = dns_time64_from32(rrsig.timeexpire); if (warn != 0 && warn > timeexpire) diff --git a/lib/isccfg/api b/lib/isccfg/api index 864bdc90..a27437f4 100644 --- a/lib/isccfg/api +++ b/lib/isccfg/api @@ -5,5 +5,5 @@ # 9.9: 90-109 # 9.9-sub: 130-139 LIBINTERFACE = 90 -LIBREVISION = 6 +LIBREVISION = 7 LIBAGE = 0 diff --git a/lib/isccfg/namedconf.c b/lib/isccfg/namedconf.c index 15fd5549..be28ea71 100644 --- a/lib/isccfg/namedconf.c +++ b/lib/isccfg/namedconf.c @@ -1434,7 +1434,6 @@ view_clauses[] = { { "queryport-pool-updateinterval", &cfg_type_uint32, CFG_CLAUSEFLAG_OBSOLETE }, { "recursion", &cfg_type_boolean, 0 }, - { "request-ixfr", &cfg_type_boolean, 0 }, { "request-nsid", &cfg_type_boolean, 0 }, { "resolver-query-timeout", &cfg_type_uint32, 0 }, { "rfc2308-type1", &cfg_type_boolean, CFG_CLAUSEFLAG_NYI }, |