diff options
Diffstat (limited to 'lib/dns/validator.c')
-rw-r--r-- | lib/dns/validator.c | 57 |
1 files changed, 45 insertions, 12 deletions
diff --git a/lib/dns/validator.c b/lib/dns/validator.c index f3bd4d5b..4002181a 100644 --- a/lib/dns/validator.c +++ b/lib/dns/validator.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: validator.c,v 1.204 2011-06-08 22:13:51 each Exp $ */ +/* $Id: validator.c,v 1.207 2011-10-20 23:46:51 tbox Exp $ */ #include <config.h> @@ -846,7 +846,7 @@ cnamevalidated(isc_task_t *task, isc_event_t *event) { * Return ISC_R_IGNORE when the NSEC is not the appropriate one. */ static isc_result_t -nsecnoexistnodata(dns_validator_t *val, dns_name_t* name, dns_name_t *nsecname, +nsecnoexistnodata(dns_validator_t *val, dns_name_t *name, dns_name_t *nsecname, dns_rdataset_t *nsecset, isc_boolean_t *exists, isc_boolean_t *data, dns_name_t *wild) { @@ -887,9 +887,11 @@ nsecnoexistnodata(dns_validator_t *val, dns_name_t* name, dns_name_t *nsecname, if (order == 0) { /* - * The names are the same. + * The names are the same. If we are validating "." + * then atparent should not be set as there is no parent. */ - atparent = dns_rdatatype_atparent(val->event->type); + atparent = (olabels != 1) && + dns_rdatatype_atparent(val->event->type); ns = dns_nsec_typepresent(&rdata, dns_rdatatype_ns); soa = dns_nsec_typepresent(&rdata, dns_rdatatype_soa); if (ns && !soa) { @@ -1920,13 +1922,14 @@ verify(dns_validator_t *val, dst_key_t *key, dns_rdata_t *rdata, isc_result_t result; dns_fixedname_t fixed; isc_boolean_t ignore = ISC_FALSE; + dns_name_t *wild; val->attributes |= VALATTR_TRIEDVERIFY; dns_fixedname_init(&fixed); + wild = dns_fixedname_name(&fixed); again: result = dns_dnssec_verify2(val->event->name, val->event->rdataset, - key, ignore, val->view->mctx, rdata, - dns_fixedname_name(&fixed)); + key, ignore, val->view->mctx, rdata, wild); if (result == DNS_R_SIGEXPIRED && val->view->acceptexpired) { ignore = ISC_TRUE; goto again; @@ -1941,9 +1944,20 @@ verify(dns_validator_t *val, dst_key_t *key, dns_rdata_t *rdata, "verify rdataset (keyid=%u): %s", keyid, isc_result_totext(result)); if (result == DNS_R_FROMWILDCARD) { - if (!dns_name_equal(val->event->name, - dns_fixedname_name(&fixed))) + if (!dns_name_equal(val->event->name, wild)) { + dns_name_t *closest; + unsigned int labels; + + /* + * Compute the closest encloser in case we need it + * for the NSEC3 NOQNAME proof. + */ + closest = dns_fixedname_name(&val->closest); + dns_name_copy(wild, closest, NULL); + labels = dns_name_countlabels(closest) - 1; + dns_name_getlabelsequence(closest, 1, labels, closest); val->attributes |= VALATTR_NEEDNOQNAME; + } result = ISC_R_SUCCESS; } return (result); @@ -2871,9 +2885,9 @@ findnsec3proofs(dns_validator_t *val) { dns_name_t *name, tname; isc_result_t result; isc_boolean_t exists, data, optout, unknown; - isc_boolean_t setclosest, setnearest; + isc_boolean_t setclosest, setnearest, *setclosestp; dns_fixedname_t fclosest, fnearest, fzonename; - dns_name_t *closest, *nearest, *zonename; + dns_name_t *closest, *nearest, *zonename, *closestp; dns_name_t **proofs = val->event->proofs; dns_rdataset_t *rdataset, trdataset; @@ -2920,6 +2934,25 @@ findnsec3proofs(dns_validator_t *val) { if (dns_name_countlabels(zonename) == 0) return (ISC_R_SUCCESS); + /* + * If the val->closest is set then we want to use it otherwise + * we need to discover it. + */ + if (dns_name_countlabels(dns_fixedname_name(&val->closest)) != 0) { + char namebuf[DNS_NAME_FORMATSIZE]; + + dns_name_format(dns_fixedname_name(&val->closest), + namebuf, sizeof(namebuf)); + validator_log(val, ISC_LOG_DEBUG(3), "closest encloser from " + "wildcard signature '%s'", namebuf); + dns_name_copy(dns_fixedname_name(&val->closest), closest, NULL); + closestp = NULL; + setclosestp = NULL; + } else { + closestp = closest; + setclosestp = &setclosest; + } + for (result = val_rdataset_first(val, &name, &rdataset); result == ISC_R_SUCCESS; result = val_rdataset_next(val, &name, &rdataset)) @@ -2937,8 +2970,8 @@ findnsec3proofs(dns_validator_t *val) { unknown = ISC_FALSE; (void)nsec3noexistnodata(val, val->event->name, name, rdataset, zonename, &exists, &data, &optout, - &unknown, &setclosest, &setnearest, - closest, nearest); + &unknown, setclosestp, &setnearest, + closestp, nearest); if (setclosest) proofs[DNS_VALIDATOR_CLOSESTENCLOSER] = name; if (unknown) |