mirror of
http://thekelleys.org.uk/git/dnsmasq.git
synced 2026-11-04 13:48:30 +00:00
Compare commits
7
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9ed3ee67ec | ||
|
|
1f9215f5f9 | ||
|
|
f52cfdd8c3 | ||
|
|
2fc904111d | ||
|
|
262dadf50e | ||
|
|
6c596f1cc1 | ||
|
|
dafa16c400 |
No files matched your search
@@ -44,8 +44,13 @@ version 2.88
|
||||
cases where is can be useful. Thanks to Dominik Derigs for
|
||||
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
|
||||
--domain=....,local
|
||||
|
||||
|
||||
+21
-8
@@ -309,14 +309,14 @@ static int dnsmasq_gostdsa_verify(struct blockdata *key_data, unsigned int key_l
|
||||
mpz_init(y);
|
||||
}
|
||||
|
||||
mpz_import(x, 32 , 1, 1, 0, 0, p);
|
||||
mpz_import(y, 32 , 1, 1, 0, 0, p + 32);
|
||||
mpz_import(x, 32, -1, 1, 0, 0, p);
|
||||
mpz_import(y, 32, -1, 1, 0, 0, p + 32);
|
||||
|
||||
if (!ecc_point_set(gost_key, x, y))
|
||||
return 0;
|
||||
return 0;
|
||||
|
||||
mpz_import(sig_struct->r, 32, 1, 1, 0, 0, sig);
|
||||
mpz_import(sig_struct->s, 32, 1, 1, 0, 0, sig + 32);
|
||||
mpz_import(sig_struct->s, 32, 1, 1, 0, 0, sig);
|
||||
mpz_import(sig_struct->r, 32, 1, 1, 0, 0, sig + 32);
|
||||
|
||||
return nettle_gostdsa_verify(gost_key, digest_len, digest, sig_struct);
|
||||
}
|
||||
@@ -390,7 +390,12 @@ static int (*verify_func(int algo))(struct blockdata *key_data, unsigned int key
|
||||
return dnsmasq_ecdsa_verify;
|
||||
|
||||
#if MIN_VERSION(3, 1)
|
||||
case 15: case 16:
|
||||
case 15:
|
||||
return dnsmasq_eddsa_verify;
|
||||
#endif
|
||||
|
||||
#if MIN_VERSION(3, 6)
|
||||
case 16:
|
||||
return dnsmasq_eddsa_verify;
|
||||
#endif
|
||||
}
|
||||
@@ -425,7 +430,9 @@ char *ds_digest_name(int digest)
|
||||
{
|
||||
case 1: return "sha1";
|
||||
case 2: return "sha256";
|
||||
case 3: return "gosthash94";
|
||||
#if MIN_VERSION(3, 6)
|
||||
case 3: return "gosthash94cp";
|
||||
#endif
|
||||
case 4: return "sha384";
|
||||
default: return NULL;
|
||||
}
|
||||
@@ -444,11 +451,17 @@ char *algo_digest_name(int algo)
|
||||
case 7: return "sha1"; /* RSASHA1-NSEC3-SHA1 */
|
||||
case 8: return "sha256"; /* RSA/SHA-256 */
|
||||
case 10: return "sha512"; /* RSA/SHA-512 */
|
||||
case 12: return "gosthash94"; /* ECC-GOST */
|
||||
#if MIN_VERSION(3, 6)
|
||||
case 12: return "gosthash94cp"; /* ECC-GOST */
|
||||
#endif
|
||||
case 13: return "sha256"; /* ECDSAP256SHA256 */
|
||||
case 14: return "sha384"; /* ECDSAP384SHA384 */
|
||||
#if MIN_VERSION(3, 1)
|
||||
case 15: return "null_hash"; /* ED25519 */
|
||||
# if MIN_VERSION(3, 6)
|
||||
case 16: return "null_hash"; /* ED448 */
|
||||
# endif
|
||||
#endif
|
||||
default: return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
+56
-18
@@ -379,21 +379,6 @@ static DBusMessage* dbus_read_servers_ex(DBusMessage *message, int strings)
|
||||
strcpy(str_addr, str);
|
||||
}
|
||||
|
||||
/* parse the IP address */
|
||||
if ((addr_err = parse_server(str_addr, &sdetails)) ||
|
||||
(addr_err = parse_server_addr(&sdetails)))
|
||||
{
|
||||
error = dbus_message_new_error_printf(message, DBUS_ERROR_INVALID_ARGS,
|
||||
"Invalid IP address '%s': %s",
|
||||
str, addr_err);
|
||||
break;
|
||||
}
|
||||
|
||||
/* 0.0.0.0 for server address == NULL, for Dbus */
|
||||
if (addr.in.sin_family == AF_INET &&
|
||||
addr.in.sin_addr.s_addr == 0)
|
||||
flags |= SERV_LITERAL_ADDRESS;
|
||||
|
||||
if (strings)
|
||||
{
|
||||
char *p;
|
||||
@@ -407,7 +392,31 @@ static DBusMessage* dbus_read_servers_ex(DBusMessage *message, int strings)
|
||||
else
|
||||
p = NULL;
|
||||
|
||||
add_update_server(flags | SERV_FROM_DBUS, &addr, &source_addr, interface, str_domain, NULL);
|
||||
if (strings && strlen(str_addr) == 0)
|
||||
add_update_server(SERV_LITERAL_ADDRESS | SERV_FROM_DBUS, &addr, &source_addr, interface, str_domain, NULL);
|
||||
else
|
||||
{
|
||||
if ((addr_err = parse_server(str_addr, &sdetails)))
|
||||
{
|
||||
error = dbus_message_new_error_printf(message, DBUS_ERROR_INVALID_ARGS,
|
||||
"Invalid IP address '%s': %s",
|
||||
str, addr_err);
|
||||
break;
|
||||
}
|
||||
|
||||
while (parse_server_next(&sdetails))
|
||||
{
|
||||
if ((addr_err = parse_server_addr(&sdetails)))
|
||||
{
|
||||
error = dbus_message_new_error_printf(message, DBUS_ERROR_INVALID_ARGS,
|
||||
"Invalid IP address '%s': %s",
|
||||
str, addr_err);
|
||||
break;
|
||||
}
|
||||
|
||||
add_update_server(flags | SERV_FROM_DBUS, &addr, &source_addr, interface, str_domain, NULL);
|
||||
}
|
||||
}
|
||||
} while ((str_domain = p));
|
||||
}
|
||||
else
|
||||
@@ -421,11 +430,40 @@ static DBusMessage* dbus_read_servers_ex(DBusMessage *message, int strings)
|
||||
if (dbus_message_iter_get_arg_type(&string_iter) == DBUS_TYPE_STRING)
|
||||
dbus_message_iter_get_basic(&string_iter, &str);
|
||||
dbus_message_iter_next (&string_iter);
|
||||
|
||||
if ((addr_err = parse_server(str_addr, &sdetails)))
|
||||
{
|
||||
error = dbus_message_new_error_printf(message, DBUS_ERROR_INVALID_ARGS,
|
||||
"Invalid IP address '%s': %s",
|
||||
str, addr_err);
|
||||
break;
|
||||
}
|
||||
|
||||
add_update_server(flags | SERV_FROM_DBUS, &addr, &source_addr, interface, str, NULL);
|
||||
while (parse_server_next(&sdetails))
|
||||
{
|
||||
if ((addr_err = parse_server_addr(&sdetails)))
|
||||
{
|
||||
error = dbus_message_new_error_printf(message, DBUS_ERROR_INVALID_ARGS,
|
||||
"Invalid IP address '%s': %s",
|
||||
str, addr_err);
|
||||
break;
|
||||
}
|
||||
|
||||
/* 0.0.0.0 for server address == NULL, for Dbus */
|
||||
if (addr.in.sin_family == AF_INET &&
|
||||
addr.in.sin_addr.s_addr == 0)
|
||||
flags |= SERV_LITERAL_ADDRESS;
|
||||
else
|
||||
flags &= ~SERV_LITERAL_ADDRESS;
|
||||
|
||||
add_update_server(flags | SERV_FROM_DBUS, &addr, &source_addr, interface, str, NULL);
|
||||
}
|
||||
} while (dbus_message_iter_get_arg_type(&string_iter) == DBUS_TYPE_STRING);
|
||||
}
|
||||
|
||||
|
||||
if (sdetails.resolved)
|
||||
freeaddrinfo(sdetails.hostinfo);
|
||||
|
||||
/* jump to next element in outer array */
|
||||
dbus_message_iter_next(&array_iter);
|
||||
}
|
||||
|
||||
@@ -1478,6 +1478,7 @@ void reset_option_bool(unsigned int opt);
|
||||
struct hostsfile *expand_filelist(struct hostsfile *list);
|
||||
char *parse_server(char *arg, struct server_details *sdetails);
|
||||
char *parse_server_addr(struct server_details *sdetails);
|
||||
int parse_server_next(struct server_details *sdetails);
|
||||
int option_read_dynfile(char *file, int flags);
|
||||
|
||||
/* forward.c */
|
||||
|
||||
+37
-22
@@ -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
|
||||
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,
|
||||
either because the zone is unsigned or this isn't a zone cut. These are
|
||||
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:
|
||||
STAT_OK At least one valid DS found and in cache.
|
||||
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)
|
||||
{
|
||||
unsigned char *p = (unsigned char *)(header+1);
|
||||
int qtype, qclass, rc, i, neganswer, nons, neg_ttl = 0;
|
||||
int aclass, atype, rdlen;
|
||||
int qtype, qclass, rc, i, neganswer, nons, neg_ttl = 0, found_supported = 0;
|
||||
int aclass, atype, rdlen, flags;
|
||||
unsigned long ttl;
|
||||
union all_addr a;
|
||||
|
||||
@@ -1065,14 +1068,22 @@ int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char
|
||||
algo = *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.keydata = key;
|
||||
a.ds.algo = algo;
|
||||
a.ds.keytag = keytag;
|
||||
a.ds.keylen = rdlen - 4;
|
||||
|
||||
|
||||
if (!cache_insert(name, &a, class, now, ttl, F_FORWARD | F_DS | F_DNSSECOK))
|
||||
{
|
||||
blockdata_free(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.algo = algo;
|
||||
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);
|
||||
else
|
||||
log_query(F_NOEXTRA | F_KEYTAG | F_UPSTREAM, name, &a, "DS keytag %hu, algo %hu, digest %hu (not supported)", 0);
|
||||
log_query(F_NOEXTRA | F_KEYTAG | F_UPSTREAM, name, &a, "DS keytag %hu, algo %hu, digest %hu", 0);
|
||||
found_supported = 1;
|
||||
}
|
||||
}
|
||||
|
||||
p = psave;
|
||||
}
|
||||
|
||||
if (!ADD_RDLEN(header, p, plen, rdlen))
|
||||
return STAT_BOGUS; /* bad packet */
|
||||
}
|
||||
|
||||
cache_end_insert();
|
||||
|
||||
/* Fall through if no supported algo DS found. */
|
||||
if (found_supported)
|
||||
return STAT_OK;
|
||||
}
|
||||
else
|
||||
|
||||
flags = F_FORWARD | F_DS | F_NEG | F_DNSSECOK;
|
||||
|
||||
if (neganswer)
|
||||
{
|
||||
int flags = F_FORWARD | F_DS | F_NEG | F_DNSSECOK;
|
||||
|
||||
if (RCODE(header) == NXDOMAIN)
|
||||
flags |= F_NXDOMAIN;
|
||||
|
||||
@@ -1110,17 +1124,18 @@ int dnssec_validate_ds(time_t now, struct dns_header *header, size_t plen, char
|
||||
to store presence/absence of NS. */
|
||||
if (nons)
|
||||
flags &= ~F_DNSSECOK;
|
||||
|
||||
cache_start_insert();
|
||||
|
||||
/* Use TTL from NSEC for negative cache entries */
|
||||
if (!cache_insert(name, NULL, class, now, neg_ttl, flags))
|
||||
return STAT_BOGUS;
|
||||
|
||||
cache_end_insert();
|
||||
|
||||
log_query(F_NOEXTRA | F_UPSTREAM, name, NULL, nons ? "no DS/cut" : "no DS", 0);
|
||||
}
|
||||
|
||||
cache_start_insert();
|
||||
|
||||
/* Use TTL from NSEC for negative cache entries */
|
||||
if (!cache_insert(name, NULL, class, now, neg_ttl, flags))
|
||||
return STAT_BOGUS;
|
||||
|
||||
cache_end_insert();
|
||||
|
||||
if (neganswer)
|
||||
log_query(F_NOEXTRA | F_UPSTREAM, name, NULL, nons ? "no DS/cut" : "no DS", 0);
|
||||
|
||||
return STAT_OK;
|
||||
}
|
||||
|
||||
+32
-20
@@ -863,11 +863,13 @@ char *parse_server(char *arg, struct server_details *sdetails)
|
||||
struct addrinfo hints = { 0 };
|
||||
|
||||
*sdetails->interface = 0;
|
||||
|
||||
sdetails->addr_type = AF_UNSPEC;
|
||||
|
||||
if (strcmp(arg, "#") == 0)
|
||||
{
|
||||
if (sdetails->flags)
|
||||
*sdetails->flags |= SERV_USE_RESOLV;
|
||||
sdetails->addr_type = AF_LOCAL;
|
||||
sdetails->valid = 1;
|
||||
return NULL;
|
||||
}
|
||||
@@ -1047,12 +1049,13 @@ char *parse_server_addr(struct server_details *sdetails)
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (sdetails->addr_type != AF_LOCAL)
|
||||
return _("bad address");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int parse_server_next(struct server_details *sdetails)
|
||||
int parse_server_next(struct server_details *sdetails)
|
||||
{
|
||||
/* Looping over resolved addresses? */
|
||||
if (sdetails->hostinfo)
|
||||
@@ -1157,6 +1160,9 @@ static char *domain_rev4(int from_file, char *server, struct in_addr *addr4, int
|
||||
if (!add_update_server(flags, &serv_addr, &source_addr, interface, domain, NULL))
|
||||
return _("error");
|
||||
}
|
||||
|
||||
if (sdetails.resolved)
|
||||
freeaddrinfo(sdetails.hostinfo);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1237,6 +1243,9 @@ static char *domain_rev6(int from_file, char *server, struct in6_addr *addr6, in
|
||||
if (!add_update_server(flags, &serv_addr, &source_addr, interface, domain, NULL))
|
||||
return _("error");
|
||||
}
|
||||
|
||||
if (sdetails.resolved)
|
||||
freeaddrinfo(sdetails.hostinfo);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2950,7 +2959,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
||||
case LOPT_LOCAL: /* --local */
|
||||
case 'A': /* --address */
|
||||
{
|
||||
char *lastdomain = NULL, *domain = "";
|
||||
char *lastdomain = NULL, *domain = "", *cur_domain;
|
||||
u16 flags = 0;
|
||||
char *err;
|
||||
union all_addr addr;
|
||||
@@ -3001,9 +3010,12 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
||||
|
||||
if (servers_only && option == 'S')
|
||||
flags |= SERV_FROM_FILE;
|
||||
|
||||
|
||||
cur_domain = domain;
|
||||
while ((flags & SERV_LITERAL_ADDRESS) || parse_server_next(&sdetails))
|
||||
{
|
||||
cur_domain = domain;
|
||||
|
||||
if (!(flags & SERV_LITERAL_ADDRESS) && (err = parse_server_addr(&sdetails)))
|
||||
ret_err(err);
|
||||
|
||||
@@ -3015,24 +3027,24 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
||||
{
|
||||
/* server=//1.2.3.4 is special. */
|
||||
if (lastdomain)
|
||||
{
|
||||
if (strlen(domain) == 0)
|
||||
flags |= SERV_FOR_NODOTS;
|
||||
else
|
||||
flags &= ~SERV_FOR_NODOTS;
|
||||
|
||||
/* address=/#/ matches the same as without domain */
|
||||
if (option == 'A' && domain[0] == '#' && domain[1] == 0)
|
||||
domain[0] = 0;
|
||||
}
|
||||
|
||||
if (!add_update_server(flags, sdetails.addr, sdetails.source_addr, sdetails.interface, domain, &addr))
|
||||
{
|
||||
if (strlen(cur_domain) == 0)
|
||||
flags |= SERV_FOR_NODOTS;
|
||||
else
|
||||
flags &= ~SERV_FOR_NODOTS;
|
||||
|
||||
/* address=/#/ matches the same as without domain */
|
||||
if (option == 'A' && cur_domain[0] == '#' && cur_domain[1] == 0)
|
||||
cur_domain[0] = 0;
|
||||
}
|
||||
|
||||
if (!add_update_server(flags, sdetails.addr, sdetails.source_addr, sdetails.interface, cur_domain, &addr))
|
||||
ret_err(gen_err);
|
||||
|
||||
if (!lastdomain || domain == lastdomain)
|
||||
|
||||
if (!lastdomain || cur_domain == lastdomain)
|
||||
break;
|
||||
|
||||
domain += strlen(domain) + 1;
|
||||
cur_domain += strlen(cur_domain) + 1;
|
||||
}
|
||||
|
||||
if (flags & SERV_LITERAL_ADDRESS)
|
||||
|
||||
Reference in new issue
Block a user