mirror of
https://github.com/isc-projects/bind9.git
synced 2026-06-10 11:10:00 -04:00
Fix "no DS" proofs for wildcard+CNAME delegations
When answering a query requires wildcard expansion, the AUTHORITY section of the response needs to include NSEC(3) record(s) proving that the QNAME does not exist. When a response to a query is an insecure delegation, the AUTHORITY section needs to include an NSEC(3) proof that no DS record exists at the parent side of the zone cut. These two conditions combined trip up the NSEC part of the logic contained in query_addds(), which expects the NS RRset to be owned by the first name found in the AUTHORITY section of a delegation response. This may not always be true, for example if wildcard expansion causes an NSEC record proving QNAME nonexistence to be added to the AUTHORITY section before the delegation is added to the response. In such a case, named incorrectly omits the NSEC record proving nonexistence of QNAME from the AUTHORITY section. The same block of code is affected by another flaw: if the same NSEC record proves nonexistence of both the QNAME and the DS record at the parent side of the zone cut, this NSEC record will be added to the AUTHORITY section twice. Fix by looking for the NS RRset in the entire AUTHORITY section and adding the NSEC record to the delegation using query_addrrset() (which handles duplicate RRset detection).
This commit is contained in:
parent
26ec4b9a89
commit
7a87bf468b
1 changed files with 24 additions and 10 deletions
|
|
@ -9017,26 +9017,40 @@ query_addds(query_ctx_t *qctx) {
|
|||
|
||||
/*
|
||||
* We've already added the NS record, so if the name's not there,
|
||||
* we have other problems. Use this name rather than calling
|
||||
* query_addrrset().
|
||||
* we have other problems.
|
||||
*/
|
||||
result = dns_message_firstname(client->message, DNS_SECTION_AUTHORITY);
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
rname = NULL;
|
||||
dns_message_currentname(client->message, DNS_SECTION_AUTHORITY, &rname);
|
||||
result = dns_message_findtype(rname, dns_rdatatype_ns, 0, NULL);
|
||||
/*
|
||||
* Find the delegation in the response message - it is not necessarily
|
||||
* the first name in the AUTHORITY section when wildcard processing is
|
||||
* involved.
|
||||
*/
|
||||
while (result == ISC_R_SUCCESS) {
|
||||
rname = NULL;
|
||||
dns_message_currentname(client->message, DNS_SECTION_AUTHORITY,
|
||||
&rname);
|
||||
result = dns_message_findtype(rname, dns_rdatatype_ns, 0, NULL);
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
result = dns_message_nextname(client->message,
|
||||
DNS_SECTION_AUTHORITY);
|
||||
}
|
||||
|
||||
if (result != ISC_R_SUCCESS) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
ISC_LIST_APPEND(rname->list, rdataset, link);
|
||||
ISC_LIST_APPEND(rname->list, sigrdataset, link);
|
||||
rdataset = NULL;
|
||||
sigrdataset = NULL;
|
||||
return;
|
||||
/*
|
||||
* Add the NSEC record to the delegation.
|
||||
*/
|
||||
query_addrrset(qctx, &rname, &rdataset, &sigrdataset, NULL,
|
||||
DNS_SECTION_AUTHORITY);
|
||||
goto cleanup;
|
||||
|
||||
addnsec3:
|
||||
if (!dns_db_iszone(qctx->db)) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue