mirror of
https://github.com/pi-hole/dnsmasq.git
synced 2025-12-19 10:18:25 +00:00
Fix DNSSEC failure to validate unsigned NoDATA replies.
A reply with an empty answer section would not always be checked for either suitable NSEC records or proof of non-existence of the relevant DS record.
This commit is contained in:
52
src/dnssec.c
52
src/dnssec.c
@@ -1989,7 +1989,7 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
|
|||||||
{
|
{
|
||||||
/* NSEC and NSEC3 records must be signed. We make this assumption elsewhere. */
|
/* NSEC and NSEC3 records must be signed. We make this assumption elsewhere. */
|
||||||
if (type1 == T_NSEC || type1 == T_NSEC3)
|
if (type1 == T_NSEC || type1 == T_NSEC3)
|
||||||
rc = STAT_INSECURE;
|
return STAT_BOGUS | DNSSEC_FAIL_NOSIG;
|
||||||
else if (nons && i >= ntohs(header->ancount))
|
else if (nons && i >= ntohs(header->ancount))
|
||||||
/* If we're validating a DS reply, rather than looking for the value of AD bit,
|
/* If we're validating a DS reply, rather than looking for the value of AD bit,
|
||||||
we only care that NSEC and NSEC3 RRs in the auth section are signed.
|
we only care that NSEC and NSEC3 RRs in the auth section are signed.
|
||||||
@@ -2003,6 +2003,7 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
|
|||||||
rc = zone_status(name, class1, keyname, now);
|
rc = zone_status(name, class1, keyname, now);
|
||||||
if (STAT_ISEQUAL(rc, STAT_SECURE))
|
if (STAT_ISEQUAL(rc, STAT_SECURE))
|
||||||
rc = STAT_BOGUS | DNSSEC_FAIL_NOSIG;
|
rc = STAT_BOGUS | DNSSEC_FAIL_NOSIG;
|
||||||
|
|
||||||
if (class)
|
if (class)
|
||||||
*class = class1; /* Class for NEED_DS or NEED_KEY */
|
*class = class1; /* Class for NEED_DS or NEED_KEY */
|
||||||
}
|
}
|
||||||
@@ -2081,36 +2082,35 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* OK, all the RRsets validate, now see if we have a missing answer or CNAME target. */
|
/* OK, all the RRsets validate, now see if we have a missing answer or CNAME target. */
|
||||||
if (STAT_ISEQUAL(secure, STAT_SECURE))
|
for (j = 0; j <targetidx; j++)
|
||||||
for (j = 0; j <targetidx; j++)
|
if ((p2 = targets[j]))
|
||||||
if ((p2 = targets[j]))
|
{
|
||||||
{
|
if (neganswer)
|
||||||
if (neganswer)
|
*neganswer = 1;
|
||||||
*neganswer = 1;
|
|
||||||
|
|
||||||
if (!extract_name(header, plen, &p2, name, 1, 10))
|
if (!extract_name(header, plen, &p2, name, 1, 10))
|
||||||
return STAT_BOGUS; /* bad packet */
|
return STAT_BOGUS; /* bad packet */
|
||||||
|
|
||||||
/* NXDOMAIN or NODATA reply, unanswered question is (name, qclass, qtype) */
|
/* NXDOMAIN or NODATA reply, unanswered question is (name, qclass, qtype) */
|
||||||
|
|
||||||
/* For anything other than a DS record, this situation is OK if either
|
/* For anything other than a DS record, this situation is OK if either
|
||||||
the answer is in an unsigned zone, or there's a NSEC records. */
|
the answer is in an unsigned zone, or there's a NSEC records. */
|
||||||
if (!prove_non_existence(header, plen, keyname, name, qtype, qclass, NULL, nons, nsec_ttl))
|
if (!prove_non_existence(header, plen, keyname, name, qtype, qclass, NULL, nons, nsec_ttl))
|
||||||
{
|
{
|
||||||
/* Empty DS without NSECS */
|
/* Empty DS without NSECS */
|
||||||
if (qtype == T_DS)
|
if (qtype == T_DS)
|
||||||
return STAT_BOGUS | DNSSEC_FAIL_NONSEC;
|
return STAT_BOGUS | DNSSEC_FAIL_NONSEC;
|
||||||
|
|
||||||
if (!STAT_ISEQUAL((rc = zone_status(name, qclass, keyname, now)), STAT_SECURE))
|
if (!STAT_ISEQUAL((rc = zone_status(name, qclass, keyname, now)), STAT_SECURE))
|
||||||
{
|
{
|
||||||
if (class)
|
if (class)
|
||||||
*class = qclass; /* Class for NEED_DS or NEED_KEY */
|
*class = qclass; /* Class for NEED_DS or NEED_KEY */
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
return STAT_BOGUS | DNSSEC_FAIL_NONSEC; /* signed zone, no NSECs */
|
return STAT_BOGUS | DNSSEC_FAIL_NONSEC; /* signed zone, no NSECs */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return secure;
|
return secure;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user