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

📄 validator.c

📁 bind-3.2.
💻 C
📖 第 1 页 / 共 3 页
字号:
		validator_log(val, ISC_LOG_DEBUG(3),			      "negauthvalidated: got %s",			      dns_result_totext(eresult));		validator_done(val, eresult);	}	UNLOCK(&val->lock);	/*	 * Free stuff from the event.	 */	if (dns_rdataset_isassociated(&val->frdataset))		dns_rdataset_disassociate(&val->frdataset);}static voidnullkeyvalidated(isc_task_t *task, isc_event_t *event) {	dns_validatorevent_t *devent;	dns_validator_t *val;	isc_result_t result;	isc_result_t eresult;	UNUSED(task);	INSIST(event->ev_type == DNS_EVENT_VALIDATORDONE);	devent = (dns_validatorevent_t *)event;	val = devent->ev_arg;	eresult = devent->result;	dns_name_free(devent->name, val->view->mctx);	isc_mem_put(val->view->mctx, devent->name, sizeof(dns_name_t));	dns_validator_destroy(&val->keyvalidator);	isc_event_free(&event);	if (SHUTDOWN(val)) {		dns_validator_destroy(&val);		return;	}	if (val->event == NULL)		return;	validator_log(val, ISC_LOG_DEBUG(3), "in nullkeyvalidated");	LOCK(&val->lock);	if (eresult == ISC_R_SUCCESS) {		validator_log(val, ISC_LOG_DEBUG(3),			      "proved that name is in an unsecure domain");		validator_log(val, ISC_LOG_DEBUG(3), "marking as answer");		val->event->rdataset->trust = dns_trust_answer;		validator_done(val, ISC_R_SUCCESS);	} else {		result = proveunsecure(val, ISC_TRUE);		if (result != DNS_R_WAIT)			validator_done(val, result);	}	UNLOCK(&val->lock);	/*	 * Free stuff from the event.	 */	if (dns_rdataset_isassociated(&val->frdataset))		dns_rdataset_disassociate(&val->frdataset);	if (dns_rdataset_isassociated(&val->fsigrdataset))		dns_rdataset_disassociate(&val->fsigrdataset);}/* * Try to find a null zone key among those in 'rdataset'.  If found, build * a dst_key_t for it and point val->key at it. */static inline isc_boolean_tcontainsnullkey(dns_validator_t *val, dns_rdataset_t *rdataset) {	isc_result_t result;	dst_key_t *key = NULL;	isc_buffer_t b;	dns_rdata_t rdata = DNS_RDATA_INIT;	isc_boolean_t found = ISC_FALSE;	result = dns_rdataset_first(rdataset);	if (result != ISC_R_SUCCESS)		return (ISC_FALSE);	while (result == ISC_R_SUCCESS && !found) {		dns_rdataset_current(rdataset, &rdata);		isc_buffer_init(&b, rdata.data, rdata.length);		isc_buffer_add(&b, rdata.length);		key = NULL;		/*		 * The key name is unimportant, so we can avoid any name/text		 * conversion.		 */		result = dst_key_fromdns(dns_rootname, rdata.rdclass, &b,					 val->view->mctx, &key);		if (result != ISC_R_SUCCESS)			continue;		if (dst_key_isnullkey(key))			found = ISC_TRUE;		dst_key_free(&key);		dns_rdata_reset(&rdata);		result = dns_rdataset_next(rdataset);	}	return (found);}/* * 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 inline isc_result_tget_dst_key(dns_validator_t *val, dns_rdata_sig_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 inline isc_result_tget_key(dns_validator_t *val, dns_rdata_sig_t *siginfo) {	isc_result_t result;	dns_validatorevent_t *event;	unsigned int nbits, nlabels;	int order;	dns_namereln_t namereln;	event = val->event;	/*	 * Is the key name appropriate for this signature?	 * This previously checked for self-signed keys.  Now, if the key	 * is self signed with a preconfigured key, it's ok.	 */	namereln = dns_name_fullcompare(event->name, &siginfo->signer,					&order, &nlabels, &nbits);	if (namereln != dns_namereln_subdomain &&	    namereln != dns_namereln_equal) {		/*		 * The key name is not at the same level		 * as 'rdataset', nor is it closer to the		 * DNS root.		 */		return (DNS_R_CONTINUE);	}	/*	 * Is the key used for the signature a security root?	 */	INSIST(val->keynode == NULL);	val->keytable = val->view->secroots;	result = dns_keytable_findkeynode(val->view->secroots,					  &siginfo->signer,					  siginfo->algorithm, siginfo->keyid,					  &val->keynode);	if (result == ISC_R_SUCCESS) {		/*		 * The key is a security root.		 */		val->key = dns_keynode_key(val->keynode);		return (ISC_R_SUCCESS);	}	/*	 * A key set may not be self-signed unless the signing key is a	 * security root.  We don't want a KEY RR to authenticate	 * itself, so we ignore the signature if it was not made by	 * an ancestor of the KEY or a preconfigured key.	 */	if (event->rdataset->type == dns_rdatatype_key &&	    namereln == dns_namereln_equal)	{		validator_log(val, ISC_LOG_DEBUG(3),			      "keyset was self-signed but not preconfigured");		return (DNS_R_CONTINUE);	}	/*	 * Do we know about this key?	 */	if (dns_rdataset_isassociated(&val->frdataset))		dns_rdataset_disassociate(&val->frdataset);	if (dns_rdataset_isassociated(&val->fsigrdataset))		dns_rdataset_disassociate(&val->fsigrdataset);	result = dns_view_simplefind(val->view, &siginfo->signer,				     dns_rdatatype_key, 0,				     DNS_DBFIND_PENDINGOK, ISC_FALSE,				     &val->frdataset, &val->fsigrdataset);	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 = dns_validator_create(val->view,						      &siginfo->signer,						      dns_rdatatype_key,						      &val->frdataset,						      &val->fsigrdataset,						      NULL,						      0,						      val->task,						      keyvalidated,						      val,						      &val->keyvalidator);			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.		 */		val->fetch = NULL;		result = dns_resolver_createfetch(val->view->resolver,						  &siginfo->signer,						  dns_rdatatype_key,						  NULL, NULL, NULL, 0,						  val->event->ev_sender,						  fetch_callback_validator,						  val,						  &val->frdataset,						  &val->fsigrdataset,						  &val->fetch);		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);}/* * If the rdataset being validated is a key set, is each key a security root? */static isc_boolean_tissecurityroot(dns_validator_t *val) {	dns_name_t *name;	dns_rdataset_t *rdataset;	isc_mem_t *mctx;	dns_keytable_t *secroots;	dns_rdata_t rdata = DNS_RDATA_INIT;	isc_result_t result;	dns_keynode_t *keynode, *nextnode;	dst_key_t *key, *secrootkey;	isc_boolean_t match = ISC_FALSE;	name = val->event->name;	rdataset = val->event->rdataset;	mctx = val->view->mctx;	secroots = val->view->secroots;	for (result = dns_rdataset_first(rdataset);	     result == ISC_R_SUCCESS;	     result = dns_rdataset_next(rdataset))	{		dns_rdataset_current(rdataset, &rdata);		key = NULL;		result = dns_dnssec_keyfromrdata(name, &rdata, mctx, &key);		dns_rdata_reset(&rdata);		if (result != ISC_R_SUCCESS)			 continue;		keynode = NULL;		result = dns_keytable_findkeynode(						secroots, name,						(dns_secalg_t)dst_key_alg(key),						dst_key_id(key),						&keynode);		match = ISC_FALSE;		while (result == ISC_R_SUCCESS) {			secrootkey = dns_keynode_key(keynode);			if (dst_key_compare(key, secrootkey)) {				match = ISC_TRUE;				dns_keytable_detachkeynode(secroots, &keynode);				break;			}			nextnode = NULL;			result = dns_keytable_findnextkeynode(secroots,							      keynode,							      &nextnode);			dns_keytable_detachkeynode(secroots, &keynode);		}		dst_key_free(&key);		if (!match)			return (ISC_FALSE);	}	return (match);}/* * Attempts positive response validation. * * 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 inline 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 this is a security root, it's ok.	 */	if (!resume) {		dns_fixedname_t fsecroot;		dns_name_t *secroot;		dns_fixedname_init(&fsecroot);		secroot = dns_fixedname_name(&fsecroot);		result = dns_keytable_finddeepestmatch(val->view->secroots,						       val->event->name,						       secroot);		if (result == ISC_R_SUCCESS &&		    val->event->type == dns_rdatatype_key &&		    dns_name_equal(val->event->name, secroot) &&		    issecurityroot(val))		{			val->event->rdataset->trust = dns_trust_secure;			return (ISC_R_SUCCESS);		}	}	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)			isc_mem_put(val->view->mctx, val->siginfo,				    sizeof *val->siginfo);		val->siginfo = isc_mem_get(val->view->mctx,					   sizeof *val->siginfo);		if (val->siginfo == NULL)			return (ISC_R_NOMEMORY);		dns_rdata_tostruct(&rdata, val->siginfo, NULL);		/*		 * At this point we could check that the signature algorithm		 * was known and "sufficiently good".  For now, any algorithm		 * is acceptable.		 */		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);		}		if (val->key == NULL) {			event->rdataset->trust = dns_trust_answer;			event->sigrdataset->trust = dns_trust_answer;			validator_log(val, ISC_LOG_DEBUG(3),				      "marking as answer");			return (ISC_R_SUCCESS);		}		do {			val->attributes |= VALATTR_TRIEDVERIFY;			result = dns_dnssec_verify(event->name,						   event->rdataset,						   val->key, ISC_FALSE,						   val->view->mctx, &rdata);			validator_log(val, ISC_LOG_DEBUG(3),				      "verify rdataset: %s",				      isc_result_totext(result));			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 (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);}

⌨️ 快捷键说明

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