Commit c3e0b9b6 authored by Simon Kelley's avatar Simon Kelley

backup

parent 963c380d
...@@ -26,7 +26,7 @@ static union bigname *big_free = NULL; ...@@ -26,7 +26,7 @@ static union bigname *big_free = NULL;
static int bignames_left, hash_size; static int bignames_left, hash_size;
static int uid = 1; static int uid = 1;
#ifdef HAVE_DNSSEC #ifdef HAVE_DNSSEC
static struct keydata *keyblock_free = NULL; static struct blockdata *keyblock_free = NULL;
#endif #endif
/* type->string mapping: this is also used by the name-hash function as a mixing table. */ /* type->string mapping: this is also used by the name-hash function as a mixing table. */
...@@ -198,7 +198,7 @@ static void cache_free(struct crec *crecp) ...@@ -198,7 +198,7 @@ static void cache_free(struct crec *crecp)
} }
#ifdef HAVE_DNSSEC #ifdef HAVE_DNSSEC
else if (crecp->flags & (F_DNSKEY | F_DS)) else if (crecp->flags & (F_DNSKEY | F_DS))
keydata_free(crecp->addr.key.keydata); blockdata_free(crecp->addr.key.keydata);
#endif #endif
} }
...@@ -1361,10 +1361,10 @@ void log_query(unsigned int flags, char *name, struct all_addr *addr, char *arg) ...@@ -1361,10 +1361,10 @@ void log_query(unsigned int flags, char *name, struct all_addr *addr, char *arg)
} }
#ifdef HAVE_DNSSEC #ifdef HAVE_DNSSEC
struct keydata *keydata_alloc(char *data, size_t len) struct blockdata *blockdata_alloc(char *data, size_t len)
{ {
struct keydata *block, *ret = NULL; struct blockdata *block, *ret = NULL;
struct keydata **prev = &ret; struct blockdata **prev = &ret;
size_t blen; size_t blen;
while (len > 0) while (len > 0)
...@@ -1375,12 +1375,12 @@ struct keydata *keydata_alloc(char *data, size_t len) ...@@ -1375,12 +1375,12 @@ struct keydata *keydata_alloc(char *data, size_t len)
keyblock_free = block->next; keyblock_free = block->next;
} }
else else
block = whine_malloc(sizeof(struct keydata)); block = whine_malloc(sizeof(struct blockdata));
if (!block) if (!block)
{ {
/* failed to alloc, free partial chain */ /* failed to alloc, free partial chain */
keydata_free(ret); blockdata_free(ret);
return NULL; return NULL;
} }
...@@ -1396,7 +1396,7 @@ struct keydata *keydata_alloc(char *data, size_t len) ...@@ -1396,7 +1396,7 @@ struct keydata *keydata_alloc(char *data, size_t len)
return ret; return ret;
} }
size_t keydata_walk(struct keydata **key, unsigned char **p, size_t cnt) size_t blockdata_walk(struct blockdata **key, unsigned char **p, size_t cnt)
{ {
if (*p == NULL) if (*p == NULL)
*p = (*key)->key; *p = (*key)->key;
...@@ -1411,9 +1411,9 @@ size_t keydata_walk(struct keydata **key, unsigned char **p, size_t cnt) ...@@ -1411,9 +1411,9 @@ size_t keydata_walk(struct keydata **key, unsigned char **p, size_t cnt)
return MIN(cnt, (*key)->key + KEYBLOCK_LEN - (*p)); return MIN(cnt, (*key)->key + KEYBLOCK_LEN - (*p));
} }
void keydata_free(struct keydata *blocks) void blockdata_free(struct blockdata *blocks)
{ {
struct keydata *tmp; struct blockdata *tmp;
if (blocks) if (blocks)
{ {
......
...@@ -140,3 +140,9 @@ struct dns_header { ...@@ -140,3 +140,9 @@ struct dns_header {
GETLONG(var, ptr); \ GETLONG(var, ptr); \
(len) -= 4; \ (len) -= 4; \
} while (0) } while (0)
#define CHECK_LEN(header, pp, plen, len) \
((size_t)((pp) - (unsigned char *)(header) + (len)) <= (plen))
#define ADD_RDLEN(header, pp, plen, len) \
(!CHECK_LEN(header, pp, plen, len) ? 0 : (((pp) += (len)), 1))
...@@ -81,8 +81,14 @@ int main (int argc, char **argv) ...@@ -81,8 +81,14 @@ int main (int argc, char **argv)
umask(022); /* known umask, create leases and pid files as 0644 */ umask(022); /* known umask, create leases and pid files as 0644 */
read_opts(argc, argv, compile_opts); read_opts(argc, argv, compile_opts);
#ifdef HAVE_DNSSEC
if (option_bool(OPT_DNSSEC_VALID)) if (option_bool(OPT_DNSSEC_VALID))
if (daemon->doctors) exit(1); /* TODO */ if (daemon->doctors) exit(1); /* TODO */
daemon->keyname = safe_malloc(MAXDNAME);
#endif
if (daemon->edns_pktsz < PACKETSZ) if (daemon->edns_pktsz < PACKETSZ)
daemon->edns_pktsz = option_bool(OPT_DNSSEC_VALID) ? EDNS_PKTSZ : PACKETSZ; daemon->edns_pktsz = option_bool(OPT_DNSSEC_VALID) ? EDNS_PKTSZ : PACKETSZ;
daemon->packet_buff_sz = daemon->edns_pktsz > DNSMASQ_PACKETSZ ? daemon->packet_buff_sz = daemon->edns_pktsz > DNSMASQ_PACKETSZ ?
......
...@@ -335,8 +335,8 @@ union bigname { ...@@ -335,8 +335,8 @@ union bigname {
union bigname *next; /* freelist */ union bigname *next; /* freelist */
}; };
struct keydata { struct blockdata {
struct keydata *next; struct blockdata *next;
unsigned char key[KEYBLOCK_LEN]; unsigned char key[KEYBLOCK_LEN];
}; };
...@@ -528,6 +528,7 @@ struct frec { ...@@ -528,6 +528,7 @@ struct frec {
unsigned int crc; unsigned int crc;
time_t time; time_t time;
#ifdef HAVE_DNSSEC #ifdef HAVE_DNSSEC
int class;
struct blockdata *stash; /* Saved reply, whilst we validate */ struct blockdata *stash; /* Saved reply, whilst we validate */
size_t stash_len; size_t stash_len;
struct frec *dependent; /* Query awaiting internally-generated DNSKEY or DS query */ struct frec *dependent; /* Query awaiting internally-generated DNSKEY or DS query */
...@@ -900,6 +901,9 @@ extern struct daemon { ...@@ -900,6 +901,9 @@ extern struct daemon {
char *packet; /* packet buffer */ char *packet; /* packet buffer */
int packet_buff_sz; /* size of above */ int packet_buff_sz; /* size of above */
char *namebuff; /* MAXDNAME size buffer */ char *namebuff; /* MAXDNAME size buffer */
#ifdef HAVE_DNSSEC
char *keyname; /* MAXDNAME size buffer */
#endif
unsigned int local_answer, queries_forwarded, auth_answer; unsigned int local_answer, queries_forwarded, auth_answer;
struct frec *frec_list; struct frec *frec_list;
struct serverfd *sfds; struct serverfd *sfds;
...@@ -1030,7 +1034,11 @@ int in_zone(struct auth_zone *zone, char *name, char **cut); ...@@ -1030,7 +1034,11 @@ int in_zone(struct auth_zone *zone, char *name, char **cut);
#endif #endif
/* dnssec.c */ /* dnssec.c */
int dnssec_validate(int flags, struct dns_header *header, size_t plen); size_t dnssec_generate_query(struct dns_header *header, char *name, int class, int type);
int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t n, 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);
int validate_rrset(time_t now, struct dns_header *header, size_t plen, int class, int type, char *name, char *keyname);
int dnssec_validate_reply(struct dns_header *header, size_t plen, char *name, char *keyname, int *class);
/* util.c */ /* util.c */
void rand_init(void); void rand_init(void);
......
This diff is collapsed.
...@@ -678,15 +678,14 @@ void reply_query(int fd, int family, time_t now) ...@@ -678,15 +678,14 @@ void reply_query(int fd, int family, time_t now)
if (option_bool(OPT_DNSSEC_VALID) && !(forward->flags & FREC_CHECKING_DISABLED)) if (option_bool(OPT_DNSSEC_VALID) && !(forward->flags & FREC_CHECKING_DISABLED))
{ {
int status; int status;
char rrbitmap[256/8];
int class; int class;
if (forward->flags && FREC_DNSSKEY_QUERY) if (forward->flags & FREC_DNSKEY_QUERY)
status = dnssec_validate_by_ds(header, n, daemon->namebuff, &class); status = dnssec_validate_by_ds(now, header, n, daemon->namebuff, daemon->keyname, forward->class);
else if (forward->flags && FREC_DS_QUERY) else if (forward->flags & FREC_DS_QUERY)
status = dnssec_validate_dnskey(header, n, daemon->namebuff, &class); status = dnssec_validate_ds(now, header, n, daemon->namebuff, daemon->keyname, forward->class);
else else
status = dnssec_validate_reply(&rrbitmap, header, n, daemon->namebuff, &class); status = dnssec_validate_reply(header, n, daemon->namebuff, daemon->keyname, &forward->class);
/* Can't validate, as we're missing key data. Put this /* Can't validate, as we're missing key data. Put this
answer aside, whilst we get that. */ answer aside, whilst we get that. */
...@@ -717,7 +716,7 @@ void reply_query(int fd, int family, time_t now) ...@@ -717,7 +716,7 @@ void reply_query(int fd, int family, time_t now)
} }
new->crc = questions_crc(header, nn, daemon->namebuff); new->crc = questions_crc(header, nn, daemon->namebuff);
new->new_id = get_id(new->crc); new->new_id = get_id(new->crc);
header->id = htons(new->id); header->id = htons(new->new_id);
/* Don't resend this. */ /* Don't resend this. */
daemon->srv_save = NULL; daemon->srv_save = NULL;
...@@ -751,22 +750,30 @@ void reply_query(int fd, int family, time_t now) ...@@ -751,22 +750,30 @@ void reply_query(int fd, int family, time_t now)
and validate them with the new data. Failure to find needed data here is an internal error. and validate them with the new data. Failure to find needed data here is an internal error.
Once we get to the original answer (FREC_DNSSEC_QUERY not set) and it validates, Once we get to the original answer (FREC_DNSSEC_QUERY not set) and it validates,
return it to the original requestor. */ return it to the original requestor. */
while (forward->flags & FREC_DNSSEC_QUERY) while (forward->dependent)
{ {
if (status == STAT_SECURE) struct frec *prev = forward->dependent;
extract_dnssec_replies();
free_frec(forward); free_frec(forward);
forward = forward->dependent; forward = prev;
blockdata_retrieve_and_free(forward->stash, forward->stash_len, (void *)header); blockdata_retrieve_and_free(forward->stash, forward->stash_len, (void *)header);
n = forward->stash_len; n = forward->stash_len;
if (status == STAT_SECURE) if (status == STAT_SECURE)
{ {
status = dnssec_validate(forward->flags, header, n); if (forward->flags & FREC_DNSKEY_QUERY)
status = dnssec_validate_by_ds(now, header, n, daemon->namebuff, daemon->keyname, forward->class);
else if (forward->flags & FREC_DS_QUERY)
status = dnssec_validate_dnskey(now, header, n, daemon->namebuff, daemon->keyname, forward->class);
if (status == STAT_NEED_DS || status == STAT_NEED_KEY) if (status == STAT_NEED_DS || status == STAT_NEED_KEY)
my_syslog(LOG_ERR, _("Unexpected missing data for DNSSEC validation")); my_syslog(LOG_ERR, _("Unexpected missing data for DNSSEC validation"));
} }
} }
/* All DNSKEY and DS records done and in cache, now finally validate original
answer, provided last DNSKEY is OK. */
if (status == STAT_SECURE)
status = dnssec_validate_reply(header, n, daemon->namebuff, daemon->keyname, &forward->class);
if (status == STAT_SECURE) if (status == STAT_SECURE)
cache_secure = 1; cache_secure = 1;
/* TODO return SERVFAIL here */ /* TODO return SERVFAIL here */
......
...@@ -16,13 +16,6 @@ ...@@ -16,13 +16,6 @@
#include "dnsmasq.h" #include "dnsmasq.h"
#define CHECK_LEN(header, pp, plen, len) \
((size_t)((pp) - (unsigned char *)(header) + (len)) <= (plen))
#define ADD_RDLEN(header, pp, plen, len) \
(!CHECK_LEN(header, pp, plen, len) ? 0 : (((pp) += (len)), 1))
int extract_name(struct dns_header *header, size_t plen, unsigned char **pp, int extract_name(struct dns_header *header, size_t plen, unsigned char **pp,
char *name, int isExtract, int extrabytes) char *name, int isExtract, int extrabytes)
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment