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

📄 validator.c

📁 bind-3.2.
💻 C
📖 第 1 页 / 共 3 页
字号:
static inline isc_result_tnxtvalidate(dns_validator_t *val, isc_boolean_t resume) {	dns_name_t *name;	dns_message_t *message = val->event->message;	isc_result_t result;	if (!resume) {		result = dns_message_firstname(message, DNS_SECTION_AUTHORITY);		if (result != ISC_R_SUCCESS)			validator_done(val, ISC_R_NOTFOUND);	} else {		result = ISC_R_SUCCESS;		validator_log(val, ISC_LOG_DEBUG(3), "resuming nxtvalidate");	}	for (;	     result == ISC_R_SUCCESS;	     result = dns_message_nextname(message, DNS_SECTION_AUTHORITY))	{		dns_rdataset_t *rdataset = NULL, *sigrdataset = NULL;		name = NULL;		dns_message_currentname(message, DNS_SECTION_AUTHORITY, &name);		if (resume) {			rdataset = ISC_LIST_NEXT(val->currentset, link);			val->currentset = NULL;			resume = ISC_FALSE;		}		else			rdataset = ISC_LIST_HEAD(name->list);		for (;		     rdataset != NULL;		     rdataset = ISC_LIST_NEXT(rdataset, link))		{			if (rdataset->type == dns_rdatatype_sig)				continue;			for (sigrdataset = ISC_LIST_HEAD(name->list);			     sigrdataset != NULL;			     sigrdataset = ISC_LIST_NEXT(sigrdataset,							 link))			{				if (sigrdataset->type == dns_rdatatype_sig &&				    sigrdataset->covers == rdataset->type)					break;			}			if (sigrdataset == NULL)				continue;			val->seensig = ISC_TRUE;			/*			 * If a signed zone is missing the zone key, bad			 * things could happen.  A query for data in the zone			 * would lead to a query for the zone key, which			 * would return a negative answer, which would contain			 * an SOA and an NXT signed by the missing key, which			 * would trigger another query for the KEY (since the			 * first one is still in progress), and go into an			 * infinite loop.  Avoid that.			 */			if (val->event->type == dns_rdatatype_key &&			    dns_name_equal(name, val->event->name))			{				dns_rdata_t nxt = DNS_RDATA_INIT;				if (rdataset->type != dns_rdatatype_nxt)					continue;				result = dns_rdataset_first(rdataset);				if (result != ISC_R_SUCCESS)					return (result);				dns_rdataset_current(rdataset, &nxt);				if (dns_nxt_typepresent(&nxt,							dns_rdatatype_soa))					continue;			}			val->authvalidator = NULL;			val->currentset = rdataset;			result = dns_validator_create(val->view, name,						      rdataset->type,						      rdataset,						      sigrdataset,						      NULL, 0,						      val->task,						      authvalidated,						      val,						      &val->authvalidator);			if (result != ISC_R_SUCCESS)				return (result);			return (DNS_R_WAIT);		}	}	if (result == ISC_R_NOMORE)		result = ISC_R_SUCCESS;	if (result != ISC_R_SUCCESS)		validator_done(val, result);	if ((val->attributes & VALATTR_FOUNDNONEXISTENCE) == 0) {		if (!val->seensig) {			result = dns_validator_create(val->view, name,						      dns_rdatatype_soa,						      &val->frdataset,						      NULL, NULL, 0,						      val->task,						      negauthvalidated,						      val,						      &val->authvalidator);			if (result != ISC_R_SUCCESS)				return (result);			return (DNS_R_WAIT);		}		validator_log(val, ISC_LOG_DEBUG(3),			      "nonexistence proof not found");		return (DNS_R_NOVALIDNXT);	} else {		validator_log(val, ISC_LOG_DEBUG(3),			      "nonexistence proof found");		return (ISC_R_SUCCESS);	}}static inline isc_result_tproveunsecure(dns_validator_t *val, isc_boolean_t resume) {	isc_result_t result;	dns_fixedname_t secroot, tfname;	dns_name_t *tname;	dns_fixedname_init(&secroot);	dns_fixedname_init(&tfname);	result = dns_keytable_finddeepestmatch(val->view->secroots,					       val->event->name,					       dns_fixedname_name(&secroot));	/*	 * If the name is not under a security root, it must be insecure.	 */	if (result == ISC_R_NOTFOUND)		return (ISC_R_SUCCESS);	else if (result != ISC_R_SUCCESS)		return (result);	/*	 * If this is a security root, it's ok.	 */	if (val->event->type == dns_rdatatype_key &&	    dns_name_equal(val->event->name, dns_fixedname_name(&secroot)) &&	    issecurityroot(val))	{		val->event->rdataset->trust = dns_trust_secure;		return (ISC_R_SUCCESS);	}	if (!resume)		val->labels = dns_name_depth(dns_fixedname_name(&secroot)) + 1;	else {		validator_log(val, ISC_LOG_DEBUG(3), "resuming proveunsecure");		val->labels++;	}	for (;	     val->labels <= dns_name_depth(val->event->name);	     val->labels++)	{		char namebuf[1024];		if (val->labels == dns_name_depth(val->event->name)) {			if (val->event->type == dns_rdatatype_key)				break;			tname = val->event->name;		} else {			tname = dns_fixedname_name(&tfname);			result = dns_name_splitatdepth(val->event->name,						       val->labels,						       NULL, tname);			if (result != ISC_R_SUCCESS)				return (result);		}		dns_name_format(tname, namebuf, sizeof(namebuf));		validator_log(val, ISC_LOG_DEBUG(3),			      "looking for null keyset at '%s'",			      namebuf);		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, tname,					     dns_rdatatype_key, 0,					     DNS_DBFIND_PENDINGOK, ISC_FALSE,					     &val->frdataset,					     &val->fsigrdataset);		if (result == ISC_R_SUCCESS) {			dns_name_t *fname = NULL;			if (!dns_rdataset_isassociated(&val->fsigrdataset)) {				result = DNS_R_NOTINSECURE;				goto out;			}			validator_log(val, ISC_LOG_DEBUG(3),				      "found keyset, looking for null key");			if (!containsnullkey(val, &val->frdataset))				continue;			if (val->frdataset.trust >= dns_trust_secure) {				validator_log(val, ISC_LOG_DEBUG(3),					      "insecurity proof succeeded");				val->event->rdataset->trust = dns_trust_answer;				result = ISC_R_SUCCESS;				goto out;			}			fname = isc_mem_get(val->view->mctx, sizeof *fname);			if (fname == NULL)				return (ISC_R_NOMEMORY);			dns_name_init(fname, NULL);			result = dns_name_dup(tname, val->view->mctx, fname);			if (result != ISC_R_SUCCESS) {				isc_mem_put(val->view->mctx, fname,					    sizeof *fname);				result = ISC_R_NOMEMORY;				goto out;			}			result = dns_validator_create(val->view,						      fname,						      dns_rdatatype_key,						      &val->frdataset,						      &val->fsigrdataset,						      NULL,						      0,						      val->task,						      nullkeyvalidated,						      val,						      &val->keyvalidator);			if (result != ISC_R_SUCCESS)				goto out;			return (DNS_R_WAIT);		} else if (result == ISC_R_NOTFOUND) {			val->fetch = NULL;			result = dns_resolver_createfetch(val->view->resolver,							tname,							dns_rdatatype_key,							NULL, NULL, NULL, 0,							val->event->ev_sender,							fetch_callback_nullkey,							val,							&val->frdataset,							&val->fsigrdataset,							&val->fetch);			if (result != ISC_R_SUCCESS)				goto out;			return (DNS_R_WAIT);		} else if (result == DNS_R_NCACHENXDOMAIN ||			 result == DNS_R_NCACHENXRRSET ||			 result == DNS_R_NXDOMAIN ||			 result == DNS_R_NXRRSET)		{			continue;		} else			goto out;	}	validator_log(val, ISC_LOG_DEBUG(3), "insecurity proof failed");	return (DNS_R_NOTINSECURE); /* Didn't find a null key */ out:	if (dns_rdataset_isassociated(&val->frdataset))		dns_rdataset_disassociate(&val->frdataset);	if (dns_rdataset_isassociated(&val->fsigrdataset))		dns_rdataset_disassociate(&val->fsigrdataset);	return (result);}static voidvalidator_start(isc_task_t *task, isc_event_t *event) {	dns_validator_t *val;	dns_validatorevent_t *vevent;	isc_result_t result = ISC_R_FAILURE;	UNUSED(task);	REQUIRE(event->ev_type == DNS_EVENT_VALIDATORSTART);	vevent = (dns_validatorevent_t *)event;	val = vevent->validator;	/* If the validator has been cancelled, val->event == NULL */	if (val->event == NULL)		return;	validator_log(val, ISC_LOG_DEBUG(3), "starting");	LOCK(&val->lock);	if (val->event->rdataset != NULL && val->event->sigrdataset != NULL) {		isc_result_t saved_result;		/*		 * This looks like a simple validation.  We say "looks like"		 * because we don't know if wildcards are involved yet so it		 * could still get complicated.		 */		validator_log(val, ISC_LOG_DEBUG(3),			      "attempting positive response validation");		result = validate(val, ISC_FALSE);		if (result == DNS_R_NOVALIDSIG &&		    (val->attributes & VALATTR_TRIEDVERIFY) == 0)		{			saved_result = result;			validator_log(val, ISC_LOG_DEBUG(3),				      "falling back to insecurity proof");			result = proveunsecure(val, ISC_FALSE);			if (result == DNS_R_NOTINSECURE)				result = saved_result;		}	} else if (val->event->rdataset != NULL) {		/*		 * This is either an unsecure subdomain or a response from		 * a broken server.		 */		validator_log(val, ISC_LOG_DEBUG(3),			      "attempting insecurity proof");		result = proveunsecure(val, ISC_FALSE);	} else if (val->event->rdataset == NULL &&		 val->event->sigrdataset == NULL)	{		/*		 * This is a nonexistence validation.		 */		validator_log(val, ISC_LOG_DEBUG(3),			      "attempting negative response validation");		result = nxtvalidate(val, ISC_FALSE);	} else {		/*		 * This shouldn't happen.		 */		INSIST(0);	}	if (result != DNS_R_WAIT)		validator_done(val, result);	UNLOCK(&val->lock);}isc_result_tdns_validator_create(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,		     dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset,		     dns_message_t *message, unsigned int options,		     isc_task_t *task, isc_taskaction_t action, void *arg,		     dns_validator_t **validatorp){	isc_result_t result;	dns_validator_t *val;	isc_task_t *tclone;	dns_validatorevent_t *event;	REQUIRE(name != NULL);	REQUIRE(type != 0);	REQUIRE(rdataset != NULL ||		(rdataset == NULL && sigrdataset == NULL && message != NULL));	REQUIRE(options == 0);	REQUIRE(validatorp != NULL && *validatorp == NULL);	tclone = NULL;	result = ISC_R_FAILURE;	val = isc_mem_get(view->mctx, sizeof *val);	if (val == NULL)		return (ISC_R_NOMEMORY);	val->view = NULL;	dns_view_weakattach(view, &val->view);	event = (dns_validatorevent_t *)		isc_event_allocate(view->mctx, task,				   DNS_EVENT_VALIDATORSTART,				   validator_start, NULL,				   sizeof (dns_validatorevent_t));	if (event == NULL) {		result = ISC_R_NOMEMORY;		goto cleanup_val;	}	isc_task_attach(task, &tclone);	event->validator = val;	event->result = ISC_R_FAILURE;	event->name = name;	event->type = type;	event->rdataset = rdataset;	event->sigrdataset = sigrdataset;	event->message = message;	result = isc_mutex_init(&val->lock);	if (result != ISC_R_SUCCESS)		goto cleanup_event;	val->event = event;	val->options = options;	val->attributes = 0;	val->fetch = NULL;	val->keyvalidator = NULL;	val->authvalidator = NULL;	val->keynode = NULL;	val->key = NULL;	val->siginfo = NULL;	val->task = task;	val->action = action;	val->arg = arg;	val->labels = 0;	val->currentset = NULL;	val->keyset = NULL;	val->seensig = ISC_FALSE;	dns_rdataset_init(&val->frdataset);	dns_rdataset_init(&val->fsigrdataset);	ISC_LINK_INIT(val, link);	val->magic = VALIDATOR_MAGIC;	isc_task_send(task, (isc_event_t **)&event);	*validatorp = val;	return (ISC_R_SUCCESS); cleanup_event:	isc_task_detach(&tclone);	isc_event_free((isc_event_t **)&val->event); cleanup_val:	dns_view_weakdetach(&val->view);	isc_mem_put(view->mctx, val, sizeof *val);	return (result);}voiddns_validator_cancel(dns_validator_t *validator) {	REQUIRE(VALID_VALIDATOR(validator));	LOCK(&validator->lock);	validator_log(validator, ISC_LOG_DEBUG(3), "dns_validator_cancel");	if (validator->event != NULL) {		validator_done(validator, ISC_R_CANCELED);		if (validator->fetch != NULL)			dns_resolver_cancelfetch(validator->fetch);		if (validator->keyvalidator != NULL)			dns_validator_cancel(validator->keyvalidator);		if (validator->authvalidator != NULL)			dns_validator_cancel(validator->authvalidator);	}	UNLOCK(&validator->lock);}static voiddestroy(dns_validator_t *val) {	isc_mem_t *mctx;	REQUIRE(SHUTDOWN(val));	REQUIRE(val->event == NULL);	REQUIRE(val->fetch == NULL);	if (val->keynode != NULL)		dns_keytable_detachkeynode(val->keytable, &val->keynode);	else if (val->key != NULL)		dst_key_free(&val->key);	if (val->keyvalidator != NULL)		dns_validator_destroy(&val->keyvalidator);	if (val->authvalidator != NULL)		dns_validator_destroy(&val->authvalidator);	mctx = val->view->mctx;	if (val->siginfo != NULL)		isc_mem_put(mctx, val->siginfo, sizeof *val->siginfo);	DESTROYLOCK(&val->lock);	dns_view_weakdetach(&val->view);	val->magic = 0;	isc_mem_put(mctx, val, sizeof *val);}voiddns_validator_destroy(dns_validator_t **validatorp) {	dns_validator_t *val;	isc_boolean_t want_destroy = ISC_FALSE;	REQUIRE(validatorp != NULL);	val = *validatorp;	REQUIRE(VALID_VALIDATOR(val));	LOCK(&val->lock);	REQUIRE(val->event == NULL);	validator_log(val, ISC_LOG_DEBUG(3), "dns_validator_destroy");	val->attributes |= VALATTR_SHUTDOWN;	if (val->fetch == NULL && val->keyvalidator == NULL &&	    val->authvalidator == NULL)		want_destroy = ISC_TRUE;	UNLOCK(&val->lock);	if (want_destroy)		destroy(val);	*validatorp = NULL;}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_logv(dns_validator_t *val, isc_logcategory_t *category,	       isc_logmodule_t *module, int level, const char *fmt, va_list ap){	char msgbuf[2048];	vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap);	if (val->event != NULL && val->event->name != NULL) {		char namebuf[1024];		char typebuf[256];		isc_buffer_t b;		isc_region_t r;		dns_name_format(val->event->name, namebuf, sizeof(namebuf));		isc_buffer_init(&b, (unsigned char *)typebuf, sizeof(typebuf));		if (dns_rdatatype_totext(val->event->type, &b)		    != ISC_R_SUCCESS)		{			isc_buffer_clear(&b);			isc_buffer_putstr(&b, "<bad type>");		}		isc_buffer_usedregion(&b, &r);		isc_log_write(dns_lctx, category, module, level,			      "validating %s %.*s: %s", namebuf,			      (int)r.length, (char *)r.base, msgbuf);	} else {		isc_log_write(dns_lctx, category, module, level,			      "validator @%p: %s", val, msgbuf);	}}static voidvalidator_log(dns_validator_t *val, int level, const char *fmt, ...){	va_list ap;	if (! isc_log_wouldlog(dns_lctx, level))		return;	va_start(ap, fmt);	validator_logv(val, DNS_LOGCATEGORY_DNSSEC,		       DNS_LOGMODULE_VALIDATOR, level, fmt, ap);	va_end(ap);}

⌨️ 快捷键说明

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