diff options
Diffstat (limited to 'contrib/bind9/lib/dns/validator.c')
-rw-r--r-- | contrib/bind9/lib/dns/validator.c | 110 |
1 files changed, 68 insertions, 42 deletions
diff --git a/contrib/bind9/lib/dns/validator.c b/contrib/bind9/lib/dns/validator.c index 9538b302..e686336 100644 --- a/contrib/bind9/lib/dns/validator.c +++ b/contrib/bind9/lib/dns/validator.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: validator.c,v 1.119.18.35 2007/09/26 04:39:45 each Exp $ */ +/* $Id: validator.c,v 1.119.18.41 2008/08/21 04:59:42 marka Exp $ */ /*! \file */ @@ -55,7 +55,7 @@ * dlv_validator_start -> validator_start -> validate -> proveunsecure * * validator_start -> validate -> nsecvalidate (secure wildcard answer) - * + * * \li When called with rdataset, sigrdataset and with DNS_VALIDATOR_DLV: * validator_start -> startfinddlvsep -> dlv_validator_start -> * validator_start -> validate -> proveunsecure @@ -134,7 +134,8 @@ static isc_result_t nsecvalidate(dns_validator_t *val, isc_boolean_t resume); static isc_result_t -proveunsecure(dns_validator_t *val, isc_boolean_t resume); +proveunsecure(dns_validator_t *val, isc_boolean_t have_ds, + isc_boolean_t resume); static void validator_logv(dns_validator_t *val, isc_logcategory_t *category, @@ -365,7 +366,7 @@ dsfetched(isc_task_t *task, isc_event_t *event) { "falling back to insecurity proof (%s)", dns_result_totext(eresult)); val->attributes |= VALATTR_INSECURITY; - result = proveunsecure(val, ISC_FALSE); + result = proveunsecure(val, ISC_FALSE, ISC_FALSE); if (result != DNS_R_WAIT) validator_done(val, result); } else { @@ -444,7 +445,7 @@ dsfetched2(isc_task_t *task, isc_event_t *event) { validator_done(val, result); } } else { - result = proveunsecure(val, ISC_TRUE); + result = proveunsecure(val, ISC_FALSE, ISC_TRUE); if (result != DNS_R_WAIT) validator_done(val, result); } @@ -453,11 +454,12 @@ dsfetched2(isc_task_t *task, isc_event_t *event) { eresult == DNS_R_NCACHENXDOMAIN) { /* - * There is a DS which may or may not be a zone cut. + * There is a DS which may or may not be a zone cut. * In either case we are still in a secure zone resume * validation. */ - result = proveunsecure(val, ISC_TRUE); + result = proveunsecure(val, ISC_TF(eresult == ISC_R_SUCCESS), + ISC_TRUE); if (result != DNS_R_WAIT) validator_done(val, result); } else { @@ -558,7 +560,7 @@ dsvalidated(isc_task_t *task, isc_event_t *event) { validator_log(val, ISC_LOG_DEBUG(3), "dsset with trust %d", val->frdataset.trust); if ((val->attributes & VALATTR_INSECURITY) != 0) - result = proveunsecure(val, ISC_TRUE); + result = proveunsecure(val, ISC_TRUE, ISC_TRUE); else result = validatezonekey(val); if (result != DNS_R_WAIT) @@ -779,7 +781,7 @@ authvalidated(isc_task_t *task, isc_event_t *event) { } else { dns_name_t **proofs = val->event->proofs; dns_name_t *wild = dns_fixedname_name(&val->wild); - + if (rdataset->trust == dns_trust_secure) val->seensig = ISC_TRUE; @@ -787,7 +789,7 @@ authvalidated(isc_task_t *task, isc_event_t *event) { rdataset->trust == dns_trust_secure && ((val->attributes & VALATTR_NEEDNODATA) != 0 || (val->attributes & VALATTR_NEEDNOQNAME) != 0) && - (val->attributes & VALATTR_FOUNDNODATA) == 0 && + (val->attributes & VALATTR_FOUNDNODATA) == 0 && (val->attributes & VALATTR_FOUNDNOQNAME) == 0 && nsecnoexistnodata(val, val->event->name, devent->name, rdataset, &exists, &data, wild) @@ -900,7 +902,7 @@ view_find(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type) { /* End of zone chain. */ if (!dns_name_issubdomain(name, &nsec.next)) { /* - * XXXMPA We could look for a parent NSEC + * XXXMPA We could look for a parent NSEC * at nsec.next and if found retest with * this NSEC. */ @@ -937,10 +939,11 @@ view_find(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type) { dns_rdata_freestruct(&nsec); result = DNS_R_NCACHENXDOMAIN; } else if (result != ISC_R_SUCCESS && - result != DNS_R_NCACHENXDOMAIN && - result != DNS_R_NCACHENXRRSET && - result != DNS_R_NXRRSET && - result != ISC_R_NOTFOUND) { + result != DNS_R_NCACHENXDOMAIN && + result != DNS_R_NCACHENXRRSET && + result != DNS_R_EMPTYNAME && + result != DNS_R_NXRRSET && + result != ISC_R_NOTFOUND) { goto notfound; } return (result); @@ -1196,6 +1199,7 @@ get_key(dns_validator_t *val, dns_rdata_rrsig_t *siginfo) { return (DNS_R_WAIT); } else if (result == DNS_R_NCACHENXDOMAIN || result == DNS_R_NCACHENXRRSET || + result == DNS_R_EMPTYNAME || result == DNS_R_NXDOMAIN || result == DNS_R_NXRRSET) { @@ -1246,7 +1250,8 @@ isselfsigned(dns_validator_t *val) { { dns_rdata_reset(&rdata); dns_rdataset_current(rdataset, &rdata); - (void)dns_rdata_tostruct(&rdata, &key, NULL); + result = dns_rdata_tostruct(&rdata, &key, NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); keytag = compute_keytag(&rdata, &key); for (result = dns_rdataset_first(sigrdataset); result == ISC_R_SUCCESS; @@ -1254,7 +1259,8 @@ isselfsigned(dns_validator_t *val) { { dns_rdata_reset(&sigrdata); dns_rdataset_current(sigrdataset, &sigrdata); - (void)dns_rdata_tostruct(&sigrdata, &sig, NULL); + result = dns_rdata_tostruct(&sigrdata, &sig, NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); if (sig.algorithm == key.algorithm && sig.keyid == keytag) @@ -1514,7 +1520,8 @@ dlv_validatezonekey(dns_validator_t *val) { result = dns_rdataset_next(&val->dlv)) { dns_rdata_reset(&dlvrdata); dns_rdataset_current(&val->dlv, &dlvrdata); - dns_rdata_tostruct(&dlvrdata, &dlv, NULL); + result = dns_rdata_tostruct(&dlvrdata, &dlv, NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); if (!dns_resolver_algorithm_supported(val->view->resolver, val->event->name, @@ -1534,12 +1541,13 @@ dlv_validatezonekey(dns_validator_t *val) { { dns_rdata_reset(&dlvrdata); dns_rdataset_current(&val->dlv, &dlvrdata); - (void)dns_rdata_tostruct(&dlvrdata, &dlv, NULL); + result = dns_rdata_tostruct(&dlvrdata, &dlv, NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); if (!dns_resolver_digest_supported(val->view->resolver, dlv.digest_type)) continue; - + if (dlv.digest_type != digest_type) continue; @@ -1559,7 +1567,8 @@ dlv_validatezonekey(dns_validator_t *val) { { dns_rdata_reset(&keyrdata); dns_rdataset_current(&trdataset, &keyrdata); - (void)dns_rdata_tostruct(&keyrdata, &key, NULL); + result = dns_rdata_tostruct(&keyrdata, &key, NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); keytag = compute_keytag(&keyrdata, &key); if (dlv.key_tag != keytag || dlv.algorithm != key.algorithm) @@ -1594,7 +1603,8 @@ dlv_validatezonekey(dns_validator_t *val) { dns_rdata_reset(&sigrdata); dns_rdataset_current(val->event->sigrdataset, &sigrdata); - (void)dns_rdata_tostruct(&sigrdata, &sig, NULL); + result = dns_rdata_tostruct(&sigrdata, &sig, NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); if (dlv.key_tag != sig.keyid && dlv.algorithm != sig.algorithm) continue; @@ -1691,7 +1701,8 @@ validatezonekey(dns_validator_t *val) { dns_rdata_reset(&sigrdata); dns_rdataset_current(val->event->sigrdataset, &sigrdata); - (void)dns_rdata_tostruct(&sigrdata, &sig, NULL); + result = dns_rdata_tostruct(&sigrdata, &sig, NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); result = dns_keytable_findkeynode(val->keytable, val->event->name, sig.algorithm, @@ -1745,7 +1756,7 @@ validatezonekey(dns_validator_t *val) { * the RRset is invalid. */ dns_name_format(val->event->name, namebuf, - sizeof(namebuf)); + sizeof(namebuf)); validator_log(val, ISC_LOG_DEBUG(2), "unable to find a DNSKEY which verifies " "the DNSKEY RRset and also matches one " @@ -1796,8 +1807,9 @@ validatezonekey(dns_validator_t *val) { if (result != ISC_R_SUCCESS) return (result); return (DNS_R_WAIT); - } else if (result == DNS_R_NCACHENXDOMAIN || + } else if (result == DNS_R_NCACHENXDOMAIN || result == DNS_R_NCACHENXRRSET || + result == DNS_R_EMPTYNAME || result == DNS_R_NXDOMAIN || result == DNS_R_NXRRSET) { @@ -1848,7 +1860,8 @@ validatezonekey(dns_validator_t *val) { result = dns_rdataset_next(val->dsset)) { dns_rdata_reset(&dsrdata); dns_rdataset_current(val->dsset, &dsrdata); - dns_rdata_tostruct(&dsrdata, &ds, NULL); + result = dns_rdata_tostruct(&dsrdata, &ds, NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); if (!dns_resolver_algorithm_supported(val->view->resolver, val->event->name, @@ -1868,7 +1881,8 @@ validatezonekey(dns_validator_t *val) { { dns_rdata_reset(&dsrdata); dns_rdataset_current(val->dsset, &dsrdata); - (void)dns_rdata_tostruct(&dsrdata, &ds, NULL); + result = dns_rdata_tostruct(&dsrdata, &ds, NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); if (!dns_resolver_digest_supported(val->view->resolver, ds.digest_type)) @@ -1896,7 +1910,8 @@ validatezonekey(dns_validator_t *val) { { dns_rdata_reset(&keyrdata); dns_rdataset_current(&trdataset, &keyrdata); - (void)dns_rdata_tostruct(&keyrdata, &key, NULL); + result = dns_rdata_tostruct(&keyrdata, &key, NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); keytag = compute_keytag(&keyrdata, &key); if (ds.key_tag != keytag || ds.algorithm != key.algorithm) @@ -1915,7 +1930,7 @@ validatezonekey(dns_validator_t *val) { "no DNSKEY matching DS"); continue; } - + for (result = dns_rdataset_first(val->event->sigrdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(val->event->sigrdataset)) @@ -1923,7 +1938,8 @@ validatezonekey(dns_validator_t *val) { dns_rdata_reset(&sigrdata); dns_rdataset_current(val->event->sigrdataset, &sigrdata); - (void)dns_rdata_tostruct(&sigrdata, &sig, NULL); + result = dns_rdata_tostruct(&sigrdata, &sig, NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); if (ds.key_tag != sig.keyid || ds.algorithm != sig.algorithm) continue; @@ -1994,7 +2010,7 @@ start_positive_validation(dns_validator_t *val) { * exclusive we stop when one is found. * * Returns - * \li ISC_R_SUCCESS + * \li ISC_R_SUCCESS */ static isc_result_t checkwildcard(dns_validator_t *val) { @@ -2213,7 +2229,7 @@ nsecvalidate(dns_validator_t *val, isc_boolean_t resume) { validator_log(val, ISC_LOG_DEBUG(3), "nonexistence proof(s) not found"); val->attributes |= VALATTR_INSECURITY; - return (proveunsecure(val, ISC_FALSE)); + return (proveunsecure(val, ISC_FALSE, ISC_FALSE)); } static isc_boolean_t @@ -2226,7 +2242,8 @@ check_ds(dns_validator_t *val, dns_name_t *name, dns_rdataset_t *rdataset) { result == ISC_R_SUCCESS; result = dns_rdataset_next(rdataset)) { dns_rdataset_current(rdataset, &dsrdata); - (void)dns_rdata_tostruct(&dsrdata, &ds, NULL); + result = dns_rdata_tostruct(&dsrdata, &ds, NULL); + RUNTIME_CHECK(result == ISC_R_SUCCESS); if (dns_resolver_digest_supported(val->view->resolver, ds.digest_type) && @@ -2242,7 +2259,7 @@ check_ds(dns_validator_t *val, dns_name_t *name, dns_rdataset_t *rdataset) { /*% * Callback from fetching a DLV record. - * + * * Resumes the DLV lookup process. */ static void @@ -2316,7 +2333,7 @@ dlvfetched(isc_task_t *task, isc_event_t *event) { /*% * Start the DLV lookup proccess. - * + * * Returns * \li ISC_R_SUCCESS * \li DNS_R_WAIT @@ -2450,6 +2467,7 @@ finddlvsep(dns_validator_t *val, isc_boolean_t resume) { } if (result != DNS_R_NXRRSET && result != DNS_R_NXDOMAIN && + result != DNS_R_EMPTYNAME && result != DNS_R_NCACHENXRRSET && result != DNS_R_NCACHENXDOMAIN) return (result); @@ -2486,7 +2504,8 @@ finddlvsep(dns_validator_t *val, isc_boolean_t resume) { * \li DNS_R_NOTINSECURE */ static isc_result_t -proveunsecure(dns_validator_t *val, isc_boolean_t resume) { +proveunsecure(dns_validator_t *val, isc_boolean_t have_ds, isc_boolean_t resume) +{ isc_result_t result; dns_fixedname_t fixedsecroot; dns_name_t *secroot; @@ -2508,7 +2527,7 @@ proveunsecure(dns_validator_t *val, isc_boolean_t resume) { dns_name_split(secroot, 1, NULL, secroot); result = dns_keytable_finddeepestmatch(val->keytable, secroot, secroot); - + if (result == ISC_R_NOTFOUND) { validator_log(val, ISC_LOG_DEBUG(3), "not beneath secure root"); @@ -2534,12 +2553,19 @@ proveunsecure(dns_validator_t *val, isc_boolean_t resume) { val->labels = dns_name_countlabels(secroot) + 1; } else { validator_log(val, ISC_LOG_DEBUG(3), "resuming proveunsecure"); - if (val->frdataset.trust >= dns_trust_secure && + /* + * If we have a DS rdataset and it is secure then check if + * the DS rdataset has a supported algorithm combination. + * If not this is a insecure delegation as far as this + * resolver is concerned. Fall back to DLV if available. + */ + if (have_ds && val->frdataset.trust >= dns_trust_secure && !check_ds(val, dns_fixedname_name(&val->fname), &val->frdataset)) { dns_name_format(dns_fixedname_name(&val->fname), namebuf, sizeof(namebuf)); - if (val->mustbesecure) { + if ((val->view->dlv == NULL || DLVTRIED(val)) && + val->mustbesecure) { validator_log(val, ISC_LOG_WARNING, "must be secure failure at '%s'", namebuf); @@ -2784,7 +2810,7 @@ validator_start(isc_task_t *task, isc_event_t *event) { validator_log(val, ISC_LOG_DEBUG(3), "falling back to insecurity proof"); val->attributes |= VALATTR_INSECURITY; - result = proveunsecure(val, ISC_FALSE); + result = proveunsecure(val, ISC_FALSE, ISC_FALSE); if (result == DNS_R_NOTINSECURE) result = saved_result; } @@ -2798,7 +2824,7 @@ validator_start(isc_task_t *task, isc_event_t *event) { "attempting insecurity proof"); val->attributes |= VALATTR_INSECURITY; - result = proveunsecure(val, ISC_FALSE); + result = proveunsecure(val, ISC_FALSE, ISC_FALSE); } else if (val->event->rdataset == NULL && val->event->sigrdataset == NULL) { |