Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > media > main-src > by-pkgid > a0ef309aba3a78d3350b149f382e72aa > files > 68

bind-9.3.6-25.P1.el5_11.12.src.rpm

diff -up bind-9.3.6-P1/lib/dns/rbtdb.c.rh659266 bind-9.3.6-P1/lib/dns/rbtdb.c
--- bind-9.3.6-P1/lib/dns/rbtdb.c.rh659266	2010-12-02 16:20:04.000000000 +0100
+++ bind-9.3.6-P1/lib/dns/rbtdb.c	2010-12-02 16:25:45.000000000 +0100
@@ -3905,14 +3905,14 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *r
     dns_rdataset_t *addedrdataset, isc_stdtime_t now)
 {
 	rbtdb_changed_t *changed = NULL;
-	rdatasetheader_t *topheader, *topheader_prev, *header;
+	rdatasetheader_t *topheader, *topheader_prev, *header, *sigheader;
 	unsigned char *merged;
 	isc_result_t result;
 	isc_boolean_t header_nx;
 	isc_boolean_t newheader_nx;
 	isc_boolean_t merge;
 	dns_rdatatype_t rdtype, covers;
-	rbtdb_rdatatype_t negtype;
+	rbtdb_rdatatype_t negtype, sigtype;
 	dns_trust_t trust;
 
 	/*
@@ -3950,6 +3950,7 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *r
 	newheader_nx = NONEXISTENT(newheader) ? ISC_TRUE : ISC_FALSE;
 	topheader_prev = NULL;
 
+	sigheader = NULL;
 	negtype = 0;
 	if (rbtversion == NULL && !newheader_nx) {
 		rdtype = RBTDB_RDATATYPE_BASE(newheader->type);
@@ -3958,26 +3959,34 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *r
 			 * We're adding a negative cache entry.
 			 */
 			covers = RBTDB_RDATATYPE_EXT(newheader->type);
-			if (covers == dns_rdatatype_any) {
+			sigtype = RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig,
+							covers);
+			for (topheader = rbtnode->data;
+			     topheader != NULL;
+			     topheader = topheader->next) {
 				/*
-				 * We're adding an negative cache entry
+				 * If we're adding an negative cache entry
 				 * which covers all types (NXDOMAIN,
 				 * NODATA(QTYPE=ANY)).
 				 *
 				 * We make all other data stale so that the
 				 * only rdataset that can be found at this
 				 * node is the negative cache entry.
+				 *
+				 * Otherwise look for any RRSIGs of the
+				 * given type so they can be marked stale
+				 * later.
 				 */
-				for (topheader = rbtnode->data;
-				     topheader != NULL;
-				     topheader = topheader->next) {
+				if (covers == dns_rdatatype_any) {
 					topheader->ttl = 0;
 					topheader->attributes |=
 						RDATASET_ATTR_STALE;
-				}
-				rbtnode->dirty = 1;
-				goto find_header;
+					rbtnode->dirty = 1;
+				}  else if (topheader->type == sigtype)
+					sigheader = topheader;
 			}
+			if (covers == dns_rdatatype_any)
+				goto find_header;
 			negtype = RBTDB_RDATATYPE_VALUE(covers, 0);
 		} else {
 			/*
@@ -4198,6 +4207,11 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *r
 			if (rbtversion == NULL) {
 				header->ttl = 0;
 				header->attributes |= RDATASET_ATTR_STALE;
+				if (sigheader != NULL) {
+					sigheader->ttl = 0;
+					sigheader->attributes |=
+						RDATASET_ATTR_STALE;
+				}
 			}
 		}
 	} else {
diff -up bind-9.3.6-P1/lib/dns/validator.c.rh659266 bind-9.3.6-P1/lib/dns/validator.c
--- bind-9.3.6-P1/lib/dns/validator.c.rh659266	2010-12-02 16:20:04.000000000 +0100
+++ bind-9.3.6-P1/lib/dns/validator.c	2010-12-02 16:20:04.000000000 +0100
@@ -324,6 +324,7 @@ fetch_callback_validator(isc_task_t *tas
 	isc_boolean_t want_destroy;
 	isc_result_t result;
 	isc_result_t eresult;
+	isc_result_t saved_result;
 
 	UNUSED(task);
 	INSIST(event->ev_type == DNS_EVENT_FETCHDONE);
@@ -360,6 +361,17 @@ fetch_callback_validator(isc_task_t *tas
 				val->keyset = &val->frdataset;
 		}
 		result = validate(val, ISC_TRUE);
+		if (result == DNS_R_NOVALIDSIG &&
+		    (val->attributes & VALATTR_TRIEDVERIFY) == 0)
+		{
+			saved_result = result;
+			validator_log(val, ISC_LOG_DEBUG(3),
+				      "falling back to insecurity proof");
+			val->attributes |= VALATTR_INSECURITY;
+			result = proveunsecure(val, ISC_FALSE, ISC_FALSE);
+			if (result == DNS_R_NOTINSECURE)
+				result = saved_result;
+		}
 		if (result != DNS_R_WAIT)
 			validator_done(val, result);
 	} else {
@@ -550,6 +562,7 @@ keyvalidated(isc_task_t *task, isc_event
 	isc_boolean_t want_destroy;
 	isc_result_t result;
 	isc_result_t eresult;
+	isc_result_t saved_result;
 
 	UNUSED(task);
 	INSIST(event->ev_type == DNS_EVENT_VALIDATORDONE);
@@ -576,6 +589,17 @@ keyvalidated(isc_task_t *task, isc_event
 		if (val->frdataset.trust >= dns_trust_secure)
 			(void) get_dst_key(val, val->siginfo, &val->frdataset);
 		result = validate(val, ISC_TRUE);
+		if (result == DNS_R_NOVALIDSIG &&
+		    (val->attributes & VALATTR_TRIEDVERIFY) == 0)
+		{
+			saved_result = result;
+			validator_log(val, ISC_LOG_DEBUG(3),
+				      "falling back to insecurity proof");
+			val->attributes |= VALATTR_INSECURITY;
+			result = proveunsecure(val, ISC_FALSE, ISC_FALSE);
+			if (result == DNS_R_NOTINSECURE)
+				result = saved_result;
+		}
 		if (result != DNS_R_WAIT)
 			validator_done(val, result);
 	} else {
@@ -1426,7 +1450,10 @@ validate(dns_validator_t *val, isc_boole
 		if (!dns_resolver_algorithm_supported(val->view->resolver,
 						      event->name,
 						      val->siginfo->algorithm))
+		{
+			resume = ISC_FALSE;
 			continue;
+		}
 
 		if (!resume) {
 			result = get_key(val, val->siginfo);
@@ -1437,16 +1464,12 @@ validate(dns_validator_t *val, isc_boole
 		}
 
 		/*
-		 * The key is insecure, so mark the data as insecure also.
+		 * There isn't a secure DNSKEY for this signature so move
+		 * onto the next RRSIG.
 		 */
 		if (val->key == NULL) {
-			if (val->mustbesecure) {
-				validator_log(val, ISC_LOG_WARNING,
-					      "must be secure failure");
-				return (DNS_R_MUSTBESECURE);
-			}
-			markanswer(val);
-			return (ISC_R_SUCCESS);
+			resume = ISC_FALSE;
+			continue;
 		}
 
 		do {
@@ -2733,6 +2757,22 @@ proveunsecure(dns_validator_t *val, isc_
 				 */
 				result = DNS_R_NOVALIDNSEC;
 				goto out;
+#define DNS_TRUST_ANSWER(x) ((x) == dns_trust_answer)
+			} else if (DNS_TRUST_PENDING(val->frdataset.trust) ||
+				   DNS_TRUST_ANSWER(val->frdataset.trust)) {
+#undef DNS_TRUST_ANSWER
+				/*
+				 * If we have "trust == answer" then this namespace
+				 * has switched from insecure to should be secure.
+				 */
+				result = create_validator(val, tname,
+							  dns_rdatatype_ds,
+							  &val->frdataset,
+							  NULL, dsvalidated,
+							  "proveunsecure");
+				if (result != ISC_R_SUCCESS)
+					goto out;
+				return (DNS_R_WAIT);
 			} else if (val->frdataset.trust < dns_trust_secure) {
 				/*
 				 * This shouldn't happen, since the negative