mirror of
https://github.com/vincentmli/bpfire.git
synced 2026-04-09 18:45:54 +02:00
dnsmasq: Update to development snatpshot
This commit is contained in:
18
lfs/dnsmasq
18
lfs/dnsmasq
@@ -24,10 +24,10 @@
|
||||
|
||||
include Config
|
||||
|
||||
VER = 2.72
|
||||
VER = 1062667
|
||||
|
||||
THISAPP = dnsmasq-$(VER)
|
||||
DL_FILE = $(THISAPP).tar.xz
|
||||
DL_FILE = $(THISAPP)-20150201.tar.gz
|
||||
DL_FROM = $(URL_IPFIRE)
|
||||
DIR_APP = $(DIR_SRC)/$(THISAPP)
|
||||
TARGET = $(DIR_INFO)/$(THISAPP)
|
||||
@@ -42,7 +42,7 @@ objects = $(DL_FILE)
|
||||
|
||||
$(DL_FILE) = $(DL_FROM)/$(DL_FILE)
|
||||
|
||||
$(DL_FILE)_MD5 = 0256e0a71e27c8d8a5c89a0d18f3cfe2
|
||||
$(DL_FILE)_MD5 = ee58d033a892faa69b099ed598f500c2
|
||||
|
||||
install : $(TARGET)
|
||||
|
||||
@@ -72,13 +72,7 @@ $(subst %,%_MD5,$(objects)) :
|
||||
$(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects))
|
||||
@$(PREBUILD)
|
||||
@rm -rf $(DIR_APP) && cd $(DIR_SRC) && tar axf $(DIR_DL)/$(DL_FILE)
|
||||
cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/dnsmasq/dnsmasq-2.73-remove-floor-on-edns0-packet-size-with-DNSSEC.patch
|
||||
cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/dnsmasq/dnsmasq-2.73-fix-crash-in-DNSSEC-code-when-attempting-to-verify-large-RRs.patch
|
||||
cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/dnsmasq/dnsmasq-2.73-make-caching-work-for-CNAMEs-pointing-to-A-AAAA-records-shadowed-in-etc-hosts.patch
|
||||
cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/dnsmasq/dnsmasq-2.73-fix-problems-validating-NSEC3-and-wildcards.patch
|
||||
cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/dnsmasq/dnsmasq-2.73-initialise-return-value.patch
|
||||
cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/dnsmasq/dnsmasq-2.73-bad-packet-protection.patch
|
||||
cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/dnsmasq-2.72rc2-Add-support-to-read-ISC-DHCP-lease-file.patch
|
||||
cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/dnsmasq-Add-support-to-read-ISC-DHCP-lease-file.patch
|
||||
cd $(DIR_APP) && sed -i src/config.h \
|
||||
-e 's|/\* #define HAVE_IDN \*/|#define HAVE_IDN|g' \
|
||||
-e 's|/\* #define HAVE_DNSSEC \*/|#define HAVE_DNSSEC|g' \
|
||||
@@ -86,7 +80,7 @@ $(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects))
|
||||
-e 's|#define HAVE_DHCP6|//#define HAVE_DHCP6|g' \
|
||||
-e 's|#define HAVE_TFTP|//#define HAVE_TFTP|g'
|
||||
|
||||
cd $(DIR_APP) && make CFLAGS="$(CFLAGS)" COPTS="$(COPTS)" $(MAKETUNING)
|
||||
cd $(DIR_APP) && make PREFIX=/usr install
|
||||
cd $(DIR_APP) && make CFLAGS="$(CFLAGS)" COPTS="$(COPTS)" \
|
||||
PREFIX=/usr all install
|
||||
@rm -rf $(DIR_APP)
|
||||
@$(POSTBUILD)
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
diff --git a/Makefile b/Makefile
|
||||
index 58a7975..616c6b7 100644
|
||||
index 2910320b6452..0a76ce3c5154 100644
|
||||
--- a/Makefile
|
||||
+++ b/Makefile
|
||||
@@ -69,7 +69,7 @@ objs = cache.o rfc1035.o util.o option.o forward.o network.o \
|
||||
@@ -73,7 +73,7 @@ objs = cache.o rfc1035.o util.o option.o forward.o network.o \
|
||||
dnsmasq.o dhcp.o lease.o rfc2131.o netlink.o dbus.o bpf.o \
|
||||
helper.o tftp.o log.o conntrack.o dhcp6.o rfc3315.o \
|
||||
dhcp-common.o outpacket.o radv.o slaac.o auth.o ipset.o \
|
||||
- domain.o dnssec.o blockdata.o tables.o loop.o
|
||||
+ domain.o dnssec.o blockdata.o tables.o loop.o isc.o
|
||||
- domain.o dnssec.o blockdata.o tables.o loop.o inotify.o
|
||||
+ domain.o dnssec.o blockdata.o tables.o loop.o inotify.o isc.o
|
||||
|
||||
hdrs = dnsmasq.h config.h dhcp-protocol.h dhcp6-protocol.h \
|
||||
dns-protocol.h radv-protocol.h ip6addr.h
|
||||
diff --git a/src/cache.c b/src/cache.c
|
||||
index 2c3a498..77a7046 100644
|
||||
index 117ae279fd4e..6ee7ee362e6c 100644
|
||||
--- a/src/cache.c
|
||||
+++ b/src/cache.c
|
||||
@@ -17,7 +17,7 @@
|
||||
@@ -34,8 +34,8 @@ index 2c3a498..77a7046 100644
|
||||
#ifdef HAVE_DNSSEC
|
||||
cache_blockdata_free(crecp);
|
||||
#endif
|
||||
@@ -1110,7 +1113,7 @@ void cache_reload(void)
|
||||
total_size = read_hostsfile(ah->fname, ah->index, total_size, (struct crec **)daemon->packet, revhashsz);
|
||||
@@ -1151,7 +1154,7 @@ void cache_reload(void)
|
||||
|
||||
}
|
||||
|
||||
-#ifdef HAVE_DHCP
|
||||
@@ -43,7 +43,7 @@ index 2c3a498..77a7046 100644
|
||||
struct in_addr a_record_from_hosts(char *name, time_t now)
|
||||
{
|
||||
struct crec *crecp = NULL;
|
||||
@@ -1188,7 +1191,7 @@ void cache_add_dhcp_entry(char *host_name, int prot,
|
||||
@@ -1229,7 +1232,7 @@ void cache_add_dhcp_entry(char *host_name, int prot,
|
||||
addrlen = sizeof(struct in6_addr);
|
||||
}
|
||||
#endif
|
||||
@@ -52,7 +52,7 @@ index 2c3a498..77a7046 100644
|
||||
inet_ntop(prot, host_address, daemon->addrbuff, ADDRSTRLEN);
|
||||
|
||||
while ((crec = cache_find_by_name(crec, host_name, 0, flags | F_CNAME)))
|
||||
@@ -1253,7 +1256,11 @@ void cache_add_dhcp_entry(char *host_name, int prot,
|
||||
@@ -1294,7 +1297,11 @@ void cache_add_dhcp_entry(char *host_name, int prot,
|
||||
else
|
||||
crec->ttd = ttd;
|
||||
crec->addr.addr = *host_address;
|
||||
@@ -65,10 +65,10 @@ index 2c3a498..77a7046 100644
|
||||
cache_hash(crec);
|
||||
|
||||
diff --git a/src/dnsmasq.c b/src/dnsmasq.c
|
||||
index f4a89fc..a448ec4 100644
|
||||
index e903a24c8105..eefc7f939933 100644
|
||||
--- a/src/dnsmasq.c
|
||||
+++ b/src/dnsmasq.c
|
||||
@@ -940,6 +940,11 @@ int main (int argc, char **argv)
|
||||
@@ -970,6 +970,11 @@ int main (int argc, char **argv)
|
||||
|
||||
poll_resolv(0, daemon->last_resolv != 0, now);
|
||||
daemon->last_resolv = now;
|
||||
@@ -78,30 +78,24 @@ index f4a89fc..a448ec4 100644
|
||||
+ load_dhcp(now);
|
||||
+#endif
|
||||
}
|
||||
|
||||
if (FD_ISSET(piperead, &rset))
|
||||
diff --git a/src/dnsmasq.h b/src/dnsmasq.h
|
||||
index e74b15a..4a35168 100644
|
||||
--- a/src/dnsmasq.h
|
||||
+++ b/src/dnsmasq.h
|
||||
@@ -1463,9 +1463,13 @@ time_t periodic_slaac(time_t now, struct dhcp_lease *leases);
|
||||
void slaac_ping_reply(struct in6_addr *sender, unsigned char *packet, char *interface, struct dhcp_lease *leases);
|
||||
#endif
|
||||
|
||||
diff --git a/src/dnsmasq.h b/src/dnsmasq.h
|
||||
index 89e758b56a0a..c5edd6fdf7f5 100644
|
||||
--- a/src/dnsmasq.h
|
||||
+++ b/src/dnsmasq.h
|
||||
@@ -1502,3 +1502,8 @@ void inotify_dnsmasq_init();
|
||||
int inotify_check(time_t now);
|
||||
void set_dynamic_inotify(int flag, int total_size, struct crec **rhash, int revhashsz);
|
||||
#endif
|
||||
+
|
||||
+/* isc.c */
|
||||
+#ifdef HAVE_ISC_READER
|
||||
+void load_dhcp(time_t now);
|
||||
+#endif
|
||||
+
|
||||
/* loop.c */
|
||||
#ifdef HAVE_LOOP
|
||||
void loop_send_probes();
|
||||
int detect_loop(char *query, int type);
|
||||
#endif
|
||||
-
|
||||
diff --git a/src/isc.c b/src/isc.c
|
||||
new file mode 100644
|
||||
index 0000000..5106442
|
||||
index 000000000000..51064426f17f
|
||||
--- /dev/null
|
||||
+++ b/src/isc.c
|
||||
@@ -0,0 +1,251 @@
|
||||
@@ -357,10 +351,10 @@ index 0000000..5106442
|
||||
+
|
||||
+#endif
|
||||
diff --git a/src/option.c b/src/option.c
|
||||
index 45d8875..29c9ee5 100644
|
||||
index cb4e76ba0aa2..f6420fcbb7ab 100644
|
||||
--- a/src/option.c
|
||||
+++ b/src/option.c
|
||||
@@ -1669,7 +1669,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
||||
@@ -1693,7 +1693,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
||||
ret_err(_("bad MX target"));
|
||||
break;
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
From 0b1008d367d44e77352134a4c5178f896f0db3e7 Mon Sep 17 00:00:00 2001
|
||||
From: Simon Kelley <simon@thekelleys.org.uk>
|
||||
Date: Sat, 27 Dec 2014 15:33:32 +0000
|
||||
Subject: [PATCH] Bad packet protection.
|
||||
|
||||
---
|
||||
src/dnssec.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/dnssec.c b/src/dnssec.c
|
||||
index ed8cf89..026794b 100644
|
||||
--- a/src/dnssec.c
|
||||
+++ b/src/dnssec.c
|
||||
@@ -805,7 +805,7 @@ static int validate_rrset(time_t now, struct dns_header *header, size_t plen, in
|
||||
{
|
||||
while (*name_start != '.' && *name_start != 0)
|
||||
name_start++;
|
||||
- if (k != 1)
|
||||
+ if (k != 1 && *name_start == '.')
|
||||
name_start++;
|
||||
}
|
||||
|
||||
--
|
||||
1.7.10.4
|
||||
|
||||
@@ -1,85 +0,0 @@
|
||||
From 094b5c3d904bae9aeb3206d9f3b8348926b84975 Mon Sep 17 00:00:00 2001
|
||||
From: Simon Kelley <simon@thekelleys.org.uk>
|
||||
Date: Sun, 21 Dec 2014 16:11:52 +0000
|
||||
Subject: [PATCH] Fix crash in DNSSEC code when attempting to verify large
|
||||
RRs.
|
||||
|
||||
---
|
||||
src/dnssec.c | 27 +++++++++++++++++++--------
|
||||
1 files changed, 22 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/src/dnssec.c b/src/dnssec.c
|
||||
index 69bfc29..3208ac7 100644
|
||||
--- a/src/dnssec.c
|
||||
+++ b/src/dnssec.c
|
||||
@@ -456,16 +456,27 @@ static u16 *get_desc(int type)
|
||||
|
||||
/* Return bytes of canonicalised rdata, when the return value is zero, the remaining
|
||||
data, pointed to by *p, should be used raw. */
|
||||
-static int get_rdata(struct dns_header *header, size_t plen, unsigned char *end, char *buff,
|
||||
+static int get_rdata(struct dns_header *header, size_t plen, unsigned char *end, char *buff, int bufflen,
|
||||
unsigned char **p, u16 **desc)
|
||||
{
|
||||
int d = **desc;
|
||||
|
||||
- (*desc)++;
|
||||
-
|
||||
/* No more data needs mangling */
|
||||
if (d == (u16)-1)
|
||||
- return 0;
|
||||
+ {
|
||||
+ /* If there's more data than we have space for, just return what fits,
|
||||
+ we'll get called again for more chunks */
|
||||
+ if (end - *p > bufflen)
|
||||
+ {
|
||||
+ memcpy(buff, *p, bufflen);
|
||||
+ *p += bufflen;
|
||||
+ return bufflen;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ (*desc)++;
|
||||
|
||||
if (d == 0 && extract_name(header, plen, p, buff, 1, 0))
|
||||
/* domain-name, canonicalise */
|
||||
@@ -560,7 +571,7 @@ static void sort_rrset(struct dns_header *header, size_t plen, u16 *rr_desc, int
|
||||
if (left1 != 0)
|
||||
memmove(buff1, buff1 + len1 - left1, left1);
|
||||
|
||||
- if ((len1 = get_rdata(header, plen, end1, buff1 + left1, &p1, &dp1)) == 0)
|
||||
+ if ((len1 = get_rdata(header, plen, end1, buff1 + left1, MAXDNAME - left1, &p1, &dp1)) == 0)
|
||||
{
|
||||
quit = 1;
|
||||
len1 = end1 - p1;
|
||||
@@ -571,7 +582,7 @@ static void sort_rrset(struct dns_header *header, size_t plen, u16 *rr_desc, int
|
||||
if (left2 != 0)
|
||||
memmove(buff2, buff2 + len2 - left2, left2);
|
||||
|
||||
- if ((len2 = get_rdata(header, plen, end2, buff2 + left2, &p2, &dp2)) == 0)
|
||||
+ if ((len2 = get_rdata(header, plen, end2, buff2 + left2, MAXDNAME - left2, &p2, &dp2)) == 0)
|
||||
{
|
||||
quit = 1;
|
||||
len2 = end2 - p2;
|
||||
@@ -808,7 +819,7 @@ static int validate_rrset(time_t now, struct dns_header *header, size_t plen, in
|
||||
/* canonicalise rdata and calculate length of same, use name buffer as workspace */
|
||||
cp = p;
|
||||
dp = rr_desc;
|
||||
- for (len = 0; (seg = get_rdata(header, plen, end, name, &cp, &dp)) != 0; len += seg);
|
||||
+ for (len = 0; (seg = get_rdata(header, plen, end, name, MAXDNAME, &cp, &dp)) != 0; len += seg);
|
||||
len += end - cp;
|
||||
len = htons(len);
|
||||
hash->update(ctx, 2, (unsigned char *)&len);
|
||||
@@ -816,7 +827,7 @@ static int validate_rrset(time_t now, struct dns_header *header, size_t plen, in
|
||||
/* Now canonicalise again and digest. */
|
||||
cp = p;
|
||||
dp = rr_desc;
|
||||
- while ((seg = get_rdata(header, plen, end, name, &cp, &dp)))
|
||||
+ while ((seg = get_rdata(header, plen, end, name, MAXDNAME, &cp, &dp)))
|
||||
hash->update(ctx, seg, (unsigned char *)name);
|
||||
if (cp != end)
|
||||
hash->update(ctx, end - cp, cp);
|
||||
--
|
||||
1.7.10.4
|
||||
|
||||
@@ -1,365 +0,0 @@
|
||||
From fbc5205702c7f6f431d9f1043c553d7fb62ddfdb Mon Sep 17 00:00:00 2001
|
||||
From: Simon Kelley <simon@thekelleys.org.uk>
|
||||
Date: Tue, 23 Dec 2014 15:46:08 +0000
|
||||
Subject: [PATCH] Fix problems validating NSEC3 and wildcards.
|
||||
|
||||
---
|
||||
src/dnssec.c | 253 +++++++++++++++++++++++++++++-----------------------------
|
||||
1 file changed, 128 insertions(+), 125 deletions(-)
|
||||
|
||||
diff --git a/src/dnssec.c b/src/dnssec.c
|
||||
index 3208ac7..9350d3e 100644
|
||||
--- a/src/dnssec.c
|
||||
+++ b/src/dnssec.c
|
||||
@@ -615,6 +615,7 @@ static void sort_rrset(struct dns_header *header, size_t plen, u16 *rr_desc, int
|
||||
Return code:
|
||||
STAT_SECURE if it validates.
|
||||
STAT_SECURE_WILDCARD if it validates and is the result of wildcard expansion.
|
||||
+ (In this case *wildcard_out points to the "body" of the wildcard within name.)
|
||||
STAT_NO_SIG no RRsigs found.
|
||||
STAT_INSECURE RRset empty.
|
||||
STAT_BOGUS signature is wrong, bad packet.
|
||||
@@ -625,8 +626,8 @@ static void sort_rrset(struct dns_header *header, size_t plen, u16 *rr_desc, int
|
||||
|
||||
name is unchanged on exit. keyname is used as workspace and trashed.
|
||||
*/
|
||||
-static int validate_rrset(time_t now, struct dns_header *header, size_t plen, int class,
|
||||
- int type, char *name, char *keyname, struct blockdata *key, int keylen, int algo_in, int keytag_in)
|
||||
+static int validate_rrset(time_t now, struct dns_header *header, size_t plen, int class, int type,
|
||||
+ char *name, char *keyname, char **wildcard_out, struct blockdata *key, int keylen, int algo_in, int keytag_in)
|
||||
{
|
||||
static unsigned char **rrset = NULL, **sigs = NULL;
|
||||
static int rrset_sz = 0, sig_sz = 0;
|
||||
@@ -798,8 +799,16 @@ static int validate_rrset(time_t now, struct dns_header *header, size_t plen, in
|
||||
{
|
||||
int k;
|
||||
for (k = name_labels - labels; k != 0; k--)
|
||||
- while (*name_start != '.' && *name_start != 0)
|
||||
- name_start++;
|
||||
+ {
|
||||
+ while (*name_start != '.' && *name_start != 0)
|
||||
+ name_start++;
|
||||
+ if (k != 1)
|
||||
+ name_start++;
|
||||
+ }
|
||||
+
|
||||
+ if (wildcard_out)
|
||||
+ *wildcard_out = name_start+1;
|
||||
+
|
||||
name_start--;
|
||||
*name_start = '*';
|
||||
}
|
||||
@@ -974,7 +983,7 @@ int dnssec_validate_by_ds(time_t now, struct dns_header *header, size_t plen, ch
|
||||
if (recp1->addr.ds.keylen == (int)hash->digest_size &&
|
||||
(ds_digest = blockdata_retrieve(recp1->addr.key.keydata, recp1->addr.ds.keylen, NULL)) &&
|
||||
memcmp(ds_digest, digest, recp1->addr.ds.keylen) == 0 &&
|
||||
- validate_rrset(now, header, plen, class, T_DNSKEY, name, keyname, key, rdlen - 4, algo, keytag) == STAT_SECURE)
|
||||
+ validate_rrset(now, header, plen, class, T_DNSKEY, name, keyname, NULL, key, rdlen - 4, algo, keytag) == STAT_SECURE)
|
||||
{
|
||||
valid = 1;
|
||||
break;
|
||||
@@ -1443,11 +1452,88 @@ static int base32_decode(char *in, unsigned char *out)
|
||||
return p - out;
|
||||
}
|
||||
|
||||
+static int check_nsec3_coverage(struct dns_header *header, size_t plen, int digest_len, unsigned char *digest, int type,
|
||||
+ char *workspace1, char *workspace2, unsigned char **nsecs, int nsec_count)
|
||||
+{
|
||||
+ int i, hash_len, salt_len, base32_len, rdlen;
|
||||
+ unsigned char *p, *psave;
|
||||
+
|
||||
+ for (i = 0; i < nsec_count; i++)
|
||||
+ if ((p = nsecs[i]))
|
||||
+ {
|
||||
+ if (!extract_name(header, plen, &p, workspace1, 1, 0) ||
|
||||
+ !(base32_len = base32_decode(workspace1, (unsigned char *)workspace2)))
|
||||
+ return 0;
|
||||
+
|
||||
+ p += 8; /* class, type, TTL */
|
||||
+ GETSHORT(rdlen, p);
|
||||
+ psave = p;
|
||||
+ p += 4; /* algo, flags, iterations */
|
||||
+ salt_len = *p++; /* salt_len */
|
||||
+ p += salt_len; /* salt */
|
||||
+ hash_len = *p++; /* p now points to next hashed name */
|
||||
+
|
||||
+ if (!CHECK_LEN(header, p, plen, hash_len))
|
||||
+ return 0;
|
||||
+
|
||||
+ if (digest_len == base32_len && hash_len == base32_len)
|
||||
+ {
|
||||
+ int rc = memcmp(workspace2, digest, digest_len);
|
||||
+
|
||||
+ if (rc == 0)
|
||||
+ {
|
||||
+ /* We found an NSEC3 whose hashed name exactly matches the query, so
|
||||
+ we just need to check the type map. p points to the RR data for the record. */
|
||||
+
|
||||
+ int offset = (type & 0xff) >> 3;
|
||||
+ int mask = 0x80 >> (type & 0x07);
|
||||
+
|
||||
+ p += hash_len; /* skip next-domain hash */
|
||||
+ rdlen -= p - psave;
|
||||
+
|
||||
+ if (!CHECK_LEN(header, p, plen, rdlen))
|
||||
+ return 0;
|
||||
+
|
||||
+ while (rdlen >= 2)
|
||||
+ {
|
||||
+ if (p[0] == type >> 8)
|
||||
+ {
|
||||
+ /* Does the NSEC3 say our type exists? */
|
||||
+ if (offset < p[1] && (p[offset+2] & mask) != 0)
|
||||
+ return STAT_BOGUS;
|
||||
+
|
||||
+ break; /* finshed checking */
|
||||
+ }
|
||||
+
|
||||
+ rdlen -= p[1];
|
||||
+ p += p[1];
|
||||
+ }
|
||||
+
|
||||
+ return 1;
|
||||
+ }
|
||||
+ else if (rc <= 0)
|
||||
+ {
|
||||
+ /* Normal case, hash falls between NSEC3 name-hash and next domain name-hash,
|
||||
+ wrap around case, name-hash falls between NSEC3 name-hash and end */
|
||||
+ if (memcmp(p, digest, digest_len) > 0 || memcmp(workspace2, p, digest_len) > 0)
|
||||
+ return 1;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ /* wrap around case, name falls between start and next domain name */
|
||||
+ if (memcmp(workspace2, p, digest_len) > 0 && memcmp(p, digest, digest_len) > 0)
|
||||
+ return 1;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int prove_non_existence_nsec3(struct dns_header *header, size_t plen, unsigned char **nsecs, int nsec_count,
|
||||
- char *workspace1, char *workspace2, char *name, int type)
|
||||
+ char *workspace1, char *workspace2, char *name, int type, char *wildname)
|
||||
{
|
||||
unsigned char *salt, *p, *digest;
|
||||
- int digest_len, i, iterations, salt_len, hash_len, base32_len, algo = 0;
|
||||
+ int digest_len, i, iterations, salt_len, base32_len, algo = 0;
|
||||
struct nettle_hash const *hash;
|
||||
char *closest_encloser, *next_closest, *wildcard;
|
||||
|
||||
@@ -1520,7 +1606,14 @@ static int prove_non_existence_nsec3(struct dns_header *header, size_t plen, uns
|
||||
if (!(hash = hash_find("sha1")))
|
||||
return STAT_BOGUS;
|
||||
|
||||
- /* Now, we need the "closest encloser NSEC3" */
|
||||
+ if ((digest_len = hash_name(name, &digest, hash, salt, salt_len, iterations)) == 0)
|
||||
+ return STAT_BOGUS;
|
||||
+
|
||||
+ if (check_nsec3_coverage(header, plen, digest_len, digest, type, workspace1, workspace2, nsecs, nsec_count))
|
||||
+ return STAT_SECURE;
|
||||
+
|
||||
+ /* Can't find an NSEC3 which covers the name directly, we need the "closest encloser NSEC3"
|
||||
+ or an answer inferred from a wildcard record. */
|
||||
closest_encloser = name;
|
||||
next_closest = NULL;
|
||||
|
||||
@@ -1529,6 +1622,9 @@ static int prove_non_existence_nsec3(struct dns_header *header, size_t plen, uns
|
||||
if (*closest_encloser == '.')
|
||||
closest_encloser++;
|
||||
|
||||
+ if (wildname && hostname_isequal(closest_encloser, wildname))
|
||||
+ break;
|
||||
+
|
||||
if ((digest_len = hash_name(closest_encloser, &digest, hash, salt, salt_len, iterations)) == 0)
|
||||
return STAT_BOGUS;
|
||||
|
||||
@@ -1551,127 +1647,33 @@ static int prove_non_existence_nsec3(struct dns_header *header, size_t plen, uns
|
||||
}
|
||||
while ((closest_encloser = strchr(closest_encloser, '.')));
|
||||
|
||||
- /* No usable NSEC3s */
|
||||
- if (i == nsec_count)
|
||||
+ if (!closest_encloser)
|
||||
return STAT_BOGUS;
|
||||
|
||||
- if (!next_closest)
|
||||
- {
|
||||
- /* We found an NSEC3 whose hashed name exactly matches the query, so
|
||||
- Now we just need to check the type map. p points to the RR data for the record. */
|
||||
- int rdlen;
|
||||
- unsigned char *psave;
|
||||
- int offset = (type & 0xff) >> 3;
|
||||
- int mask = 0x80 >> (type & 0x07);
|
||||
-
|
||||
- p += 8; /* class, type, TTL */
|
||||
- GETSHORT(rdlen, p);
|
||||
- psave = p;
|
||||
- p += 5 + salt_len; /* algo, flags, iterations, salt_len, salt */
|
||||
- hash_len = *p++;
|
||||
- if (!CHECK_LEN(header, p, plen, hash_len))
|
||||
- return STAT_BOGUS; /* bad packet */
|
||||
- p += hash_len;
|
||||
- rdlen -= p - psave;
|
||||
-
|
||||
- while (rdlen >= 2)
|
||||
- {
|
||||
- if (!CHECK_LEN(header, p, plen, rdlen))
|
||||
- return STAT_BOGUS;
|
||||
-
|
||||
- if (p[0] == type >> 8)
|
||||
- {
|
||||
- /* Does the NSEC3 say our type exists? */
|
||||
- if (offset < p[1] && (p[offset+2] & mask) != 0)
|
||||
- return STAT_BOGUS;
|
||||
-
|
||||
- break; /* finshed checking */
|
||||
- }
|
||||
-
|
||||
- rdlen -= p[1];
|
||||
- p += p[1];
|
||||
- }
|
||||
-
|
||||
- return STAT_SECURE;
|
||||
- }
|
||||
-
|
||||
/* Look for NSEC3 that proves the non-existence of the next-closest encloser */
|
||||
if ((digest_len = hash_name(next_closest, &digest, hash, salt, salt_len, iterations)) == 0)
|
||||
return STAT_BOGUS;
|
||||
|
||||
- for (i = 0; i < nsec_count; i++)
|
||||
- if ((p = nsecs[i]))
|
||||
- {
|
||||
- if (!extract_name(header, plen, &p, workspace1, 1, 0) ||
|
||||
- !(base32_len = base32_decode(workspace1, (unsigned char *)workspace2)))
|
||||
- return STAT_BOGUS;
|
||||
-
|
||||
- p += 15 + salt_len; /* class, type, TTL, rdlen, algo, flags, iterations, salt_len, salt */
|
||||
- hash_len = *p++; /* p now points to next hashed name */
|
||||
-
|
||||
- if (!CHECK_LEN(header, p, plen, hash_len))
|
||||
- return STAT_BOGUS;
|
||||
-
|
||||
- if (digest_len == base32_len && hash_len == base32_len)
|
||||
- {
|
||||
- if (memcmp(workspace2, digest, digest_len) <= 0)
|
||||
- {
|
||||
- /* Normal case, hash falls between NSEC3 name-hash and next domain name-hash,
|
||||
- wrap around case, name-hash falls between NSEC3 name-hash and end */
|
||||
- if (memcmp(p, digest, digest_len) > 0 || memcmp(workspace2, p, digest_len) > 0)
|
||||
- return STAT_SECURE;
|
||||
- }
|
||||
- else
|
||||
- {
|
||||
- /* wrap around case, name falls between start and next domain name */
|
||||
- if (memcmp(workspace2, p, digest_len) > 0 && memcmp(p, digest, digest_len) > 0)
|
||||
- return STAT_SECURE;
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- /* Finally, check that there's no seat of wildcard synthesis */
|
||||
- if (!(wildcard = strchr(next_closest, '.')) || wildcard == next_closest)
|
||||
- return STAT_BOGUS;
|
||||
-
|
||||
- wildcard--;
|
||||
- *wildcard = '*';
|
||||
-
|
||||
- if ((digest_len = hash_name(wildcard, &digest, hash, salt, salt_len, iterations)) == 0)
|
||||
+ if (!check_nsec3_coverage(header, plen, digest_len, digest, type, workspace1, workspace2, nsecs, nsec_count))
|
||||
return STAT_BOGUS;
|
||||
|
||||
- for (i = 0; i < nsec_count; i++)
|
||||
- if ((p = nsecs[i]))
|
||||
- {
|
||||
- if (!extract_name(header, plen, &p, workspace1, 1, 0) ||
|
||||
- !(base32_len = base32_decode(workspace1, (unsigned char *)workspace2)))
|
||||
- return STAT_BOGUS;
|
||||
-
|
||||
- p += 15 + salt_len; /* class, type, TTL, rdlen, algo, flags, iterations, salt_len, salt */
|
||||
- hash_len = *p++; /* p now points to next hashed name */
|
||||
-
|
||||
- if (!CHECK_LEN(header, p, plen, hash_len))
|
||||
- return STAT_BOGUS;
|
||||
-
|
||||
- if (digest_len == base32_len && hash_len == base32_len)
|
||||
- {
|
||||
- if (memcmp(workspace2, digest, digest_len) <= 0)
|
||||
- {
|
||||
- /* Normal case, hash falls between NSEC3 name-hash and next domain name-hash,
|
||||
- wrap around case, name-hash falls between NSEC3 name-hash and end */
|
||||
- if (memcmp(p, digest, digest_len) > 0 || memcmp(workspace2, p, digest_len) > 0)
|
||||
- return STAT_SECURE;
|
||||
- }
|
||||
- else
|
||||
- {
|
||||
- /* wrap around case, name falls between start and next domain name */
|
||||
- if (memcmp(workspace2, p, digest_len) > 0 && memcmp(p, digest, digest_len) > 0)
|
||||
- return STAT_SECURE;
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
+ /* Finally, check that there's no seat of wildcard synthesis */
|
||||
+ if (!wildname)
|
||||
+ {
|
||||
+ if (!(wildcard = strchr(next_closest, '.')) || wildcard == next_closest)
|
||||
+ return STAT_BOGUS;
|
||||
+
|
||||
+ wildcard--;
|
||||
+ *wildcard = '*';
|
||||
+
|
||||
+ if ((digest_len = hash_name(wildcard, &digest, hash, salt, salt_len, iterations)) == 0)
|
||||
+ return STAT_BOGUS;
|
||||
+
|
||||
+ if (!check_nsec3_coverage(header, plen, digest_len, digest, type, workspace1, workspace2, nsecs, nsec_count))
|
||||
+ return STAT_BOGUS;
|
||||
+ }
|
||||
|
||||
- return STAT_BOGUS;
|
||||
+ return STAT_SECURE;
|
||||
}
|
||||
|
||||
/* Validate all the RRsets in the answer and authority sections of the reply (4035:3.2.3) */
|
||||
@@ -1792,8 +1794,9 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
|
||||
struct all_addr a;
|
||||
struct blockdata *key;
|
||||
struct crec *crecp;
|
||||
-
|
||||
- rc = validate_rrset(now, header, plen, class1, type1, name, keyname, NULL, 0, 0, 0);
|
||||
+ char *wildname;
|
||||
+
|
||||
+ rc = validate_rrset(now, header, plen, class1, type1, name, keyname, &wildname, NULL, 0, 0, 0);
|
||||
|
||||
if (rc == STAT_SECURE_WILDCARD)
|
||||
{
|
||||
@@ -1807,7 +1810,7 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
|
||||
if (nsec_type == T_NSEC)
|
||||
rc = prove_non_existence_nsec(header, plen, nsecs, nsec_count, daemon->workspacename, keyname, name, type1);
|
||||
else
|
||||
- rc = prove_non_existence_nsec3(header, plen, nsecs, nsec_count, daemon->workspacename, keyname, name, type1);
|
||||
+ rc = prove_non_existence_nsec3(header, plen, nsecs, nsec_count, daemon->workspacename, keyname, name, type1, wildname);
|
||||
|
||||
if (rc != STAT_SECURE)
|
||||
return rc;
|
||||
@@ -1933,7 +1936,7 @@ int dnssec_validate_reply(time_t now, struct dns_header *header, size_t plen, ch
|
||||
if (nsec_type == T_NSEC)
|
||||
return prove_non_existence_nsec(header, plen, nsecs, nsec_count, daemon->workspacename, keyname, name, qtype);
|
||||
else
|
||||
- return prove_non_existence_nsec3(header, plen, nsecs, nsec_count, daemon->workspacename, keyname, name, qtype);
|
||||
+ return prove_non_existence_nsec3(header, plen, nsecs, nsec_count, daemon->workspacename, keyname, name, qtype, NULL);
|
||||
}
|
||||
|
||||
/* Chase the CNAME chain in the packet until the first record which _doesn't validate.
|
||||
@@ -1980,7 +1983,7 @@ int dnssec_chase_cname(time_t now, struct dns_header *header, size_t plen, char
|
||||
return STAT_INSECURE;
|
||||
|
||||
/* validate CNAME chain, return if insecure or need more data */
|
||||
- rc = validate_rrset(now, header, plen, class, type, name, keyname, NULL, 0, 0, 0);
|
||||
+ rc = validate_rrset(now, header, plen, class, type, name, keyname, NULL, NULL, 0, 0, 0);
|
||||
if (rc != STAT_SECURE)
|
||||
{
|
||||
if (rc == STAT_NO_SIG)
|
||||
--
|
||||
1.7.10.4
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
From 83d2ed09fc0216b567d7fb2197e4ff3eae150b0d Mon Sep 17 00:00:00 2001
|
||||
From: Simon Kelley <simon@thekelleys.org.uk>
|
||||
Date: Tue, 23 Dec 2014 18:42:38 +0000
|
||||
Subject: [PATCH] Initialise return value.
|
||||
|
||||
---
|
||||
src/dnssec.c | 7 +++++--
|
||||
1 file changed, 5 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/dnssec.c b/src/dnssec.c
|
||||
index 9350d3e..ed8cf89 100644
|
||||
--- a/src/dnssec.c
|
||||
+++ b/src/dnssec.c
|
||||
@@ -637,10 +637,13 @@ static int validate_rrset(time_t now, struct dns_header *header, size_t plen, in
|
||||
struct crec *crecp = NULL;
|
||||
int type_covered, algo, labels, orig_ttl, sig_expiration, sig_inception, key_tag;
|
||||
u16 *rr_desc = get_desc(type);
|
||||
-
|
||||
+
|
||||
+ if (wildcard_out)
|
||||
+ *wildcard_out = NULL;
|
||||
+
|
||||
if (!(p = skip_questions(header, plen)))
|
||||
return STAT_BOGUS;
|
||||
-
|
||||
+
|
||||
name_labels = count_labels(name); /* For 4035 5.3.2 check */
|
||||
|
||||
/* look for RRSIGs for this RRset and get pointers to each RR in the set. */
|
||||
--
|
||||
1.7.10.4
|
||||
|
||||
@@ -1,99 +0,0 @@
|
||||
From cbc652423403e3cef00e00240f6beef713142246 Mon Sep 17 00:00:00 2001
|
||||
From: Simon Kelley <simon@thekelleys.org.uk>
|
||||
Date: Sun, 21 Dec 2014 21:21:53 +0000
|
||||
Subject: [PATCH] Make caching work for CNAMEs pointing to A/AAAA records
|
||||
shadowed in /etc/hosts
|
||||
|
||||
If the answer to an upstream query is a CNAME which points to an
|
||||
A/AAAA record which also exists in /etc/hosts and friends, then
|
||||
caching is suppressed, to avoid inconsistent answers. This is
|
||||
now modified to allow caching when the upstream and local A/AAAA
|
||||
records have the same value.
|
||||
---
|
||||
src/cache.c | 34 +++++++++++++++++++++++++---------
|
||||
1 file changed, 25 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/src/cache.c b/src/cache.c
|
||||
index f9e1d31..ff1ca6f 100644
|
||||
--- a/src/cache.c
|
||||
+++ b/src/cache.c
|
||||
@@ -322,7 +322,7 @@ static int is_expired(time_t now, struct crec *crecp)
|
||||
return 1;
|
||||
}
|
||||
|
||||
-static int cache_scan_free(char *name, struct all_addr *addr, time_t now, unsigned short flags)
|
||||
+static struct crec *cache_scan_free(char *name, struct all_addr *addr, time_t now, unsigned short flags)
|
||||
{
|
||||
/* Scan and remove old entries.
|
||||
If (flags & F_FORWARD) then remove any forward entries for name and any expired
|
||||
@@ -331,8 +331,8 @@ static int cache_scan_free(char *name, struct all_addr *addr, time_t now, unsign
|
||||
entries in the whole cache.
|
||||
If (flags == 0) remove any expired entries in the whole cache.
|
||||
|
||||
- In the flags & F_FORWARD case, the return code is valid, and returns zero if the
|
||||
- name exists in the cache as a HOSTS or DHCP entry (these are never deleted)
|
||||
+ In the flags & F_FORWARD case, the return code is valid, and returns a non-NULL pointer
|
||||
+ to a cache entry if the name exists in the cache as a HOSTS or DHCP entry (these are never deleted)
|
||||
|
||||
We take advantage of the fact that hash chains have stuff in the order <reverse>,<other>,<immortal>
|
||||
so that when we hit an entry which isn't reverse and is immortal, we're done. */
|
||||
@@ -361,7 +361,7 @@ static int cache_scan_free(char *name, struct all_addr *addr, time_t now, unsign
|
||||
(((crecp->flags | flags) & F_CNAME) && !(crecp->flags & (F_DNSKEY | F_DS))))
|
||||
{
|
||||
if (crecp->flags & (F_HOSTS | F_DHCP | F_CONFIG))
|
||||
- return 0;
|
||||
+ return crecp;
|
||||
*up = crecp->hash_next;
|
||||
cache_unlink(crecp);
|
||||
cache_free(crecp);
|
||||
@@ -378,7 +378,7 @@ static int cache_scan_free(char *name, struct all_addr *addr, time_t now, unsign
|
||||
crecp->addr.sig.type_covered == addr->addr.dnssec.type))
|
||||
{
|
||||
if (crecp->flags & F_CONFIG)
|
||||
- return 0;
|
||||
+ return crecp;
|
||||
*up = crecp->hash_next;
|
||||
cache_unlink(crecp);
|
||||
cache_free(crecp);
|
||||
@@ -423,7 +423,7 @@ static int cache_scan_free(char *name, struct all_addr *addr, time_t now, unsign
|
||||
up = &crecp->hash_next;
|
||||
}
|
||||
|
||||
- return 1;
|
||||
+ return NULL;
|
||||
}
|
||||
|
||||
/* Note: The normal calling sequence is
|
||||
@@ -471,10 +471,26 @@ struct crec *cache_insert(char *name, struct all_addr *addr,
|
||||
return NULL;
|
||||
|
||||
/* First remove any expired entries and entries for the name/address we
|
||||
- are currently inserting. Fail if we attempt to delete a name from
|
||||
- /etc/hosts or DHCP. */
|
||||
- if (!cache_scan_free(name, addr, now, flags))
|
||||
+ are currently inserting. */
|
||||
+ if ((new = cache_scan_free(name, addr, now, flags)))
|
||||
{
|
||||
+ /* We're trying to insert a record over one from
|
||||
+ /etc/hosts or DHCP, or other config. If the
|
||||
+ existing record is for an A or AAAA and
|
||||
+ the record we're trying to insert is the same,
|
||||
+ just drop the insert, but don't error the whole process. */
|
||||
+ if ((flags & (F_IPV4 | F_IPV6)) && (flags & F_FORWARD))
|
||||
+ {
|
||||
+ if ((flags & F_IPV4) && (new->flags & F_IPV4) &&
|
||||
+ new->addr.addr.addr.addr4.s_addr == addr->addr.addr4.s_addr)
|
||||
+ return new;
|
||||
+#ifdef HAVE_IPV6
|
||||
+ else if ((flags & F_IPV6) && (new->flags & F_IPV6) &&
|
||||
+ IN6_ARE_ADDR_EQUAL(&new->addr.addr.addr.addr6, &addr->addr.addr6))
|
||||
+ return new;
|
||||
+#endif
|
||||
+ }
|
||||
+
|
||||
insert_error = 1;
|
||||
return NULL;
|
||||
}
|
||||
--
|
||||
1.7.10.4
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
From 800c5cc1e7438818fd80f08c2d472df249a6942d Mon Sep 17 00:00:00 2001
|
||||
From: Simon Kelley <simon@thekelleys.org.uk>
|
||||
Date: Mon, 15 Dec 2014 17:50:15 +0000
|
||||
Subject: [PATCH] Remove floor on EDNS0 packet size with DNSSEC.
|
||||
|
||||
---
|
||||
src/dnsmasq.c | 5 -----
|
||||
1 files changed, 5 deletions(-)
|
||||
|
||||
diff --git a/src/dnsmasq.c b/src/dnsmasq.c
|
||||
index bf2e25a..5c7750d 100644
|
||||
--- a/src/dnsmasq.c
|
||||
+++ b/src/dnsmasq.c
|
||||
@@ -87,11 +87,6 @@ int main (int argc, char **argv)
|
||||
|
||||
if (daemon->edns_pktsz < PACKETSZ)
|
||||
daemon->edns_pktsz = PACKETSZ;
|
||||
-#ifdef HAVE_DNSSEC
|
||||
- /* Enforce min packet big enough for DNSSEC */
|
||||
- if (option_bool(OPT_DNSSEC_VALID) && daemon->edns_pktsz < EDNS_PKTSZ)
|
||||
- daemon->edns_pktsz = EDNS_PKTSZ;
|
||||
-#endif
|
||||
|
||||
daemon->packet_buff_sz = daemon->edns_pktsz > DNSMASQ_PACKETSZ ?
|
||||
daemon->edns_pktsz : DNSMASQ_PACKETSZ;
|
||||
--
|
||||
1.7.10.4
|
||||
|
||||
Reference in New Issue
Block a user