commit 9151d8af69661dd07dba2945a983bef0b64739b8
Author: Mark Andrews <marka@isc.org>
Date:   Tue Sep 30 12:32:25 2014 +1000

    clone rdatasets when chasing signature; don't require a TTL when loading trusted-keys in dig

diff --git a/bin/dig/dighost.c b/bin/dig/dighost.c
index 533266b..02917f0 100644
--- a/bin/dig/dighost.c
+++ b/bin/dig/dighost.c
@@ -4695,8 +4695,8 @@ get_trusted_key(isc_mem_t *mctx)
 	dns_rdatacallbacks_init_stdio(&callbacks);
 	callbacks.add = insert_trustedkey;
 	return (dns_master_loadfile(filename, dns_rootname, dns_rootname,
-				    current_lookup->rdclass, 0, &callbacks,
-				    mctx));
+				    current_lookup->rdclass, DNS_MASTER_NOTTL,
+				    &callbacks, mctx));
 }
 
 
@@ -4896,36 +4896,36 @@ child_of_zone(dns_name_t * name, dns_name_t * zone_name,
 }
 
 isc_result_t
-grandfather_pb_test(dns_name_t *zone_name, dns_rdataset_t  *sigrdataset)
-{
-	isc_result_t result;
-	dns_rdata_t sigrdata = DNS_RDATA_INIT;
+grandfather_pb_test(dns_name_t *zone_name, dns_rdataset_t  *sigrdataset) {
 	dns_rdata_sig_t siginfo;
+	dns_rdataset_t mysigrdataset;
+	isc_result_t result;
+
+	dns_rdataset_init(&mysigrdataset);
+	dns_rdataset_clone(sigrdataset, &mysigrdataset);
 
-	result = dns_rdataset_first(sigrdataset);
+	result = dns_rdataset_first(&mysigrdataset);
 	check_result(result, "empty RRSIG dataset");
-	dns_rdata_init(&sigrdata);
 
 	do {
-		dns_rdataset_current(sigrdataset, &sigrdata);
+		dns_rdata_t sigrdata = DNS_RDATA_INIT;
+
+		dns_rdataset_current(&mysigrdataset, &sigrdata);
 
 		result = dns_rdata_tostruct(&sigrdata, &siginfo, NULL);
 		check_result(result, "sigrdata tostruct siginfo");
 
 		if (dns_name_compare(&siginfo.signer, zone_name) == 0) {
-			dns_rdata_freestruct(&siginfo);
-			dns_rdata_reset(&sigrdata);
-			return (ISC_R_SUCCESS);
+			result = ISC_R_SUCCESS;
+			goto cleanup;
 		}
+	} while (dns_rdataset_next(&mysigrdataset) == ISC_R_SUCCESS);
 
-		dns_rdata_freestruct(&siginfo);
-		dns_rdata_reset(&sigrdata);
+	result = ISC_R_FAILURE;
+cleanup:
+	dns_rdataset_disassociate(&mysigrdataset);
 
-	} while (dns_rdataset_next(chase_sigkeyrdataset) == ISC_R_SUCCESS);
-
-	dns_rdata_reset(&sigrdata);
-
-	return (ISC_R_FAILURE);
+	return (result);
 }
 
 
@@ -5005,19 +5005,24 @@ contains_trusted_key(dns_name_t *name, dns_rdataset_t *rdataset,
 		     dns_rdataset_t *sigrdataset,
 		     isc_mem_t *mctx)
 {
-	isc_result_t result;
-	dns_rdata_t rdata = DNS_RDATA_INIT;
+	dns_rdataset_t myrdataset;
 	dst_key_t *dnsseckey = NULL;
 	int i;
+	isc_result_t result;
 
 	if (name == NULL || rdataset == NULL)
 		return (ISC_R_FAILURE);
 
-	result = dns_rdataset_first(rdataset);
+	dns_rdataset_init(&myrdataset);
+	dns_rdataset_clone(rdataset, &myrdataset);
+
+	result = dns_rdataset_first(&myrdataset);
 	check_result(result, "empty rdataset");
 
 	do {
-		dns_rdataset_current(rdataset, &rdata);
+		dns_rdata_t rdata = DNS_RDATA_INIT;
+
+		dns_rdataset_current(&myrdataset, &rdata);
 		INSIST(rdata.type == dns_rdatatype_dnskey);
 
 		result = dns_dnssec_keyfromrdata(name, &rdata,
@@ -5033,22 +5038,21 @@ contains_trusted_key(dns_name_t *name, dns_rdataset_t *rdataset,
 				printf(";; Ok, find a Trusted Key in the "
 				       "DNSKEY RRset: %d\n",
 				       dst_key_id(dnsseckey));
-				if (sigchase_verify_sig_key(name, rdataset,
-							    dnsseckey,
-							    sigrdataset,
-							    mctx)
-				    == ISC_R_SUCCESS) {
-					dst_key_free(&dnsseckey);
-					dnsseckey = NULL;
-					return (ISC_R_SUCCESS);
-				}
+				result = sigchase_verify_sig_key(name, rdataset,
+							         dnsseckey,
+							         sigrdataset,
+							         mctx);
+				if (result == ISC_R_SUCCESS)
+					goto cleanup;
 			}
 		}
 
-		dns_rdata_reset(&rdata);
-		if (dnsseckey != NULL)
-			dst_key_free(&dnsseckey);
-	} while (dns_rdataset_next(rdataset) == ISC_R_SUCCESS);
+	} while (dns_rdataset_next(&myrdataset) == ISC_R_SUCCESS);
+
+cleanup:
+	if (dnsseckey != NULL)
+		dst_key_free(&dnsseckey);
+	dns_rdataset_disassociate(&myrdataset);
 
 	return (ISC_R_NOTFOUND);
 }
