mirror of
https://github.com/pi-hole/dnsmasq.git
synced 2025-12-19 18:28:25 +00:00
Mass edit of INSECURE->BOGUS returns for server failure/bad input.
This commit is contained in:
157
src/dnssec.c
157
src/dnssec.c
@@ -592,8 +592,8 @@ static void sort_rrset(struct dns_header *header, size_t plen, u16 *rr_desc, int
|
||||
STAT_SECURE if it validates.
|
||||
STAT_SECURE_WILDCARD if it validates and is the result of wildcard expansion.
|
||||
STAT_NO_SIG no RRsigs found.
|
||||
STAT_INSECURE can't validate (no RRSIG, bad packet).
|
||||
STAT_BOGUS signature is wrong.
|
||||
STAT_INSECURE RRset empty.
|
||||
STAT_BOGUS signature is wrong, bad packet.
|
||||
STAT_NEED_KEY need DNSKEY to complete validation (name is returned in keyname)
|
||||
|
||||
if key is non-NULL, use that key, which has the algo and tag given in the params of those names,
|
||||
@@ -614,7 +614,7 @@ static int validate_rrset(time_t now, struct dns_header *header, size_t plen, in
|
||||
u16 *rr_desc = get_desc(type);
|
||||
|
||||
if (!(p = skip_questions(header, plen)))
|
||||
return STAT_INSECURE;
|
||||
return STAT_BOGUS;
|
||||
|
||||
name_labels = count_labels(name); /* For 4035 5.3.2 check */
|
||||
|
||||
@@ -628,7 +628,7 @@ static int validate_rrset(time_t now, struct dns_header *header, size_t plen, in
|
||||
pstart = p;
|
||||
|
||||
if (!(res = extract_name(header, plen, &p, name, 0, 10)))
|
||||
return STAT_INSECURE; /* bad packet */
|
||||
return STAT_BOGUS; /* bad packet */
|
||||
|
||||
GETSHORT(stype, p);
|
||||
GETSHORT(sclass, p);
|
||||
@@ -639,14 +639,14 @@ static int validate_rrset(time_t now, struct dns_header *header, size_t plen, in
|
||||
GETSHORT(rdlen, p);
|
||||
|
||||
if (!CHECK_LEN(header, p, plen, rdlen))
|
||||
return STAT_INSECURE;
|
||||
return STAT_BOGUS;
|
||||
|
||||
if (res == 1 && sclass == class)
|
||||
{
|
||||
if (stype == type)
|
||||
{
|
||||
if (!expand_workspace(&rrset, &rrset_sz, rrsetidx))
|
||||
return STAT_INSECURE;
|
||||
return STAT_BOGUS;
|
||||
|
||||
rrset[rrsetidx++] = pstart;
|
||||
}
|
||||
@@ -654,14 +654,14 @@ static int validate_rrset(time_t now, struct dns_header *header, size_t plen, in
|
||||
if (stype == T_RRSIG)
|
||||
{
|
||||
if (rdlen < 18)
|
||||
return STAT_INSECURE; /* bad packet */
|
||||
return STAT_BOGUS; /* bad packet */
|
||||
|
||||
GETSHORT(type_covered, p);
|
||||
|
||||
if (type_covered == type)
|
||||
{
|
||||
if (!expand_workspace(&sigs, &sig_sz, sigidx))
|
||||
return STAT_INSECURE;
|
||||
return STAT_BOGUS;
|
||||
|
||||
sigs[sigidx++] = pdata;
|
||||
}
|
||||
@@ -671,7 +671,7 @@ static int validate_rrset(time_t now, struct dns_header *header, size_t plen, in
|
||||
}
|
||||
|
||||
if (!ADD_RDLEN(header, p, plen, rdlen))
|
||||
return STAT_INSECURE;
|
||||
return STAT_BOGUS;
|
||||
}
|
||||
|
||||
/* RRset empty */
|
||||
@@ -710,7 +710,7 @@ static int validate_rrset(time_t now, struct dns_header *header, size_t plen, in
|
||||
GETSHORT(key_tag, p);
|
||||
|
||||
if (!extract_name(header, plen, &p, keyname, 1, 0))
|
||||
return STAT_INSECURE;
|
||||
return STAT_BOGUS;
|
||||
|
||||
/* RFC 4035 5.3.1 says that the Signer's Name field MUST equal
|
||||
the name of the zone containing the RRset. We can't tell that
|
||||
@@ -765,7 +765,7 @@ static int validate_rrset(time_t now, struct dns_header *header, size_t plen, in
|
||||
|
||||
p = rrset[i];
|
||||
if (!extract_name(header, plen, &p, name, 1, 10))
|
||||
return STAT_INSECURE;
|
||||
return STAT_BOGUS;
|
||||
|
||||
name_start = name;
|
||||
|
||||
@@ -788,7 +788,7 @@ static int validate_rrset(time_t now, struct dns_header *header, size_t plen, in
|
||||
p += 8; /* skip class, type, ttl */
|
||||
GETSHORT(rdlen, p);
|
||||
if (!CHECK_LEN(header, p, plen, rdlen))
|
||||
return STAT_INSECURE;
|
||||
return STAT_BOGUS;
|
||||
|
||||
end = p + rdlen;
|
||||
|
||||
@@ -839,10 +839,10 @@ static int validate_rrset(time_t now, struct dns_header *header, size_t plen, in
|
||||
/* The DNS packet is expected to contain the answer to a DNSKEY query.
|
||||
Put all DNSKEYs in the answer which are valid into the cache.
|
||||
return codes:
|
||||
STAT_INSECURE bad packet, no DNSKEYs in reply.
|
||||
STAT_INSECURE No DNSKEYs in reply.
|
||||
STAT_SECURE At least one valid DNSKEY found and in cache.
|
||||
STAT_BOGUS No DNSKEYs found, which can be validated with DS,
|
||||
or self-sign for DNSKEY RRset is not valid.
|
||||
or self-sign for DNSKEY RRset is not valid, bad packet.
|
||||
STAT_NEED_DS DS records to validate a key not found, name in keyname
|
||||
*/
|
||||
int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, char *name, char *keyname, int class)
|
||||
@@ -855,13 +855,16 @@ int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, ch
|
||||
|
||||
if (ntohs(header->qdcount) != 1 ||
|
||||
!extract_name(header, plen, &p, name, 1, 4))
|
||||
return STAT_INSECURE;
|
||||
return STAT_BOGUS;
|
||||
|
||||
GETSHORT(qtype, p);
|
||||
GETSHORT(qclass, p);
|
||||
|
||||
if (qtype != T_DNSKEY || qclass != class || ntohs(header->ancount) == 0)
|
||||
if (qtype != T_DNSKEY || qclass != class)
|
||||
return STAT_BOGUS;
|
||||
|
||||
if (ntohs(header->ancount) == 0)
|
||||
return STAT_INSECURE;
|
||||
|
||||
/* See if we have cached a DS record which validates this key */
|
||||
if (!(crecp = cache_find_by_name(NULL, name, now, F_DS)))
|
||||
@@ -879,7 +882,7 @@ int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, ch
|
||||
{
|
||||
/* Ensure we have type, class TTL and length */
|
||||
if (!(rc = extract_name(header, plen, &p, name, 0, 10)))
|
||||
return STAT_INSECURE; /* bad packet */
|
||||
return STAT_BOGUS; /* bad packet */
|
||||
|
||||
GETSHORT(qtype, p);
|
||||
GETSHORT(qclass, p);
|
||||
@@ -887,7 +890,7 @@ int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, ch
|
||||
GETSHORT(rdlen, p);
|
||||
|
||||
if (!CHECK_LEN(header, p, plen, rdlen) || rdlen < 4)
|
||||
return STAT_INSECURE; /* bad packet */
|
||||
return STAT_BOGUS; /* bad packet */
|
||||
|
||||
if (qclass != class || qtype != T_DNSKEY || rc == 2)
|
||||
{
|
||||
@@ -914,7 +917,7 @@ int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, ch
|
||||
{
|
||||
if (key)
|
||||
blockdata_free(key);
|
||||
return STAT_INSECURE; /* bad packet */
|
||||
return STAT_BOGUS; /* bad packet */
|
||||
}
|
||||
|
||||
/* No zone key flag or malloc failure */
|
||||
@@ -976,7 +979,7 @@ int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, ch
|
||||
GETSHORT(rdlen, p);
|
||||
|
||||
if (!CHECK_LEN(header, p, plen, rdlen))
|
||||
return STAT_INSECURE; /* bad packet */
|
||||
return STAT_BOGUS; /* bad packet */
|
||||
|
||||
if (qclass == class && rc == 1)
|
||||
{
|
||||
@@ -985,7 +988,7 @@ int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, ch
|
||||
if (qtype == T_DNSKEY)
|
||||
{
|
||||
if (rdlen < 4)
|
||||
return STAT_INSECURE; /* bad packet */
|
||||
return STAT_BOGUS; /* bad packet */
|
||||
|
||||
GETSHORT(flags, p);
|
||||
if (*p++ != 3)
|
||||
@@ -1017,7 +1020,7 @@ int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, ch
|
||||
{
|
||||
/* RRSIG, cache if covers DNSKEY RRset */
|
||||
if (rdlen < 18)
|
||||
return STAT_INSECURE; /* bad packet */
|
||||
return STAT_BOGUS; /* bad packet */
|
||||
|
||||
GETSHORT(type_covered, p);
|
||||
|
||||
@@ -1049,7 +1052,7 @@ int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, ch
|
||||
}
|
||||
|
||||
if (!ADD_RDLEN(header, p, plen, rdlen))
|
||||
return STAT_INSECURE; /* bad packet */
|
||||
return STAT_BOGUS; /* bad packet */
|
||||
}
|
||||
|
||||
/* commit cache insert. */
|
||||
@@ -1064,10 +1067,10 @@ int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, ch
|
||||
/* The DNS packet is expected to contain the answer to a DS query
|
||||
Put all DSs in the answer which are valid into the cache.
|
||||
return codes:
|
||||
STAT_INSECURE bad packet, no DS in reply, proven no DS in reply.
|
||||
STAT_INSECURE no DS in reply or not signed.
|
||||
STAT_SECURE At least one valid DS found and in cache.
|
||||
STAT_NO_DS It's proved there's no DS here.
|
||||
STAT_BOGUS At least one DS found, which fails validation.
|
||||
STAT_BOGUS At least one DS found, which fails validation, bad packet.
|
||||
STAT_NEED_DNSKEY DNSKEY records to validate a DS not found, name in keyname
|
||||
*/
|
||||
|
||||
@@ -1078,7 +1081,7 @@ int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char
|
||||
|
||||
if (ntohs(header->qdcount) != 1 ||
|
||||
!(p = skip_name(p, header, plen, 4)))
|
||||
return STAT_INSECURE;
|
||||
return STAT_BOGUS;
|
||||
|
||||
GETSHORT(qtype, p);
|
||||
GETSHORT(qclass, p);
|
||||
@@ -1096,7 +1099,7 @@ int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char
|
||||
p += 4; /* qtype, qclass */
|
||||
|
||||
if (!(p = skip_section(p, ntohs(header->ancount), header, plen)))
|
||||
return STAT_INSECURE;
|
||||
return STAT_BOGUS;
|
||||
|
||||
if (val == STAT_BOGUS)
|
||||
log_query(F_UPSTREAM, name, NULL, "BOGUS DS");
|
||||
@@ -1116,7 +1119,7 @@ int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char
|
||||
for (i = ntohs(header->nscount); i != 0; i--)
|
||||
{
|
||||
if (!(p = skip_name(p, header, plen, 0)))
|
||||
return STAT_INSECURE;
|
||||
return STAT_BOGUS;
|
||||
|
||||
GETSHORT(qtype, p);
|
||||
GETSHORT(qclass, p);
|
||||
@@ -1124,7 +1127,7 @@ int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char
|
||||
GETSHORT(rdlen, p);
|
||||
|
||||
if (!CHECK_LEN(header, p, plen, rdlen))
|
||||
return STAT_INSECURE; /* bad packet */
|
||||
return STAT_BOGUS; /* bad packet */
|
||||
|
||||
if (qclass != class || qtype != T_SOA)
|
||||
{
|
||||
@@ -1137,10 +1140,10 @@ int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char
|
||||
|
||||
/* MNAME */
|
||||
if (!(p = skip_name(p, header, plen, 0)))
|
||||
return STAT_INSECURE;
|
||||
return STAT_BOGUS;
|
||||
/* RNAME */
|
||||
if (!(p = skip_name(p, header, plen, 20)))
|
||||
return STAT_INSECURE;
|
||||
return STAT_BOGUS;
|
||||
p += 16; /* SERIAL REFRESH RETRY EXPIRE */
|
||||
|
||||
GETLONG(ttl, p); /* minTTL */
|
||||
@@ -1237,7 +1240,7 @@ static int find_nsec_records(struct dns_header *header, size_t plen, unsigned ch
|
||||
static unsigned char **nsecset = NULL;
|
||||
static int nsecset_sz = 0;
|
||||
|
||||
int type_found = -1;
|
||||
int type_found = 0;
|
||||
unsigned char *p = skip_questions(header, plen);
|
||||
int type, class, rdlen, i, nsecs_found;
|
||||
|
||||
@@ -1296,12 +1299,12 @@ static int prove_non_existence_nsec(struct dns_header *header, size_t plen, unsi
|
||||
{
|
||||
p = nsecs[i];
|
||||
if (!extract_name(header, plen, &p, workspace1, 1, 10))
|
||||
return STAT_INSECURE;
|
||||
return STAT_BOGUS;
|
||||
p += 8; /* class, type, TTL */
|
||||
GETSHORT(rdlen, p);
|
||||
psave = p;
|
||||
if (!extract_name(header, plen, &p, workspace2, 1, 10))
|
||||
return STAT_INSECURE;
|
||||
return STAT_BOGUS;
|
||||
|
||||
rc = hostname_cmp(workspace1, name);
|
||||
|
||||
@@ -1319,7 +1322,7 @@ static int prove_non_existence_nsec(struct dns_header *header, size_t plen, unsi
|
||||
while (rdlen >= 2)
|
||||
{
|
||||
if (!CHECK_LEN(header, p, plen, rdlen))
|
||||
return STAT_INSECURE;
|
||||
return STAT_BOGUS;
|
||||
|
||||
if (p[0] == type >> 8)
|
||||
{
|
||||
@@ -1434,7 +1437,7 @@ static int prove_non_existence_nsec3(struct dns_header *header, size_t plen, uns
|
||||
for (i = 0; i < nsec_count; i++)
|
||||
{
|
||||
if (!(p = skip_name(nsecs[i], header, plen, 15)))
|
||||
return STAT_INSECURE; /* bad packet */
|
||||
return STAT_BOGUS; /* bad packet */
|
||||
|
||||
p += 10; /* type, class, TTL, rdlen */
|
||||
algo = *p++;
|
||||
@@ -1452,7 +1455,7 @@ static int prove_non_existence_nsec3(struct dns_header *header, size_t plen, uns
|
||||
salt_len = *p++;
|
||||
salt = p;
|
||||
if (!CHECK_LEN(header, salt, plen, salt_len))
|
||||
return STAT_INSECURE; /* bad packet */
|
||||
return STAT_BOGUS; /* bad packet */
|
||||
|
||||
/* Now prune so we only have NSEC3 records with same iterations, salt and algo */
|
||||
for (i = 0; i < nsec_count; i++)
|
||||
@@ -1463,7 +1466,7 @@ static int prove_non_existence_nsec3(struct dns_header *header, size_t plen, uns
|
||||
nsecs[i] = NULL; /* Speculative, will be restored if OK. */
|
||||
|
||||
if (!(p = skip_name(nsec3p, header, plen, 15)))
|
||||
return STAT_INSECURE; /* bad packet */
|
||||
return STAT_BOGUS; /* bad packet */
|
||||
|
||||
p += 10; /* type, class, TTL, rdlen */
|
||||
|
||||
@@ -1480,7 +1483,7 @@ static int prove_non_existence_nsec3(struct dns_header *header, size_t plen, uns
|
||||
continue;
|
||||
|
||||
if (!CHECK_LEN(header, p, plen, salt_len))
|
||||
return STAT_INSECURE; /* bad packet */
|
||||
return STAT_BOGUS; /* bad packet */
|
||||
|
||||
if (memcmp(p, salt, salt_len) != 0)
|
||||
continue;
|
||||
@@ -1491,7 +1494,7 @@ static int prove_non_existence_nsec3(struct dns_header *header, size_t plen, uns
|
||||
|
||||
/* Algo is checked as 1 above */
|
||||
if (!(hash = hash_find("sha1")))
|
||||
return STAT_INSECURE;
|
||||
return STAT_BOGUS;
|
||||
|
||||
/* Now, we need the "closest encloser NSEC3" */
|
||||
closest_encloser = name;
|
||||
@@ -1503,14 +1506,14 @@ static int prove_non_existence_nsec3(struct dns_header *header, size_t plen, uns
|
||||
closest_encloser++;
|
||||
|
||||
if ((digest_len = hash_name(closest_encloser, &digest, hash, salt, salt_len, iterations)) == 0)
|
||||
return STAT_INSECURE;
|
||||
return STAT_BOGUS;
|
||||
|
||||
for (i = 0; i < nsec_count; i++)
|
||||
if ((p = nsecs[i]))
|
||||
{
|
||||
if (!extract_name(header, plen, &p, workspace1, 1, 0) ||
|
||||
!(base32_len = base32_decode(workspace1, (unsigned char *)workspace2)))
|
||||
return STAT_INSECURE;
|
||||
return STAT_BOGUS;
|
||||
|
||||
if (digest_len == base32_len &&
|
||||
memcmp(digest, workspace2, digest_len) == 0)
|
||||
@@ -1543,14 +1546,14 @@ static int prove_non_existence_nsec3(struct dns_header *header, size_t plen, uns
|
||||
p += 5 + salt_len; /* algo, flags, iterations, salt_len, salt */
|
||||
hash_len = *p++;
|
||||
if (!CHECK_LEN(header, p, plen, hash_len))
|
||||
return STAT_INSECURE; /* bad packet */
|
||||
return STAT_BOGUS; /* bad packet */
|
||||
p += hash_len;
|
||||
rdlen -= p - psave;
|
||||
|
||||
while (rdlen >= 2)
|
||||
{
|
||||
if (!CHECK_LEN(header, p, plen, rdlen))
|
||||
return STAT_INSECURE;
|
||||
return STAT_BOGUS;
|
||||
|
||||
if (p[0] == type >> 8)
|
||||
{
|
||||
@@ -1570,20 +1573,20 @@ static int prove_non_existence_nsec3(struct dns_header *header, size_t plen, uns
|
||||
|
||||
/* Look for NSEC3 that proves the non-existence of the next-closest encloser */
|
||||
if ((digest_len = hash_name(next_closest, &digest, hash, salt, salt_len, iterations)) == 0)
|
||||
return STAT_INSECURE;
|
||||
return STAT_BOGUS;
|
||||
|
||||
for (i = 0; i < nsec_count; i++)
|
||||
if ((p = nsecs[i]))
|
||||
{
|
||||
if (!extract_name(header, plen, &p, workspace1, 1, 0) ||
|
||||
!(base32_len = base32_decode(workspace1, (unsigned char *)workspace2)))
|
||||
return STAT_INSECURE;
|
||||
return STAT_BOGUS;
|
||||
|
||||
p += 15 + salt_len; /* class, type, TTL, rdlen, algo, flags, iterations, salt_len, salt */
|
||||
hash_len = *p++; /* p now points to next hashed name */
|
||||
|
||||
if (!CHECK_LEN(header, p, plen, hash_len))
|
||||
return STAT_INSECURE;
|
||||
return STAT_BOGUS;
|
||||
|
||||
if (digest_len == base32_len && hash_len == base32_len)
|
||||
{
|
||||
@@ -1611,20 +1614,20 @@ static int prove_non_existence_nsec3(struct dns_header *header, size_t plen, uns
|
||||
*wildcard = '*';
|
||||
|
||||
if ((digest_len = hash_name(wildcard, &digest, hash, salt, salt_len, iterations)) == 0)
|
||||
return STAT_INSECURE;
|
||||
return STAT_BOGUS;
|
||||
|
||||
for (i = 0; i < nsec_count; i++)
|
||||
if ((p = nsecs[i]))
|
||||
{
|
||||
if (!extract_name(header, plen, &p, workspace1, 1, 0) ||
|
||||
!(base32_len = base32_decode(workspace1, (unsigned char *)workspace2)))
|
||||
return STAT_INSECURE;
|
||||
return STAT_BOGUS;
|
||||
|
||||
p += 15 + salt_len; /* class, type, TTL, rdlen, algo, flags, iterations, salt_len, salt */
|
||||
hash_len = *p++; /* p now points to next hashed name */
|
||||
|
||||
if (!CHECK_LEN(header, p, plen, hash_len))
|
||||
return STAT_INSECURE;
|
||||
return STAT_BOGUS;
|
||||
|
||||
if (digest_len == base32_len && hash_len == base32_len)
|
||||
{
|
||||
@@ -1659,16 +1662,16 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
|
||||
if (neganswer)
|
||||
*neganswer = 0;
|
||||
|
||||
if (RCODE(header) == SERVFAIL)
|
||||
if (RCODE(header) == SERVFAIL || ntohs(header->qdcount) != 1)
|
||||
return STAT_BOGUS;
|
||||
|
||||
if ((RCODE(header) != NXDOMAIN && RCODE(header) != NOERROR) || ntohs(header->qdcount) != 1)
|
||||
if (RCODE(header) != NXDOMAIN && RCODE(header) != NOERROR)
|
||||
return STAT_INSECURE;
|
||||
|
||||
qname = p1 = (unsigned char *)(header+1);
|
||||
|
||||
if (!extract_name(header, plen, &p1, name, 1, 4))
|
||||
return STAT_INSECURE;
|
||||
return STAT_BOGUS;
|
||||
|
||||
GETSHORT(qtype, p1);
|
||||
GETSHORT(qclass, p1);
|
||||
@@ -1684,7 +1687,7 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
|
||||
/* leave pointer to missing name in qname */
|
||||
|
||||
if (!(rc = extract_name(header, plen, &p1, name, 0, 10)))
|
||||
return STAT_INSECURE; /* bad packet */
|
||||
return STAT_BOGUS; /* bad packet */
|
||||
|
||||
GETSHORT(type2, p1);
|
||||
GETSHORT(class2, p1);
|
||||
@@ -1705,7 +1708,7 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
|
||||
|
||||
/* looped CNAMES */
|
||||
if (!cname_count-- || !extract_name(header, plen, &p1, name, 1, 0))
|
||||
return STAT_INSECURE;
|
||||
return STAT_BOGUS;
|
||||
|
||||
p1 = ans_start;
|
||||
goto cname_loop;
|
||||
@@ -1713,7 +1716,7 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
|
||||
}
|
||||
|
||||
if (!ADD_RDLEN(header, p1, plen, rdlen2))
|
||||
return STAT_INSECURE;
|
||||
return STAT_BOGUS;
|
||||
}
|
||||
|
||||
if (neganswer && !have_answer)
|
||||
@@ -1726,7 +1729,7 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
|
||||
for (p1 = ans_start, i = 0; i < ntohs(header->ancount) + ntohs(header->nscount); i++)
|
||||
{
|
||||
if (!extract_name(header, plen, &p1, name, 1, 10))
|
||||
return STAT_INSECURE; /* bad packet */
|
||||
return STAT_BOGUS; /* bad packet */
|
||||
|
||||
GETSHORT(type1, p1);
|
||||
GETSHORT(class1, p1);
|
||||
@@ -1740,7 +1743,7 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
|
||||
for (p2 = ans_start, j = 0; j < i; j++)
|
||||
{
|
||||
if (!(rc = extract_name(header, plen, &p2, name, 0, 10)))
|
||||
return STAT_INSECURE; /* bad packet */
|
||||
return STAT_BOGUS; /* bad packet */
|
||||
|
||||
GETSHORT(type2, p2);
|
||||
GETSHORT(class2, p2);
|
||||
@@ -1751,7 +1754,7 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
|
||||
break; /* Done it before: name, type, class all match. */
|
||||
|
||||
if (!ADD_RDLEN(header, p2, plen, rdlen2))
|
||||
return STAT_INSECURE;
|
||||
return STAT_BOGUS;
|
||||
}
|
||||
|
||||
/* Not done, validate now */
|
||||
@@ -1771,15 +1774,8 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
|
||||
answer and overlay a genuine RR. To prove this
|
||||
hasn't happened, the answer must prove that
|
||||
the gennuine record doesn't exist. Check that here. */
|
||||
if (!nsec_type)
|
||||
{
|
||||
nsec_type = find_nsec_records(header, plen, &nsecs, &nsec_count, class1);
|
||||
|
||||
if (nsec_type == 0)
|
||||
return STAT_INSECURE; /* Bad packet */
|
||||
if (nsec_type == -1)
|
||||
return STAT_BOGUS; /* No NSECs */
|
||||
}
|
||||
if (!nsec_type && !(nsec_type = find_nsec_records(header, plen, &nsecs, &nsec_count, class1)))
|
||||
return STAT_BOGUS; /* No NSECs or bad packet */
|
||||
|
||||
if (nsec_type == T_NSEC)
|
||||
rc = prove_non_existence_nsec(header, plen, nsecs, nsec_count, daemon->workspacename, keyname, name, type1);
|
||||
@@ -1802,7 +1798,7 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
|
||||
for (p2 = ans_start, j = 0; j < ntohs(header->ancount); j++)
|
||||
{
|
||||
if (!(rc = extract_name(header, plen, &p2, name, 0, 10)))
|
||||
return STAT_INSECURE; /* bad packet */
|
||||
return STAT_BOGUS; /* bad packet */
|
||||
|
||||
GETSHORT(type2, p2);
|
||||
GETSHORT(class2, p2);
|
||||
@@ -1810,7 +1806,7 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
|
||||
GETSHORT(rdlen2, p2);
|
||||
|
||||
if (!CHECK_LEN(header, p2, plen, rdlen2))
|
||||
return STAT_INSECURE; /* bad packet */
|
||||
return STAT_BOGUS; /* bad packet */
|
||||
|
||||
if (class2 == class1 && rc == 1)
|
||||
{
|
||||
@@ -1819,7 +1815,7 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
|
||||
if (type1 == T_DS && type2 == T_DS)
|
||||
{
|
||||
if (rdlen2 < 4)
|
||||
return STAT_INSECURE; /* bad packet */
|
||||
return STAT_BOGUS; /* bad packet */
|
||||
|
||||
GETSHORT(keytag, p2);
|
||||
algo = *p2++;
|
||||
@@ -1847,7 +1843,7 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
|
||||
else if (type2 == T_RRSIG)
|
||||
{
|
||||
if (rdlen2 < 18)
|
||||
return STAT_INSECURE; /* bad packet */
|
||||
return STAT_BOGUS; /* bad packet */
|
||||
|
||||
GETSHORT(type_covered, p2);
|
||||
|
||||
@@ -1883,7 +1879,7 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
|
||||
}
|
||||
|
||||
if (!ADD_RDLEN(header, p2, plen, rdlen2))
|
||||
return STAT_INSECURE; /* bad packet */
|
||||
return STAT_BOGUS; /* bad packet */
|
||||
}
|
||||
|
||||
cache_end_insert();
|
||||
@@ -1891,7 +1887,7 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
|
||||
}
|
||||
|
||||
if (!ADD_RDLEN(header, p1, plen, rdlen1))
|
||||
return STAT_INSECURE;
|
||||
return STAT_BOGUS;
|
||||
}
|
||||
|
||||
/* OK, all the RRsets validate, now see if we have a NODATA or NXDOMAIN reply */
|
||||
@@ -1900,19 +1896,12 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
|
||||
|
||||
/* NXDOMAIN or NODATA reply, prove that (name, class1, type1) can't exist */
|
||||
/* First marshall the NSEC records, if we've not done it previously */
|
||||
if (!nsec_type)
|
||||
{
|
||||
nsec_type = find_nsec_records(header, plen, &nsecs, &nsec_count, qclass);
|
||||
|
||||
if (nsec_type == 0)
|
||||
return STAT_INSECURE; /* Bad packet */
|
||||
if (nsec_type == -1)
|
||||
return STAT_BOGUS; /* No NSECs */
|
||||
}
|
||||
if (!nsec_type && !(nsec_type = find_nsec_records(header, plen, &nsecs, &nsec_count, qclass)))
|
||||
return STAT_BOGUS; /* No NSECs */
|
||||
|
||||
/* Get name of missing answer */
|
||||
if (!extract_name(header, plen, &qname, name, 1, 0))
|
||||
return STAT_INSECURE;
|
||||
return STAT_BOGUS;
|
||||
|
||||
if (nsec_type == T_NSEC)
|
||||
return prove_non_existence_nsec(header, plen, nsecs, nsec_count, daemon->workspacename, keyname, name, qtype);
|
||||
|
||||
Reference in New Issue
Block a user