validator.c
来自「bind 9.3结合mysql数据库」· C语言 代码 · 共 2,312 行 · 第 1/5 页
C
2,312 行
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 (ds.key_tag != keytag || ds.algorithm != key.algorithm) continue; dns_rdata_reset(&newdsrdata); result = dns_ds_buildrdata(val->event->name, &keyrdata, ds.digest_type, dsbuf, &newdsrdata); if (result != ISC_R_SUCCESS) continue; if (dns_rdata_compare(&dsrdata, &newdsrdata) == 0) break; } if (result != ISC_R_SUCCESS) { validator_log(val, ISC_LOG_DEBUG(3), "no DNSKEY matching DS"); 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 (ds.key_tag != sig.keyid && ds.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 DS key"); } if (result == ISC_R_SUCCESS) { event->rdataset->trust = dns_trust_secure; event->sigrdataset->trust = dns_trust_secure; validator_log(val, ISC_LOG_DEBUG(3), "marking as secure"); return (result); } else if (result == ISC_R_NOMORE && val->view->dlv != NULL && !DLVTRIED(val) && !dns_name_issubdomain(val->event->name, val->view->dlv)) { validator_log(val, ISC_LOG_DEBUG(2), "no DS/DNSKEY pair: looking for DLV"); return (dlv_validatezonekey(val)); } 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 (ds)"); return (ISC_R_SUCCESS); } else return (DNS_R_NOVALIDSIG);}/* * Starts a positive response validation. * * 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_tstart_positive_validation(dns_validator_t *val) { /* * If this is not a key, go straight into validate(). */ if (val->event->type != dns_rdatatype_dnskey || !isselfsigned(val)) return (validate(val, ISC_FALSE)); return (validatezonekey(val));}static isc_result_tcheckwildcard(dns_validator_t *val) { dns_name_t *name, *wild; dns_message_t *message = val->event->message; isc_result_t result; isc_boolean_t exists, data; char namebuf[DNS_NAME_FORMATSIZE]; wild = dns_fixedname_name(&val->wild); dns_name_format(wild, namebuf, sizeof(namebuf)); validator_log(val, ISC_LOG_DEBUG(3), "in checkwildcard: %s", namebuf); for (result = dns_message_firstname(message, DNS_SECTION_AUTHORITY); 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); for (rdataset = ISC_LIST_HEAD(name->list); rdataset != NULL; rdataset = ISC_LIST_NEXT(rdataset, link)) { if (rdataset->type != dns_rdatatype_nsec) continue; val->nsecset = rdataset; for (sigrdataset = ISC_LIST_HEAD(name->list); sigrdataset != NULL; sigrdataset = ISC_LIST_NEXT(sigrdataset, link)) { if (sigrdataset->type == dns_rdatatype_rrsig && sigrdataset->covers == rdataset->type) break; } if (sigrdataset == NULL) continue; if (rdataset->trust != dns_trust_secure) continue; if (((val->attributes & VALATTR_NEEDNODATA) != 0 || (val->attributes & VALATTR_NEEDNOWILDCARD) != 0) && (val->attributes & VALATTR_FOUNDNODATA) == 0 && (val->attributes & VALATTR_FOUNDNOWILDCARD) == 0 && nsecnoexistnodata(val, wild, name, rdataset, &exists, &data, NULL) == ISC_R_SUCCESS) { dns_name_t **proofs = val->event->proofs; if (exists && !data) val->attributes |= VALATTR_FOUNDNODATA; if (exists && !data && NEEDNODATA(val)) proofs[DNS_VALIDATOR_NODATAPROOF] = name; if (!exists) val->attributes |= VALATTR_FOUNDNOWILDCARD; if (!exists && NEEDNOQNAME(val)) proofs[DNS_VALIDATOR_NOWILDCARDPROOF] = name; return (ISC_R_SUCCESS); } } } if (result == ISC_R_NOMORE) result = ISC_R_SUCCESS; return (result);}static isc_result_tnsecvalidate(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); else { result = ISC_R_SUCCESS; validator_log(val, ISC_LOG_DEBUG(3), "resuming nsecvalidate"); } 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_rrsig) continue; if (rdataset->type == dns_rdatatype_soa) { val->soaset = rdataset; val->soaname = name; } else if (rdataset->type == dns_rdatatype_nsec) val->nsecset = rdataset; for (sigrdataset = ISC_LIST_HEAD(name->list); sigrdataset != NULL; sigrdataset = ISC_LIST_NEXT(sigrdataset, link)) { if (sigrdataset->type == dns_rdatatype_rrsig && sigrdataset->covers == rdataset->type) break; } if (sigrdataset == NULL) continue; /* * 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 NSEC signed by the missing key, which * would trigger another query for the DNSKEY (since * the first one is still in progress), and go into an * infinite loop. Avoid that. */ if (val->event->type == dns_rdatatype_dnskey && dns_name_equal(name, val->event->name)) { dns_rdata_t nsec = DNS_RDATA_INIT; if (rdataset->type != dns_rdatatype_nsec) continue; result = dns_rdataset_first(rdataset); if (result != ISC_R_SUCCESS) return (result); dns_rdataset_current(rdataset, &nsec); if (dns_nsec_typepresent(&nsec, dns_rdatatype_soa)) continue; } val->currentset = rdataset; result = create_validator(val, name, rdataset->type, rdataset, sigrdataset, authvalidated, "nsecvalidate"); 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) return (result); /* * Do we only need to check for NOQNAME? */ if ((val->attributes & VALATTR_NEEDNODATA) == 0 && (val->attributes & VALATTR_NEEDNOWILDCARD) == 0 && (val->attributes & VALATTR_NEEDNOQNAME) != 0) { if ((val->attributes & VALATTR_FOUNDNOQNAME) != 0) { validator_log(val, ISC_LOG_DEBUG(3), "noqname proof found"); validator_log(val, ISC_LOG_DEBUG(3), "marking as secure"); val->event->rdataset->trust = dns_trust_secure; val->event->sigrdataset->trust = dns_trust_secure; return (ISC_R_SUCCESS); } validator_log(val, ISC_LOG_DEBUG(3), "noqname proof not found"); return (DNS_R_NOVALIDNSEC); } /* * Do we need to check for the wildcard? */ if ((val->attributes & VALATTR_FOUNDNOQNAME) != 0 && (((val->attributes & VALATTR_NEEDNODATA) != 0 && (val->attributes & VALATTR_FOUNDNODATA) == 0) || (val->attributes & VALATTR_NEEDNOWILDCARD) != 0)) { result = checkwildcard(val); if (result != ISC_R_SUCCESS) return (result); } if (((val->attributes & VALATTR_NEEDNODATA) != 0 && (val->attributes & VALATTR_FOUNDNODATA) != 0) || ((val->attributes & VALATTR_NEEDNOQNAME) != 0 && (val->attributes & VALATTR_FOUNDNOQNAME) != 0 && (val->attributes & VALATTR_NEEDNOWILDCARD) != 0 && (val->attributes & VALATTR_FOUNDNOWILDCARD) != 0)) val->attributes |= VALATTR_FOUNDNONEXISTENCE; if ((val->attributes & VALATTR_FOUNDNONEXISTENCE) == 0) { if (!val->seensig && val->soaset != NULL) { result = create_validator(val, name, dns_rdatatype_soa, val->soaset, NULL, negauthvalidated, "nsecvalidate"); 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_NOVALIDNSEC); } else { validator_log(val, ISC_LOG_DEBUG(3), "nonexistence proof found"); return (ISC_R_SUCCESS); }}static isc_boolean_tcheck_ds_algorithm(dns_validator_t *val, dns_name_t *name, dns_rdataset_t *rdataset) { dns_rdata_t dsrdata = DNS_RDATA_INIT; dns_rdata_ds_t ds; isc_result_t result; for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(rdataset)) { dns_rdataset_current(rdataset, &dsrdata); (void)dns_rdata_tostruct(&dsrdata, &ds, NULL); if (dns_resolver_algorithm_supported(val->view->resolver, name, ds.algorithm)) return (ISC_TRUE); dns_rdata_reset(&dsrdata); } return (ISC_FALSE);}static voiddlv_fetched2(isc_task_t *task, isc_event_t *event) { dns_fetchevent_t *devent; dns_validator_t *val; isc_boolean_t want_destroy; isc_result_t eresult; isc_result_t result; UNUSED(task); INSIST(event->ev_type == DNS_EVENT_FETCHDONE); devent = (dns_fetchevent_t *)event; val = devent->ev_arg; 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_fetched2: %s", dns_result_totext(eresult)); LOCK(&val->lock); if (eresult == ISC_R_SUCCESS) { val->havedlvsep = ISC_TRUE; result = proveunsecure(val, ISC_FALSE); if (result != DNS_R_WAIT) validator_done(val, result); } else if (eresult == DNS_R_NXRRSET || eresult == DNS_R_NXDOMAIN || eresult == DNS_R_NCACHENXRRSET || eresult == DNS_R_NCACHENXDOMAIN) { result = finddlvsep(val, ISC_TRUE); if (result == ISC_R_SUCCESS) { result = proveunsecure(val, ISC_FALSE); if (result != DNS_R_WAIT) validator_done(val, result); } else if (result == ISC_R_NOTFOUND) { validator_done(val, ISC_R_SUCCESS); } else if (result != DNS_R_WAIT) validator_done(val, result); } want_destroy = exit_check(val); UNLOCK(&val->lock); if (want_destroy) destroy(val);}static isc_result_tfinddlvsep(dns_validator_t *val, isc_boolean_t resume) { dns_fixedname_t dlvfixed; dns_name_t *dlvname; dns_name_t *dlvsep; dns_name_t noroot; isc_result_t result; unsigned int labels; if (!resume) { dns_fixedname_init(&val->dlvsep); dlvsep = dns_fixedname_name(&val->dlvsep); dns_name_copy(val->event->name, dlvsep, NULL); val->attributes |= VALATTR_DLVSEPTRIED; } else { dlvsep = dns_fixedname_name(&val->dlvsep); labels = dns_name_countlabels(dlvsep); dns_name_getlabelsequence(dlvsep, 1, labels - 1, dlvsep); } dns_name_init(&noroot, NULL); dns_fixedname_init(&dlvfixed); dlvname = dns_fixedname_name(&dlvfixed); labels = dns_name_countlabels(dlvsep); dns_name_getlabelsequence(dlvsep, 0, labels - 1, &noroot); result = dns_name_concatenate(&noroot, val->view->dlv, dlvname, NULL); while (result == ISC_R_NOSPACE) { labels = dns_name_countlabels(dlvsep); dns_name_getlabelsequence(dlvsep, 1, labels - 1, dlvsep); dns_name_getlabelsequence(dlvsep, 0, labels - 2, &noroot); result = dns_name_concatenate(&noroot, val->view->dlv, dlvname, NULL); } if (result != ISC_R_SUCCESS) { validator_log(val, ISC_LOG_DEBUG(2), "DLV concatenate failed"); return (DNS_R_NOVALIDSIG); } while (dns_name_countlabels(dlvname) > dns_name_countlabels(val->view->dlv)) { result = view_find(val, dlvname, dns_rdatatype_dlv); if (result == ISC_R_SUCCESS) { if (val->frdataset.trust < dns_trust_secure) return (DNS_R_NOVALIDSIG); val->havedlvsep = ISC_TRUE; return (ISC_R_SUCCESS); } if (result == ISC_R_NOTFOUND) { result = create_fetch(val, dlvname, dns_rdatatype_dlv, dlv_fetched2, "finddlvsep"); if (result != ISC_R_SUCCESS)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?