validator.c

来自「bind 9.3结合mysql数据库」· C语言 代码 · 共 2,312 行 · 第 1/5 页

C
2,312
字号
dlv_fetched(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;	isc_event_free(&event);	dns_resolver_destroyfetch(&val->fetch);	INSIST(val->event != NULL);	validator_log(val, ISC_LOG_DEBUG(3), "in dlv_fetched");	LOCK(&val->lock);	if (eresult == ISC_R_SUCCESS) {		validator_log(val, ISC_LOG_DEBUG(3),			      "dlv set with trust %d", rdataset->trust);		val->dlv = &val->frdataset;		result = dlv_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),			      "dlv_fetched: 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);}static isc_result_tdlv_validatezonekey(dns_validator_t *val) {	dns_fixedname_t fixed;	dns_keytag_t keytag;	dns_name_t *name;	dns_name_t tname;	dns_rdata_dlv_t dlv;	dns_rdata_dnskey_t key;	dns_rdata_rrsig_t sig;	dns_rdata_t dlvrdata = DNS_RDATA_INIT;	dns_rdata_t keyrdata = DNS_RDATA_INIT;	dns_rdata_t newdsrdata = DNS_RDATA_INIT;	dns_rdata_t sigrdata = DNS_RDATA_INIT;	dns_rdataset_t trdataset;	dst_key_t *dstkey;	isc_boolean_t supported_algorithm;	isc_result_t result;	unsigned char dsbuf[DNS_DS_BUFFERSIZE];	unsigned int labels;	val->attributes |= VALATTR_DLVTRIED;	dns_name_init(&tname, NULL);	dns_fixedname_init(&fixed);	name = dns_fixedname_name(&fixed);	labels = dns_name_countlabels(val->event->name);	dns_name_getlabelsequence(val->event->name, 0, labels - 1, &tname);	result = dns_name_concatenate(&tname, val->view->dlv, name, NULL);	if (result != ISC_R_SUCCESS) {		validator_log(val, ISC_LOG_DEBUG(2),			      "DLV concatenate failed");		return (DNS_R_NOVALIDSIG);	}	if (val->dlv == NULL) {		result = view_find(val, name, dns_rdatatype_dlv);		if (result == ISC_R_SUCCESS) {			/*			 * We have DLV records.			 */			val->dsset = &val->frdataset;			if (val->frdataset.trust == dns_trust_pending &&			    dns_rdataset_isassociated(&val->fsigrdataset))			{				result = create_validator(val,							  val->event->name,							  dns_rdatatype_ds,							  &val->frdataset,							  &val->fsigrdataset,							  dlv_validated,							  "dlv_validatezonekey");				if (result != ISC_R_SUCCESS)					return (result);				return (DNS_R_WAIT);			} else if (val->frdataset.trust == dns_trust_pending) {				/*				 * There should never be an unsigned DLV.				 */				dns_rdataset_disassociate(&val->frdataset);				validator_log(val, ISC_LOG_DEBUG(2),					      "unsigned DLV record");				return (DNS_R_NOVALIDSIG);			} else				result = ISC_R_SUCCESS;		} else if (result == ISC_R_NOTFOUND) {			result = create_fetch(val, name, dns_rdatatype_dlv,					      dlv_fetched,					      "dlv_validatezonekey");			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)		{			/*			 * The DS does not exist.			 */			if (dns_rdataset_isassociated(&val->frdataset))				dns_rdataset_disassociate(&val->frdataset);			if (dns_rdataset_isassociated(&val->fsigrdataset))				dns_rdataset_disassociate(&val->fsigrdataset);			validator_log(val, ISC_LOG_DEBUG(2), "no DLV record");			return (DNS_R_NOVALIDSIG);		}	}	/*	 * We have a DLV set.	 */	INSIST(val->dlv != NULL);	if (val->dlv->trust < dns_trust_secure) {		if (val->mustbesecure) {			validator_log(val, ISC_LOG_WARNING,				      "must be secure failure");			return (DNS_R_MUSTBESECURE);		}		val->event->rdataset->trust = dns_trust_answer;		val->event->sigrdataset->trust = dns_trust_answer;		return (ISC_R_SUCCESS);	}	/*	 * Look through the DLV record and find the keys that can sign the	 * key set and the matching signature.  For each such key, attempt	 * verification.	 */	supported_algorithm = ISC_FALSE;	for (result = dns_rdataset_first(val->dlv);	     result == ISC_R_SUCCESS;	     result = dns_rdataset_next(val->dlv))	{		dns_rdata_reset(&dlvrdata);		dns_rdataset_current(val->dlv, &dlvrdata);		(void)dns_rdata_tostruct(&dlvrdata, &dlv, NULL);		if (!dns_resolver_algorithm_supported(val->view->resolver,						      val->event->name,						      dlv.algorithm))			continue;		supported_algorithm = ISC_TRUE;		dns_rdataset_init(&trdataset);		dns_rdataset_clone(val->event->rdataset, &trdataset);		for (result = dns_rdataset_first(&trdataset);		     result == ISC_R_SUCCESS;		     result = dns_rdataset_next(&trdataset))		{			dns_rdata_reset(&keyrdata);			dns_rdataset_current(&trdataset, &keyrdata);			(void)dns_rdata_tostruct(&keyrdata, &key, NULL);			keytag = compute_keytag(&keyrdata, &key);			if (dlv.key_tag != keytag ||			    dlv.algorithm != key.algorithm)				continue;			dns_rdata_reset(&newdsrdata);			result = dns_ds_buildrdata(val->event->name,						   &keyrdata, dlv.digest_type,						   dsbuf, &newdsrdata);			if (result != ISC_R_SUCCESS)				continue;			/* Covert to DLV */			newdsrdata.type = dns_rdatatype_dlv;			if (dns_rdata_compare(&dlvrdata, &newdsrdata) == 0)				break;		}		if (result != ISC_R_SUCCESS) {			validator_log(val, ISC_LOG_DEBUG(3),				      "no DNSKEY matching DLV");			continue;		}				for (result = dns_rdataset_first(val->event->sigrdataset);		     result == ISC_R_SUCCESS;		     result = dns_rdataset_next(val->event->sigrdataset))		{			dns_rdata_reset(&sigrdata);			dns_rdataset_current(val->event->sigrdataset,					     &sigrdata);			(void)dns_rdata_tostruct(&sigrdata, &sig, NULL);			if (dlv.key_tag != sig.keyid &&			    dlv.algorithm != sig.algorithm)				continue;			dstkey = NULL;			result = dns_dnssec_keyfromrdata(val->event->name,							 &keyrdata,							 val->view->mctx,							 &dstkey);			if (result != ISC_R_SUCCESS)				/*				 * This really shouldn't happen, but...				 */				continue;			result = verify(val, dstkey, &sigrdata);			dst_key_free(&dstkey);			if (result == ISC_R_SUCCESS)				break;		}		dns_rdataset_disassociate(&trdataset);		if (result == ISC_R_SUCCESS)			break;		validator_log(val, ISC_LOG_DEBUG(3),			      "no RRSIG matching DLV key");	}	if (result == ISC_R_SUCCESS) {		val->event->rdataset->trust = dns_trust_secure;		val->event->sigrdataset->trust = dns_trust_secure;		validator_log(val, ISC_LOG_DEBUG(3), "marking as secure");		return (result);	} else if (result == ISC_R_NOMORE && !supported_algorithm) {		if (val->mustbesecure) {			validator_log(val, ISC_LOG_WARNING,				      "must be secure failure");			return (DNS_R_MUSTBESECURE);		}		val->event->rdataset->trust = dns_trust_answer;		val->event->sigrdataset->trust = dns_trust_answer;		validator_log(val, ISC_LOG_DEBUG(3),			      "no supported algorithm (dlv)");		return (ISC_R_SUCCESS);	} else		return (DNS_R_NOVALIDSIG);}/* * Attempts positive response validation of an RRset containing zone keys. * * Returns: *	ISC_R_SUCCESS	Validation completed successfully *	DNS_R_WAIT	Validation has started but is waiting *			for an event. *	Other return codes are possible and all indicate failure. */static isc_result_tvalidatezonekey(dns_validator_t *val) {	isc_result_t result;	dns_validatorevent_t *event;	dns_rdataset_t trdataset;	dns_rdata_t dsrdata = DNS_RDATA_INIT;	dns_rdata_t newdsrdata = DNS_RDATA_INIT;	dns_rdata_t keyrdata = DNS_RDATA_INIT;	dns_rdata_t sigrdata = DNS_RDATA_INIT;	unsigned char dsbuf[DNS_DS_BUFFERSIZE];	dns_keytag_t keytag;	dns_rdata_ds_t ds;	dns_rdata_dnskey_t key;	dns_rdata_rrsig_t sig;	dst_key_t *dstkey;	isc_boolean_t supported_algorithm;	/*	 * Caller must be holding the validator lock.	 */	event = val->event;	if (val->dsset == NULL) {		/*		 * First, see if this key was signed by a trusted key.		 */		for (result = dns_rdataset_first(val->event->sigrdataset);		     result == ISC_R_SUCCESS;		     result = dns_rdataset_next(val->event->sigrdataset))		{			dns_keynode_t *keynode = NULL, *nextnode = NULL;			dns_rdata_reset(&sigrdata);			dns_rdataset_current(val->event->sigrdataset,					     &sigrdata);			(void)dns_rdata_tostruct(&sigrdata, &sig, NULL);			result = dns_keytable_findkeynode(val->keytable,							  val->event->name,							  sig.algorithm,							  sig.keyid,							  &keynode);			while (result == ISC_R_SUCCESS) {				dstkey = dns_keynode_key(keynode);				result = verify(val, dstkey, &sigrdata);				if (result == ISC_R_SUCCESS) {					dns_keytable_detachkeynode(val->keytable,								   &keynode);					break;				}				result = dns_keytable_findnextkeynode(								val->keytable,								keynode,								&nextnode);				dns_keytable_detachkeynode(val->keytable,							   &keynode);				keynode = nextnode;			}			if (result == ISC_R_SUCCESS) {				event->rdataset->trust = dns_trust_secure;				event->sigrdataset->trust = dns_trust_secure;				validator_log(val, ISC_LOG_DEBUG(3),					      "signed by trusted key; "					      "marking as secure");				return (result);			}		}		/*		 * If this is the root name and there was no trusted key,		 * give up, since there's no DS at the root.		 */		if (dns_name_equal(event->name, dns_rootname)) {			if ((val->attributes & VALATTR_TRIEDVERIFY) != 0)				return (DNS_R_NOVALIDSIG);			else				return (DNS_R_NOVALIDDS);		}		/*		 * Otherwise, try to find the DS record.		 */		result = view_find(val, val->event->name, dns_rdatatype_ds);		if (result == ISC_R_SUCCESS) {			/*			 * We have DS records.			 */			val->dsset = &val->frdataset;			if (val->frdataset.trust == dns_trust_pending &&			    dns_rdataset_isassociated(&val->fsigrdataset))			{				result = create_validator(val,							  val->event->name,							  dns_rdatatype_ds,							  &val->frdataset,							  &val->fsigrdataset,							  dsvalidated,							  "validatezonekey");				if (result != ISC_R_SUCCESS)					return (result);				return (DNS_R_WAIT);			} else if (val->frdataset.trust == dns_trust_pending) {				/*				 * There should never be an unsigned DS.				 */				dns_rdataset_disassociate(&val->frdataset);				validator_log(val, ISC_LOG_DEBUG(2),					      "unsigned DS record");				return (DNS_R_NOVALIDSIG);			} else				result = ISC_R_SUCCESS;		} else if (result == ISC_R_NOTFOUND) {			/*			 * We don't have the DS.  Find it.			 */			result = create_fetch(val, val->event->name,					      dns_rdatatype_ds, dsfetched,					      "validatezonekey");			if (result != ISC_R_SUCCESS)				return (result);			return (DNS_R_WAIT);		} else if (val->view->dlv != NULL && !DLVTRIED(val) &&			   (result == DNS_R_NCACHENXRRSET ||			    result == DNS_R_NXRRSET) &&			   !dns_name_issubdomain(val->event->name,						 val->view->dlv))		{			if (dns_rdataset_isassociated(&val->frdataset))				dns_rdataset_disassociate(&val->frdataset);			if (dns_rdataset_isassociated(&val->fsigrdataset))				dns_rdataset_disassociate(&val->fsigrdataset);			validator_log(val, ISC_LOG_DEBUG(2),				      "no DS record: looking for DLV");			return (dlv_validatezonekey(val));		 } else if (result ==  DNS_R_NCACHENXDOMAIN ||			   result == DNS_R_NCACHENXRRSET ||			   result == DNS_R_NXDOMAIN ||			   result == DNS_R_NXRRSET)		{			/*			 * The DS does not exist.			 */			if (dns_rdataset_isassociated(&val->frdataset))				dns_rdataset_disassociate(&val->frdataset);			if (dns_rdataset_isassociated(&val->fsigrdataset))				dns_rdataset_disassociate(&val->fsigrdataset);			validator_log(val, ISC_LOG_DEBUG(2), "no DS record");			return (DNS_R_NOVALIDSIG);		}	}	/*	 * We have a DS set.	 */	INSIST(val->dsset != NULL);	if (val->dsset->trust < dns_trust_secure) {		if (val->mustbesecure) {			validator_log(val, ISC_LOG_WARNING,				      "must be secure failure");			return (DNS_R_MUSTBESECURE);		}		val->event->rdataset->trust = dns_trust_answer;		val->event->sigrdataset->trust = dns_trust_answer;		return (ISC_R_SUCCESS);	}	/*	 * Look through the DS record and find the keys that can sign the	 * key set and the matching signature.  For each such key, attempt	 * verification.	 */	supported_algorithm = ISC_FALSE;	for (result = dns_rdataset_first(val->dsset);	     result == ISC_R_SUCCESS;	     result = dns_rdataset_next(val->dsset))	{		dns_rdata_reset(&dsrdata);		dns_rdataset_current(val->dsset, &dsrdata);		(void)dns_rdata_tostruct(&dsrdata, &ds, NULL);		if (!dns_resolver_algorithm_supported(val->view->resolver,						      val->event->name,						      ds.algorithm))			continue;

⌨️ 快捷键说明

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