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

📄 validator.c

📁 bind 源码 最新实现 linux/unix/windows平台
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * Copyright (C) 2004, 2005  Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2003  Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. *//* $Id: validator.c,v 1.91.2.5.8.21 2005/11/02 02:07:47 marka Exp $ */#include <config.h>#include <isc/mem.h>#include <isc/print.h>#include <isc/string.h>#include <isc/task.h>#include <isc/util.h>#include <dns/db.h>#include <dns/ds.h>#include <dns/dnssec.h>#include <dns/events.h>#include <dns/keytable.h>#include <dns/log.h>#include <dns/message.h>#include <dns/ncache.h>#include <dns/nsec.h>#include <dns/rdata.h>#include <dns/rdatastruct.h>#include <dns/rdataset.h>#include <dns/rdatatype.h>#include <dns/resolver.h>#include <dns/result.h>#include <dns/validator.h>#include <dns/view.h>#define VALIDATOR_MAGIC			ISC_MAGIC('V', 'a', 'l', '?')#define VALID_VALIDATOR(v)		ISC_MAGIC_VALID(v, VALIDATOR_MAGIC)#define VALATTR_SHUTDOWN		0x0001#define VALATTR_FOUNDNONEXISTENCE	0x0002#define VALATTR_TRIEDVERIFY		0x0004#define VALATTR_NEGATIVE		0x0008#define VALATTR_INSECURITY		0x0010#define VALATTR_DLVTRIED		0x0020#define VALATTR_NEEDNOQNAME		0x0100#define VALATTR_NEEDNOWILDCARD		0x0200#define VALATTR_NEEDNODATA		0x0400#define VALATTR_FOUNDNOQNAME		0x1000#define VALATTR_FOUNDNOWILDCARD		0x2000#define VALATTR_FOUNDNODATA		0x4000#define NEEDNODATA(val) ((val->attributes & VALATTR_NEEDNODATA) != 0)#define NEEDNOQNAME(val) ((val->attributes & VALATTR_NEEDNOQNAME) != 0)#define NEEDNOWILDCARD(val) ((val->attributes & VALATTR_NEEDNOWILDCARD) != 0)#define DLVTRIED(val) ((val->attributes & VALATTR_DLVTRIED) != 0)#define SHUTDOWN(v)		(((v)->attributes & VALATTR_SHUTDOWN) != 0)static voiddestroy(dns_validator_t *val);static isc_result_tget_dst_key(dns_validator_t *val, dns_rdata_rrsig_t *siginfo,	    dns_rdataset_t *rdataset);static isc_result_tvalidate(dns_validator_t *val, isc_boolean_t resume);static isc_result_tvalidatezonekey(dns_validator_t *val);static isc_result_tnsecvalidate(dns_validator_t *val, isc_boolean_t resume);static isc_result_tproveunsecure(dns_validator_t *val, isc_boolean_t resume);static voidvalidator_logv(dns_validator_t *val, isc_logcategory_t *category,	       isc_logmodule_t *module, int level, const char *fmt, va_list ap)     ISC_FORMAT_PRINTF(5, 0);static voidvalidator_log(dns_validator_t *val, int level, const char *fmt, ...)     ISC_FORMAT_PRINTF(3, 4);static voidvalidator_logcreate(dns_validator_t *val,		    dns_name_t *name, dns_rdatatype_t type,		    const char *caller, const char *operation);static isc_result_tdlv_validatezonekey(dns_validator_t *val);static isc_result_tdlv_validator_start(dns_validator_t *val);static isc_result_tfinddlvsep(dns_validator_t *val, isc_boolean_t resume);static inline voidmarkanswer(dns_validator_t *val) {	validator_log(val, ISC_LOG_DEBUG(3), "marking as answer");	if (val->event->rdataset)		val->event->rdataset->trust = dns_trust_answer;	if (val->event->sigrdataset)		val->event->sigrdataset->trust = dns_trust_answer;}static voidvalidator_done(dns_validator_t *val, isc_result_t result) {	isc_task_t *task;	if (val->event == NULL)		return;	/*	 * Caller must be holding the lock.	 */	val->event->result = result;	task = val->event->ev_sender;	val->event->ev_sender = val;	val->event->ev_type = DNS_EVENT_VALIDATORDONE;	val->event->ev_action = val->action;	val->event->ev_arg = val->arg;	isc_task_sendanddetach(&task, (isc_event_t **)&val->event);}static inline isc_boolean_texit_check(dns_validator_t *val) {	/*	 * Caller must be holding the lock.	 */	if (!SHUTDOWN(val))		return (ISC_FALSE);	INSIST(val->event == NULL);	if (val->fetch != NULL || val->subvalidator != NULL)		return (ISC_FALSE);	return (ISC_TRUE);}static voidauth_nonpending(dns_message_t *message) {	isc_result_t result;	dns_name_t *name;	dns_rdataset_t *rdataset;	for (result = dns_message_firstname(message, DNS_SECTION_AUTHORITY);	     result == ISC_R_SUCCESS;	     result = dns_message_nextname(message, DNS_SECTION_AUTHORITY))	{		name = NULL;		dns_message_currentname(message, DNS_SECTION_AUTHORITY, &name);		for (rdataset = ISC_LIST_HEAD(name->list);		     rdataset != NULL;		     rdataset = ISC_LIST_NEXT(rdataset, link))		{			if (rdataset->trust == dns_trust_pending)				rdataset->trust = dns_trust_authauthority;		}	}}static isc_boolean_tisdelegation(dns_name_t *name, dns_rdataset_t *rdataset,	     isc_result_t dbresult){	dns_rdataset_t set;	dns_rdata_t rdata = DNS_RDATA_INIT;	isc_boolean_t found;	isc_result_t result;	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_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_rdataset_disassociate(&set);	return (found);}static voidfetch_callback_validator(isc_task_t *task, isc_event_t *event) {	dns_fetchevent_t *devent;	dns_validator_t *val;	dns_rdataset_t *rdataset;	isc_boolean_t want_destroy;	isc_result_t result;	isc_result_t eresult;	UNUSED(task);	INSIST(event->ev_type == DNS_EVENT_FETCHDONE);	devent = (dns_fetchevent_t *)event;	val = devent->ev_arg;	rdataset = &val->frdataset;	eresult = devent->result;	/* Free resources which are not of interest. */	if (devent->node != NULL)		dns_db_detachnode(devent->db, &devent->node);	if (devent->db != NULL)		dns_db_detach(&devent->db);	if (dns_rdataset_isassociated(&val->fsigrdataset))		dns_rdataset_disassociate(&val->fsigrdataset);	isc_event_free(&event);	dns_resolver_destroyfetch(&val->fetch);	INSIST(val->event != NULL);	validator_log(val, ISC_LOG_DEBUG(3), "in fetch_callback_validator");	LOCK(&val->lock);	if (eresult == ISC_R_SUCCESS) {		validator_log(val, ISC_LOG_DEBUG(3),			      "keyset with trust %d", rdataset->trust);		/*		 * Only extract the dst key if the keyset is secure.		 */		if (rdataset->trust >= dns_trust_secure) {			result = get_dst_key(val, val->siginfo, rdataset);			if (result == ISC_R_SUCCESS)				val->keyset = &val->frdataset;		}		result = validate(val, ISC_TRUE);		if (result != DNS_R_WAIT)			validator_done(val, result);	} else {		validator_log(val, ISC_LOG_DEBUG(3),			      "fetch_callback_validator: got %s",			      isc_result_totext(eresult));		if (eresult == ISC_R_CANCELED)			validator_done(val, eresult);		else			validator_done(val, DNS_R_NOVALIDKEY);	}	want_destroy = exit_check(val);	UNLOCK(&val->lock);	if (want_destroy)		destroy(val);}static voiddsfetched(isc_task_t *task, isc_event_t *event) {	dns_fetchevent_t *devent;	dns_validator_t *val;	dns_rdataset_t *rdataset;	isc_boolean_t want_destroy;	isc_result_t result;	isc_result_t eresult;	UNUSED(task);	INSIST(event->ev_type == DNS_EVENT_FETCHDONE);	devent = (dns_fetchevent_t *)event;	val = devent->ev_arg;	rdataset = &val->frdataset;	eresult = devent->result;	/* Free resources which are not of interest. */	if (devent->node != NULL)		dns_db_detachnode(devent->db, &devent->node);	if (devent->db != NULL)		dns_db_detach(&devent->db);	if (dns_rdataset_isassociated(&val->fsigrdataset))		dns_rdataset_disassociate(&val->fsigrdataset);	isc_event_free(&event);	dns_resolver_destroyfetch(&val->fetch);	INSIST(val->event != NULL);	validator_log(val, ISC_LOG_DEBUG(3), "in dsfetched");	LOCK(&val->lock);	if (eresult == ISC_R_SUCCESS) {		validator_log(val, ISC_LOG_DEBUG(3),			      "dsset with trust %d", rdataset->trust);		val->dsset = &val->frdataset;		result = validatezonekey(val);		if (result != DNS_R_WAIT)			validator_done(val, result);	} else if (eresult == DNS_R_NXRRSET ||		   eresult == DNS_R_NCACHENXRRSET)	{		validator_log(val, ISC_LOG_DEBUG(3),			      "falling back to insecurity proof");		val->attributes |= VALATTR_INSECURITY;		result = proveunsecure(val, ISC_FALSE);		if (result != DNS_R_WAIT)			validator_done(val, result);	} else {		validator_log(val, ISC_LOG_DEBUG(3),			      "dsfetched: got %s",			      isc_result_totext(eresult));		if (eresult == ISC_R_CANCELED)			validator_done(val, eresult);		else			validator_done(val, DNS_R_NOVALIDDS);	}	want_destroy = exit_check(val);	UNLOCK(&val->lock);	if (want_destroy)		destroy(val);}/* * XXX there's too much duplicated code here. */static voiddsfetched2(isc_task_t *task, isc_event_t *event) {	dns_fetchevent_t *devent;	dns_validator_t *val;	dns_name_t *tname;	isc_boolean_t want_destroy;	isc_result_t result;	isc_result_t eresult;	UNUSED(task);	INSIST(event->ev_type == DNS_EVENT_FETCHDONE);	devent = (dns_fetchevent_t *)event;	val = devent->ev_arg;	eresult = devent->result;	/* Free resources which are not of interest. */	if (devent->node != NULL)		dns_db_detachnode(devent->db, &devent->node);	if (devent->db != NULL)		dns_db_detach(&devent->db);	if (dns_rdataset_isassociated(&val->fsigrdataset))		dns_rdataset_disassociate(&val->fsigrdataset);	dns_resolver_destroyfetch(&val->fetch);	INSIST(val->event != NULL);	validator_log(val, ISC_LOG_DEBUG(3), "in dsfetched2");	LOCK(&val->lock);	if (eresult == DNS_R_NXRRSET || eresult == DNS_R_NCACHENXRRSET) {		/*		 * There is no DS.  If this is a delegation, we're done.		 */		tname = dns_fixedname_name(&devent->foundname);		if (isdelegation(tname, &val->frdataset, eresult)) {			if (val->mustbesecure) {				validator_log(val, ISC_LOG_WARNING,					      "must be secure failure");				validator_done(val, DNS_R_MUSTBESECURE);			} else {				markanswer(val);				validator_done(val, ISC_R_SUCCESS);			}		} else {			result = proveunsecure(val, ISC_TRUE);			if (result != DNS_R_WAIT)				validator_done(val, result);		}	} else if (eresult == ISC_R_SUCCESS ||		   eresult == DNS_R_NXDOMAIN ||		   eresult == DNS_R_NCACHENXDOMAIN)	{		/*		 * Either there is a DS or this is not a zone cut.  Continue.		 */		result = proveunsecure(val, ISC_TRUE);		if (result != DNS_R_WAIT)			validator_done(val, result);	} else {		if (eresult == ISC_R_CANCELED)			validator_done(val, eresult);		else			validator_done(val, DNS_R_NOVALIDDS);	}	isc_event_free(&event);	want_destroy = exit_check(val);	UNLOCK(&val->lock);	if (want_destroy)		destroy(val);}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);}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);

⌨️ 快捷键说明

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