⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 validator.c

📁 bind 源码 最新实现 linux/unix/windows平台
💻 C
📖 第 1 页 / 共 5 页
字号:
		 dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset,		 isc_taskaction_t action, const char *caller){	isc_result_t result;	if (check_deadlock(val, name, type))		return (DNS_R_NOVALIDSIG);	validator_logcreate(val, name, type, caller, "validator");	result = dns_validator_create(val->view, name, type,				      rdataset, sigrdataset, NULL, 0,				      val->task, action, val,				      &val->subvalidator);	if (result == ISC_R_SUCCESS) {		val->subvalidator->parent = val;		val->subvalidator->depth = val->depth + 1;	}	return (result);}/* * Try to find a key that could have signed 'siginfo' among those * in 'rdataset'.  If found, build a dst_key_t for it and point * val->key at it. * * If val->key is non-NULL, this returns the next matching key. */static isc_result_tget_dst_key(dns_validator_t *val, dns_rdata_rrsig_t *siginfo,	    dns_rdataset_t *rdataset){	isc_result_t result;	isc_buffer_t b;	dns_rdata_t rdata = DNS_RDATA_INIT;	dst_key_t *oldkey = val->key;	isc_boolean_t foundold;	if (oldkey == NULL)		foundold = ISC_TRUE;	else {		foundold = ISC_FALSE;		val->key = NULL;	}	result = dns_rdataset_first(rdataset);	if (result != ISC_R_SUCCESS)		goto failure;	do {		dns_rdataset_current(rdataset, &rdata);		isc_buffer_init(&b, rdata.data, rdata.length);		isc_buffer_add(&b, rdata.length);		INSIST(val->key == NULL);		result = dst_key_fromdns(&siginfo->signer, rdata.rdclass, &b,					 val->view->mctx, &val->key);		if (result != ISC_R_SUCCESS)			goto failure;		if (siginfo->algorithm ==		    (dns_secalg_t)dst_key_alg(val->key) &&		    siginfo->keyid ==		    (dns_keytag_t)dst_key_id(val->key) &&		    dst_key_iszonekey(val->key))		{			if (foundold)				/*				 * This is the key we're looking for.				 */				return (ISC_R_SUCCESS);			else if (dst_key_compare(oldkey, val->key) == ISC_TRUE)			{				foundold = ISC_TRUE;				dst_key_free(&oldkey);			}		}		dst_key_free(&val->key);		dns_rdata_reset(&rdata);		result = dns_rdataset_next(rdataset);	} while (result == ISC_R_SUCCESS);	if (result == ISC_R_NOMORE)		result = ISC_R_NOTFOUND; failure:	if (oldkey != NULL)		dst_key_free(&oldkey);	return (result);}static isc_result_tget_key(dns_validator_t *val, dns_rdata_rrsig_t *siginfo) {	isc_result_t result;	unsigned int nlabels;	int order;	dns_namereln_t namereln;	/*	 * Is the signer name appropriate for this signature?	 *	 * The signer name must be at the same level as the owner name	 * or closer to the the DNS root.	 */	namereln = dns_name_fullcompare(val->event->name, &siginfo->signer,					&order, &nlabels);	if (namereln != dns_namereln_subdomain &&	    namereln != dns_namereln_equal)		return (DNS_R_CONTINUE);	if (namereln == dns_namereln_equal) {		/*		 * If this is a self-signed keyset, it must not be a zone key		 * (since get_key is not called from validatezonekey).		 */		if (val->event->rdataset->type == dns_rdatatype_dnskey)			return (DNS_R_CONTINUE);		/*		 * Records appearing in the parent zone at delegation		 * points cannot be self-signed.		 */		if (dns_rdatatype_atparent(val->event->rdataset->type))			return (DNS_R_CONTINUE);	}	/*	 * Do we know about this key?	 */	result = view_find(val, &siginfo->signer, dns_rdatatype_dnskey);	if (result == ISC_R_SUCCESS) {		/*		 * We have an rrset for the given keyname.		 */		val->keyset = &val->frdataset;		if (val->frdataset.trust == dns_trust_pending &&		    dns_rdataset_isassociated(&val->fsigrdataset))		{			/*			 * We know the key but haven't validated it yet.			 */			result = create_validator(val, &siginfo->signer,						  dns_rdatatype_dnskey,						  &val->frdataset,						  &val->fsigrdataset,						  keyvalidated,						  "get_key");			if (result != ISC_R_SUCCESS)				return (result);			return (DNS_R_WAIT);		} else if (val->frdataset.trust == dns_trust_pending) {			/*			 * Having a pending key with no signature means that			 * something is broken.			 */			result = DNS_R_CONTINUE;		} else if (val->frdataset.trust < dns_trust_secure) {			/*			 * The key is legitimately insecure.  There's no			 * point in even attempting verification.			 */			val->key = NULL;			result = ISC_R_SUCCESS;		} else {			/*			 * See if we've got the key used in the signature.			 */			validator_log(val, ISC_LOG_DEBUG(3),				      "keyset with trust %d",				      val->frdataset.trust);			result = get_dst_key(val, siginfo, val->keyset);			if (result != ISC_R_SUCCESS) {				/*				 * Either the key we're looking for is not				 * in the rrset, or something bad happened.				 * Give up.				 */				result = DNS_R_CONTINUE;			}		}	} else if (result == ISC_R_NOTFOUND) {		/*		 * We don't know anything about this key.		 */		result = create_fetch(val, &siginfo->signer, dns_rdatatype_dnskey,				      fetch_callback_validator, "get_key");		if (result != ISC_R_SUCCESS)			return (result);		return (DNS_R_WAIT);	} else if (result ==  DNS_R_NCACHENXDOMAIN ||		   result == DNS_R_NCACHENXRRSET ||		   result == DNS_R_NXDOMAIN ||		   result == DNS_R_NXRRSET)	{		/*		 * This key doesn't exist.		 */		result = DNS_R_CONTINUE;	}	if (dns_rdataset_isassociated(&val->frdataset) &&	    val->keyset != &val->frdataset)		dns_rdataset_disassociate(&val->frdataset);	if (dns_rdataset_isassociated(&val->fsigrdataset))		dns_rdataset_disassociate(&val->fsigrdataset);	return (result);}static dns_keytag_tcompute_keytag(dns_rdata_t *rdata, dns_rdata_dnskey_t *key) {	isc_region_t r;	dns_rdata_toregion(rdata, &r);	return (dst_region_computeid(&r, key->algorithm));}/* * Is this keyset self-signed? */static isc_boolean_tisselfsigned(dns_validator_t *val) {	dns_rdataset_t *rdataset, *sigrdataset;	dns_rdata_t rdata = DNS_RDATA_INIT;	dns_rdata_t sigrdata = DNS_RDATA_INIT;	dns_rdata_dnskey_t key;	dns_rdata_rrsig_t sig;	dns_keytag_t keytag;	isc_result_t result;	rdataset = val->event->rdataset;	sigrdataset = val->event->sigrdataset;	INSIST(rdataset->type == dns_rdatatype_dnskey);	for (result = dns_rdataset_first(rdataset);	     result == ISC_R_SUCCESS;	     result = dns_rdataset_next(rdataset))	{		dns_rdata_reset(&rdata);		dns_rdataset_current(rdataset, &rdata);		(void)dns_rdata_tostruct(&rdata, &key, NULL);		keytag = compute_keytag(&rdata, &key);		for (result = dns_rdataset_first(sigrdataset);		     result == ISC_R_SUCCESS;		     result = dns_rdataset_next(sigrdataset))		{			dns_rdata_reset(&sigrdata);			dns_rdataset_current(sigrdataset, &sigrdata);			(void)dns_rdata_tostruct(&sigrdata, &sig, NULL);			if (sig.algorithm == key.algorithm &&			    sig.keyid == keytag)				return (ISC_TRUE);		}	}	return (ISC_FALSE);}static isc_result_tverify(dns_validator_t *val, dst_key_t *key, dns_rdata_t *rdata) {	isc_result_t result;	dns_fixedname_t fixed;	val->attributes |= VALATTR_TRIEDVERIFY;	dns_fixedname_init(&fixed);	result = dns_dnssec_verify2(val->event->name, val->event->rdataset,				    key, ISC_FALSE, val->view->mctx, rdata,				    dns_fixedname_name(&fixed));	validator_log(val, ISC_LOG_DEBUG(3),		      "verify rdataset: %s",		      isc_result_totext(result));	if (result == DNS_R_FROMWILDCARD) {		if (!dns_name_equal(val->event->name,				    dns_fixedname_name(&fixed)))			val->attributes |= VALATTR_NEEDNOQNAME;		result = ISC_R_SUCCESS;	}	return (result);}/* * Attempts positive response validation of a normal RRset. * * Returns: *	ISC_R_SUCCESS	Validation completed successfully *	DNS_R_WAIT	Validation has started but is waiting *			for an event. *	Other return codes are possible and all indicate failure. */static isc_result_tvalidate(dns_validator_t *val, isc_boolean_t resume) {	isc_result_t result;	dns_validatorevent_t *event;	dns_rdata_t rdata = DNS_RDATA_INIT;	/*	 * Caller must be holding the validator lock.	 */	event = val->event;	if (resume) {		/*		 * We already have a sigrdataset.		 */		result = ISC_R_SUCCESS;		validator_log(val, ISC_LOG_DEBUG(3), "resuming validate");	} else {		result = dns_rdataset_first(event->sigrdataset);	}	for (;	     result == ISC_R_SUCCESS;	     result = dns_rdataset_next(event->sigrdataset))	{		dns_rdata_reset(&rdata);		dns_rdataset_current(event->sigrdataset, &rdata);		if (val->siginfo == NULL) {			val->siginfo = isc_mem_get(val->view->mctx,						   sizeof(*val->siginfo));			if (val->siginfo == NULL)				return (ISC_R_NOMEMORY);		}		result = dns_rdata_tostruct(&rdata, val->siginfo, NULL);		if (result != ISC_R_SUCCESS)			return (result);		/*		 * At this point we could check that the signature algorithm		 * was known and "sufficiently good".		 */		if (!dns_resolver_algorithm_supported(val->view->resolver,						      event->name,						      val->siginfo->algorithm))			continue;		if (!resume) {			result = get_key(val, val->siginfo);			if (result == DNS_R_CONTINUE)				continue; /* Try the next SIG RR. */			if (result != ISC_R_SUCCESS)				return (result);		}		/*		 * The key is insecure, so mark the data as insecure also.		 */		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);		}		do {			result = verify(val, val->key, &rdata);			if (result == ISC_R_SUCCESS)				break;			if (val->keynode != NULL) {				dns_keynode_t *nextnode = NULL;				result = dns_keytable_findnextkeynode(							val->keytable,							val->keynode,							&nextnode);				dns_keytable_detachkeynode(val->keytable,							   &val->keynode);				val->keynode = nextnode;				if (result != ISC_R_SUCCESS) {					val->key = NULL;					break;				}				val->key = dns_keynode_key(val->keynode);			} else {				if (get_dst_key(val, val->siginfo, val->keyset)				    != ISC_R_SUCCESS)					break;			}		} while (1);		if (result != ISC_R_SUCCESS)			validator_log(val, ISC_LOG_DEBUG(3),				      "failed to verify rdataset");		else {			isc_uint32_t ttl;			isc_stdtime_t now;			isc_stdtime_get(&now);			ttl = ISC_MIN(event->rdataset->ttl,				      val->siginfo->timeexpire - now);			if (val->keyset != NULL)				ttl = ISC_MIN(ttl, val->keyset->ttl);			event->rdataset->ttl = ttl;			event->sigrdataset->ttl = ttl;		}		if (val->keynode != NULL)			dns_keytable_detachkeynode(val->keytable,						   &val->keynode);		else {			if (val->key != NULL)				dst_key_free(&val->key);			if (val->keyset != NULL) {				dns_rdataset_disassociate(val->keyset);				val->keyset = NULL;			}		}		val->key = NULL;		if ((val->attributes & VALATTR_NEEDNOQNAME) != 0) {			if (val->event->message == NULL) {				validator_log(val, ISC_LOG_DEBUG(3),				      "no message available for noqname proof");				return (DNS_R_NOVALIDSIG);			}			validator_log(val, ISC_LOG_DEBUG(3),				      "looking for noqname proof");			return (nsecvalidate(val, ISC_FALSE));		} else if (result == ISC_R_SUCCESS) {			event->rdataset->trust = dns_trust_secure;			event->sigrdataset->trust = dns_trust_secure;			validator_log(val, ISC_LOG_DEBUG(3),				      "marking as secure");			return (result);		} else {			validator_log(val, ISC_LOG_DEBUG(3),				      "verify failure: %s",				      isc_result_totext(result));			resume = ISC_FALSE;		}	}	if (result != ISC_R_NOMORE) {		validator_log(val, ISC_LOG_DEBUG(3),			      "failed to iterate signatures: %s",			      isc_result_totext(result));		return (result);	}	validator_log(val, ISC_LOG_INFO, "no valid signature found");	return (DNS_R_NOVALIDSIG);}static isc_result_tdlv_validatezonekey(dns_validator_t *val) {	dns_keytag_t keytag;	dns_rdata_dlv_t dlv;	dns_rdata_dnskey_t key;	dns_rdata_rrsig_t sig;	dns_rdata_t dlvrdata = DNS_RDATA_INIT;	dns_rdata_t keyrdata = DNS_RDATA_INIT;	dns_rdata_t newdsrdata = DNS_RDATA_INIT;	dns_rdata_t sigrdata = DNS_RDATA_INIT;	dns_rdataset_t trdataset;	dst_key_t *dstkey;	isc_boolean_t supported_algorithm;	isc_result_t result;	unsigned char dsbuf[DNS_DS_BUFFERSIZE];	validator_log(val, ISC_LOG_DEBUG(3), "dlv_validatezonekey");	/*	 * Look through the DLV record and find the keys that can sign the

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -