Implement "DNS-0x20 encoding".

This provides extra protection against reply-spoof attacks.

Since DNS queries are case-insensitive, it's possible to randomly flip
the case of letters in a query and still get the correct answer back.
This adds an extra dimension for a cache-poisoning attacker to guess
when sending replies in-the-blind since it's expected that the
legitimate answer will have the same pattern of upper and lower case
as the query, so any replies which don't can be ignored as
malicious.

The amount of extra entropy clearly depends on the number
of a-z and A-Z characters in the query, and this implementation puts a
hard limit of 32 bits to make rescource allocation easy. This about
doubles entropy over the standard random ID and random port
combination.
This commit is contained in:
Simon Kelley
2025-01-19 21:44:19 +00:00
parent 65f9c1aca1
commit 995a16ca0c
6 changed files with 113 additions and 66 deletions

View File

@@ -790,6 +790,7 @@ struct frec {
int forwardall, flags;
time_t time;
u32 forward_timestamp;
unsigned int encode_bitmap;
int forward_delay;
struct blockdata *stash; /* saved query or saved reply, whilst we validate */
size_t stash_len;
@@ -1386,7 +1387,7 @@ int is_rev_synth(int flag, union all_addr *addr, char *name);
/* rfc1035.c */
int do_doctor(struct dns_header *header, size_t qlen, char *namebuff);
int extract_name(struct dns_header *header, size_t plen, unsigned char **pp,
char *name, int isExtract, int extrabytes);
char *name, int func, unsigned int parm);
unsigned char *skip_name(unsigned char *ansp, struct dns_header *header, size_t plen, int extrabytes);
unsigned char *skip_questions(struct dns_header *header, size_t plen);
unsigned char *skip_section(unsigned char *ansp, int count, struct dns_header *header, size_t plen);
@@ -1413,6 +1414,11 @@ int add_resource_record(struct dns_header *header, char *limit, int *truncp,
int *offset, unsigned short type, unsigned short class, char *format, ...);
int in_arpa_name_2_addr(char *namein, union all_addr *addrp);
int private_net(struct in_addr addr, int ban_localhost);
/* extract_name ops */
#define EXTR_NAME_EXTRACT 1
#define EXTR_NAME_COMPARE 2
#define EXTR_NAME_NOCASE 3
#define EXTR_NAME_FLIP 4
/* auth.c */
#ifdef HAVE_AUTH