mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-29 13:38:26 +00:00
[9.18] fix: usr: Remove NSEC/DS/NSEC3 RRSIG check from dns_message_parse
Previously, when parsing responses, named incorrectly rejected responses without matching RRSIG records for NSEC/DS/NSEC3 records in the authority section. This rejection, if appropriate, should have been left for the validator to determine and has been fixed. Closes #5185 Backport of MR !10125 Merge branch 'backport-5185-remove-rrsig-check-from-dns_message_parse-9.18' into 'bind-9.18' See merge request isc-projects/bind9!10143
This commit is contained in:
commit
b601cb32ee
@ -38,6 +38,7 @@ def logquery(type, qname):
|
|||||||
# NS gets a unsigned response.
|
# NS gets a unsigned response.
|
||||||
# DNSKEY get a unsigned NODATA response.
|
# DNSKEY get a unsigned NODATA response.
|
||||||
# A gets a signed response.
|
# A gets a signed response.
|
||||||
|
# TXT gets a signed NODATA response without RRSIG.
|
||||||
# All other types get a unsigned NODATA response.
|
# All other types get a unsigned NODATA response.
|
||||||
############################################################################
|
############################################################################
|
||||||
def create_response(msg):
|
def create_response(msg):
|
||||||
@ -72,6 +73,11 @@ def create_response(msg):
|
|||||||
r.answer.append(dns.rrset.from_text(qname, 1, IN, NS, "."))
|
r.answer.append(dns.rrset.from_text(qname, 1, IN, NS, "."))
|
||||||
elif rrtype == SOA:
|
elif rrtype == SOA:
|
||||||
r.answer.append(dns.rrset.from_text(qname, 1, IN, SOA, ". . 0 0 0 0 0"))
|
r.answer.append(dns.rrset.from_text(qname, 1, IN, SOA, ". . 0 0 0 0 0"))
|
||||||
|
elif rrtype == TXT:
|
||||||
|
r.authority.append(dns.rrset.from_text(qname, 1, IN, SOA, ". . 0 0 0 0 0"))
|
||||||
|
r.authority.append(
|
||||||
|
dns.rrset.from_text(qname, 1, IN, NSEC, qname + " A NS SOA RRSIG NSEC")
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
r.authority.append(dns.rrset.from_text(qname, 1, IN, SOA, ". . 0 0 0 0 0"))
|
r.authority.append(dns.rrset.from_text(qname, 1, IN, SOA, ". . 0 0 0 0 0"))
|
||||||
r.flags |= dns.flags.AA
|
r.flags |= dns.flags.AA
|
||||||
|
@ -43,3 +43,5 @@ ds-rrsigs-stripped. NS ns2.ds-rrsigs-stripped.
|
|||||||
ns2.ds-rrsigs-stripped. A 10.53.0.2
|
ns2.ds-rrsigs-stripped. A 10.53.0.2
|
||||||
inconsistent. NS ns2.inconsistent.
|
inconsistent. NS ns2.inconsistent.
|
||||||
ns2.inconsistent. A 10.53.0.2
|
ns2.inconsistent. A 10.53.0.2
|
||||||
|
nsec-rrsigs-stripped. NS ns10.nsec-rrsigs-stripped.
|
||||||
|
ns10.nsec-rrsigs-stripped. A 10.53.0.10
|
||||||
|
@ -4553,5 +4553,21 @@ n=$((n + 1))
|
|||||||
if [ "$ret" -ne 0 ]; then echo_i "failed"; fi
|
if [ "$ret" -ne 0 ]; then echo_i "failed"; fi
|
||||||
status=$((status + ret))
|
status=$((status + ret))
|
||||||
|
|
||||||
|
echo_i "checking that a insecure negative response where there is a NSEC without a RRSIG succeeds ($n)"
|
||||||
|
ret=0
|
||||||
|
# check server preconditions
|
||||||
|
dig_with_opts +notcp @10.53.0.10 nsec-rrsigs-stripped. TXT +dnssec >dig.out.ns10.test$n
|
||||||
|
grep "status: NOERROR" dig.out.ns10.test$n >/dev/null || ret=1
|
||||||
|
grep "QUERY: 1, ANSWER: 0, AUTHORITY: 2, ADDITIONAL: 1" dig.out.ns10.test$n >/dev/null || ret=1
|
||||||
|
grep "IN.RRSIG.NSEC" dig.out.ns10.test$n >/dev/null && ret=1
|
||||||
|
# check resolver succeeds
|
||||||
|
dig_with_opts @10.53.0.4 nsec-rrsigs-stripped. TXT +dnssec >dig.out.ns4.test$n
|
||||||
|
grep "status: NOERROR" dig.out.ns4.test$n >/dev/null || ret=1
|
||||||
|
grep "QUERY: 1, ANSWER: 0, AUTHORITY: 2, ADDITIONAL: 1" dig.out.ns4.test$n >/dev/null || ret=1
|
||||||
|
grep "IN.RRSIG.NSEC" dig.out.ns4.test$n >/dev/null && ret=1
|
||||||
|
n=$((n + 1))
|
||||||
|
if [ "$ret" -ne 0 ]; then echo_i "failed"; fi
|
||||||
|
status=$((status + ret))
|
||||||
|
|
||||||
echo_i "exit status: $status"
|
echo_i "exit status: $status"
|
||||||
[ $status -eq 0 ] || exit 1
|
[ $status -eq 0 ] || exit 1
|
||||||
|
@ -1197,62 +1197,6 @@ update(dns_section_t section, dns_rdataclass_t rdclass) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Check to confirm that all DNSSEC records (DS, NSEC, NSEC3) have
|
|
||||||
* covering RRSIGs.
|
|
||||||
*/
|
|
||||||
static bool
|
|
||||||
auth_signed(dns_namelist_t *section) {
|
|
||||||
dns_name_t *name;
|
|
||||||
|
|
||||||
for (name = ISC_LIST_HEAD(*section); name != NULL;
|
|
||||||
name = ISC_LIST_NEXT(name, link))
|
|
||||||
{
|
|
||||||
int auth_dnssec = 0, auth_rrsig = 0;
|
|
||||||
dns_rdataset_t *rds;
|
|
||||||
|
|
||||||
for (rds = ISC_LIST_HEAD(name->list); rds != NULL;
|
|
||||||
rds = ISC_LIST_NEXT(rds, link))
|
|
||||||
{
|
|
||||||
switch (rds->type) {
|
|
||||||
case dns_rdatatype_ds:
|
|
||||||
auth_dnssec |= 0x1;
|
|
||||||
break;
|
|
||||||
case dns_rdatatype_nsec:
|
|
||||||
auth_dnssec |= 0x2;
|
|
||||||
break;
|
|
||||||
case dns_rdatatype_nsec3:
|
|
||||||
auth_dnssec |= 0x4;
|
|
||||||
break;
|
|
||||||
case dns_rdatatype_rrsig:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (rds->covers) {
|
|
||||||
case dns_rdatatype_ds:
|
|
||||||
auth_rrsig |= 0x1;
|
|
||||||
break;
|
|
||||||
case dns_rdatatype_nsec:
|
|
||||||
auth_rrsig |= 0x2;
|
|
||||||
break;
|
|
||||||
case dns_rdatatype_nsec3:
|
|
||||||
auth_rrsig |= 0x4;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (auth_dnssec != auth_rrsig) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static isc_result_t
|
static isc_result_t
|
||||||
getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
|
getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
|
||||||
dns_section_t sectionid, unsigned int options) {
|
dns_section_t sectionid, unsigned int options) {
|
||||||
@ -1723,21 +1667,6 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
|
|||||||
INSIST(!free_name);
|
INSIST(!free_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* If any of DS, NSEC or NSEC3 appeared in the
|
|
||||||
* authority section of a query response without
|
|
||||||
* a covering RRSIG, FORMERR
|
|
||||||
*/
|
|
||||||
if (sectionid == DNS_SECTION_AUTHORITY &&
|
|
||||||
msg->opcode == dns_opcode_query &&
|
|
||||||
((msg->flags & DNS_MESSAGEFLAG_QR) != 0) &&
|
|
||||||
((msg->flags & DNS_MESSAGEFLAG_TC) == 0) && !preserve_order &&
|
|
||||||
!auth_signed(section))
|
|
||||||
{
|
|
||||||
/* XXX test coverage */
|
|
||||||
DO_ERROR(DNS_R_FORMERR);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (seen_problem) {
|
if (seen_problem) {
|
||||||
result = DNS_R_RECOVERABLE;
|
result = DNS_R_RECOVERABLE;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user