mirror of
https://github.com/pi-hole/dnsmasq.git
synced 2025-12-20 02:38:32 +00:00
Handle DS records for unsupported crypto algorithms correctly.
Such a DS, as long as it is validated, should allow answers in the domain is attests to be returned as unvalidated, and not as a validation error.
This commit is contained in:
@@ -44,8 +44,13 @@ version 2.88
|
|||||||
cases where is can be useful. Thanks to Dominik Derigs for
|
cases where is can be useful. Thanks to Dominik Derigs for
|
||||||
the patch.
|
the patch.
|
||||||
|
|
||||||
|
Handle DS records for unsupported crypto algorithms correctly.
|
||||||
|
Such a DS, as long as it is validated, should allow answers
|
||||||
|
in the domain is attests to be returned as unvalidated, and not
|
||||||
|
as a validation error.
|
||||||
|
|
||||||
(version 2.87
|
|
||||||
|
version 2.87
|
||||||
Allow arbitrary prefix lengths in --rev-server and
|
Allow arbitrary prefix lengths in --rev-server and
|
||||||
--domain=....,local
|
--domain=....,local
|
||||||
|
|
||||||
|
|||||||
37
src/dnssec.c
37
src/dnssec.c
@@ -979,10 +979,13 @@ 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
|
/* 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.
|
Put all DSs in the answer which are valid and have hash and signature algos
|
||||||
|
we support into the cache.
|
||||||
Also handles replies which prove that there's no DS at this location,
|
Also handles replies which prove that there's no DS at this location,
|
||||||
either because the zone is unsigned or this isn't a zone cut. These are
|
either because the zone is unsigned or this isn't a zone cut. These are
|
||||||
cached too.
|
cached too.
|
||||||
|
If none of the DS's are for supported algos, treat the answer as if
|
||||||
|
it's a proof of no DS at this location. RFC4035 para 5.2.
|
||||||
return codes:
|
return codes:
|
||||||
STAT_OK At least one valid DS found and in cache.
|
STAT_OK At least one valid DS found and in cache.
|
||||||
STAT_BOGUS no DS in reply or not signed, fails validation, bad packet.
|
STAT_BOGUS no DS in reply or not signed, fails validation, bad packet.
|
||||||
@@ -993,8 +996,8 @@ int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, ch
|
|||||||
int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char *name, char *keyname, int class)
|
int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char *name, char *keyname, int class)
|
||||||
{
|
{
|
||||||
unsigned char *p = (unsigned char *)(header+1);
|
unsigned char *p = (unsigned char *)(header+1);
|
||||||
int qtype, qclass, rc, i, neganswer, nons, neg_ttl = 0;
|
int qtype, qclass, rc, i, neganswer, nons, neg_ttl = 0, found_supported = 0;
|
||||||
int aclass, atype, rdlen;
|
int aclass, atype, rdlen, flags;
|
||||||
unsigned long ttl;
|
unsigned long ttl;
|
||||||
union all_addr a;
|
union all_addr a;
|
||||||
|
|
||||||
@@ -1065,7 +1068,15 @@ int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char
|
|||||||
algo = *p++;
|
algo = *p++;
|
||||||
digest = *p++;
|
digest = *p++;
|
||||||
|
|
||||||
if ((key = blockdata_alloc((char*)p, rdlen - 4)))
|
if (!ds_digest_name(digest) || !ds_digest_name(digest))
|
||||||
|
{
|
||||||
|
a.log.keytag = keytag;
|
||||||
|
a.log.algo = algo;
|
||||||
|
a.log.digest = digest;
|
||||||
|
log_query(F_NOEXTRA | F_KEYTAG | F_UPSTREAM, name, &a, "DS keytag %hu, algo %hu, digest %hu (not supported)", 0);
|
||||||
|
neg_ttl = ttl;
|
||||||
|
}
|
||||||
|
else if ((key = blockdata_alloc((char*)p, rdlen - 4)))
|
||||||
{
|
{
|
||||||
a.ds.digest = digest;
|
a.ds.digest = digest;
|
||||||
a.ds.keydata = key;
|
a.ds.keydata = key;
|
||||||
@@ -1083,26 +1094,29 @@ int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char
|
|||||||
a.log.keytag = keytag;
|
a.log.keytag = keytag;
|
||||||
a.log.algo = algo;
|
a.log.algo = algo;
|
||||||
a.log.digest = digest;
|
a.log.digest = digest;
|
||||||
if (ds_digest_name(digest) && algo_digest_name(algo))
|
|
||||||
log_query(F_NOEXTRA | F_KEYTAG | F_UPSTREAM, name, &a, "DS keytag %hu, algo %hu, digest %hu", 0);
|
log_query(F_NOEXTRA | F_KEYTAG | F_UPSTREAM, name, &a, "DS keytag %hu, algo %hu, digest %hu", 0);
|
||||||
else
|
found_supported = 1;
|
||||||
log_query(F_NOEXTRA | F_KEYTAG | F_UPSTREAM, name, &a, "DS keytag %hu, algo %hu, digest %hu (not supported)", 0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
p = psave;
|
p = psave;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ADD_RDLEN(header, p, plen, rdlen))
|
if (!ADD_RDLEN(header, p, plen, rdlen))
|
||||||
return STAT_BOGUS; /* bad packet */
|
return STAT_BOGUS; /* bad packet */
|
||||||
}
|
}
|
||||||
|
|
||||||
cache_end_insert();
|
cache_end_insert();
|
||||||
|
|
||||||
|
/* Fall through if no supported algo DS found. */
|
||||||
|
if (found_supported)
|
||||||
|
return STAT_OK;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
int flags = F_FORWARD | F_DS | F_NEG | F_DNSSECOK;
|
|
||||||
|
|
||||||
|
flags = F_FORWARD | F_DS | F_NEG | F_DNSSECOK;
|
||||||
|
|
||||||
|
if (neganswer)
|
||||||
|
{
|
||||||
if (RCODE(header) == NXDOMAIN)
|
if (RCODE(header) == NXDOMAIN)
|
||||||
flags |= F_NXDOMAIN;
|
flags |= F_NXDOMAIN;
|
||||||
|
|
||||||
@@ -1110,6 +1124,7 @@ int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char
|
|||||||
to store presence/absence of NS. */
|
to store presence/absence of NS. */
|
||||||
if (nons)
|
if (nons)
|
||||||
flags &= ~F_DNSSECOK;
|
flags &= ~F_DNSSECOK;
|
||||||
|
}
|
||||||
|
|
||||||
cache_start_insert();
|
cache_start_insert();
|
||||||
|
|
||||||
@@ -1119,8 +1134,8 @@ int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char
|
|||||||
|
|
||||||
cache_end_insert();
|
cache_end_insert();
|
||||||
|
|
||||||
|
if (neganswer)
|
||||||
log_query(F_NOEXTRA | F_UPSTREAM, name, NULL, nons ? "no DS/cut" : "no DS", 0);
|
log_query(F_NOEXTRA | F_UPSTREAM, name, NULL, nons ? "no DS/cut" : "no DS", 0);
|
||||||
}
|
|
||||||
|
|
||||||
return STAT_OK;
|
return STAT_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user