lib/dns/validator.c
/*%
 * Look in the NSEC record returned from a DS query to see if there is
 * a NS RRset at this name.  If it is found we are at a delegation point.
 */
%
Look in the NSEC record returned from a DS query to see if there is
a NS RRset at this name.  If it is found we are at a delegation point.
% Look in the NSEC record returned from a DS query to see if there is a NS RRset at this name . If it is found we are at a delegation point .
static isc_boolean_t
isdelegation(dns_name_t *name, dns_rdataset_t *rdataset,
	     isc_result_t dbresult)
{
	dns_fixedname_t fixed;
	dns_label_t hashlabel;
	dns_name_t nsec3name;
	dns_rdata_nsec3_t nsec3;
	dns_rdata_t rdata = DNS_RDATA_INIT;
	dns_rdataset_t set;
	int order;
	int scope;
	isc_boolean_t found;
	isc_buffer_t buffer;
	isc_result_t result;
	unsigned char hash[NSEC3_MAX_HASH_LENGTH];
	unsigned char owner[NSEC3_MAX_HASH_LENGTH];
	unsigned int length;
	REQUIRE(dbresult == DNS_R_NXRRSET || dbresult == DNS_R_NCACHENXRRSET);
	dns_rdataset_init(&set);
	if (dbresult == DNS_R_NXRRSET)
		dns_rdataset_clone(rdataset, &set);
	else {
		result = dns_ncache_getrdataset(rdataset, name,
						dns_rdatatype_nsec, &set);
		if (result == ISC_R_NOTFOUND)
			goto trynsec3;
		if (result != ISC_R_SUCCESS)
			return (ISC_FALSE);
	}
	INSIST(set.type == dns_rdatatype_nsec);
	found = ISC_FALSE;
	result = dns_rdataset_first(&set);
	if (result == ISC_R_SUCCESS) {
		dns_rdataset_current(&set, &rdata);
		found = dns_nsec_typepresent(&rdata, dns_rdatatype_ns);
		dns_rdata_reset(&rdata);
	}
	dns_rdataset_disassociate(&set);
	return (found);
 trynsec3:
	found = ISC_FALSE;
	dns_name_init(&nsec3name, NULL);
	dns_fixedname_init(&fixed);
	dns_name_downcase(name, dns_fixedname_name(&fixed), NULL);
	name = dns_fixedname_name(&fixed);
	for (result = dns_rdataset_first(rdataset);
	     result == ISC_R_SUCCESS;
	     result = dns_rdataset_next(rdataset))
	{
		dns_ncache_current(rdataset, &nsec3name, &set);
		if (set.type != dns_rdatatype_nsec3) {
			dns_rdataset_disassociate(&set);
			continue;
		}
		dns_name_getlabel(&nsec3name, 0, &hashlabel);
		isc_region_consume(&hashlabel, 1);
		isc_buffer_init(&buffer, owner, sizeof(owner));
		result = isc_base32hex_decoderegion(&hashlabel, &buffer);
		if (result != ISC_R_SUCCESS) {
			dns_rdataset_disassociate(&set);
			continue;
		}
		for (result = dns_rdataset_first(&set);
		     result == ISC_R_SUCCESS;
		     result = dns_rdataset_next(&set))
		{
			dns_rdata_reset(&rdata);
			dns_rdataset_current(&set, &rdata);
			(void)dns_rdata_tostruct(&rdata, &nsec3, NULL);
			if (nsec3.hash != 1)
				continue;
			length = isc_iterated_hash(hash, nsec3.hash,
						   nsec3.iterations, nsec3.salt,
						   nsec3.salt_length,
						   name->ndata, name->length);
			if (length != isc_buffer_usedlength(&buffer))
				continue;
			order = memcmp(hash, owner, length);
			if (order == 0) {
				found = dns_nsec3_typepresent(&rdata,
							      dns_rdatatype_ns);
				dns_rdataset_disassociate(&set);
				return (found);
			}
			if ((nsec3.flags & DNS_NSEC3FLAG_OPTOUT) == 0)
				continue;
			scope = memcmp(owner, nsec3.next, nsec3.next_length);
			if ((scope < 0 && order > 0 &&
			     memcmp(hash, nsec3.next, length) < 0) ||
			    (scope >= 0 && (order > 0 ||
					memcmp(hash, nsec3.next, length) < 0)))
			{
				dns_rdataset_disassociate(&set);
				return (ISC_TRUE);
			}
		}
		dns_rdataset_disassociate(&set);
	}
	return (found);
}
static isc_boolean_t isdelegation ( dns_name_t * name , dns_rdataset_t * rdataset , isc_result_t dbresult ) { dns_fixedname_t fixed ; dns_label_t hashlabel ; dns_name_t nsec3name ; dns_rdata_nsec3_t nsec3 ; dns_rdata_t rdata = DNS_RDATA_INIT ; dns_rdataset_t set ; int order ; int scope ; isc_boolean_t found ; isc_buffer_t buffer ; isc_result_t result ; unsigned char hash [ NSEC3_MAX_HASH_LENGTH ] ; unsigned char owner [ NSEC3_MAX_HASH_LENGTH ] ; unsigned int length ; REQUIRE ( dbresult == DNS_R_NXRRSET || dbresult == DNS_R_NCACHENXRRSET ) ; dns_rdataset_init ( & set ) ; if ( dbresult == DNS_R_NXRRSET ) dns_rdataset_clone ( rdataset , & set ) ; else { result = dns_ncache_getrdataset ( rdataset , name , dns_rdatatype_nsec , & set ) ; if ( result == ISC_R_NOTFOUND ) goto trynsec3 ; if ( result != ISC_R_SUCCESS ) return ( ISC_FALSE ) ; } INSIST ( set . type == dns_rdatatype_nsec ) ; found = ISC_FALSE ; result = dns_rdataset_first ( & set ) ; if ( result == ISC_R_SUCCESS ) { dns_rdataset_current ( & set , & rdata ) ; found = dns_nsec_typepresent ( & rdata , dns_rdatatype_ns ) ; dns_rdata_reset ( & rdata ) ; } dns_rdataset_disassociate ( & set ) ; return ( found ) ; trynsec3 : found = ISC_FALSE ; dns_name_init ( & nsec3name , NULL ) ; dns_fixedname_init ( & fixed ) ; dns_name_downcase ( name , dns_fixedname_name ( & fixed ) , NULL ) ; name = dns_fixedname_name ( & fixed ) ; for ( result = dns_rdataset_first ( rdataset ) ; result == ISC_R_SUCCESS ; result = dns_rdataset_next ( rdataset ) ) { dns_ncache_current ( rdataset , & nsec3name , & set ) ; if ( set . type != dns_rdatatype_nsec3 ) { dns_rdataset_disassociate ( & set ) ; continue ; } dns_name_getlabel ( & nsec3name , 0 , & hashlabel ) ; isc_region_consume ( & hashlabel , 1 ) ; isc_buffer_init ( & buffer , owner , sizeof ( owner ) ) ; result = isc_base32hex_decoderegion ( & hashlabel , & buffer ) ; if ( result != ISC_R_SUCCESS ) { dns_rdataset_disassociate ( & set ) ; continue ; } for ( result = dns_rdataset_first ( & set ) ; result == ISC_R_SUCCESS ; result = dns_rdataset_next ( & set ) ) { dns_rdata_reset ( & rdata ) ; dns_rdataset_current ( & set , & rdata ) ; ( void ) dns_rdata_tostruct ( & rdata , & nsec3 , NULL ) ; if ( nsec3 . hash != 1 ) continue ; length = isc_iterated_hash ( hash , nsec3 . hash , nsec3 . iterations , nsec3 . salt , nsec3 . salt_length , name -> ndata , name -> length ) ; if ( length != isc_buffer_usedlength ( & buffer ) ) continue ; order = memcmp ( hash , owner , length ) ; if ( order == 0 ) { found = dns_nsec3_typepresent ( & rdata , dns_rdatatype_ns ) ; dns_rdataset_disassociate ( & set ) ; return ( found ) ; } if ( ( nsec3 . flags & DNS_NSEC3FLAG_OPTOUT ) == 0 ) continue ; scope = memcmp ( owner , nsec3 . next , nsec3 . next_length ) ; if ( ( scope < 0 && order > 0 && memcmp ( hash , nsec3 . next , length ) < 0 ) || ( scope >= 0 && ( order > 0 || memcmp ( hash , nsec3 . next , length ) < 0 ) ) ) { dns_rdataset_disassociate ( & set ) ; return ( ISC_TRUE ) ; } } dns_rdataset_disassociate ( & set ) ; } return ( found ) ; }
%
 Look in the NSEC record returned from a DS query to see if there is
 a NS RRset at this name.
% Look in the NSEC record returned from a DS query to see if there is a NS RRset at this name .
/*
	 * Iterate over the ncache entry.
	 */ /*
			 * Does this optout span cover the name?
			 */