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 + -
显示快捷键?