users:x:100:
snort:x:101:
logwatch:x:102:
-dnsmasq:x:103:
cron:x:104:
syslogd:x:105:
klogd:x:106:
postfix:x:100:100::/var/spool/postfix:/bin/false
snort:x:101:101:ftp:/var/log/snort:/bin/false
logwatch:x:102:102::/var/log/logwatch:/bin/false
-dnsmasq:x:103:103::/:/bin/false
cron:x:104:104::/:/bin/false
syslogd:x:105:105:/var/empty:/bin/false
klogd:x:106:106:/var/empty:/bin/false
etc/rc.d/init.d/dhcp
etc/rc.d/init.d/dhcrelay
#etc/rc.d/init.d/dnsdist
-etc/rc.d/init.d/dnsmasq
etc/rc.d/init.d/fcron
#etc/rc.d/init.d/fetchmail
etc/rc.d/init.d/fireinfo
etc/rc.d/init.d/networking/orange
etc/rc.d/init.d/networking/red
#etc/rc.d/init.d/networking/red.down
-etc/rc.d/init.d/networking/red.down/05-RS-dnsmasq
etc/rc.d/init.d/networking/red.down/10-ipsec
etc/rc.d/init.d/networking/red.down/10-miniupnpd
etc/rc.d/init.d/networking/red.down/10-ovpn
etc/rc.d/init.d/networking/red.down/20-firewall
#etc/rc.d/init.d/networking/red.up
etc/rc.d/init.d/networking/red.up/01-conntrack-cleanup
-etc/rc.d/init.d/networking/red.up/05-RS-dnsmasq
etc/rc.d/init.d/networking/red.up/10-miniupnpd
etc/rc.d/init.d/networking/red.up/10-multicast
etc/rc.d/init.d/networking/red.up/10-static-routes
+++ /dev/null
-usr/sbin/dnsmasq
-#usr/share/man/man8/dnsmasq.8
etc/rc.d/init.d/dhcp
etc/rc.d/init.d/dhcrelay
#etc/rc.d/init.d/dnsdist
-etc/rc.d/init.d/dnsmasq
etc/rc.d/init.d/fcron
#etc/rc.d/init.d/fetchmail
etc/rc.d/init.d/fireinfo
etc/rc.d/init.d/networking/orange
etc/rc.d/init.d/networking/red
#etc/rc.d/init.d/networking/red.down
-etc/rc.d/init.d/networking/red.down/05-RS-dnsmasq
etc/rc.d/init.d/networking/red.down/10-ipsec
etc/rc.d/init.d/networking/red.down/10-miniupnpd
etc/rc.d/init.d/networking/red.down/10-ovpn
etc/rc.d/init.d/networking/red.down/20-firewall
#etc/rc.d/init.d/networking/red.up
etc/rc.d/init.d/networking/red.up/01-conntrack-cleanup
-etc/rc.d/init.d/networking/red.up/05-RS-dnsmasq
etc/rc.d/init.d/networking/red.up/10-miniupnpd
etc/rc.d/init.d/networking/red.up/10-multicast
etc/rc.d/init.d/networking/red.up/10-static-routes
usr/local/bin/collectdctrl
usr/local/bin/ddnsctrl
usr/local/bin/dhcpctrl
-usr/local/bin/dnsmasqctrl
usr/local/bin/extrahdctrl
usr/local/bin/fireinfoctrl
usr/local/bin/getconntracktable
etc/rc.d/init.d/dhcp
etc/rc.d/init.d/dhcrelay
#etc/rc.d/init.d/dnsdist
-etc/rc.d/init.d/dnsmasq
etc/rc.d/init.d/fcron
#etc/rc.d/init.d/fetchmail
etc/rc.d/init.d/fireinfo
etc/rc.d/init.d/networking/orange
etc/rc.d/init.d/networking/red
#etc/rc.d/init.d/networking/red.down
-etc/rc.d/init.d/networking/red.down/05-RS-dnsmasq
etc/rc.d/init.d/networking/red.down/10-ipsec
etc/rc.d/init.d/networking/red.down/10-miniupnpd
etc/rc.d/init.d/networking/red.down/10-ovpn
etc/rc.d/init.d/networking/red.down/20-firewall
#etc/rc.d/init.d/networking/red.up
etc/rc.d/init.d/networking/red.up/01-conntrack-cleanup
-etc/rc.d/init.d/networking/red.up/05-RS-dnsmasq
etc/rc.d/init.d/networking/red.up/10-miniupnpd
etc/rc.d/init.d/networking/red.up/10-multicast
etc/rc.d/init.d/networking/red.up/10-static-routes
+++ /dev/null
-###############################################################################
-# #
-# IPFire.org - A linux based firewall #
-# Copyright (C) 2016 Michael Tremer & Christian Schmidt #
-# #
-# 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, either version 3 of the License, or #
-# (at your option) any later version. #
-# #
-# 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/>. #
-# #
-###############################################################################
-
-###############################################################################
-# Definitions
-###############################################################################
-
-include Config
-
-VER = 2.76
-
-THISAPP = dnsmasq-$(VER)
-DL_FILE = $(THISAPP).tar.xz
-DL_FROM = $(URL_IPFIRE)
-DIR_APP = $(DIR_SRC)/$(THISAPP)
-TARGET = $(DIR_INFO)/$(THISAPP)
-
-# We cannot use INOTIFY because our ISC reader code does not support that
-COPTS = -DHAVE_ISC_READER -DNO_INOTIFY
-
-###############################################################################
-# Top-level Rules
-###############################################################################
-
-objects = $(DL_FILE)
-
-$(DL_FILE) = $(DL_FROM)/$(DL_FILE)
-
-$(DL_FILE)_MD5 = 00f5ee66b4e4b7f14538bf62ae3c9461
-
-install : $(TARGET)
-
-check : $(patsubst %,$(DIR_CHK)/%,$(objects))
-
-download :$(patsubst %,$(DIR_DL)/%,$(objects))
-
-md5 : $(subst %,%_MD5,$(objects))
-
-###############################################################################
-# Downloading, checking, md5sum
-###############################################################################
-
-$(patsubst %,$(DIR_CHK)/%,$(objects)) :
- @$(CHECK)
-
-$(patsubst %,$(DIR_DL)/%,$(objects)) :
- @$(LOAD)
-
-$(subst %,%_MD5,$(objects)) :
- @$(MD5)
-
-###############################################################################
-# Installation Details
-###############################################################################
-
-$(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/001-Calculate_length_of_TFTP_error_reply_correctly.patch
- cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/dnsmasq/002-Zero_newly_malloc_ed_memory.patch
- cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/dnsmasq/003-Check_return_of_expand_always.patch
- cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/dnsmasq/004-Fix_editing_error_on_man_page.patch
- cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/dnsmasq/005-Manpage_typo.patch
- cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/dnsmasq/006-Fix_bad_behaviour_with_some_DHCP_option_arrangements.patch
- cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/dnsmasq/007-Fix_logic_error_in_Linux_netlink_code.patch
- cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/dnsmasq/008-Fix_problem_with_--dnssec-timestamp.patch
- cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/dnsmasq/009-malloc_memset_calloc_for_efficiency.patch
- cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/dnsmasq/010-Zero_packet_buffers_before_building_output_to_reduce_risk_of_information_leakage.patch
- cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/dnsmasq/011-Dont_reset_packet_length_on_transmission_in_case_of_retransmission.patch
- cd $(DIR_APP) && patch -Np1 -i $(DIR_SRC)/src/patches/dnsmasq/012-Compile-time_check_on_buffer_sizes_for_leasefile_parsing_code.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' \
- -e 's|#define HAVE_DHCP|//#define HAVE_DHCP|g' \
- -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)" \
- PREFIX=/usr all install
- @rm -rf $(DIR_APP)
- @$(POSTBUILD)
ln -sf ../init.d/wlanclient /etc/rc.d/rc3.d/S19wlanclient
ln -sf ../init.d/wlanclient /etc/rc.d/rc6.d/K82wlanclient
- ln -sf ../../dnsmasq /etc/rc.d/init.d/networking/red.up/05-RS-dnsmasq
ln -sf ../../../../../usr/local/bin/snortctrl \
/etc/rc.d/init.d/networking/red.up/23-RS-snort
ln -sf ../../../../../usr/local/bin/qosctrl \
/etc/rc.d/init.d/networking/red.up/24-RS-qos
ln -sf ../../squid /etc/rc.d/init.d/networking/red.up/27-RS-squid
- ln -sf ../../dnsmasq /etc/rc.d/init.d/networking/red.down/05-RS-dnsmasq
for i in green blue orange; do \
ln -sf any /etc/rc.d/init.d/networking/$$i; \
ipfiremake beep
ipfiremake dvdrtools
ipfiremake nettle
- ipfiremake dnsmasq
ipfiremake unbound
ipfiremake dosfstools
ipfiremake reiserfsprogs
+++ /dev/null
-#!/bin/sh
-########################################################################
-# Begin $rc_base/init.d/dnsmasq
-#
-# Description : dnsmasq init script
-#
-# Authors : Michael Tremer - mitch@ipfire.org
-#
-# Version : 01.00
-#
-# Notes :
-#
-########################################################################
-
-. /etc/sysconfig/rc
-. ${rc_functions}
-
-CACHE_SIZE=2500
-ENABLE_DNSSEC=1
-SHOW_SRV=1
-TRUST_ANCHOR=".,19036,8,2,49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE32F24E8FB5"
-TIMESTAMP_FILE="/var/ipfire/dns/dnssec-timestamp"
-
-# Pull custom configuration file
-if [ -e "/etc/sysconfig/dnsmasq" ]; then
- . /etc/sysconfig/dnsmasq
-fi
-
-function dnssec_args() {
- local cmdline="--dnssec --dnssec-timestamp ${TIMESTAMP_FILE}"
-
- if [ -n "${TRUST_ANCHOR}" ]; then
- cmdline="${cmdline} --trust-anchor=${TRUST_ANCHOR}"
- fi
-
- echo "${cmdline}"
-}
-
-function dns_forward_args() {
- local file="${1}"
-
- # Do nothing if file is empty.
- [ -s "${file}" ] || return
-
- local cmdline
-
- local enabled zone server remark
- while IFS="," read -r enabled zone server remark; do
- # Line must be enabled.
- [ "${enabled}" = "on" ] || continue
-
- cmdline="${cmdline} --server=/${zone}/${server}"
- done < ${file}
-
- echo "${cmdline}"
-}
-
-function dns_leases_args() {
- eval $(/usr/local/bin/readhash /var/ipfire/dhcp/settings)
-
- # If the DHCP server is enabled and DNS Update (RFC2136) is
- # enabled, too, we won't overlay the internal domain with
- # the dynamic/static leases.
-
- if ([ "${ENABLE_GREEN}" = "on" ] || [ "${ENABLE_BLUE}" = "on" ]) \
- && [ "${DNS_UPDATE_ENABLED}" = "on" ]; then
- return
- fi
-
- echo "-l /var/state/dhcp/dhcpd.leases"
-}
-
-case "${1}" in
- start)
- # kill already running copy of dnsmasq...
- killproc /usr/sbin/dnsmasq 2>&1 > /dev/null
-
- boot_mesg "Starting Domain Name Service Proxy..."
-
- eval $(/usr/local/bin/readhash /var/ipfire/ethernet/settings)
- ARGS="$CUSTOM_ARGS"
- [ "$DOMAIN_NAME_GREEN" != "" ] && ARGS="$ARGS -s $DOMAIN_NAME_GREEN"
-
- # DHCP configuration
- ARGS="${ARGS} $(dns_leases_args)"
-
- echo > /var/ipfire/red/resolv.conf # Clear it
- if [ -e "/var/ipfire/red/dns1" ]; then
- DNS1=$(cat /var/ipfire/red/dns1 2>/dev/null)
- if [ ! -z ${DNS1} ]; then
- echo "nameserver ${DNS1}" >> /var/ipfire/red/resolv.conf
- fi
- fi
- if [ -e "/var/ipfire/red/dns2" ]; then
- DNS2=$(cat /var/ipfire/red/dns2 2>/dev/null)
- if [ ! -z ${DNS2} ]; then
- echo "nameserver ${DNS2}" >> /var/ipfire/red/resolv.conf
- fi
- fi
- [ -e "/var/ipfire/red/active" ] && ARGS="$ARGS -r /var/ipfire/red/resolv.conf"
-
- ARGS="$ARGS --domain=`cat /var/ipfire/main/settings |grep DOMAIN |cut -d = -f 2`"
-
- # Add custom forward dns zones.
- ARGS="${ARGS} $(dns_forward_args /var/ipfire/dnsforward/config)"
-
- # Enabled DNSSEC validation
- if [ "${ENABLE_DNSSEC}" -eq 1 ]; then
- ARGS="${ARGS} $(dnssec_args)"
- fi
-
- if [ -n "${CACHE_SIZE}" ]; then
- ARGS="${ARGS} --cache-size=${CACHE_SIZE}"
- fi
-
- loadproc /usr/sbin/dnsmasq ${ARGS}
-
- if [ "${SHOW_SRV}" -eq 1 ] && [ "${DNS1}" != "" -o "${DNS2}" != "" ]; then
- boot_mesg "Using DNS server(s): ${DNS1} ${DNS2}"
- boot_mesg_flush
- fi
- ;;
-
- stop)
- boot_mesg "Stopping Domain Name Service Proxy..."
- killproc /usr/sbin/dnsmasq
- ;;
-
- restart)
- ${0} stop
- sleep 1
- ${0} start
- ;;
-
- status)
- statusproc /usr/sbin/dnsmasq
- ;;
-
- *)
- echo "Usage: ${0} {start|stop|restart|status}"
- exit 1
- ;;
-esac
-
-# End $rc_base/init.d/dnsmasq
. ${rc_functions}
eval $(/usr/local/bin/readhash /var/ipfire/ethernet/settings)
-init_networking() {
- /etc/rc.d/init.d/dnsmasq start
-}
-
DO="${1}"
shift
case "${DO}" in
start)
- [ "${ALL}" == "1" ] && init_networking
-
# Starting interfaces...
# GREEN
[ "$green" == "1" ] && /etc/rc.d/init.d/networking/green start
fi
fi
- # Stopping dnsmasq if network all networks shutdown
- [ "${ALL}" == "1" ] && /etc/rc.d/init.d/dnsmasq stop
-
exit 0
;;
redctrl syslogdctrl extrahdctrl sambactrl upnpctrl \
smartctrl clamavctrl addonctrl pakfire mpfirectrl wlanapctrl \
setaliases urlfilterctrl updxlratorctrl fireinfoctrl rebuildroutes \
- getconntracktable wirelessclient dnsmasqctrl torctrl ddnsctrl
+ getconntracktable wirelessclient torctrl ddnsctrl
SUID_UPDX = updxsetperms
OBJS = $(patsubst %,%.o,$(PROGS) $(SUID_PROGS))
+++ /dev/null
-/* This file is part of the IPFire Firewall.
- *
- * This program is distributed under the terms of the GNU General Public
- * Licence. See the file COPYING for details.
- *
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <fcntl.h>
-#include "setuid.h"
-
-int main(int argc, char *argv[]) {
-
- if (!(initsetuid()))
- exit(1);
-
- if (argc < 2) {
- fprintf(stderr, "\nNo argument given.\n\ndnsmasqctrl (restart)\n\n");
- exit(1);
- }
-
- if (strcmp(argv[1], "restart") == 0) {
- safe_system("/etc/rc.d/init.d/dnsmasq restart");
- } else {
- fprintf(stderr, "\nBad argument given.\n\ndnsmasqctrl (restart)\n\n");
- exit(1);
- }
-
- return 0;
-}
+++ /dev/null
---- a/src/cache.c Wed Dec 16 19:24:12 2015
-+++ b/src/cache.c Wed Dec 16 19:37:37 2015
-@@ -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;
-@@ -217,6 +217,9 @@
- crecp->flags &= ~F_BIGNAME;
- }
-
-+ if (crecp->flags & F_DHCP)
-+ free(crecp->name.namep);
-+
- #ifdef HAVE_DNSSEC
- cache_blockdata_free(crecp);
- #endif
-@@ -1138,7 +1141,7 @@
-
- }
-
--#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;
-@@ -1281,7 +1284,11 @@
- 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);
-
---- a/src/dnsmasq.c Thu Jul 30 20:59:06 2015
-+++ b/src/dnsmasq.c Wed Dec 16 19:38:32 2015
-@@ -1017,6 +1017,11 @@
-
- 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
-
---- a/src/dnsmasq.h Wed Dec 16 19:24:12 2015
-+++ b/src/dnsmasq.h Wed Dec 16 19:40:11 2015
-@@ -1516,6 +1516,11 @@
- void poll_listen(int fd, short event);
- int do_poll(int timeout);
-
-+/* isc.c */
-+#ifdef HAVE_ISC_READER
-+void load_dhcp(time_t now);
-+#endif
-+
- /* rrfilter.c */
- size_t rrfilter(struct dns_header *header, size_t plen, int mode);
- u16 *rrfilter_desc(int type);
- int expand_workspace(unsigned char ***wkspc, int *szp, int new);
--
---- /dev/null Wed Dec 16 19:48:08 2015
-+++ b/src/isc.c Wed Dec 16 19:41:35 2015
-@@ -0,0 +1,266 @@
-+/* 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.
-+*/
-+
-+
-+#define _GNU_SOURCE
-+
-+#include <assert.h>
-+#include <stdio.h>
-+
-+#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));
-+ if (!lease)
-+ return NULL;
-+
-+ lease->name = strdup(hostname);
-+ if (daemon->domain_suffix) {
-+ int r = asprintf(&lease->fqdn, "%s.%s", hostname, daemon->domain_suffix);
-+
-+ // Handle OOM
-+ if (r < 0) {
-+ free(lease);
-+ return NULL;
-+ }
-+ }
-+ 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);
-+ assert(lease);
-+
-+ 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
---- a/src/option.c Wed Dec 16 19:24:12 2015
-+++ b/src/option.c Wed Dec 16 19:42:48 2015
-@@ -1771,7 +1771,7 @@
- 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;
---- a/Makefile Wed Dec 16 19:24:12 2015
-+++ b/Makefile Wed Dec 16 19:28:45 2015
-@@ -74,7 +74,7 @@
- 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 \
-- poll.o rrfilter.o edns0.o arp.o
-+ poll.o rrfilter.o edns0.o arp.o isc.o
-
- hdrs = dnsmasq.h config.h dhcp-protocol.h dhcp6-protocol.h \
- dns-protocol.h radv-protocol.h ip6addr.h
+++ /dev/null
-From 294d36df4749e01199ab220d44c170e7db2b0c05 Mon Sep 17 00:00:00 2001
-From: Simon Kelley <simon@thekelleys.org.uk>
-Date: Wed, 6 Jul 2016 21:30:25 +0100
-Subject: [PATCH] Calculate length of TFTP error reply correctly.
-
----
- CHANGELOG | 14 ++++++++++++++
- src/tftp.c | 7 +++++--
- 2 files changed, 19 insertions(+), 2 deletions(-)
-
-diff --git a/CHANGELOG b/CHANGELOG
-index 04ff3f0..0559a6f 100644
---- a/CHANGELOG
-+++ b/CHANGELOG
-@@ -1,3 +1,17 @@
-+version 2.77
-+ Calculate the length of TFTP error reply packet
-+ correctly. This fixes a problem when the error
-+ message in a TFTP packet exceeds the arbitrary
-+ limit of 500 characters. The message was correctly
-+ truncated, but not the packet length, so
-+ extra data was appended. This is a possible
-+ security risk, since the extra data comes from
-+ a buffer which is also used for DNS, so that
-+ previous DNS queries or replies may be leaked.
-+ Thanks to Mozilla for funding the security audit
-+ which spotted this bug.
-+
-+
- version 2.76
- Include 0.0.0.0/8 in DNS rebind checks. This range
- translates to hosts on the local network, or, at
-diff --git a/src/tftp.c b/src/tftp.c
-index 5e4a32a..3e1b5c5 100644
---- a/src/tftp.c
-+++ b/src/tftp.c
-@@ -652,20 +652,23 @@ static void sanitise(char *buf)
-
- }
-
-+#define MAXMESSAGE 500 /* limit to make packet < 512 bytes and definitely smaller than buffer */
- static ssize_t tftp_err(int err, char *packet, char *message, char *file)
- {
- struct errmess {
- unsigned short op, err;
- char message[];
- } *mess = (struct errmess *)packet;
-- ssize_t ret = 4;
-+ ssize_t len, ret = 4;
- char *errstr = strerror(errno);
-
- sanitise(file);
-
- mess->op = htons(OP_ERR);
- mess->err = htons(err);
-- ret += (snprintf(mess->message, 500, message, file, errstr) + 1);
-+ len = snprintf(mess->message, MAXMESSAGE, message, file, errstr);
-+ ret += (len < MAXMESSAGE) ? len + 1 : MAXMESSAGE; /* include terminating zero */
-+
- my_syslog(MS_TFTP | LOG_ERR, "%s", mess->message);
-
- return ret;
---
-1.7.10.4
-
+++ /dev/null
-From d55f81f5fd53b1dfc2c4b3249b542f2d9679e236 Mon Sep 17 00:00:00 2001
-From: Simon Kelley <simon@thekelleys.org.uk>
-Date: Wed, 6 Jul 2016 21:33:56 +0100
-Subject: [PATCH] Zero newly malloc'ed memory.
-
----
- src/util.c | 6 +++++-
- 1 file changed, 5 insertions(+), 1 deletion(-)
-
-diff --git a/src/util.c b/src/util.c
-index 93b24f5..82443c9 100644
---- a/src/util.c
-+++ b/src/util.c
-@@ -248,6 +248,8 @@ void *safe_malloc(size_t size)
-
- if (!ret)
- die(_("could not get memory"), NULL, EC_NOMEM);
-+ else
-+ memset(ret, 0, size);
-
- return ret;
- }
-@@ -266,7 +268,9 @@ void *whine_malloc(size_t size)
-
- if (!ret)
- my_syslog(LOG_ERR, _("failed to allocate %d bytes"), (int) size);
--
-+ else
-+ memset(ret, 0, size);
-+
- return ret;
- }
-
---
-1.7.10.4
-
+++ /dev/null
-From ce7845bf5429bd2962c9b2e7d75e2659f3b5c1a8 Mon Sep 17 00:00:00 2001
-From: Simon Kelley <simon@thekelleys.org.uk>
-Date: Wed, 6 Jul 2016 21:42:27 +0100
-Subject: [PATCH] Check return of expand() always.
-
----
- src/radv.c | 4 +++-
- src/slaac.c | 5 ++++-
- 2 files changed, 7 insertions(+), 2 deletions(-)
-
-diff --git a/src/radv.c b/src/radv.c
-index 749b666..faa0f6d 100644
---- a/src/radv.c
-+++ b/src/radv.c
-@@ -262,7 +262,9 @@ static void send_ra_alias(time_t now, int iface, char *iface_name, struct in6_ad
- parm.prio = calc_prio(ra_param);
-
- save_counter(0);
-- ra = expand(sizeof(struct ra_packet));
-+
-+ if (!(ra = expand(sizeof(struct ra_packet))))
-+ return;
-
- ra->type = ND_ROUTER_ADVERT;
- ra->code = 0;
-diff --git a/src/slaac.c b/src/slaac.c
-index 8034805..07b8ba4 100644
---- a/src/slaac.c
-+++ b/src/slaac.c
-@@ -147,7 +147,10 @@ time_t periodic_slaac(time_t now, struct dhcp_lease *leases)
- struct sockaddr_in6 addr;
-
- save_counter(0);
-- ping = expand(sizeof(struct ping_packet));
-+
-+ if (!(ping = expand(sizeof(struct ping_packet))))
-+ continue;
-+
- ping->type = ICMP6_ECHO_REQUEST;
- ping->code = 0;
- ping->identifier = ping_id;
---
-1.7.10.4
-
+++ /dev/null
-From 5874f3e9222397d82aabd9884d9bf5ce7e4109b0 Mon Sep 17 00:00:00 2001
-From: Simon Kelley <simon@thekelleys.org.uk>
-Date: Sun, 10 Jul 2016 22:12:08 +0100
-Subject: [PATCH] Fix editing error on man page.
-
-Thanks to Eric Westbrook for spotting this.
----
- man/dnsmasq.8 | 9 ++++-----
- 1 file changed, 4 insertions(+), 5 deletions(-)
-
-diff --git a/man/dnsmasq.8 b/man/dnsmasq.8
-index 0521534..bd8c0b3 100644
---- a/man/dnsmasq.8
-+++ b/man/dnsmasq.8
-@@ -1037,6 +1037,10 @@ is given, then read all the files contained in that directory. The advantage of
- using this option is the same as for --dhcp-hostsfile: the
- dhcp-optsfile will be re-read when dnsmasq receives SIGHUP. Note that
- it is possible to encode the information in a
-+.B --dhcp-boot
-+flag as DHCP options, using the options names bootfile-name,
-+server-ip-address and tftp-server. This allows these to be included
-+in a dhcp-optsfile.
- .TP
- .B --dhcp-hostsdir=<path>
- This is equivalent to dhcp-hostsfile, except for the following. The path MUST be a
-@@ -1048,11 +1052,6 @@ is restarted; ie host records are only added dynamically.
- .TP
- .B --dhcp-optsdir=<path>
- This is equivalent to dhcp-optsfile, with the differences noted for --dhcp-hostsdir.
--.TP
--.B --dhcp-boot
--flag as DHCP options, using the options names bootfile-name,
--server-ip-address and tftp-server. This allows these to be included
--in a dhcp-optsfile.
- .TP
- .B \-Z, --read-ethers
- Read /etc/ethers for information about hosts for the DHCP server. The
---
-1.7.10.4
-
+++ /dev/null
-From 907efeb2dc712603271093bce8a93c7c3e6fe64d Mon Sep 17 00:00:00 2001
-From: Kristjan Onu <jeixav@gmail.com>
-Date: Sun, 10 Jul 2016 22:37:57 +0100
-Subject: [PATCH] Manpage typo.
-
----
- man/dnsmasq.8 | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/man/dnsmasq.8 b/man/dnsmasq.8
-index bd8c0b3..ac8d921 100644
---- a/man/dnsmasq.8
-+++ b/man/dnsmasq.8
-@@ -242,7 +242,7 @@ addresses associated with the interface.
- .B --local-service
- Accept DNS queries only from hosts whose address is on a local subnet,
- ie a subnet for which an interface exists on the server. This option
--only has effect is there are no --interface --except-interface,
-+only has effect if there are no --interface --except-interface,
- --listen-address or --auth-server options. It is intended to be set as
- a default on installation, to allow unconfigured installations to be
- useful but also safe from being used for DNS amplification attacks.
---
-1.7.10.4
-
+++ /dev/null
-From 591ed1e90503817938ccf5f127e677a8dd48b6d8 Mon Sep 17 00:00:00 2001
-From: Simon Kelley <simon@thekelleys.org.uk>
-Date: Mon, 11 Jul 2016 18:18:42 +0100
-Subject: [PATCH] Fix bad behaviour with some DHCP option arrangements.
-
-The check that there's enough space to store the DHCP agent-id
-at the end of the packet could succeed when it should fail
-if the END option is in either of the oprion-overload areas.
-That could overwrite legit options in the request and cause
-bad behaviour. It's highly unlikely that any sane DHCP client
-would trigger this bug, and it's never been seen, but this
-fixes the problem.
-
-Also fix off-by-one in bounds checking of option processing.
-Worst case scenario on that is a read one byte beyond the
-end off a buffer with a crafted packet, and maybe therefore
-a SIGV crash if the memory after the buffer is not mapped.
-
-Thanks to Timothy Becker for spotting these.
----
- src/rfc2131.c | 5 +++--
- 1 file changed, 3 insertions(+), 2 deletions(-)
-
-diff --git a/src/rfc2131.c b/src/rfc2131.c
-index b7c167e..8b99d4b 100644
---- a/src/rfc2131.c
-+++ b/src/rfc2131.c
-@@ -186,7 +186,8 @@ size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
- be enough free space at the end of the packet to copy the option. */
- unsigned char *sopt;
- unsigned int total = option_len(opt) + 2;
-- unsigned char *last_opt = option_find(mess, sz, OPTION_END, 0);
-+ unsigned char *last_opt = option_find1(&mess->options[0] + sizeof(u32), ((unsigned char *)mess) + sz,
-+ OPTION_END, 0);
- if (last_opt && last_opt < end - total)
- {
- end -= total;
-@@ -1606,7 +1607,7 @@ static unsigned char *option_find1(unsigned char *p, unsigned char *end, int opt
- {
- while (1)
- {
-- if (p > end)
-+ if (p >= end)
- return NULL;
- else if (*p == OPTION_END)
- return opt == OPTION_END ? p : NULL;
---
-1.7.10.4
-
+++ /dev/null
-From 1d07667ac77c55b9de56b1b2c385167e0e0ec27a Mon Sep 17 00:00:00 2001
-From: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
-Date: Mon, 11 Jul 2016 18:36:05 +0100
-Subject: [PATCH] Fix logic error in Linux netlink code.
-
-This could cause dnsmasq to enter a tight loop on systems
-with a very large number of network interfaces.
----
- CHANGELOG | 6 ++++++
- src/netlink.c | 8 +++++++-
- 2 files changed, 13 insertions(+), 1 deletion(-)
-
-diff --git a/CHANGELOG b/CHANGELOG
-index 0559a6f..59c9c49 100644
---- a/CHANGELOG
-+++ b/CHANGELOG
-@@ -11,6 +11,12 @@ version 2.77
- Thanks to Mozilla for funding the security audit
- which spotted this bug.
-
-+ Fix logic error in Linux netlink code. This could
-+ cause dnsmasq to enter a tight loop on systems
-+ with a very large number of network interfaces.
-+ Thanks to Ivan Kokshaysky for the diagnosis and
-+ patch.
-+
-
- version 2.76
- Include 0.0.0.0/8 in DNS rebind checks. This range
-diff --git a/src/netlink.c b/src/netlink.c
-index 049247b..8cd51af 100644
---- a/src/netlink.c
-+++ b/src/netlink.c
-@@ -188,11 +188,17 @@ int iface_enumerate(int family, void *parm, int (*callback)())
- }
-
- for (h = (struct nlmsghdr *)iov.iov_base; NLMSG_OK(h, (size_t)len); h = NLMSG_NEXT(h, len))
-- if (h->nlmsg_seq != seq || h->nlmsg_pid != netlink_pid || h->nlmsg_type == NLMSG_ERROR)
-+ if (h->nlmsg_pid != netlink_pid || h->nlmsg_type == NLMSG_ERROR)
- {
- /* May be multicast arriving async */
- nl_async(h);
- }
-+ else if (h->nlmsg_seq != seq)
-+ {
-+ /* May be part of incomplete response to previous request after
-+ ENOBUFS. Drop it. */
-+ continue;
-+ }
- else if (h->nlmsg_type == NLMSG_DONE)
- return callback_ok;
- else if (h->nlmsg_type == RTM_NEWADDR && family != AF_UNSPEC && family != AF_LOCAL)
---
-1.7.10.4
-
+++ /dev/null
-From 06093a9a845bb597005d892d5d1bc7859933ada4 Mon Sep 17 00:00:00 2001
-From: Kevin Darbyshire-Bryant <kevin@darbyshire-bryant.me.uk>
-Date: Mon, 11 Jul 2016 21:03:27 +0100
-Subject: [PATCH] Fix problem with --dnssec-timestamp whereby receipt of
- SIGHUP would erroneously engage timestamp checking.
-
----
- CHANGELOG | 4 ++++
- src/dnsmasq.c | 7 ++++---
- src/dnsmasq.h | 1 +
- src/dnssec.c | 5 +++--
- 4 files changed, 12 insertions(+), 5 deletions(-)
-
-diff --git a/CHANGELOG b/CHANGELOG
-index 59c9c49..9f1e404 100644
---- a/CHANGELOG
-+++ b/CHANGELOG
-@@ -17,6 +17,10 @@ version 2.77
- Thanks to Ivan Kokshaysky for the diagnosis and
- patch.
-
-+ Fix problem with --dnssec-timestamp whereby receipt
-+ of SIGHUP would erroneously engage timestamp checking.
-+ Thanks to Kevin Darbyshire-Bryant for this work.
-+
-
- version 2.76
- Include 0.0.0.0/8 in DNS rebind checks. This range
-diff --git a/src/dnsmasq.c b/src/dnsmasq.c
-index 045ec53..a47273f 100644
---- a/src/dnsmasq.c
-+++ b/src/dnsmasq.c
-@@ -750,7 +750,8 @@ int main (int argc, char **argv)
-
- my_syslog(LOG_INFO, _("DNSSEC validation enabled"));
-
-- if (option_bool(OPT_DNSSEC_TIME))
-+ daemon->dnssec_no_time_check = option_bool(OPT_DNSSEC_TIME);
-+ if (option_bool(OPT_DNSSEC_TIME) && !daemon->back_to_the_future)
- my_syslog(LOG_INFO, _("DNSSEC signature timestamps not checked until first cache reload"));
-
- if (rc == 1)
-@@ -1226,10 +1227,10 @@ static void async_event(int pipe, time_t now)
- {
- case EVENT_RELOAD:
- #ifdef HAVE_DNSSEC
-- if (option_bool(OPT_DNSSEC_VALID) && option_bool(OPT_DNSSEC_TIME))
-+ if (daemon->dnssec_no_time_check && option_bool(OPT_DNSSEC_VALID) && option_bool(OPT_DNSSEC_TIME))
- {
- my_syslog(LOG_INFO, _("now checking DNSSEC signature timestamps"));
-- reset_option_bool(OPT_DNSSEC_TIME);
-+ daemon->dnssec_no_time_check = 0;
- }
- #endif
- /* fall through */
-diff --git a/src/dnsmasq.h b/src/dnsmasq.h
-index 1896a64..be27ae0 100644
---- a/src/dnsmasq.h
-+++ b/src/dnsmasq.h
-@@ -992,6 +992,7 @@ extern struct daemon {
- #endif
- #ifdef HAVE_DNSSEC
- struct ds_config *ds;
-+ int dnssec_no_time_check;
- int back_to_the_future;
- char *timestamp_file;
- #endif
-diff --git a/src/dnssec.c b/src/dnssec.c
-index 3c77c7d..64358fa 100644
---- a/src/dnssec.c
-+++ b/src/dnssec.c
-@@ -522,15 +522,16 @@ static int check_date_range(u32 date_start, u32 date_end)
- if (utime(daemon->timestamp_file, NULL) != 0)
- my_syslog(LOG_ERR, _("failed to update mtime on %s: %s"), daemon->timestamp_file, strerror(errno));
-
-+ my_syslog(LOG_INFO, _("system time considered valid, now checking DNSSEC signature timestamps."));
- daemon->back_to_the_future = 1;
-- set_option_bool(OPT_DNSSEC_TIME);
-+ daemon->dnssec_no_time_check = 0;
- queue_event(EVENT_RELOAD); /* purge cache */
- }
-
- if (daemon->back_to_the_future == 0)
- return 1;
- }
-- else if (option_bool(OPT_DNSSEC_TIME))
-+ else if (daemon->dnssec_no_time_check)
- return 1;
-
- /* We must explicitly check against wanted values, because of SERIAL_UNDEF */
---
-1.7.10.4
-
+++ /dev/null
-From d6dce53e08b3a06be16d43e1bf566c6c1988e4a9 Mon Sep 17 00:00:00 2001
-From: Simon Kelley <simon@thekelleys.org.uk>
-Date: Mon, 11 Jul 2016 21:34:31 +0100
-Subject: [PATCH] malloc(); memset() -> calloc() for efficiency.
-
----
- src/util.c | 10 +++-------
- 1 file changed, 3 insertions(+), 7 deletions(-)
-
-diff --git a/src/util.c b/src/util.c
-index 82443c9..211690e 100644
---- a/src/util.c
-+++ b/src/util.c
-@@ -244,13 +244,11 @@ unsigned char *do_rfc1035_name(unsigned char *p, char *sval)
- /* for use during startup */
- void *safe_malloc(size_t size)
- {
-- void *ret = malloc(size);
-+ void *ret = calloc(1, size);
-
- if (!ret)
- die(_("could not get memory"), NULL, EC_NOMEM);
-- else
-- memset(ret, 0, size);
--
-+
- return ret;
- }
-
-@@ -264,12 +262,10 @@ void safe_pipe(int *fd, int read_noblock)
-
- void *whine_malloc(size_t size)
- {
-- void *ret = malloc(size);
-+ void *ret = calloc(1, size);
-
- if (!ret)
- my_syslog(LOG_ERR, _("failed to allocate %d bytes"), (int) size);
-- else
-- memset(ret, 0, size);
-
- return ret;
- }
---
-1.7.10.4
-
+++ /dev/null
-From fa78573778cb23337f67f5d0c9de723169919047 Mon Sep 17 00:00:00 2001
-From: Simon Kelley <simon@thekelleys.org.uk>
-Date: Fri, 22 Jul 2016 20:56:01 +0100
-Subject: [PATCH] Zero packet buffers before building output, to reduce risk
- of information leakage.
-
----
- src/auth.c | 5 +++++
- src/dnsmasq.h | 1 +
- src/outpacket.c | 10 ++++++++++
- src/radv.c | 2 +-
- src/rfc1035.c | 5 +++++
- src/rfc3315.c | 6 +++---
- src/slaac.c | 2 +-
- src/tftp.c | 5 ++++-
- 8 files changed, 30 insertions(+), 6 deletions(-)
-
-diff --git a/src/auth.c b/src/auth.c
-index 198572d..3c5c37f 100644
---- a/src/auth.c
-+++ b/src/auth.c
-@@ -101,6 +101,11 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
- struct all_addr addr;
- struct cname *a;
-
-+ /* Clear buffer beyond request to avoid risk of
-+ information disclosure. */
-+ memset(((char *)header) + qlen, 0,
-+ (limit - ((char *)header)) - qlen);
-+
- if (ntohs(header->qdcount) == 0 || OPCODE(header) != QUERY )
- return 0;
-
-diff --git a/src/dnsmasq.h b/src/dnsmasq.h
-index be27ae0..2bda5d0 100644
---- a/src/dnsmasq.h
-+++ b/src/dnsmasq.h
-@@ -1471,6 +1471,7 @@ void log_relay(int family, struct dhcp_relay *relay);
- /* outpacket.c */
- #ifdef HAVE_DHCP6
- void end_opt6(int container);
-+void reset_counter(void);
- int save_counter(int newval);
- void *expand(size_t headroom);
- int new_opt6(int opt);
-diff --git a/src/outpacket.c b/src/outpacket.c
-index a414efa..2caacd9 100644
---- a/src/outpacket.c
-+++ b/src/outpacket.c
-@@ -29,9 +29,19 @@ void end_opt6(int container)
- PUTSHORT(len, p);
- }
-
-+void reset_counter(void)
-+{
-+ /* Clear out buffer when starting from begining */
-+ if (daemon->outpacket.iov_base)
-+ memset(daemon->outpacket.iov_base, 0, daemon->outpacket.iov_len);
-+
-+ save_counter(0);
-+}
-+
- int save_counter(int newval)
- {
- int ret = outpacket_counter;
-+
- if (newval != -1)
- outpacket_counter = newval;
-
-diff --git a/src/radv.c b/src/radv.c
-index faa0f6d..39c9217 100644
---- a/src/radv.c
-+++ b/src/radv.c
-@@ -261,7 +261,7 @@ static void send_ra_alias(time_t now, int iface, char *iface_name, struct in6_ad
- parm.adv_interval = calc_interval(ra_param);
- parm.prio = calc_prio(ra_param);
-
-- save_counter(0);
-+ reset_counter();
-
- if (!(ra = expand(sizeof(struct ra_packet))))
- return;
-diff --git a/src/rfc1035.c b/src/rfc1035.c
-index 24d08c1..9e730a9 100644
---- a/src/rfc1035.c
-+++ b/src/rfc1035.c
-@@ -1209,6 +1209,11 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
- int nxdomain = 0, auth = 1, trunc = 0, sec_data = 1;
- struct mx_srv_record *rec;
- size_t len;
-+
-+ /* Clear buffer beyond request to avoid risk of
-+ information disclosure. */
-+ memset(((char *)header) + qlen, 0,
-+ (limit - ((char *)header)) - qlen);
-
- if (ntohs(header->ancount) != 0 ||
- ntohs(header->nscount) != 0 ||
-diff --git a/src/rfc3315.c b/src/rfc3315.c
-index 3f4d69c..e1271a1 100644
---- a/src/rfc3315.c
-+++ b/src/rfc3315.c
-@@ -89,7 +89,7 @@ unsigned short dhcp6_reply(struct dhcp_context *context, int interface, char *if
- for (vendor = daemon->dhcp_vendors; vendor; vendor = vendor->next)
- vendor->netid.next = &vendor->netid;
-
-- save_counter(0);
-+ reset_counter();
- state.context = context;
- state.interface = interface;
- state.iface_name = iface_name;
-@@ -2084,7 +2084,7 @@ void relay_upstream6(struct dhcp_relay *relay, ssize_t sz,
- if (hopcount > 32)
- return;
-
-- save_counter(0);
-+ reset_counter();
-
- if ((header = put_opt6(NULL, 34)))
- {
-@@ -2161,7 +2161,7 @@ unsigned short relay_reply6(struct sockaddr_in6 *peer, ssize_t sz, char *arrival
- (!relay->interface || wildcard_match(relay->interface, arrival_interface)))
- break;
-
-- save_counter(0);
-+ reset_counter();
-
- if (relay)
- {
-diff --git a/src/slaac.c b/src/slaac.c
-index 07b8ba4..bd6c9b4 100644
---- a/src/slaac.c
-+++ b/src/slaac.c
-@@ -146,7 +146,7 @@ time_t periodic_slaac(time_t now, struct dhcp_lease *leases)
- struct ping_packet *ping;
- struct sockaddr_in6 addr;
-
-- save_counter(0);
-+ reset_counter();
-
- if (!(ping = expand(sizeof(struct ping_packet))))
- continue;
-diff --git a/src/tftp.c b/src/tftp.c
-index 3e1b5c5..618c406 100644
---- a/src/tftp.c
-+++ b/src/tftp.c
-@@ -662,8 +662,9 @@ static ssize_t tftp_err(int err, char *packet, char *message, char *file)
- ssize_t len, ret = 4;
- char *errstr = strerror(errno);
-
-+ memset(packet, 0, daemon->packet_buff_sz);
- sanitise(file);
--
-+
- mess->op = htons(OP_ERR);
- mess->err = htons(err);
- len = snprintf(mess->message, MAXMESSAGE, message, file, errstr);
-@@ -684,6 +685,8 @@ static ssize_t tftp_err_oops(char *packet, char *file)
- /* return -1 for error, zero for done. */
- static ssize_t get_block(char *packet, struct tftp_transfer *transfer)
- {
-+ memset(packet, 0, daemon->packet_buff_sz);
-+
- if (transfer->block == 0)
- {
- /* send OACK */
---
-1.7.10.4
-
+++ /dev/null
-From 6b1c464d6de3d7d2afc9b53afe78cda6d6e3316f Mon Sep 17 00:00:00 2001
-From: Simon Kelley <simon@thekelleys.org.uk>
-Date: Fri, 22 Jul 2016 20:59:16 +0100
-Subject: [PATCH] Don't reset packet length on transmission, in case of
- retransmission.
-
----
- src/radv.c | 2 +-
- src/rfc3315.c | 2 +-
- src/slaac.c | 2 +-
- 3 files changed, 3 insertions(+), 3 deletions(-)
-
-diff --git a/src/radv.c b/src/radv.c
-index 39c9217..ffc37f2 100644
---- a/src/radv.c
-+++ b/src/radv.c
-@@ -528,7 +528,7 @@ static void send_ra_alias(time_t now, int iface, char *iface_name, struct in6_ad
- }
-
- while (retry_send(sendto(daemon->icmp6fd, daemon->outpacket.iov_base,
-- save_counter(0), 0, (struct sockaddr *)&addr,
-+ save_counter(-1), 0, (struct sockaddr *)&addr,
- sizeof(addr))));
-
- }
-diff --git a/src/rfc3315.c b/src/rfc3315.c
-index e1271a1..c7bf46f 100644
---- a/src/rfc3315.c
-+++ b/src/rfc3315.c
-@@ -2127,7 +2127,7 @@ void relay_upstream6(struct dhcp_relay *relay, ssize_t sz,
- my_syslog(MS_DHCP | LOG_ERR, _("Cannot multicast to DHCPv6 server without correct interface"));
- }
-
-- send_from(daemon->dhcp6fd, 0, daemon->outpacket.iov_base, save_counter(0), &to, &from, 0);
-+ send_from(daemon->dhcp6fd, 0, daemon->outpacket.iov_base, save_counter(-1), &to, &from, 0);
-
- if (option_bool(OPT_LOG_OPTS))
- {
-diff --git a/src/slaac.c b/src/slaac.c
-index bd6c9b4..7ecf127 100644
---- a/src/slaac.c
-+++ b/src/slaac.c
-@@ -164,7 +164,7 @@ time_t periodic_slaac(time_t now, struct dhcp_lease *leases)
- addr.sin6_port = htons(IPPROTO_ICMPV6);
- addr.sin6_addr = slaac->addr;
-
-- if (sendto(daemon->icmp6fd, daemon->outpacket.iov_base, save_counter(0), 0,
-+ if (sendto(daemon->icmp6fd, daemon->outpacket.iov_base, save_counter(-1), 0,
- (struct sockaddr *)&addr, sizeof(addr)) == -1 &&
- errno == EHOSTUNREACH)
- slaac->ping_time = 0; /* Give up */
---
-1.7.10.4
-
+++ /dev/null
-From bf4e62c19e619f7edf8d03d58d33a5752f190bfd Mon Sep 17 00:00:00 2001
-From: Simon Kelley <simon@thekelleys.org.uk>
-Date: Fri, 22 Jul 2016 21:37:59 +0100
-Subject: [PATCH] Compile-time check on buffer sizes for leasefile parsing
- code.
-
----
- src/dhcp-common.c | 16 ++++++++--------
- src/dhcp-protocol.h | 4 ++++
- src/lease.c | 9 ++++++++-
- src/rfc3315.c | 2 +-
- 4 files changed, 21 insertions(+), 10 deletions(-)
-
-diff --git a/src/dhcp-common.c b/src/dhcp-common.c
-index 08528e8..ecc752b 100644
---- a/src/dhcp-common.c
-+++ b/src/dhcp-common.c
-@@ -20,11 +20,11 @@
-
- void dhcp_common_init(void)
- {
-- /* These each hold a DHCP option max size 255
-- and get a terminating zero added */
-- daemon->dhcp_buff = safe_malloc(256);
-- daemon->dhcp_buff2 = safe_malloc(256);
-- daemon->dhcp_buff3 = safe_malloc(256);
-+ /* These each hold a DHCP option max size 255
-+ and get a terminating zero added */
-+ daemon->dhcp_buff = safe_malloc(DHCP_BUFF_SZ);
-+ daemon->dhcp_buff2 = safe_malloc(DHCP_BUFF_SZ);
-+ daemon->dhcp_buff3 = safe_malloc(DHCP_BUFF_SZ);
-
- /* dhcp_packet is used by v4 and v6, outpacket only by v6
- sizeof(struct dhcp_packet) is as good an initial size as any,
-@@ -855,14 +855,14 @@ void log_context(int family, struct dhcp_context *context)
- if (context->flags & CONTEXT_RA_STATELESS)
- {
- if (context->flags & CONTEXT_TEMPLATE)
-- strncpy(daemon->dhcp_buff, context->template_interface, 256);
-+ strncpy(daemon->dhcp_buff, context->template_interface, DHCP_BUFF_SZ);
- else
- strcpy(daemon->dhcp_buff, daemon->addrbuff);
- }
- else
- #endif
-- inet_ntop(family, start, daemon->dhcp_buff, 256);
-- inet_ntop(family, end, daemon->dhcp_buff3, 256);
-+ inet_ntop(family, start, daemon->dhcp_buff, DHCP_BUFF_SZ);
-+ inet_ntop(family, end, daemon->dhcp_buff3, DHCP_BUFF_SZ);
- my_syslog(MS_DHCP | LOG_INFO,
- (context->flags & CONTEXT_RA_STATELESS) ?
- _("%s stateless on %s%.0s%.0s%s") :
-diff --git a/src/dhcp-protocol.h b/src/dhcp-protocol.h
-index a31d829..0ea449b 100644
---- a/src/dhcp-protocol.h
-+++ b/src/dhcp-protocol.h
-@@ -19,6 +19,10 @@
- #define DHCP_CLIENT_ALTPORT 1068
- #define PXE_PORT 4011
-
-+/* These each hold a DHCP option max size 255
-+ and get a terminating zero added */
-+#define DHCP_BUFF_SZ 256
-+
- #define BOOTREQUEST 1
- #define BOOTREPLY 2
- #define DHCP_COOKIE 0x63825363
-diff --git a/src/lease.c b/src/lease.c
-index 20cac90..ca62cc5 100644
---- a/src/lease.c
-+++ b/src/lease.c
-@@ -65,7 +65,14 @@ void lease_init(time_t now)
- }
-
- /* client-id max length is 255 which is 255*2 digits + 254 colons
-- borrow DNS packet buffer which is always larger than 1000 bytes */
-+ borrow DNS packet buffer which is always larger than 1000 bytes
-+
-+ Check various buffers are big enough for the code below */
-+
-+#if (DHCP_BUFF_SZ < 255) || (MAXDNAME < 64) || (PACKETSZ+MAXDNAME+RRFIXEDSZ < 764)
-+# error Buffer size breakage in leasfile parsing.
-+#endif
-+
- if (leasestream)
- while (fscanf(leasestream, "%255s %255s", daemon->dhcp_buff3, daemon->dhcp_buff2) == 2)
- {
-diff --git a/src/rfc3315.c b/src/rfc3315.c
-index c7bf46f..568b0c8 100644
---- a/src/rfc3315.c
-+++ b/src/rfc3315.c
-@@ -1975,7 +1975,7 @@ static void log6_packet(struct state *state, char *type, struct in6_addr *addr,
-
- if (addr)
- {
-- inet_ntop(AF_INET6, addr, daemon->dhcp_buff2, 255);
-+ inet_ntop(AF_INET6, addr, daemon->dhcp_buff2, DHCP_BUFF_SZ - 1);
- strcat(daemon->dhcp_buff2, " ");
- }
- else
---
-1.7.10.4
-