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

📄 validator.c

📁 非常好的dns解析软件
💻 C
📖 第 1 页 / 共 5 页
字号:
	}	isc_event_free(&event);	want_destroy = exit_check(val);	UNLOCK(&val->lock);	if (want_destroy)		destroy(val);}/*% * Callback from when a DNSKEY RRset has been validated. * * Resumes the stalled validation process. */static voidkeyvalidated(isc_task_t *task, isc_event_t *event) {	dns_validatorevent_t *devent;	dns_validator_t *val;	isc_boolean_t want_destroy;	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;	isc_event_free(&event);	dns_validator_destroy(&val->subvalidator);	INSIST(val->event != NULL);	validator_log(val, ISC_LOG_DEBUG(3), "in keyvalidated");	LOCK(&val->lock);	if (eresult == ISC_R_SUCCESS) {		validator_log(val, ISC_LOG_DEBUG(3),			      "keyset with trust %d", val->frdataset.trust);		/*		 * Only extract the dst key if the keyset is secure.		 */		if (val->frdataset.trust >= dns_trust_secure)			(void) get_dst_key(val, val->siginfo, &val->frdataset);		result = validate(val, ISC_TRUE);		if (result != DNS_R_WAIT)			validator_done(val, result);	} else {		validator_log(val, ISC_LOG_DEBUG(3),			      "keyvalidated: got %s",			      isc_result_totext(eresult));		validator_done(val, eresult);	}	want_destroy = exit_check(val);	UNLOCK(&val->lock);	if (want_destroy)		destroy(val);}/*% * Callback when the DS record has been validated. * * Resumes validation of the zone key or the unsecure zone proof. */static voiddsvalidated(isc_task_t *task, isc_event_t *event) {	dns_validatorevent_t *devent;	dns_validator_t *val;	isc_boolean_t want_destroy;	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;	isc_event_free(&event);	dns_validator_destroy(&val->subvalidator);	INSIST(val->event != NULL);	validator_log(val, ISC_LOG_DEBUG(3), "in dsvalidated");	LOCK(&val->lock);	if (eresult == ISC_R_SUCCESS) {		validator_log(val, ISC_LOG_DEBUG(3),			      "dsset with trust %d", val->frdataset.trust);		if ((val->attributes & VALATTR_INSECURITY) != 0)			result = proveunsecure(val, ISC_TRUE);		else			result = validatezonekey(val);		if (result != DNS_R_WAIT)			validator_done(val, result);	} else {		validator_log(val, ISC_LOG_DEBUG(3),			      "dsvalidated: got %s",			      isc_result_totext(eresult));		validator_done(val, eresult);	}	want_destroy = exit_check(val);	UNLOCK(&val->lock);	if (want_destroy)		destroy(val);}/*% * Return ISC_R_SUCCESS if we can determine that the name doesn't exist * or we can determine whether there is data or not at the name. * If the name does not exist return the wildcard name. * * Return ISC_R_IGNORE when the NSEC is not the appropriate one. */static isc_result_tnsecnoexistnodata(dns_validator_t *val, dns_name_t* name, dns_name_t *nsecname,		  dns_rdataset_t *nsecset, isc_boolean_t *exists,		  isc_boolean_t *data, dns_name_t *wild){	int order;	dns_rdata_t rdata = DNS_RDATA_INIT;	isc_result_t result;	dns_namereln_t relation;	unsigned int olabels, nlabels, labels;	dns_rdata_nsec_t nsec;	isc_boolean_t atparent;	isc_boolean_t ns;	isc_boolean_t soa;	REQUIRE(exists != NULL);	REQUIRE(data != NULL);	REQUIRE(nsecset != NULL &&		nsecset->type == dns_rdatatype_nsec);	result = dns_rdataset_first(nsecset);	if (result != ISC_R_SUCCESS) {		validator_log(val, ISC_LOG_DEBUG(3),			"failure processing NSEC set");		return (result);	}	dns_rdataset_current(nsecset, &rdata);	validator_log(val, ISC_LOG_DEBUG(3), "looking for relevant nsec");	relation = dns_name_fullcompare(name, nsecname, &order, &olabels);	if (order < 0) {		/*		 * The name is not within the NSEC range.		 */		validator_log(val, ISC_LOG_DEBUG(3),			      "NSEC does not cover name, before NSEC");		return (ISC_R_IGNORE);	}	if (order == 0) {		/*		 * The names are the same.		 */		atparent = dns_rdatatype_atparent(val->event->type);		ns = dns_nsec_typepresent(&rdata, dns_rdatatype_ns);		soa = dns_nsec_typepresent(&rdata, dns_rdatatype_soa);		if (ns && !soa) {			if (!atparent) {				/*				 * This NSEC record is from somewhere higher in				 * the DNS, and at the parent of a delegation.				 * It can not be legitimately used here.				 */				validator_log(val, ISC_LOG_DEBUG(3),					      "ignoring parent nsec");				return (ISC_R_IGNORE);			}		} else if (atparent && ns && soa) {			/*			 * This NSEC record is from the child.			 * It can not be legitimately used here.			 */			validator_log(val, ISC_LOG_DEBUG(3),				      "ignoring child nsec");			return (ISC_R_IGNORE);		}		if (val->event->type == dns_rdatatype_cname ||		    val->event->type == dns_rdatatype_nxt ||		    val->event->type == dns_rdatatype_nsec ||		    val->event->type == dns_rdatatype_key ||		    !dns_nsec_typepresent(&rdata, dns_rdatatype_cname)) {			*exists = ISC_TRUE;			*data = dns_nsec_typepresent(&rdata, val->event->type);			validator_log(val, ISC_LOG_DEBUG(3),				      "nsec proves name exists (owner) data=%d",				      *data);			return (ISC_R_SUCCESS);		}		validator_log(val, ISC_LOG_DEBUG(3), "NSEC proves CNAME exists");		return (ISC_R_IGNORE);	}	if (relation == dns_namereln_subdomain &&	    dns_nsec_typepresent(&rdata, dns_rdatatype_ns) &&	    !dns_nsec_typepresent(&rdata, dns_rdatatype_soa))	{		/*		 * This NSEC record is from somewhere higher in		 * the DNS, and at the parent of a delegation.		 * It can not be legitimately used here.		 */		validator_log(val, ISC_LOG_DEBUG(3), "ignoring parent nsec");		return (ISC_R_IGNORE);	}	result = dns_rdata_tostruct(&rdata, &nsec, NULL);	if (result != ISC_R_SUCCESS)		return (result);	relation = dns_name_fullcompare(&nsec.next, name, &order, &nlabels);	if (order == 0) {		dns_rdata_freestruct(&nsec);		validator_log(val, ISC_LOG_DEBUG(3),			      "ignoring nsec matches next name");		return (ISC_R_IGNORE);	}	if (order < 0 && !dns_name_issubdomain(nsecname, &nsec.next)) {		/*		 * The name is not within the NSEC range.		 */		dns_rdata_freestruct(&nsec);		validator_log(val, ISC_LOG_DEBUG(3),			    "ignoring nsec because name is past end of range");		return (ISC_R_IGNORE);	}	if (order > 0 && relation == dns_namereln_subdomain) {		validator_log(val, ISC_LOG_DEBUG(3),			      "nsec proves name exist (empty)");		dns_rdata_freestruct(&nsec);		*exists = ISC_TRUE;		*data = ISC_FALSE;		return (ISC_R_SUCCESS);	}	if (wild != NULL) {		dns_name_t common;		dns_name_init(&common, NULL);		if (olabels > nlabels) {			labels = dns_name_countlabels(nsecname);			dns_name_getlabelsequence(nsecname, labels - olabels,						  olabels, &common);		} else {			labels = dns_name_countlabels(&nsec.next);			dns_name_getlabelsequence(&nsec.next, labels - nlabels,						  nlabels, &common);		}		result = dns_name_concatenate(dns_wildcardname, &common,					       wild, NULL);		if (result != ISC_R_SUCCESS) {			dns_rdata_freestruct(&nsec);			validator_log(val, ISC_LOG_DEBUG(3),				    "failure generating wildcard name");			return (result);		}	}	dns_rdata_freestruct(&nsec);	validator_log(val, ISC_LOG_DEBUG(3), "nsec range ok");	*exists = ISC_FALSE;	return (ISC_R_SUCCESS);}/*% * Callback for when NSEC records have been validated. * * Looks for NOQNAME and NODATA proofs. * * Resumes nsecvalidate. */static voidauthvalidated(isc_task_t *task, isc_event_t *event) {	dns_validatorevent_t *devent;	dns_validator_t *val;	dns_rdataset_t *rdataset;	isc_boolean_t want_destroy;	isc_result_t result;	isc_boolean_t exists, data;	UNUSED(task);	INSIST(event->ev_type == DNS_EVENT_VALIDATORDONE);	devent = (dns_validatorevent_t *)event;	rdataset = devent->rdataset;	val = devent->ev_arg;	result = devent->result;	dns_validator_destroy(&val->subvalidator);	INSIST(val->event != NULL);	validator_log(val, ISC_LOG_DEBUG(3), "in authvalidated");	LOCK(&val->lock);	if (result != ISC_R_SUCCESS) {		validator_log(val, ISC_LOG_DEBUG(3),			      "authvalidated: got %s",			      isc_result_totext(result));		if (result == ISC_R_CANCELED)			validator_done(val, result);		else {			result = nsecvalidate(val, ISC_TRUE);			if (result != DNS_R_WAIT)				validator_done(val, result);		}	} else {		dns_name_t **proofs = val->event->proofs;		dns_name_t *wild = dns_fixedname_name(&val->wild);				if (rdataset->trust == dns_trust_secure)			val->seensig = ISC_TRUE;		if (rdataset->type == dns_rdatatype_nsec &&		    rdataset->trust == dns_trust_secure &&		    ((val->attributes & VALATTR_NEEDNODATA) != 0 ||		     (val->attributes & VALATTR_NEEDNOQNAME) != 0) &&	            (val->attributes & VALATTR_FOUNDNODATA) == 0 &&		    (val->attributes & VALATTR_FOUNDNOQNAME) == 0 &&		    nsecnoexistnodata(val, val->event->name, devent->name,				      rdataset, &exists, &data, wild)				      == ISC_R_SUCCESS)		{			if (exists && !data) {				val->attributes |= VALATTR_FOUNDNODATA;				if (NEEDNODATA(val))					proofs[DNS_VALIDATOR_NODATAPROOF] =						devent->name;			}			if (!exists) {				val->attributes |= VALATTR_FOUNDNOQNAME;				if (NEEDNOQNAME(val))					proofs[DNS_VALIDATOR_NOQNAMEPROOF] =						devent->name;			}		}		result = nsecvalidate(val, ISC_TRUE);		if (result != DNS_R_WAIT)			validator_done(val, result);	}	want_destroy = exit_check(val);	UNLOCK(&val->lock);	if (want_destroy)		destroy(val);	/*	 * Free stuff from the event.	 */	isc_event_free(&event);}/*% * Looks for the requested name and type in the view (zones and cache). * * When looking for a DLV record also checks to make sure the NSEC record * returns covers the query name as part of aggressive negative caching. * * Returns: * \li	ISC_R_SUCCESS * \li	ISC_R_NOTFOUND * \li	DNS_R_NCACHENXDOMAIN * \li	DNS_R_NCACHENXRRSET * \li	DNS_R_NXRRSET * \li	DNS_R_NXDOMAIN */static inline isc_result_tview_find(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type) {	dns_fixedname_t fixedname;	dns_name_t *foundname;	dns_rdata_nsec_t nsec;	dns_rdata_t rdata = DNS_RDATA_INIT;	isc_result_t result;	unsigned int options;	char buf1[DNS_NAME_FORMATSIZE];	char buf2[DNS_NAME_FORMATSIZE];	char buf3[DNS_NAME_FORMATSIZE];	if (dns_rdataset_isassociated(&val->frdataset))		dns_rdataset_disassociate(&val->frdataset);	if (dns_rdataset_isassociated(&val->fsigrdataset))		dns_rdataset_disassociate(&val->fsigrdataset);	if (val->view->zonetable == NULL)		return (ISC_R_CANCELED);	options = DNS_DBFIND_PENDINGOK;	if (type == dns_rdatatype_dlv)		options |= DNS_DBFIND_COVERINGNSEC;	dns_fixedname_init(&fixedname);	foundname = dns_fixedname_name(&fixedname);	result = dns_view_find(val->view, name, type, 0, options,			       ISC_FALSE, NULL, NULL, foundname,			       &val->frdataset, &val->fsigrdataset);	if (result == DNS_R_NXDOMAIN) {		if (dns_rdataset_isassociated(&val->frdataset))			dns_rdataset_disassociate(&val->frdataset);		if (dns_rdataset_isassociated(&val->fsigrdataset))			dns_rdataset_disassociate(&val->fsigrdataset);	} else if (result == DNS_R_COVERINGNSEC) {		validator_log(val, ISC_LOG_DEBUG(3), "DNS_R_COVERINGNSEC");		/*		 * Check if the returned NSEC covers the name.		 */		INSIST(type == dns_rdatatype_dlv);		if (val->frdataset.trust != dns_trust_secure) {			validator_log(val, ISC_LOG_DEBUG(3),				      "covering nsec: trust %u",				      val->frdataset.trust);			goto notfound;		}		result = dns_rdataset_first(&val->frdataset);		if (result != ISC_R_SUCCESS)			goto notfound;		dns_rdataset_current(&val->frdataset, &rdata);		if (dns_nsec_typepresent(&rdata, dns_rdatatype_ns) &&		    !dns_nsec_typepresent(&rdata, dns_rdatatype_soa)) {			/* Parent NSEC record. */			if (dns_name_issubdomain(name, foundname)) {				validator_log(val, ISC_LOG_DEBUG(3),					      "covering nsec: for parent");				goto notfound;			}		}		result = dns_rdata_tostruct(&rdata, &nsec, NULL);		if (result != ISC_R_SUCCESS)			goto notfound;		if (dns_name_compare(foundname, &nsec.next) >= 0) {			/* End of zone chain. */			if (!dns_name_issubdomain(name, &nsec.next)) {				/* 				 * XXXMPA We could look for a parent NSEC				 * at nsec.next and if found retest with				 * this NSEC.				 */				dns_rdata_freestruct(&nsec);				validator_log(val, ISC_LOG_DEBUG(3),					      "covering nsec: not in zone");				goto notfound;			}		} else if (dns_name_compare(name, &nsec.next) >= 0) {			/*			 * XXXMPA We could check if this NSEC is at a zone			 * apex and if the qname is not below it and look for			 * a parent NSEC with the same name.  This requires			 * that we can cache both NSEC records which we			 * currently don't support.			 */			dns_rdata_freestruct(&nsec);			validator_log(val, ISC_LOG_DEBUG(3),				      "covering nsec: not in range");			goto notfound;		}		if (isc_log_wouldlog(dns_lctx,ISC_LOG_DEBUG(3))) {			dns_name_format(name, buf1, sizeof buf1);			dns_name_format(foundname, buf2, sizeof buf2);			dns_name_format(&nsec.next, buf3, sizeof buf3);			validator_log(val, ISC_LOG_DEBUG(3),

⌨️ 快捷键说明

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