This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "IPFire 2.x development tree".
The branch, next has been updated via 32e321b248ae4501ad17d7edc50bb23aaa4b5c6e (commit) from 06f451c0beaba72872fa7ab81a043eb92a3f63ee (commit)
Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below.
- Log ----------------------------------------------------------------- commit 32e321b248ae4501ad17d7edc50bb23aaa4b5c6e Author: Michael Tremer michael.tremer@ipfire.org Date: Mon Feb 2 00:33:04 2015 +0100
dnsmasq: Update to development snatpshot
-----------------------------------------------------------------------
Summary of changes: lfs/dnsmasq | 18 +- ...-Add-support-to-read-ISC-DHCP-lease-file.patch} | 48 ++- .../dnsmasq-2.73-bad-packet-protection.patch | 25 -- ...-code-when-attempting-to-verify-large-RRs.patch | 85 ----- ...x-problems-validating-NSEC3-and-wildcards.patch | 365 --------------------- .../dnsmasq-2.73-initialise-return-value.patch | 32 -- ...g-to-A-AAAA-records-shadowed-in-etc-hosts.patch | 99 ------ ...ve-floor-on-edns0-packet-size-with-DNSSEC.patch | 28 -- 8 files changed, 27 insertions(+), 673 deletions(-) rename src/patches/{dnsmasq-2.72rc2-Add-support-to-read-ISC-DHCP-lease-file.patch => dnsmasq-Add-support-to-read-ISC-DHCP-lease-file.patch} (89%) delete mode 100644 src/patches/dnsmasq/dnsmasq-2.73-bad-packet-protection.patch delete mode 100644 src/patches/dnsmasq/dnsmasq-2.73-fix-crash-in-DNSSEC-code-when-attempting-to-verify-large-RRs.patch delete mode 100644 src/patches/dnsmasq/dnsmasq-2.73-fix-problems-validating-NSEC3-and-wildcards.patch delete mode 100644 src/patches/dnsmasq/dnsmasq-2.73-initialise-return-value.patch delete mode 100644 src/patches/dnsmasq/dnsmasq-2.73-make-caching-work-for-CNAMEs-pointing-to-A-AAAA-records-shadowed-in-etc-hosts.patch delete mode 100644 src/patches/dnsmasq/dnsmasq-2.73-remove-floor-on-edns0-packet-size-with-DNSSEC.patch
Difference in files: diff --git a/lfs/dnsmasq b/lfs/dnsmasq index 8493657..244077c 100644 --- a/lfs/dnsmasq +++ b/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) diff --git a/src/patches/dnsmasq-2.72rc2-Add-support-to-read-ISC-DHCP-lease-file.patch b/src/patches/dnsmasq-2.72rc2-Add-support-to-read-ISC-DHCP-lease-file.patch deleted file mode 100644 index 9912c7c..0000000 --- a/src/patches/dnsmasq-2.72rc2-Add-support-to-read-ISC-DHCP-lease-file.patch +++ /dev/null @@ -1,371 +0,0 @@ -diff --git a/Makefile b/Makefile -index 58a7975..616c6b7 100644 ---- a/Makefile -+++ b/Makefile -@@ -69,7 +69,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 - - 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 ---- a/src/cache.c -+++ b/src/cache.c -@@ -17,7 +17,7 @@ - #include "dnsmasq.h" - - static struct crec *cache_head = NULL, *cache_tail = NULL, **hash_table = NULL; --#ifdef HAVE_DHCP -+#if (defined HAVE_DHCP) || (defined HAVE_ISC_READER) - static struct crec *dhcp_spare = NULL; - #endif - static struct crec *new_chain = NULL; -@@ -222,6 +222,9 @@ static void cache_free(struct crec *crecp) - crecp->flags &= ~F_BIGNAME; - } - -+ if (crecp->flags & F_DHCP) -+ free(crecp->name.namep); -+ - #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); - } - --#ifdef HAVE_DHCP -+#if (defined HAVE_DHCP) || (defined HAVE_ISC_READER) - 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, - addrlen = sizeof(struct in6_addr); - } - #endif -- -+ - 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, - else - crec->ttd = ttd; - crec->addr.addr = *host_address; -+#ifdef HAVE_ISC_READER -+ crec->name.namep = strdup(host_name); -+#else - crec->name.namep = host_name; -+#endif - crec->uid = next_uid(); - cache_hash(crec); - -diff --git a/src/dnsmasq.c b/src/dnsmasq.c -index f4a89fc..a448ec4 100644 ---- a/src/dnsmasq.c -+++ b/src/dnsmasq.c -@@ -940,6 +940,11 @@ int main (int argc, char **argv) - - poll_resolv(0, daemon->last_resolv != 0, now); - daemon->last_resolv = now; -+ -+#ifdef HAVE_ISC_READER -+ if (daemon->lease_file && !daemon->dhcp) -+ 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 - -+/* 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 ---- /dev/null -+++ b/src/isc.c -@@ -0,0 +1,251 @@ -+/* dnsmasq is Copyright (c) 2014 John Volpe, Simon Kelley and -+ Michael Tremer -+ -+ This program is free software; you can redistribute it and/or modify -+ it under the terms of the GNU General Public License as published by -+ the Free Software Foundation; version 2 dated June, 1991, or -+ (at your option) version 3 dated 29 June, 2007. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program. If not, see http://www.gnu.org/licenses/. -+ -+ Code in this file is based on contributions by John Volpe and -+ Simon Kelley. Updated for recent versions of dnsmasq by -+ Michael Tremer. -+*/ -+ -+#include "dnsmasq.h" -+ -+#ifdef HAVE_ISC_READER -+#define MAXTOK 50 -+ -+struct isc_dhcp_lease { -+ char* name; -+ char* fqdn; -+ time_t expires; -+ struct in_addr addr; -+ struct isc_dhcp_lease* next; -+}; -+ -+static struct isc_dhcp_lease* dhcp_lease_new(const char* hostname) { -+ struct isc_dhcp_lease* lease = whine_malloc(sizeof(*lease)); -+ -+ lease->name = strdup(hostname); -+ if (daemon->domain_suffix) { -+ asprintf(&lease->fqdn, "%s.%s", hostname, daemon->domain_suffix); -+ } -+ lease->expires = 0; -+ lease->next = NULL; -+ -+ return lease; -+} -+ -+static void dhcp_lease_free(struct isc_dhcp_lease* lease) { -+ if (!lease) -+ return; -+ -+ if (lease->name) -+ free(lease->name); -+ if (lease->fqdn) -+ free(lease->fqdn); -+ free(lease); -+} -+ -+static int next_token(char* token, int buffsize, FILE* fp) { -+ int c, count = 0; -+ char* cp = token; -+ -+ while ((c = getc(fp)) != EOF) { -+ if (c == '#') { -+ do { -+ c = getc(fp); -+ } while (c != '\n' && c != EOF); -+ } -+ -+ if (c == ' ' || c == '\t' || c == '\n' || c == ';') { -+ if (count) -+ break; -+ } else if ((c != '"') && (count < buffsize - 1)) { -+ *cp++ = c; -+ count++; -+ } -+ } -+ -+ *cp = 0; -+ return count ? 1 : 0; -+} -+ -+static long get_utc_offset() { -+ time_t t = time(NULL); -+ struct tm* time_struct = localtime(&t); -+ -+ return time_struct->tm_gmtoff; -+} -+ -+static time_t parse_lease_time(const char* token_date, const char* token_time) { -+ time_t time = (time_t)(-1); -+ struct tm lease_time; -+ -+ if (sscanf(token_date, "%d/%d/%d", &lease_time.tm_year, &lease_time.tm_mon, &lease_time.tm_mday) == 3) { -+ lease_time.tm_year -= 1900; -+ lease_time.tm_mon -= 1; -+ -+ if (sscanf(token_time, "%d:%d:%d", &lease_time.tm_hour, &lease_time.tm_min, &lease_time.tm_sec) == 3) { -+ time = mktime(&lease_time) + get_utc_offset(); -+ } -+ } -+ -+ return time; -+} -+ -+static struct isc_dhcp_lease* find_lease(const char* hostname, struct isc_dhcp_lease* leases) { -+ struct isc_dhcp_lease* lease = leases; -+ -+ while (lease) { -+ if (strcmp(hostname, lease->name) == 0) { -+ return lease; -+ } -+ lease = lease->next; -+ } -+ -+ return NULL; -+} -+ -+static off_t lease_file_size = (off_t)0; -+static ino_t lease_file_inode = (ino_t)0; -+ -+void load_dhcp(time_t now) { -+ struct isc_dhcp_lease* leases = NULL; -+ -+ struct stat statbuf; -+ if (stat(daemon->lease_file, &statbuf) == -1) { -+ return; -+ } -+ -+ /* Do nothing if the lease file has not changed. */ -+ if ((statbuf.st_size <= lease_file_size) && (statbuf.st_ino == lease_file_inode)) -+ return; -+ -+ lease_file_size = statbuf.st_size; -+ lease_file_inode = statbuf.st_ino; -+ -+ FILE* fp = fopen(daemon->lease_file, "r"); -+ if (!fp) { -+ my_syslog(LOG_ERR, _("failed to load %s:%s"), daemon->lease_file, strerror(errno)); -+ return; -+ } -+ -+ my_syslog(LOG_INFO, _("reading %s"), daemon->lease_file); -+ -+ char* hostname = daemon->namebuff; -+ struct in_addr host_address; -+ time_t time_starts = -1; -+ time_t time_ends = -1; -+ int nomem; -+ -+ char token[MAXTOK]; -+ while ((next_token(token, MAXTOK, fp))) { -+ if (strcmp(token, "lease") == 0) { -+ hostname[0] = '\0'; -+ -+ if (next_token(token, MAXTOK, fp) && ((host_address.s_addr = inet_addr(token)) != (in_addr_t)-1)) { -+ if (next_token(token, MAXTOK, fp) && *token == '{') { -+ while (next_token(token, MAXTOK, fp) && *token != '}') { -+ if ((strcmp(token, "client-hostname") == 0) || (strcmp(token, "hostname") == 0)) { -+ if (next_token(hostname, MAXDNAME, fp)) { -+ if (!canonicalise(hostname, &nomem)) { -+ *hostname = 0; -+ my_syslog(LOG_ERR, _("bad name in %s"), daemon->lease_file); -+ } -+ } -+ } else if ((strcmp(token, "starts") == 0) || (strcmp(token, "ends") == 0)) { -+ char token_date[MAXTOK]; -+ char token_time[MAXTOK]; -+ -+ int is_starts = strcmp(token, "starts") == 0; -+ -+ // Throw away the weekday and parse the date. -+ if (next_token(token, MAXTOK, fp) && next_token(token_date, MAXTOK, fp) && next_token(token_time, MAXTOK, fp)) { -+ time_t time = parse_lease_time(token_date, token_time); -+ -+ if (is_starts) -+ time_starts = time; -+ else -+ time_ends = time; -+ } -+ } -+ } -+ -+ if (!*hostname) -+ continue; -+ -+ if ((time_starts == -1) || (time_ends == -1)) -+ continue; -+ -+ if (difftime(now, time_ends) > 0) -+ continue; -+ -+ char* dot = strchr(hostname, '.'); -+ if (dot) { -+ if (!daemon->domain_suffix || hostname_isequal(dot + 1, daemon->domain_suffix)) { -+ my_syslog(LOG_WARNING, -+ _("Ignoring DHCP lease for %s because it has an illegal domain part"), -+ hostname); -+ continue; -+ } -+ *dot = 0; -+ } -+ -+ // Search for an existing lease in the list -+ // with the given host name and update the data -+ // if needed. -+ struct isc_dhcp_lease* lease = find_lease(hostname, leases); -+ -+ // If no lease already exists, we create a new one -+ // and append it to the list. -+ if (!lease) { -+ lease = dhcp_lease_new(hostname); -+ -+ lease->next = leases; -+ leases = lease; -+ } -+ -+ // Only update more recent leases. -+ if (lease->expires > time_ends) -+ continue; -+ -+ lease->addr = host_address; -+ lease->expires = time_ends; -+ } -+ } -+ } -+ } -+ -+ fclose(fp); -+ -+ // Drop all entries. -+ cache_unhash_dhcp(); -+ -+ while (leases) { -+ struct isc_dhcp_lease *lease = leases; -+ leases = lease->next; -+ -+ if (lease->fqdn) { -+ cache_add_dhcp_entry(lease->fqdn, AF_INET, (struct all_addr*)&lease->addr.s_addr, lease->expires); -+ } -+ -+ if (lease->name) { -+ cache_add_dhcp_entry(lease->name, AF_INET, (struct all_addr*)&lease->addr.s_addr, lease->expires); -+ } -+ -+ // Cleanup -+ dhcp_lease_free(lease); -+ } -+} -+ -+#endif -diff --git a/src/option.c b/src/option.c -index 45d8875..29c9ee5 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 - ret_err(_("bad MX target")); - break; - --#ifdef HAVE_DHCP -+#if (defined HAVE_DHCP) || (defined HAVE_ISC_READER) - case 'l': /* --dhcp-leasefile */ - daemon->lease_file = opt_string_alloc(arg); - break; diff --git a/src/patches/dnsmasq-Add-support-to-read-ISC-DHCP-lease-file.patch b/src/patches/dnsmasq-Add-support-to-read-ISC-DHCP-lease-file.patch new file mode 100644 index 0000000..1a89b36 --- /dev/null +++ b/src/patches/dnsmasq-Add-support-to-read-ISC-DHCP-lease-file.patch @@ -0,0 +1,365 @@ +diff --git a/Makefile b/Makefile +index 2910320b6452..0a76ce3c5154 100644 +--- a/Makefile ++++ b/Makefile +@@ -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 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 117ae279fd4e..6ee7ee362e6c 100644 +--- a/src/cache.c ++++ b/src/cache.c +@@ -17,7 +17,7 @@ + #include "dnsmasq.h" + + static struct crec *cache_head = NULL, *cache_tail = NULL, **hash_table = NULL; +-#ifdef HAVE_DHCP ++#if (defined HAVE_DHCP) || (defined HAVE_ISC_READER) + static struct crec *dhcp_spare = NULL; + #endif + static struct crec *new_chain = NULL; +@@ -222,6 +222,9 @@ static void cache_free(struct crec *crecp) + crecp->flags &= ~F_BIGNAME; + } + ++ if (crecp->flags & F_DHCP) ++ free(crecp->name.namep); ++ + #ifdef HAVE_DNSSEC + cache_blockdata_free(crecp); + #endif +@@ -1151,7 +1154,7 @@ void cache_reload(void) + + } + +-#ifdef HAVE_DHCP ++#if (defined HAVE_DHCP) || (defined HAVE_ISC_READER) + struct in_addr a_record_from_hosts(char *name, time_t now) + { + struct crec *crecp = NULL; +@@ -1229,7 +1232,7 @@ void cache_add_dhcp_entry(char *host_name, int prot, + addrlen = sizeof(struct in6_addr); + } + #endif +- ++ + inet_ntop(prot, host_address, daemon->addrbuff, ADDRSTRLEN); + + while ((crec = cache_find_by_name(crec, host_name, 0, flags | F_CNAME))) +@@ -1294,7 +1297,11 @@ void cache_add_dhcp_entry(char *host_name, int prot, + else + crec->ttd = ttd; + crec->addr.addr = *host_address; ++#ifdef HAVE_ISC_READER ++ crec->name.namep = strdup(host_name); ++#else + crec->name.namep = host_name; ++#endif + crec->uid = next_uid(); + cache_hash(crec); + +diff --git a/src/dnsmasq.c b/src/dnsmasq.c +index e903a24c8105..eefc7f939933 100644 +--- a/src/dnsmasq.c ++++ b/src/dnsmasq.c +@@ -970,6 +970,11 @@ int main (int argc, char **argv) + + poll_resolv(0, daemon->last_resolv != 0, now); + daemon->last_resolv = now; ++ ++#ifdef HAVE_ISC_READER ++ if (daemon->lease_file && !daemon->dhcp) ++ load_dhcp(now); ++#endif + } + #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 +diff --git a/src/isc.c b/src/isc.c +new file mode 100644 +index 000000000000..51064426f17f +--- /dev/null ++++ b/src/isc.c +@@ -0,0 +1,251 @@ ++/* dnsmasq is Copyright (c) 2014 John Volpe, Simon Kelley and ++ Michael Tremer ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; version 2 dated June, 1991, or ++ (at your option) version 3 dated 29 June, 2007. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program. If not, see http://www.gnu.org/licenses/. ++ ++ Code in this file is based on contributions by John Volpe and ++ Simon Kelley. Updated for recent versions of dnsmasq by ++ Michael Tremer. ++*/ ++ ++#include "dnsmasq.h" ++ ++#ifdef HAVE_ISC_READER ++#define MAXTOK 50 ++ ++struct isc_dhcp_lease { ++ char* name; ++ char* fqdn; ++ time_t expires; ++ struct in_addr addr; ++ struct isc_dhcp_lease* next; ++}; ++ ++static struct isc_dhcp_lease* dhcp_lease_new(const char* hostname) { ++ struct isc_dhcp_lease* lease = whine_malloc(sizeof(*lease)); ++ ++ lease->name = strdup(hostname); ++ if (daemon->domain_suffix) { ++ asprintf(&lease->fqdn, "%s.%s", hostname, daemon->domain_suffix); ++ } ++ lease->expires = 0; ++ lease->next = NULL; ++ ++ return lease; ++} ++ ++static void dhcp_lease_free(struct isc_dhcp_lease* lease) { ++ if (!lease) ++ return; ++ ++ if (lease->name) ++ free(lease->name); ++ if (lease->fqdn) ++ free(lease->fqdn); ++ free(lease); ++} ++ ++static int next_token(char* token, int buffsize, FILE* fp) { ++ int c, count = 0; ++ char* cp = token; ++ ++ while ((c = getc(fp)) != EOF) { ++ if (c == '#') { ++ do { ++ c = getc(fp); ++ } while (c != '\n' && c != EOF); ++ } ++ ++ if (c == ' ' || c == '\t' || c == '\n' || c == ';') { ++ if (count) ++ break; ++ } else if ((c != '"') && (count < buffsize - 1)) { ++ *cp++ = c; ++ count++; ++ } ++ } ++ ++ *cp = 0; ++ return count ? 1 : 0; ++} ++ ++static long get_utc_offset() { ++ time_t t = time(NULL); ++ struct tm* time_struct = localtime(&t); ++ ++ return time_struct->tm_gmtoff; ++} ++ ++static time_t parse_lease_time(const char* token_date, const char* token_time) { ++ time_t time = (time_t)(-1); ++ struct tm lease_time; ++ ++ if (sscanf(token_date, "%d/%d/%d", &lease_time.tm_year, &lease_time.tm_mon, &lease_time.tm_mday) == 3) { ++ lease_time.tm_year -= 1900; ++ lease_time.tm_mon -= 1; ++ ++ if (sscanf(token_time, "%d:%d:%d", &lease_time.tm_hour, &lease_time.tm_min, &lease_time.tm_sec) == 3) { ++ time = mktime(&lease_time) + get_utc_offset(); ++ } ++ } ++ ++ return time; ++} ++ ++static struct isc_dhcp_lease* find_lease(const char* hostname, struct isc_dhcp_lease* leases) { ++ struct isc_dhcp_lease* lease = leases; ++ ++ while (lease) { ++ if (strcmp(hostname, lease->name) == 0) { ++ return lease; ++ } ++ lease = lease->next; ++ } ++ ++ return NULL; ++} ++ ++static off_t lease_file_size = (off_t)0; ++static ino_t lease_file_inode = (ino_t)0; ++ ++void load_dhcp(time_t now) { ++ struct isc_dhcp_lease* leases = NULL; ++ ++ struct stat statbuf; ++ if (stat(daemon->lease_file, &statbuf) == -1) { ++ return; ++ } ++ ++ /* Do nothing if the lease file has not changed. */ ++ if ((statbuf.st_size <= lease_file_size) && (statbuf.st_ino == lease_file_inode)) ++ return; ++ ++ lease_file_size = statbuf.st_size; ++ lease_file_inode = statbuf.st_ino; ++ ++ FILE* fp = fopen(daemon->lease_file, "r"); ++ if (!fp) { ++ my_syslog(LOG_ERR, _("failed to load %s:%s"), daemon->lease_file, strerror(errno)); ++ return; ++ } ++ ++ my_syslog(LOG_INFO, _("reading %s"), daemon->lease_file); ++ ++ char* hostname = daemon->namebuff; ++ struct in_addr host_address; ++ time_t time_starts = -1; ++ time_t time_ends = -1; ++ int nomem; ++ ++ char token[MAXTOK]; ++ while ((next_token(token, MAXTOK, fp))) { ++ if (strcmp(token, "lease") == 0) { ++ hostname[0] = '\0'; ++ ++ if (next_token(token, MAXTOK, fp) && ((host_address.s_addr = inet_addr(token)) != (in_addr_t)-1)) { ++ if (next_token(token, MAXTOK, fp) && *token == '{') { ++ while (next_token(token, MAXTOK, fp) && *token != '}') { ++ if ((strcmp(token, "client-hostname") == 0) || (strcmp(token, "hostname") == 0)) { ++ if (next_token(hostname, MAXDNAME, fp)) { ++ if (!canonicalise(hostname, &nomem)) { ++ *hostname = 0; ++ my_syslog(LOG_ERR, _("bad name in %s"), daemon->lease_file); ++ } ++ } ++ } else if ((strcmp(token, "starts") == 0) || (strcmp(token, "ends") == 0)) { ++ char token_date[MAXTOK]; ++ char token_time[MAXTOK]; ++ ++ int is_starts = strcmp(token, "starts") == 0; ++ ++ // Throw away the weekday and parse the date. ++ if (next_token(token, MAXTOK, fp) && next_token(token_date, MAXTOK, fp) && next_token(token_time, MAXTOK, fp)) { ++ time_t time = parse_lease_time(token_date, token_time); ++ ++ if (is_starts) ++ time_starts = time; ++ else ++ time_ends = time; ++ } ++ } ++ } ++ ++ if (!*hostname) ++ continue; ++ ++ if ((time_starts == -1) || (time_ends == -1)) ++ continue; ++ ++ if (difftime(now, time_ends) > 0) ++ continue; ++ ++ char* dot = strchr(hostname, '.'); ++ if (dot) { ++ if (!daemon->domain_suffix || hostname_isequal(dot + 1, daemon->domain_suffix)) { ++ my_syslog(LOG_WARNING, ++ _("Ignoring DHCP lease for %s because it has an illegal domain part"), ++ hostname); ++ continue; ++ } ++ *dot = 0; ++ } ++ ++ // Search for an existing lease in the list ++ // with the given host name and update the data ++ // if needed. ++ struct isc_dhcp_lease* lease = find_lease(hostname, leases); ++ ++ // If no lease already exists, we create a new one ++ // and append it to the list. ++ if (!lease) { ++ lease = dhcp_lease_new(hostname); ++ ++ lease->next = leases; ++ leases = lease; ++ } ++ ++ // Only update more recent leases. ++ if (lease->expires > time_ends) ++ continue; ++ ++ lease->addr = host_address; ++ lease->expires = time_ends; ++ } ++ } ++ } ++ } ++ ++ fclose(fp); ++ ++ // Drop all entries. ++ cache_unhash_dhcp(); ++ ++ while (leases) { ++ struct isc_dhcp_lease *lease = leases; ++ leases = lease->next; ++ ++ if (lease->fqdn) { ++ cache_add_dhcp_entry(lease->fqdn, AF_INET, (struct all_addr*)&lease->addr.s_addr, lease->expires); ++ } ++ ++ if (lease->name) { ++ cache_add_dhcp_entry(lease->name, AF_INET, (struct all_addr*)&lease->addr.s_addr, lease->expires); ++ } ++ ++ // Cleanup ++ dhcp_lease_free(lease); ++ } ++} ++ ++#endif +diff --git a/src/option.c b/src/option.c +index cb4e76ba0aa2..f6420fcbb7ab 100644 +--- a/src/option.c ++++ b/src/option.c +@@ -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; + +-#ifdef HAVE_DHCP ++#if (defined HAVE_DHCP) || (defined HAVE_ISC_READER) + case 'l': /* --dhcp-leasefile */ + daemon->lease_file = opt_string_alloc(arg); + break; diff --git a/src/patches/dnsmasq/dnsmasq-2.73-bad-packet-protection.patch b/src/patches/dnsmasq/dnsmasq-2.73-bad-packet-protection.patch deleted file mode 100644 index bdbe168..0000000 --- a/src/patches/dnsmasq/dnsmasq-2.73-bad-packet-protection.patch +++ /dev/null @@ -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 - diff --git a/src/patches/dnsmasq/dnsmasq-2.73-fix-crash-in-DNSSEC-code-when-attempting-to-verify-large-RRs.patch b/src/patches/dnsmasq/dnsmasq-2.73-fix-crash-in-DNSSEC-code-when-attempting-to-verify-large-RRs.patch deleted file mode 100644 index 82c68ed..0000000 --- a/src/patches/dnsmasq/dnsmasq-2.73-fix-crash-in-DNSSEC-code-when-attempting-to-verify-large-RRs.patch +++ /dev/null @@ -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 - diff --git a/src/patches/dnsmasq/dnsmasq-2.73-fix-problems-validating-NSEC3-and-wildcards.patch b/src/patches/dnsmasq/dnsmasq-2.73-fix-problems-validating-NSEC3-and-wildcards.patch deleted file mode 100644 index 25bbbb7..0000000 --- a/src/patches/dnsmasq/dnsmasq-2.73-fix-problems-validating-NSEC3-and-wildcards.patch +++ /dev/null @@ -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 */