]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blob - src/patches/dnsmasq/0057-Tweak-DNSSEC-timestamp-code-to-create-file-later-rem.patch
Merge remote-tracking branch 'mfischer/python' into next
[people/pmueller/ipfire-2.x.git] / src / patches / dnsmasq / 0057-Tweak-DNSSEC-timestamp-code-to-create-file-later-rem.patch
1 From 360f2513ab12a9bf1e262d388dd2ea8a566590a3 Mon Sep 17 00:00:00 2001
2 From: Simon Kelley <simon@thekelleys.org.uk>
3 Date: Sat, 7 Mar 2015 18:28:06 +0000
4 Subject: [PATCH 57/98] Tweak DNSSEC timestamp code to create file later,
5 removing need to chown it.
6
7 ---
8 man/dnsmasq.8 | 3 ++-
9 src/dnsmasq.c | 35 ++++++++++++++++++++++-------------
10 src/dnsmasq.h | 3 ++-
11 src/dnssec.c | 18 ++++++++++--------
12 4 files changed, 36 insertions(+), 23 deletions(-)
13
14 diff --git a/man/dnsmasq.8 b/man/dnsmasq.8
15 index 097e7d75145c..2db780d90987 100644
16 --- a/man/dnsmasq.8
17 +++ b/man/dnsmasq.8
18 @@ -678,7 +678,8 @@ which have not been throughly checked.
19 Enables an alternative way of checking the validity of the system time for DNSSEC (see --dnssec-no-timecheck). In this case, the
20 system time is considered to be valid once it becomes later than the timestamp on the specified file. The file is created and
21 its timestamp set automatically by dnsmasq. The file must be stored on a persistent filesystem, so that it and its mtime are carried
22 -over system restarts.
23 +over system restarts. The timestamp file is created after dnsmasq has dropped root, so it must be in a location writable by the
24 +unprivileged user that dnsmasq runs as.
25 .TP
26 .B --proxy-dnssec
27 Copy the DNSSEC Authenticated Data bit from upstream servers to downstream clients and cache it. This is an
28 diff --git a/src/dnsmasq.c b/src/dnsmasq.c
29 index 9e05c0e31569..f3e5bcffec4f 100644
30 --- a/src/dnsmasq.c
31 +++ b/src/dnsmasq.c
32 @@ -58,9 +58,6 @@ int main (int argc, char **argv)
33 struct dhcp_context *context;
34 struct dhcp_relay *relay;
35 #endif
36 -#ifdef HAVE_DNSSEC
37 - int badtime;
38 -#endif
39
40 #ifdef LOCALEDIR
41 setlocale(LC_ALL, "");
42 @@ -156,10 +153,10 @@ int main (int argc, char **argv)
43 {
44 #ifdef HAVE_DNSSEC
45 if (!daemon->ds)
46 - die(_("No trust anchors provided for DNSSEC"), NULL, EC_BADCONF);
47 + die(_("no trust anchors provided for DNSSEC"), NULL, EC_BADCONF);
48
49 if (daemon->cachesize < CACHESIZ)
50 - die(_("Cannot reduce cache size from default when DNSSEC enabled"), NULL, EC_BADCONF);
51 + die(_("cannot reduce cache size from default when DNSSEC enabled"), NULL, EC_BADCONF);
52 #else
53 die(_("DNSSEC not available: set HAVE_DNSSEC in src/config.h"), NULL, EC_BADCONF);
54 #endif
55 @@ -172,10 +169,10 @@ int main (int argc, char **argv)
56
57 #ifdef HAVE_CONNTRACK
58 if (option_bool(OPT_CONNTRACK) && (daemon->query_port != 0 || daemon->osport))
59 - die (_("Cannot use --conntrack AND --query-port"), NULL, EC_BADCONF);
60 + die (_("cannot use --conntrack AND --query-port"), NULL, EC_BADCONF);
61 #else
62 if (option_bool(OPT_CONNTRACK))
63 - die(_("Conntrack support not available: set HAVE_CONNTRACK in src/config.h"), NULL, EC_BADCONF);
64 + die(_("conntrack support not available: set HAVE_CONNTRACK in src/config.h"), NULL, EC_BADCONF);
65 #endif
66
67 #ifdef HAVE_SOLARIS_NETWORK
68 @@ -195,7 +192,7 @@ int main (int argc, char **argv)
69
70 #ifndef HAVE_LOOP
71 if (option_bool(OPT_LOOP_DETECT))
72 - die(_("Loop detection not available: set HAVE_LOOP in src/config.h"), NULL, EC_BADCONF);
73 + die(_("loop detection not available: set HAVE_LOOP in src/config.h"), NULL, EC_BADCONF);
74 #endif
75
76 now = dnsmasq_time();
77 @@ -373,10 +370,6 @@ int main (int argc, char **argv)
78 if (baduser)
79 die(_("unknown user or group: %s"), baduser, EC_BADCONF);
80
81 -#ifdef HAVE_DNSSEC
82 - badtime = setup_timestamp(ent_pw);
83 -#endif
84 -
85 /* implement group defaults, "dip" if available, or group associated with uid */
86 if (!daemon->group_set && !gp)
87 {
88 @@ -693,10 +686,23 @@ int main (int argc, char **argv)
89 #ifdef HAVE_DNSSEC
90 if (option_bool(OPT_DNSSEC_VALID))
91 {
92 + int rc;
93 +
94 + /* Delay creating the timestamp file until here, after we've changed user, so that
95 + it has the correct owner to allow updating the mtime later.
96 + This means we have to report fatal errors via the pipe. */
97 + if ((rc = setup_timestamp()) == -1)
98 + {
99 + send_event(err_pipe[1], EVENT_TIME_ERR, errno, daemon->timestamp_file);
100 + _exit(0);
101 + }
102 +
103 my_syslog(LOG_INFO, _("DNSSEC validation enabled"));
104 +
105 if (option_bool(OPT_DNSSEC_TIME))
106 my_syslog(LOG_INFO, _("DNSSEC signature timestamps not checked until first cache reload"));
107 - if (badtime)
108 +
109 + if (rc == 1)
110 my_syslog(LOG_INFO, _("DNSSEC signature timestamps not checked until system time valid"));
111 }
112 #endif
113 @@ -1170,6 +1176,9 @@ static void fatal_event(struct event_desc *ev, char *msg)
114
115 case EVENT_TFTP_ERR:
116 die(_("TFTP directory %s inaccessible: %s"), msg, EC_FILE);
117 +
118 + case EVENT_TIME_ERR:
119 + die(_("cannot create timestamp file %s: %s" ), msg, EC_BADCONF);
120 }
121 }
122
123 diff --git a/src/dnsmasq.h b/src/dnsmasq.h
124 index a451cb4dd03c..fc7259881358 100644
125 --- a/src/dnsmasq.h
126 +++ b/src/dnsmasq.h
127 @@ -167,6 +167,7 @@ struct event_desc {
128 #define EVENT_INIT 21
129 #define EVENT_NEWADDR 22
130 #define EVENT_NEWROUTE 23
131 +#define EVENT_TIME_ERR 24
132
133 /* Exit codes. */
134 #define EC_GOOD 0
135 @@ -1152,7 +1153,7 @@ int dnssec_chase_cname(time_t now, struct dns_header *header, size_t plen, char
136 int dnskey_keytag(int alg, int flags, unsigned char *rdata, int rdlen);
137 size_t filter_rrsigs(struct dns_header *header, size_t plen);
138 unsigned char* hash_questions(struct dns_header *header, size_t plen, char *name);
139 -int setup_timestamp(struct passwd *ent_pw);
140 +int setup_timestamp(void);
141
142 /* util.c */
143 void rand_init(void);
144 diff --git a/src/dnssec.c b/src/dnssec.c
145 index c60eacf73c6b..ad0d6f072ba2 100644
146 --- a/src/dnssec.c
147 +++ b/src/dnssec.c
148 @@ -397,18 +397,21 @@ static int serial_compare_32(unsigned long s1, unsigned long s2)
149
150 /* Called at startup. If the timestamp file is configured and exists, put its mtime on
151 timestamp_time. If it doesn't exist, create it, and set the mtime to 1-1-2015.
152 - Change the ownership to the user we'll be running as, so that we can update the mtime.
153 + return -1 -> Cannot create file.
154 + 0 -> not using timestamp, or timestamp exists and is in past.
155 + 1 -> timestamp exists and is in future.
156 */
157 +
158 static time_t timestamp_time;
159 static int back_to_the_future;
160
161 -int setup_timestamp(struct passwd *ent_pw)
162 +int setup_timestamp(void)
163 {
164 struct stat statbuf;
165
166 back_to_the_future = 0;
167
168 - if (!option_bool(OPT_DNSSEC_VALID) || !daemon->timestamp_file)
169 + if (!daemon->timestamp_file)
170 return 0;
171
172 if (stat(daemon->timestamp_file, &statbuf) != -1)
173 @@ -428,7 +431,8 @@ int setup_timestamp(struct passwd *ent_pw)
174
175 if (errno == ENOENT)
176 {
177 - int fd = open(daemon->timestamp_file, O_WRONLY | O_CREAT | O_NONBLOCK, 0666);
178 + /* NB. for explanation of O_EXCL flag, see comment on pidfile in dnsmasq.c */
179 + int fd = open(daemon->timestamp_file, O_WRONLY | O_CREAT | O_NONBLOCK | O_EXCL, 0666);
180 if (fd != -1)
181 {
182 struct utimbuf timbuf;
183 @@ -436,14 +440,12 @@ int setup_timestamp(struct passwd *ent_pw)
184 close(fd);
185
186 timestamp_time = timbuf.actime = timbuf.modtime = 1420070400; /* 1-1-2015 */
187 - if (utime(daemon->timestamp_file, &timbuf) == 0 &&
188 - (!ent_pw || getuid() != 0 || chown(daemon->timestamp_file, ent_pw->pw_uid, -1) == 0))
189 + if (utime(daemon->timestamp_file, &timbuf) == 0)
190 goto check_and_exit;
191 }
192 }
193
194 - die(_("Cannot create timestamp file %s: %s" ), daemon->timestamp_file, EC_BADCONF);
195 - return 0;
196 + return -1;
197 }
198
199 /* Check whether today/now is between date_start and date_end */
200 --
201 2.1.0
202