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

📄 validator.c

📁 非常好的dns解析软件
💻 C
📖 第 1 页 / 共 5 页
字号:
				      "covering nsec found: '%s' '%s' '%s'",				      buf1, buf2, buf3);		}		if (dns_rdataset_isassociated(&val->frdataset))			dns_rdataset_disassociate(&val->frdataset);		if (dns_rdataset_isassociated(&val->fsigrdataset))			dns_rdataset_disassociate(&val->fsigrdataset);		dns_rdata_freestruct(&nsec);		result = DNS_R_NCACHENXDOMAIN;	} else if (result != ISC_R_SUCCESS &&                   result != DNS_R_NCACHENXDOMAIN &&                   result != DNS_R_NCACHENXRRSET &&                   result != DNS_R_NXRRSET &&                   result != ISC_R_NOTFOUND) {		goto  notfound;	}	return (result); notfound:	if (dns_rdataset_isassociated(&val->frdataset))		dns_rdataset_disassociate(&val->frdataset);	if (dns_rdataset_isassociated(&val->fsigrdataset))		dns_rdataset_disassociate(&val->fsigrdataset);	return (ISC_R_NOTFOUND);}/*% * Checks to make sure we are not going to loop.  As we use a SHARED fetch * the validation process will stall if looping was to occur. */static inline isc_boolean_tcheck_deadlock(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type) {	dns_validator_t *parent;	for (parent = val; parent != NULL; parent = parent->parent) {		if (parent->event != NULL &&		    parent->event->type == type &&		    dns_name_equal(parent->event->name, name))		{			validator_log(val, ISC_LOG_DEBUG(3),				      "continuing validation would lead to "				      "deadlock: aborting validation");			return (ISC_TRUE);		}	}	return (ISC_FALSE);}/*% * Start a fetch for the requested name and type. */static inline isc_result_tcreate_fetch(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type,	     isc_taskaction_t callback, const char *caller){	if (dns_rdataset_isassociated(&val->frdataset))		dns_rdataset_disassociate(&val->frdataset);	if (dns_rdataset_isassociated(&val->fsigrdataset))		dns_rdataset_disassociate(&val->fsigrdataset);	if (check_deadlock(val, name, type))		return (DNS_R_NOVALIDSIG);	validator_logcreate(val, name, type, caller, "fetch");	return (dns_resolver_createfetch(val->view->resolver, name, type,					 NULL, NULL, NULL, 0,					 val->event->ev_sender,					 callback, val,					 &val->frdataset,					 &val->fsigrdataset,					 &val->fetch));}/*% * Start a subvalidation process. */static inline isc_result_tcreate_validator(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type,		 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);}/*% * Get the key that genertated this signature. */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);}/*% * Attempt to verify the rdataset using the given key and rdata (RRSIG). * The signature was good and from a wildcard record and the QNAME does * not match the wildcard we need to look for a NOQNAME proof. * * Returns: * \li	ISC_R_SUCCESS if the verification succeeds. * \li	Others if the verification fails. */static isc_result_tverify(dns_validator_t *val, dst_key_t *key, dns_rdata_t *rdata,       isc_uint16_t keyid){	isc_result_t result;	dns_fixedname_t fixed;	isc_boolean_t ignore = ISC_FALSE;	val->attributes |= VALATTR_TRIEDVERIFY;	dns_fixedname_init(&fixed); again:	result = dns_dnssec_verify2(val->event->name, val->event->rdataset,				    key, ignore, val->view->mctx, rdata,				    dns_fixedname_name(&fixed));	if (result == DNS_R_SIGEXPIRED && val->view->acceptexpired) {		ignore = ISC_TRUE;		goto again;	}	if (ignore && (result == ISC_R_SUCCESS || result == DNS_R_FROMWILDCARD))		validator_log(val, ISC_LOG_INFO,			      "accepted expired %sRRSIG (keyid=%u)",			      (result == DNS_R_FROMWILDCARD) ?			      "wildcard " : "", keyid);	else		validator_log(val, ISC_LOG_DEBUG(3),			      "verify rdataset (keyid=%u): %s",			      keyid, 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: * \li	ISC_R_SUCCESS	Validation completed successfully * \li	DNS_R_WAIT	Validation has started but is waiting *			for an event. * \li	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);

⌨️ 快捷键说明

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