Commit c3e0b9b6 authored by Simon Kelley's avatar Simon Kelley

backup

parent 963c380d
......@@ -26,7 +26,7 @@ static union bigname *big_free = NULL;
static int bignames_left, hash_size;
static int uid = 1;
#ifdef HAVE_DNSSEC
static struct keydata *keyblock_free = NULL;
static struct blockdata *keyblock_free = NULL;
#endif
/* 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)
}
#ifdef HAVE_DNSSEC
else if (crecp->flags & (F_DNSKEY | F_DS))
keydata_free(crecp->addr.key.keydata);
blockdata_free(crecp->addr.key.keydata);
#endif
}
......@@ -1361,10 +1361,10 @@ void log_query(unsigned int flags, char *name, struct all_addr *addr, char *arg)
}
#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 keydata **prev = &ret;
struct blockdata *block, *ret = NULL;
struct blockdata **prev = &ret;
size_t blen;
while (len > 0)
......@@ -1375,12 +1375,12 @@ struct keydata *keydata_alloc(char *data, size_t len)
keyblock_free = block->next;
}
else
block = whine_malloc(sizeof(struct keydata));
block = whine_malloc(sizeof(struct blockdata));
if (!block)
{
/* failed to alloc, free partial chain */
keydata_free(ret);
blockdata_free(ret);
return NULL;
}
......@@ -1396,7 +1396,7 @@ struct keydata *keydata_alloc(char *data, size_t len)
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)
*p = (*key)->key;
......@@ -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));
}
void keydata_free(struct keydata *blocks)
void blockdata_free(struct blockdata *blocks)
{
struct keydata *tmp;
struct blockdata *tmp;
if (blocks)
{
......
......@@ -140,3 +140,9 @@ struct dns_header {
GETLONG(var, ptr); \
(len) -= 4; \
} 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)
umask(022); /* known umask, create leases and pid files as 0644 */
read_opts(argc, argv, compile_opts);
#ifdef HAVE_DNSSEC
if (option_bool(OPT_DNSSEC_VALID))
if (daemon->doctors) exit(1); /* TODO */
daemon->keyname = safe_malloc(MAXDNAME);
#endif
if (daemon->edns_pktsz < PACKETSZ)
daemon->edns_pktsz = option_bool(OPT_DNSSEC_VALID) ? EDNS_PKTSZ : PACKETSZ;
daemon->packet_buff_sz = daemon->edns_pktsz > DNSMASQ_PACKETSZ ?
......
......@@ -335,8 +335,8 @@ union bigname {
union bigname *next; /* freelist */
};
struct keydata {
struct keydata *next;
struct blockdata {
struct blockdata *next;
unsigned char key[KEYBLOCK_LEN];
};
......@@ -528,6 +528,7 @@ struct frec {
unsigned int crc;
time_t time;
#ifdef HAVE_DNSSEC
int class;
struct blockdata *stash; /* Saved reply, whilst we validate */
size_t stash_len;
struct frec *dependent; /* Query awaiting internally-generated DNSKEY or DS query */
......@@ -900,6 +901,9 @@ extern struct daemon {
char *packet; /* packet buffer */
int packet_buff_sz; /* size of above */
char *namebuff; /* MAXDNAME size buffer */
#ifdef HAVE_DNSSEC
char *keyname; /* MAXDNAME size buffer */
#endif
unsigned int local_answer, queries_forwarded, auth_answer;
struct frec *frec_list;
struct serverfd *sfds;
......@@ -1030,7 +1034,11 @@ int in_zone(struct auth_zone *zone, char *name, char **cut);
#endif
/* 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 */
void rand_init(void);
......
This diff is collapsed.
......@@ -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))
{
int status;
char rrbitmap[256/8];
int class;
if (forward->flags && FREC_DNSSKEY_QUERY)
status = dnssec_validate_by_ds(header, n, daemon->namebuff, &class);
else if (forward->flags && FREC_DS_QUERY)
status = dnssec_validate_dnskey(header, n, daemon->namebuff, &class);
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_ds(now, header, n, daemon->namebuff, daemon->keyname, forward->class);
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
answer aside, whilst we get that. */
......@@ -717,7 +716,7 @@ void reply_query(int fd, int family, time_t now)
}
new->crc = questions_crc(header, nn, daemon->namebuff);
new->new_id = get_id(new->crc);
header->id = htons(new->id);
header->id = htons(new->new_id);
/* Don't resend this. */
daemon->srv_save = NULL;
......@@ -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.
Once we get to the original answer (FREC_DNSSEC_QUERY not set) and it validates,
return it to the original requestor. */
while (forward->flags & FREC_DNSSEC_QUERY)
while (forward->dependent)
{
if (status == STAT_SECURE)
extract_dnssec_replies();
struct frec *prev = forward->dependent;
free_frec(forward);
forward = forward->dependent;
forward = prev;
blockdata_retrieve_and_free(forward->stash, forward->stash_len, (void *)header);
n = forward->stash_len;
if (status == STAT_SECURE)
{
status = dnssec_validate(forward->flags, header, n);
if (status == STAT_NEED_DS || status == STAT_NEED_KEY)
my_syslog(LOG_ERR, _("Unexpected missing data for DNSSEC validation"));
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)
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)
cache_secure = 1;
/* TODO return SERVFAIL here */
......
......@@ -16,13 +16,6 @@
#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,
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