--- bind-9.3.6-P1/bin/named/query.c.rh538744 2009-11-19 15:01:05.922165541 +0100 +++ bind-9.3.6-P1/bin/named/query.c 2009-11-19 15:02:31.422164887 +0100 @@ -92,6 +92,8 @@ #define DNS_GETDB_NOLOG 0x02U #define DNS_GETDB_PARTIAL 0x04U +#define PENDINGOK(x) (((x) & DNS_DBFIND_PENDINGOK) != 0) + static void query_find(ns_client_t *client, dns_fetchevent_t *event, dns_rdatatype_t qtype); @@ -1698,14 +1700,14 @@ query_addbestns(ns_client_t *client) { zsigrdataset = NULL; } - if ((client->query.dboptions & DNS_DBFIND_PENDINGOK) == 0 && - (rdataset->trust == dns_trust_pending || - (sigrdataset != NULL && sigrdataset->trust == dns_trust_pending))) + if (!PENDINGOK(client->query.dboptions) && + (DNS_TRUST_PENDING(rdataset->trust) || + (sigrdataset != NULL && DNS_TRUST_PENDING(sigrdataset->trust)))) goto cleanup; if (WANTDNSSEC(client) && SECURE(client) && - (rdataset->trust == dns_trust_glue || - (sigrdataset != NULL && sigrdataset->trust == dns_trust_glue))) + (DNS_TRUST_GLUE(rdataset->trust) || + (sigrdataset != NULL && DNS_TRUST_GLUE(sigrdataset->trust)))) goto cleanup; query_addrrset(client, &fname, &rdataset, &sigrdataset, dbuf, --- bind-9.3.6-P1/lib/dns/include/dns/types.h.rh538744 2009-11-19 15:01:05.942166028 +0100 +++ bind-9.3.6-P1/lib/dns/include/dns/types.h 2009-11-19 15:01:05.952166608 +0100 @@ -230,40 +230,52 @@ enum { dns_trust_none = 0, #define dns_trust_none ((dns_trust_t)dns_trust_none) + /* + * Subject to DNSSEC validation but has not yet been validated + * (from the additional section). + */ + dns_trust_pending_additional = 1, +#define dns_trust_pending_additional \ + ((dns_trust_t)dns_trust_pending_additional) + /* Subject to DNSSEC validation but has not yet been validated */ - dns_trust_pending = 1, -#define dns_trust_pending ((dns_trust_t)dns_trust_pending) + dns_trust_pending_answer = 2, +#define dns_trust_pending ((dns_trust_t)dns_trust_pending_answer) /* Received in the additional section of a response. */ - dns_trust_additional = 2, + dns_trust_additional = 3, #define dns_trust_additional ((dns_trust_t)dns_trust_additional) /* Received in a referral response. */ - dns_trust_glue = 3, + dns_trust_glue = 4, #define dns_trust_glue ((dns_trust_t)dns_trust_glue) /* Answser from a non-authoritative server */ - dns_trust_answer = 4, + dns_trust_answer = 5, #define dns_trust_answer ((dns_trust_t)dns_trust_answer) /* Received in the authority section as part of an authoritative response */ - dns_trust_authauthority = 5, + dns_trust_authauthority = 6, #define dns_trust_authauthority ((dns_trust_t)dns_trust_authauthority) /* Answser from an authoritative server */ - dns_trust_authanswer = 6, + dns_trust_authanswer = 7, #define dns_trust_authanswer ((dns_trust_t)dns_trust_authanswer) /* Successfully DNSSEC validated */ - dns_trust_secure = 7, + dns_trust_secure = 8, #define dns_trust_secure ((dns_trust_t)dns_trust_secure) /* This server is authoritative */ - dns_trust_ultimate = 8 + dns_trust_ultimate = 9 #define dns_trust_ultimate ((dns_trust_t)dns_trust_ultimate) }; +#define DNS_TRUST_PENDING(x) ((x) == dns_trust_pending_answer || \ + (x) == dns_trust_pending_additional) +#define DNS_TRUST_GLUE(x) ((x) == dns_trust_glue) + /* * Name checking severites. */ --- bind-9.3.6-P1/lib/dns/masterdump.c.rh538744 2008-08-14 01:45:33.000000000 +0200 +++ bind-9.3.6-P1/lib/dns/masterdump.c 2009-11-19 15:01:05.952166608 +0100 @@ -763,7 +763,8 @@ dump_order_compare(const void *a, const static const char *trustnames[] = { "none", - "pending", + "pending-additional", + "pending-answer", "additional", "glue", "answer", --- bind-9.3.6-P1/lib/dns/rbtdb.c.rh538744 2008-01-25 00:45:27.000000000 +0100 +++ bind-9.3.6-P1/lib/dns/rbtdb.c 2009-11-19 15:01:05.952166608 +0100 @@ -2667,7 +2667,7 @@ cache_zonecut_callback(dns_rbtnode_t *no } if (dname_header != NULL && - (dname_header->trust != dns_trust_pending || + (!DNS_TRUST_PENDING(dname_header->trust) || (search->options & DNS_DBFIND_PENDINGOK) != 0)) { /* * We increment the reference count on node to ensure that @@ -3129,7 +3129,7 @@ cache_find(dns_db_t *db, dns_name_t *nam if (found == NULL || (found->trust == dns_trust_glue && ((options & DNS_DBFIND_GLUEOK) == 0)) || - (found->trust == dns_trust_pending && + (DNS_TRUST_PENDING(found->trust) && ((options & DNS_DBFIND_PENDINGOK) == 0))) { /* * If there is an NS rdataset at this node, then this is the diff -u bind-9.3.6-P1/lib/dns/resolver.c bind-9.3.6-P1/lib/dns/resolver.c --- bind-9.3.6-P1/lib/dns/resolver.c 2009-11-19 15:01:05.952166608 +0100 +++ bind-9.3.6-P1/lib/dns/resolver.c 2010-01-18 15:34:58.835888666 +0100 @@ -3690,10 +3690,19 @@ rdataset->ttl = res->view->maxcachettl; /* - * If this rrset is in a secure domain, do DNSSEC validation - * for it, unless it is glue. + * If this RRset is in a secure domain, is in bailiwick, + * and is not glue, attempt DNSSEC validation. (We do not + * attempt to validate glue or out-of-bailiwick data--even + * though there might be some performance benefit to doing + * so--because it makes it simpler and safer to ensure that + * records from a secure domain are only cached if validated + * within the context of a query to the domain that owns + * them.) */ - if (secure_domain && rdataset->trust != dns_trust_glue) { + if (secure_domain && rdataset->trust != dns_trust_glue && + !EXTERNAL(rdataset)) { + dns_trust_t trust; + /* * RRSIGs are validated as part of validating the * type they cover. @@ -3731,11 +3740,17 @@ /* * Cache this rdataset/sigrdataset pair as - * pending data. + * pending data. Track whether it was additional + * or not. */ - rdataset->trust = dns_trust_pending; + if (rdataset->trust == dns_trust_additional) + trust = dns_trust_pending_additional; + else + trust = dns_trust_pending_answer; + + rdataset->trust = trust; if (sigrdataset != NULL) - sigrdataset->trust = dns_trust_pending; + sigrdataset->trust = trust; if (!need_validation) addedrdataset = ardataset; else @@ -4081,7 +4096,7 @@ for (trdataset = ISC_LIST_HEAD(tname->list); trdataset != NULL; trdataset = ISC_LIST_NEXT(trdataset, link)) - trdataset->trust = dns_trust_pending; + trdataset->trust = dns_trust_pending_answer; result = dns_message_nextname(fctx->rmessage, DNS_SECTION_AUTHORITY); } @@ -4826,9 +4841,7 @@ /* * This data is outside of * our query domain, and - * may only be cached if it - * comes from a secure zone - * and validates. + * may not be cached. */ rdataset->attributes |= DNS_RDATASETATTR_EXTERNAL; --- bind-9.3.6-P1/lib/dns/validator.c.rh538744 2008-08-21 06:59:16.000000000 +0200 +++ bind-9.3.6-P1/lib/dns/validator.c 2009-11-19 15:01:06.142166214 +0100 @@ -1023,8 +1053,11 @@ create_fetch(dns_validator_t *val, dns_n if (dns_rdataset_isassociated(&val->fsigrdataset)) dns_rdataset_disassociate(&val->fsigrdataset); - if (check_deadlock(val, name, type)) + if (check_deadlock(val, name, type)) { + validator_log(val, ISC_LOG_DEBUG(3), + "deadlock found (create_fetch)"); return (DNS_R_NOVALIDSIG); + } validator_logcreate(val, name, type, caller, "fetch"); return (dns_resolver_createfetch(val->view->resolver, name, type, @@ -1046,8 +1079,11 @@ create_validator(dns_validator_t *val, d { isc_result_t result; - if (check_deadlock(val, name, type)) + if (check_deadlock(val, name, type)) { + validator_log(val, ISC_LOG_DEBUG(3), + "deadlock found (create_validator)"); return (DNS_R_NOVALIDSIG); + } validator_logcreate(val, name, type, caller, "validator"); result = dns_validator_create(val->view, name, type, @@ -1176,7 +1212,7 @@ get_key(dns_validator_t *val, dns_rdata_ * We have an rrset for the given keyname. */ val->keyset = &val->frdataset; - if (val->frdataset.trust == dns_trust_pending && + if (DNS_TRUST_PENDING(val->frdataset.trust) && dns_rdataset_isassociated(&val->fsigrdataset)) { /* @@ -1191,7 +1227,7 @@ get_key(dns_validator_t *val, dns_rdata_ if (result != ISC_R_SUCCESS) return (result); return (DNS_R_WAIT); - } else if (val->frdataset.trust == dns_trust_pending) { + } else if (DNS_TRUST_PENDING(val->frdataset.trust)) { /* * Having a pending key with no signature means that * something is broken. @@ -1729,10 +1765,15 @@ validatezonekey(dns_validator_t *val) { * give up, since there's no DS at the root. */ if (dns_name_equal(event->name, dns_rootname)) { - if ((val->attributes & VALATTR_TRIEDVERIFY) != 0) + if ((val->attributes & VALATTR_TRIEDVERIFY) != 0) { + validator_log(val, ISC_LOG_DEBUG(3), + "root key failed to validate"); return (DNS_R_NOVALIDSIG); - else + } else { + validator_log(val, ISC_LOG_DEBUG(3), + "no trusted root key"); return (DNS_R_NOVALIDDS); + } } if (atsep) { @@ -1760,7 +1801,7 @@ validatezonekey(dns_validator_t *val) { * We have DS records. */ val->dsset = &val->frdataset; - if (val->frdataset.trust == dns_trust_pending && + if (DNS_TRUST_PENDING(val->frdataset.trust) && dns_rdataset_isassociated(&val->fsigrdataset)) { result = create_validator(val, @@ -1773,7 +1814,7 @@ validatezonekey(dns_validator_t *val) { if (result != ISC_R_SUCCESS) return (result); return (DNS_R_WAIT); - } else if (val->frdataset.trust == dns_trust_pending) { + } else if (DNS_TRUST_PENDING(val->frdataset.trust)) { /* * There should never be an unsigned DS. */ @@ -1934,8 +1975,11 @@ validatezonekey(dns_validator_t *val) { "no supported algorithm/digest (DS)"); markanswer(val); return (ISC_R_SUCCESS); - } else + } else { + validator_log(val, ISC_LOG_INFO, + "no valid signature found (DS)"); return (DNS_R_NOVALIDSIG); + } } /*% @@ -2408,8 +2476,11 @@ finddlvsep(dns_validator_t *val, isc_boo namebuf); result = view_find(val, dlvname, dns_rdatatype_dlv); if (result == ISC_R_SUCCESS) { - if (val->frdataset.trust < dns_trust_secure) + if (val->frdataset.trust < dns_trust_secure) { + validator_log(val, ISC_LOG_DEBUG(3), + "DLV not validated"); return (DNS_R_NOVALIDSIG); + } val->havedlvsep = ISC_TRUE; dns_rdataset_clone(&val->frdataset, &val->dlv); return (ISC_R_SUCCESS); @@ -2523,7 +2594,8 @@ proveunsecure(dns_validator_t *val, isc_ if ((val->view->dlv == NULL || DLVTRIED(val)) && val->mustbesecure) { validator_log(val, ISC_LOG_WARNING, - "must be secure failure at '%s'", + "must be secure failure at '%s', " + "can't fall back to DLV", namebuf); result = DNS_R_MUSTBESECURE; goto out; @@ -2568,7 +2640,7 @@ proveunsecure(dns_validator_t *val, isc_ * There is no DS. If this is a delegation, * we maybe done. */ - if (val->frdataset.trust == dns_trust_pending) { + if (DNS_TRUST_PENDING(val->frdataset.trust)) { result = create_fetch(val, tname, dns_rdatatype_ds, dsfetched2, @@ -2584,6 +2656,9 @@ proveunsecure(dns_validator_t *val, isc_ * there's no way of validating existing * negative response blobs, give up. */ + validator_log(val, ISC_LOG_WARNING, + "can't validate existing " + "negative responses (no DS)"); result = DNS_R_NOVALIDSIG; goto out; } @@ -2630,6 +2705,8 @@ proveunsecure(dns_validator_t *val, isc_ } else if (!dns_rdataset_isassociated(&val->fsigrdataset)) { + validator_log(val, ISC_LOG_DEBUG(3), + "DS is unsigned"); result = DNS_R_NOVALIDSIG; goto out; } @@ -2661,6 +2738,10 @@ proveunsecure(dns_validator_t *val, isc_ * there's no way of validating existing * negative response blobs, give up. */ + validator_log(val, ISC_LOG_WARNING, + "can't validate existing " + "negative responses " + "(not a zone cut)"); result = DNS_R_NOVALIDSIG; goto out; }