@@ -5059,16 +5063,20 @@ sigchase_verify_sig(dns_name_t *name, dns_rdataset_t *rdataset,
 		    dns_rdataset_t *sigrdataset,
 		    isc_mem_t *mctx)
 {
-	isc_result_t result;
-	dns_rdata_t keyrdata = DNS_RDATA_INIT;
+	dns_rdataset_t mykeyrdataset;
 	dst_key_t *dnsseckey = NULL;
+	isc_result_t result;
+
+	dns_rdataset_init(&mykeyrdataset);
+	dns_rdataset_clone(keyrdataset, &mykeyrdataset);
 
-	result = dns_rdataset_first(keyrdataset);
+	result = dns_rdataset_first(&mykeyrdataset);
 	check_result(result, "empty DNSKEY dataset");
-	dns_rdata_init(&keyrdata);
 
 	do {
-		dns_rdataset_current(keyrdataset, &keyrdata);
+		dns_rdata_t keyrdata = DNS_RDATA_INIT;
+
+		dns_rdataset_current(&mykeyrdataset, &keyrdata);
 		INSIST(keyrdata.type == dns_rdatatype_dnskey);
 
 		result = dns_dnssec_keyfromrdata(name, &keyrdata,
@@ -5077,18 +5085,19 @@ sigchase_verify_sig(dns_name_t *name, dns_rdataset_t *rdataset,
 
 		result = sigchase_verify_sig_key(name, rdataset, dnsseckey,
 						 sigrdataset, mctx);
-		if (result == ISC_R_SUCCESS) {
-			dns_rdata_reset(&keyrdata);
-			dst_key_free(&dnsseckey);
-			return (ISC_R_SUCCESS);
-		}
+		if (result == ISC_R_SUCCESS)
+			goto cleanup;
 		dst_key_free(&dnsseckey);
-		dns_rdata_reset(&keyrdata);
-	} while (dns_rdataset_next(chase_keyrdataset) == ISC_R_SUCCESS);
+	} while (dns_rdataset_next(&mykeyrdataset) == ISC_R_SUCCESS);
 
-	dns_rdata_reset(&keyrdata);
+	result = ISC_R_NOTFOUND;
 
-	return (ISC_R_NOTFOUND);
+ cleanup:
+	if (dnsseckey != NULL)
+		dst_key_free(&dnsseckey);
+	dns_rdataset_disassociate(&mykeyrdataset);
+
+	return (result);
 }
 
 isc_result_t
@@ -5096,16 +5105,23 @@ sigchase_verify_sig_key(dns_name_t *name, dns_rdataset_t *rdataset,
 			dst_key_t *dnsseckey, dns_rdataset_t *sigrdataset,
 			isc_mem_t *mctx)
 {
-	isc_result_t result;
-	dns_rdata_t sigrdata = DNS_RDATA_INIT;
 	dns_rdata_sig_t siginfo;
+	dns_rdataset_t myrdataset;
+	dns_rdataset_t mysigrdataset;
+	isc_result_t result;
+
+	dns_rdataset_init(&myrdataset);
+	dns_rdataset_clone(rdataset, &myrdataset);
+	dns_rdataset_init(&mysigrdataset);
+	dns_rdataset_clone(sigrdataset, &mysigrdataset);
 
-	result = dns_rdataset_first(sigrdataset);
+	result = dns_rdataset_first(&mysigrdataset);
 	check_result(result, "empty RRSIG dataset");
-	dns_rdata_init(&sigrdata);
 
 	do {
-		dns_rdataset_current(sigrdataset, &sigrdata);
+		dns_rdata_t sigrdata = DNS_RDATA_INIT;
+
+		dns_rdataset_current(&mysigrdataset, &sigrdata);
 
 		result = dns_rdata_tostruct(&sigrdata, &siginfo, NULL);
 		check_result(result, "sigrdata tostruct siginfo");
@@ -5116,10 +5132,10 @@ sigchase_verify_sig_key(dns_name_t *name, dns_rdataset_t *rdataset,
 		 */
 		if (siginfo.keyid == dst_key_id(dnsseckey)) {
 
-			result = dns_rdataset_first(rdataset);
+			result = dns_rdataset_first(&myrdataset);
 			check_result(result, "empty DS dataset");
 
-			result = dns_dnssec_verify(name, rdataset, dnsseckey,
+			result = dns_dnssec_verify(name, &myrdataset, dnsseckey,
 						   ISC_FALSE, mctx, &sigrdata);
 
 			printf(";; VERIFYING ");
@@ -5129,19 +5145,18 @@ sigchase_verify_sig_key(dns_name_t *name, dns_rdataset_t *rdataset,
 			printf(" with DNSKEY:%d: %s\n", dst_key_id(dnsseckey),
 			       isc_result_totext(result));
 
-			if (result == ISC_R_SUCCESS) {
-				dns_rdata_reset(&sigrdata);
-				return (result);
-			}
+			if (result == ISC_R_SUCCESS)
+				goto cleanup;
 		}
-		dns_rdata_freestruct(&siginfo);
-		dns_rdata_reset(&sigrdata);
+	} while (dns_rdataset_next(&mysigrdataset) == ISC_R_SUCCESS);
 
-	} while (dns_rdataset_next(chase_sigkeyrdataset) == ISC_R_SUCCESS);
+	result = ISC_R_NOTFOUND;
 
-	dns_rdata_reset(&sigrdata);
+ cleanup:
+	dns_rdataset_disassociate(&myrdataset);
+	dns_rdataset_disassociate(&mysigrdataset);
 
-	return (ISC_R_NOTFOUND);
+	return (result);
 }
 
 
@@ -5149,27 +5164,35 @@ isc_result_t
 sigchase_verify_ds(dns_name_t *name, dns_rdataset_t *keyrdataset,
 		   dns_rdataset_t *dsrdataset, isc_mem_t *mctx)
 {
-	isc_result_t result;
-	dns_rdata_t keyrdata = DNS_RDATA_INIT;
-	dns_rdata_t newdsrdata = DNS_RDATA_INIT;
-	dns_rdata_t dsrdata = DNS_RDATA_INIT;
 	dns_rdata_ds_t dsinfo;
+	dns_rdataset_t mydsrdataset;
+	dns_rdataset_t mykeyrdataset;
 	dst_key_t *dnsseckey = NULL;
+	isc_result_t result;
 	unsigned char dsbuf[DNS_DS_BUFFERSIZE];
 
-	result = dns_rdataset_first(dsrdataset);
+	dns_rdataset_init(&mydsrdataset);
+	dns_rdataset_clone(dsrdataset, &mydsrdataset);
+	dns_rdataset_init(&mykeyrdataset);
+	dns_rdataset_clone(keyrdataset, &mykeyrdataset);
+
+	result = dns_rdataset_first(&mydsrdataset);
 	check_result(result, "empty DSset dataset");
 	do {
-		dns_rdataset_current(dsrdataset, &dsrdata);
+		dns_rdata_t dsrdata = DNS_RDATA_INIT;
+
+		dns_rdataset_current(&mydsrdataset, &dsrdata);
 
 		result = dns_rdata_tostruct(&dsrdata, &dsinfo, NULL);
 		check_result(result, "dns_rdata_tostruct for DS");
 
-		result = dns_rdataset_first(keyrdataset);
+		result = dns_rdataset_first(&mykeyrdataset);
 		check_result(result, "empty KEY dataset");
 
 		do {
-			dns_rdataset_current(keyrdataset, &keyrdata);
+			dns_rdata_t keyrdata = DNS_RDATA_INIT;
+
+			dns_rdataset_current(&mykeyrdataset, &keyrdata);
 			INSIST(keyrdata.type == dns_rdatatype_dnskey);
 
 			result = dns_dnssec_keyfromrdata(name, &keyrdata,
@@ -5181,6 +5204,7 @@ sigchase_verify_ds(dns_name_t *name, dns_rdataset_t *keyrdataset,
 			 * id of DNSKEY referenced by the DS
 			 */
 			if (dsinfo.key_tag == dst_key_id(dnsseckey)) {
+				dns_rdata_t newdsrdata = DNS_RDATA_INIT;
 
 				result = dns_ds_buildrdata(name, &keyrdata,
 							   dsinfo.digest_type,
@@ -5188,14 +5212,9 @@ sigchase_verify_ds(dns_name_t *name, dns_rdataset_t *keyrdataset,
 				dns_rdata_freestruct(&dsinfo);
 
 				if (result != ISC_R_SUCCESS) {
-					dns_rdata_reset(&keyrdata);
-					dns_rdata_reset(&newdsrdata);
-					dns_rdata_reset(&dsrdata);
-					dst_key_free(&dnsseckey);
-					dns_rdata_freestruct(&dsinfo);
 					printf("Oops: impossible to build"
 					       " new DS rdata\n");
-					return (result);
+					goto cleanup;
 				}
 
 
@@ -5212,34 +5231,26 @@ sigchase_verify_ds(dns_name_t *name, dns_rdataset_t *keyrdataset,
 							 dnsseckey,
 							 chase_sigkeyrdataset,
 							 mctx);
-					if (result ==  ISC_R_SUCCESS) {
-						dns_rdata_reset(&keyrdata);
-						dns_rdata_reset(&newdsrdata);
-						dns_rdata_reset(&dsrdata);
-						dst_key_free(&dnsseckey);
-
-						return (result);
-					}
+					if (result ==  ISC_R_SUCCESS)
+						goto cleanup;
 				} else {
 					printf(";; This DS is NOT the DS for"
 					       " the chasing KEY: FAILED\n");
 				}
-
-				dns_rdata_reset(&newdsrdata);
 			}
 			dst_key_free(&dnsseckey);
-			dns_rdata_reset(&keyrdata);
-			dnsseckey = NULL;
-		} while (dns_rdataset_next(chase_keyrdataset) == ISC_R_SUCCESS);
-		dns_rdata_reset(&dsrdata);
+		} while (dns_rdataset_next(&mykeyrdataset) == ISC_R_SUCCESS);
+	} while (dns_rdataset_next(&mydsrdataset) == ISC_R_SUCCESS);
 
-	} while (dns_rdataset_next(chase_dsrdataset) == ISC_R_SUCCESS);
+	result = ISC_R_NOTFOUND;
 
-	dns_rdata_reset(&keyrdata);
-	dns_rdata_reset(&newdsrdata);
-	dns_rdata_reset(&dsrdata);
+ cleanup:
+	if (dnsseckey != NULL)
+		dst_key_free(&dnsseckey);
+	dns_rdataset_disassociate(&mydsrdataset);
+	dns_rdataset_disassociate(&mykeyrdataset);
 
-	return (ISC_R_NOTFOUND);
+	return (result);
 }
 
 /*
@@ -5722,7 +5733,7 @@ getneededrr(dns_message_t *msg)
 					   dns_rdatatype_dnskey,
 					   &chase_sigkeylookedup);
 		if (result == ISC_R_FAILURE) {
-			printf("\n;; RRSIG for DNSKEY  is missing  to continue"
+			printf("\n;; RRSIG for DNSKEY is missing  to continue"
 			       " validation : FAILED\n\n");
 			free_name(&chase_signame, mctx);
 			if (dns_name_dynamic(&chase_name))
@@ -5742,9 +5753,8 @@ getneededrr(dns_message_t *msg)
 
 	if (chase_dsrdataset == NULL) {
 		result = advanced_rrsearch(&chase_dsrdataset, &chase_signame,
-					   dns_rdatatype_ds,
-					   dns_rdatatype_any,
-		&chase_dslookedup);
+					   dns_rdatatype_ds, dns_rdatatype_any,
+					   &chase_dslookedup);
 		if (result == ISC_R_FAILURE) {
 			printf("\n;; WARNING There is no DS for the zone: ");
 			dns_name_print(&chase_signame, stdout);
@@ -6032,7 +6042,6 @@ prove_nx_domain(dns_message_t *msg,
 		     result = dns_rdataset_next(nsecset)) {
 			dns_rdataset_current(nsecset, &nsec);
 
-
 			signsecset
 				= chase_scanname_section(msg, nsecname,
 						 dns_rdatatype_rrsig,
