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

📄 validator.c

📁 非常好的dns解析软件
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * Copyright (C) 2004-2007  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.119.18.29 2007/01/08 02:41:59 marka Exp $ *//*! \file */#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>/*! \file * \brief * Basic processing sequences. * * \li When called with rdataset and sigrdataset: * validator_start -> validate -> proveunsecure -> startfinddlvsep -> *	dlv_validator_start -> validator_start -> validate -> proveunsecure * * validator_start -> validate -> nsecvalidate	(secure wildcard answer) *  * \li When called with rdataset, sigrdataset and with DNS_VALIDATOR_DLV: * validator_start -> startfinddlvsep -> dlv_validator_start -> *	validator_start -> validate -> proveunsecure * * \li When called with rdataset: * validator_start -> proveunsecure -> startfinddlvsep -> *	dlv_validator_start -> validator_start -> proveunsecure * * \li When called with rdataset and with DNS_VALIDATOR_DLV: * validator_start -> startfinddlvsep -> dlv_validator_start -> *	validator_start -> proveunsecure * * \li When called without a rdataset: * validator_start -> nsecvalidate -> proveunsecure -> startfinddlvsep -> *	dlv_validator_start -> validator_start -> nsecvalidate -> proveunsecure * * Note: there isn't a case for DNS_VALIDATOR_DLV here as we want nsecvalidate() * to always validate the authority section even when it does not contain * signatures. * * validator_start: determines what type of validation to do. * validate: attempts to perform a positive validation. * proveunsecure: attempts to prove the answer comes from a unsecure zone. * nsecvalidate: attempts to prove a negative response. * startfinddlvsep: starts the DLV record lookup. * dlv_validator_start: resets state and restarts the lookup using the *	DLV RRset found by startfinddlvsep. */#define VALIDATOR_MAGIC			ISC_MAGIC('V', 'a', 'l', '?')#define VALID_VALIDATOR(v)		ISC_MAGIC_VALID(v, VALIDATOR_MAGIC)#define VALATTR_SHUTDOWN		0x0001	/*%< Shutting down. */#define VALATTR_TRIEDVERIFY		0x0004  /*%< We have found a key and						 * have attempted a verify. */#define VALATTR_INSECURITY		0x0010	/*%< Attempting proveunsecure. */#define VALATTR_DLVTRIED		0x0020	/*%< Looked for a DLV record. *//*! * NSEC proofs to be looked for. */#define VALATTR_NEEDNOQNAME		0x0100#define VALATTR_NEEDNOWILDCARD		0x0200#define VALATTR_NEEDNODATA		0x0400/*! * NSEC proofs that have been found. */#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 voiddlv_validator_start(dns_validator_t *val);static isc_result_tfinddlvsep(dns_validator_t *val, isc_boolean_t resume);static isc_result_tstartfinddlvsep(dns_validator_t *val, dns_name_t *unsecure);/*% * Mark the RRsets as a answer. */static inline voidmarkanswer(dns_validator_t *val) {	validator_log(val, ISC_LOG_DEBUG(3), "marking as answer");	if (val->event->rdataset != NULL)		val->event->rdataset->trust = dns_trust_answer;	if (val->event->sigrdataset != NULL)		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);}/*% * Look in the NSEC record returned from a DS query to see if there is * a NS RRset at this name.  If it is found we are at a delegation point. */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);}/*% * We have been asked to to look for a key. * If found resume the validation process. * If not found fail the validation process. */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);}/*% * We were asked to look for a DS record as part of following a key chain * upwards.  If found resume the validation process.  If not found fail the * validation process. */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);}/*% * We were asked to look for the DS record as part of proving that a * name is unsecure. * * If the DS record doesn't exist and the query name corresponds to * a delegation point we are transitioning from a secure zone to a * unsecure zone. * * If the DS record exists it will be secure.  We can continue looking * for the break point in the chain of trust. */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: %s",		      dns_result_totext(eresult));	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 if (val->view->dlv == NULL || DLVTRIED(val)) {				markanswer(val);				validator_done(val, ISC_R_SUCCESS);			} else {				result = startfinddlvsep(val, tname);				if (result != DNS_R_WAIT)					validator_done(val, result);			}		} 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)	{		/*		 * There is a DS which may or may not be a zone cut. 		 * In either case we are still in a secure zone resume		 * validation.		 */		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);

⌨️ 快捷键说明

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