mirror of
https://github.com/pi-hole/dnsmasq.git
synced 2025-12-19 10:18:25 +00:00
Tweak DNSSEC timestamp code to create file later, removing need to chown it.
This commit is contained in:
@@ -678,7 +678,8 @@ which have not been throughly checked.
|
|||||||
Enables an alternative way of checking the validity of the system time for DNSSEC (see --dnssec-no-timecheck). In this case, the
|
Enables an alternative way of checking the validity of the system time for DNSSEC (see --dnssec-no-timecheck). In this case, the
|
||||||
system time is considered to be valid once it becomes later than the timestamp on the specified file. The file is created and
|
system time is considered to be valid once it becomes later than the timestamp on the specified file. The file is created and
|
||||||
its timestamp set automatically by dnsmasq. The file must be stored on a persistent filesystem, so that it and its mtime are carried
|
its timestamp set automatically by dnsmasq. The file must be stored on a persistent filesystem, so that it and its mtime are carried
|
||||||
over system restarts.
|
over system restarts. The timestamp file is created after dnsmasq has dropped root, so it must be in a location writable by the
|
||||||
|
unprivileged user that dnsmasq runs as.
|
||||||
.TP
|
.TP
|
||||||
.B --proxy-dnssec
|
.B --proxy-dnssec
|
||||||
Copy the DNSSEC Authenticated Data bit from upstream servers to downstream clients and cache it. This is an
|
Copy the DNSSEC Authenticated Data bit from upstream servers to downstream clients and cache it. This is an
|
||||||
|
|||||||
@@ -58,9 +58,6 @@ int main (int argc, char **argv)
|
|||||||
struct dhcp_context *context;
|
struct dhcp_context *context;
|
||||||
struct dhcp_relay *relay;
|
struct dhcp_relay *relay;
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_DNSSEC
|
|
||||||
int badtime;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef LOCALEDIR
|
#ifdef LOCALEDIR
|
||||||
setlocale(LC_ALL, "");
|
setlocale(LC_ALL, "");
|
||||||
@@ -156,10 +153,10 @@ int main (int argc, char **argv)
|
|||||||
{
|
{
|
||||||
#ifdef HAVE_DNSSEC
|
#ifdef HAVE_DNSSEC
|
||||||
if (!daemon->ds)
|
if (!daemon->ds)
|
||||||
die(_("No trust anchors provided for DNSSEC"), NULL, EC_BADCONF);
|
die(_("no trust anchors provided for DNSSEC"), NULL, EC_BADCONF);
|
||||||
|
|
||||||
if (daemon->cachesize < CACHESIZ)
|
if (daemon->cachesize < CACHESIZ)
|
||||||
die(_("Cannot reduce cache size from default when DNSSEC enabled"), NULL, EC_BADCONF);
|
die(_("cannot reduce cache size from default when DNSSEC enabled"), NULL, EC_BADCONF);
|
||||||
#else
|
#else
|
||||||
die(_("DNSSEC not available: set HAVE_DNSSEC in src/config.h"), NULL, EC_BADCONF);
|
die(_("DNSSEC not available: set HAVE_DNSSEC in src/config.h"), NULL, EC_BADCONF);
|
||||||
#endif
|
#endif
|
||||||
@@ -172,10 +169,10 @@ int main (int argc, char **argv)
|
|||||||
|
|
||||||
#ifdef HAVE_CONNTRACK
|
#ifdef HAVE_CONNTRACK
|
||||||
if (option_bool(OPT_CONNTRACK) && (daemon->query_port != 0 || daemon->osport))
|
if (option_bool(OPT_CONNTRACK) && (daemon->query_port != 0 || daemon->osport))
|
||||||
die (_("Cannot use --conntrack AND --query-port"), NULL, EC_BADCONF);
|
die (_("cannot use --conntrack AND --query-port"), NULL, EC_BADCONF);
|
||||||
#else
|
#else
|
||||||
if (option_bool(OPT_CONNTRACK))
|
if (option_bool(OPT_CONNTRACK))
|
||||||
die(_("Conntrack support not available: set HAVE_CONNTRACK in src/config.h"), NULL, EC_BADCONF);
|
die(_("conntrack support not available: set HAVE_CONNTRACK in src/config.h"), NULL, EC_BADCONF);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_SOLARIS_NETWORK
|
#ifdef HAVE_SOLARIS_NETWORK
|
||||||
@@ -195,7 +192,7 @@ int main (int argc, char **argv)
|
|||||||
|
|
||||||
#ifndef HAVE_LOOP
|
#ifndef HAVE_LOOP
|
||||||
if (option_bool(OPT_LOOP_DETECT))
|
if (option_bool(OPT_LOOP_DETECT))
|
||||||
die(_("Loop detection not available: set HAVE_LOOP in src/config.h"), NULL, EC_BADCONF);
|
die(_("loop detection not available: set HAVE_LOOP in src/config.h"), NULL, EC_BADCONF);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
now = dnsmasq_time();
|
now = dnsmasq_time();
|
||||||
@@ -373,10 +370,6 @@ int main (int argc, char **argv)
|
|||||||
if (baduser)
|
if (baduser)
|
||||||
die(_("unknown user or group: %s"), baduser, EC_BADCONF);
|
die(_("unknown user or group: %s"), baduser, EC_BADCONF);
|
||||||
|
|
||||||
#ifdef HAVE_DNSSEC
|
|
||||||
badtime = setup_timestamp(ent_pw);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* implement group defaults, "dip" if available, or group associated with uid */
|
/* implement group defaults, "dip" if available, or group associated with uid */
|
||||||
if (!daemon->group_set && !gp)
|
if (!daemon->group_set && !gp)
|
||||||
{
|
{
|
||||||
@@ -693,10 +686,23 @@ int main (int argc, char **argv)
|
|||||||
#ifdef HAVE_DNSSEC
|
#ifdef HAVE_DNSSEC
|
||||||
if (option_bool(OPT_DNSSEC_VALID))
|
if (option_bool(OPT_DNSSEC_VALID))
|
||||||
{
|
{
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
/* Delay creating the timestamp file until here, after we've changed user, so that
|
||||||
|
it has the correct owner to allow updating the mtime later.
|
||||||
|
This means we have to report fatal errors via the pipe. */
|
||||||
|
if ((rc = setup_timestamp()) == -1)
|
||||||
|
{
|
||||||
|
send_event(err_pipe[1], EVENT_TIME_ERR, errno, daemon->timestamp_file);
|
||||||
|
_exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
my_syslog(LOG_INFO, _("DNSSEC validation enabled"));
|
my_syslog(LOG_INFO, _("DNSSEC validation enabled"));
|
||||||
|
|
||||||
if (option_bool(OPT_DNSSEC_TIME))
|
if (option_bool(OPT_DNSSEC_TIME))
|
||||||
my_syslog(LOG_INFO, _("DNSSEC signature timestamps not checked until first cache reload"));
|
my_syslog(LOG_INFO, _("DNSSEC signature timestamps not checked until first cache reload"));
|
||||||
if (badtime)
|
|
||||||
|
if (rc == 1)
|
||||||
my_syslog(LOG_INFO, _("DNSSEC signature timestamps not checked until system time valid"));
|
my_syslog(LOG_INFO, _("DNSSEC signature timestamps not checked until system time valid"));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -1170,6 +1176,9 @@ static void fatal_event(struct event_desc *ev, char *msg)
|
|||||||
|
|
||||||
case EVENT_TFTP_ERR:
|
case EVENT_TFTP_ERR:
|
||||||
die(_("TFTP directory %s inaccessible: %s"), msg, EC_FILE);
|
die(_("TFTP directory %s inaccessible: %s"), msg, EC_FILE);
|
||||||
|
|
||||||
|
case EVENT_TIME_ERR:
|
||||||
|
die(_("cannot create timestamp file %s: %s" ), msg, EC_BADCONF);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -167,6 +167,7 @@ struct event_desc {
|
|||||||
#define EVENT_INIT 21
|
#define EVENT_INIT 21
|
||||||
#define EVENT_NEWADDR 22
|
#define EVENT_NEWADDR 22
|
||||||
#define EVENT_NEWROUTE 23
|
#define EVENT_NEWROUTE 23
|
||||||
|
#define EVENT_TIME_ERR 24
|
||||||
|
|
||||||
/* Exit codes. */
|
/* Exit codes. */
|
||||||
#define EC_GOOD 0
|
#define EC_GOOD 0
|
||||||
@@ -1152,7 +1153,7 @@ int dnssec_chase_cname(time_t now, struct dns_header *header, size_t plen, char
|
|||||||
int dnskey_keytag(int alg, int flags, unsigned char *rdata, int rdlen);
|
int dnskey_keytag(int alg, int flags, unsigned char *rdata, int rdlen);
|
||||||
size_t filter_rrsigs(struct dns_header *header, size_t plen);
|
size_t filter_rrsigs(struct dns_header *header, size_t plen);
|
||||||
unsigned char* hash_questions(struct dns_header *header, size_t plen, char *name);
|
unsigned char* hash_questions(struct dns_header *header, size_t plen, char *name);
|
||||||
int setup_timestamp(struct passwd *ent_pw);
|
int setup_timestamp(void);
|
||||||
|
|
||||||
/* util.c */
|
/* util.c */
|
||||||
void rand_init(void);
|
void rand_init(void);
|
||||||
|
|||||||
18
src/dnssec.c
18
src/dnssec.c
@@ -397,18 +397,21 @@ static int serial_compare_32(unsigned long s1, unsigned long s2)
|
|||||||
|
|
||||||
/* Called at startup. If the timestamp file is configured and exists, put its mtime on
|
/* Called at startup. If the timestamp file is configured and exists, put its mtime on
|
||||||
timestamp_time. If it doesn't exist, create it, and set the mtime to 1-1-2015.
|
timestamp_time. If it doesn't exist, create it, and set the mtime to 1-1-2015.
|
||||||
Change the ownership to the user we'll be running as, so that we can update the mtime.
|
return -1 -> Cannot create file.
|
||||||
|
0 -> not using timestamp, or timestamp exists and is in past.
|
||||||
|
1 -> timestamp exists and is in future.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static time_t timestamp_time;
|
static time_t timestamp_time;
|
||||||
static int back_to_the_future;
|
static int back_to_the_future;
|
||||||
|
|
||||||
int setup_timestamp(struct passwd *ent_pw)
|
int setup_timestamp(void)
|
||||||
{
|
{
|
||||||
struct stat statbuf;
|
struct stat statbuf;
|
||||||
|
|
||||||
back_to_the_future = 0;
|
back_to_the_future = 0;
|
||||||
|
|
||||||
if (!option_bool(OPT_DNSSEC_VALID) || !daemon->timestamp_file)
|
if (!daemon->timestamp_file)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (stat(daemon->timestamp_file, &statbuf) != -1)
|
if (stat(daemon->timestamp_file, &statbuf) != -1)
|
||||||
@@ -428,7 +431,8 @@ int setup_timestamp(struct passwd *ent_pw)
|
|||||||
|
|
||||||
if (errno == ENOENT)
|
if (errno == ENOENT)
|
||||||
{
|
{
|
||||||
int fd = open(daemon->timestamp_file, O_WRONLY | O_CREAT | O_NONBLOCK, 0666);
|
/* NB. for explanation of O_EXCL flag, see comment on pidfile in dnsmasq.c */
|
||||||
|
int fd = open(daemon->timestamp_file, O_WRONLY | O_CREAT | O_NONBLOCK | O_EXCL, 0666);
|
||||||
if (fd != -1)
|
if (fd != -1)
|
||||||
{
|
{
|
||||||
struct utimbuf timbuf;
|
struct utimbuf timbuf;
|
||||||
@@ -436,14 +440,12 @@ int setup_timestamp(struct passwd *ent_pw)
|
|||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
timestamp_time = timbuf.actime = timbuf.modtime = 1420070400; /* 1-1-2015 */
|
timestamp_time = timbuf.actime = timbuf.modtime = 1420070400; /* 1-1-2015 */
|
||||||
if (utime(daemon->timestamp_file, &timbuf) == 0 &&
|
if (utime(daemon->timestamp_file, &timbuf) == 0)
|
||||||
(!ent_pw || getuid() != 0 || chown(daemon->timestamp_file, ent_pw->pw_uid, -1) == 0))
|
|
||||||
goto check_and_exit;
|
goto check_and_exit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
die(_("Cannot create timestamp file %s: %s" ), daemon->timestamp_file, EC_BADCONF);
|
return -1;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check whether today/now is between date_start and date_end */
|
/* Check whether today/now is between date_start and date_end */
|
||||||
|
|||||||
Reference in New Issue
Block a user