summaryrefslogtreecommitdiffstats
path: root/contrib/bind9/lib/dns/validator.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/bind9/lib/dns/validator.c')
-rw-r--r--contrib/bind9/lib/dns/validator.c110
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)
{
OpenPOWER on IntegriCloud