Deleted Added
full compact
authreadkeys.c (294554) authreadkeys.c (298695)
1/*
2 * authreadkeys.c - routines to support the reading of the key file
3 */
4#include <config.h>
5#include <stdio.h>
6#include <ctype.h>
7
8#include "ntpd.h" /* Only for DPRINTF */

--- 87 unchanged lines hidden (view full) ---

96
97static void
98log_maybe(
99 u_int *pnerr,
100 const char *fmt ,
101 ...)
102{
103 va_list ap;
1/*
2 * authreadkeys.c - routines to support the reading of the key file
3 */
4#include <config.h>
5#include <stdio.h>
6#include <ctype.h>
7
8#include "ntpd.h" /* Only for DPRINTF */

--- 87 unchanged lines hidden (view full) ---

96
97static void
98log_maybe(
99 u_int *pnerr,
100 const char *fmt ,
101 ...)
102{
103 va_list ap;
104 if (++(*pnerr) <= nerr_loglimit) {
104 if ((NULL == pnerr) || (++(*pnerr) <= nerr_loglimit)) {
105 va_start(ap, fmt);
106 mvsyslog(LOG_ERR, fmt, ap);
107 va_end(ap);
108 }
109}
110
105 va_start(ap, fmt);
106 mvsyslog(LOG_ERR, fmt, ap);
107 va_end(ap);
108 }
109}
110
111static void
112free_keydata(
113 KeyDataT *node
114 )
115{
116 KeyAccT *kap;
117
118 if (node) {
119 while (node->keyacclist) {
120 kap = node->keyacclist;
121 node->keyacclist = kap->next;
122 free(kap);
123 }
124
125 /* purge secrets from memory before free()ing it */
126 memset(node, 0, sizeof(*node) + node->seclen);
127 free(node);
128 }
129}
130
111/*
112 * authreadkeys - (re)read keys from a file.
113 */
114int
115authreadkeys(
116 const char *file
117 )
118{

--- 32 unchanged lines hidden (view full) ---

151 token = nexttok(&line);
152 if (token == NULL)
153 continue;
154
155 /*
156 * First is key number. See if it is okay.
157 */
158 keyno = atoi(token);
131/*
132 * authreadkeys - (re)read keys from a file.
133 */
134int
135authreadkeys(
136 const char *file
137 )
138{

--- 32 unchanged lines hidden (view full) ---

171 token = nexttok(&line);
172 if (token == NULL)
173 continue;
174
175 /*
176 * First is key number. See if it is okay.
177 */
178 keyno = atoi(token);
159 if (keyno == 0) {
179 if (keyno < 1) {
160 log_maybe(&nerr,
161 "authreadkeys: cannot change key %s",
162 token);
163 continue;
164 }
165
166 if (keyno > NTP_MAXKEY) {
167 log_maybe(&nerr,

--- 7 unchanged lines hidden (view full) ---

175 */
176 token = nexttok(&line);
177 if (token == NULL) {
178 log_maybe(&nerr,
179 "authreadkeys: no key type for key %d",
180 keyno);
181 continue;
182 }
180 log_maybe(&nerr,
181 "authreadkeys: cannot change key %s",
182 token);
183 continue;
184 }
185
186 if (keyno > NTP_MAXKEY) {
187 log_maybe(&nerr,

--- 7 unchanged lines hidden (view full) ---

195 */
196 token = nexttok(&line);
197 if (token == NULL) {
198 log_maybe(&nerr,
199 "authreadkeys: no key type for key %d",
200 keyno);
201 continue;
202 }
203
204 /* We want to silently ignore keys where we do not
205 * support the requested digest type. OTOH, we want to
206 * make sure the file is well-formed. That means we
207 * have to process the line completely and have to
208 * finally throw away the result... This is a bit more
209 * work, but it also results in better error detection.
210 */
183#ifdef OPENSSL
184 /*
185 * The key type is the NID used by the message digest
186 * algorithm. There are a number of inconsistencies in
187 * the OpenSSL database. We attempt to discover them
188 * here and prevent use of inconsistent data later.
189 */
190 keytype = keytype_from_text(token, NULL);
191 if (keytype == 0) {
211#ifdef OPENSSL
212 /*
213 * The key type is the NID used by the message digest
214 * algorithm. There are a number of inconsistencies in
215 * the OpenSSL database. We attempt to discover them
216 * here and prevent use of inconsistent data later.
217 */
218 keytype = keytype_from_text(token, NULL);
219 if (keytype == 0) {
192 log_maybe(&nerr,
220 log_maybe(NULL,
193 "authreadkeys: invalid type for key %d",
194 keyno);
221 "authreadkeys: invalid type for key %d",
222 keyno);
195 continue;
196 }
197 if (EVP_get_digestbynid(keytype) == NULL) {
198 log_maybe(&nerr,
223 } else if (EVP_get_digestbynid(keytype) == NULL) {
224 log_maybe(NULL,
199 "authreadkeys: no algorithm for key %d",
200 keyno);
225 "authreadkeys: no algorithm for key %d",
226 keyno);
201 continue;
227 keytype = 0;
202 }
203#else /* !OPENSSL follows */
228 }
229#else /* !OPENSSL follows */
204
205 /*
206 * The key type is unused, but is required to be 'M' or
207 * 'm' for compatibility.
208 */
209 if (!(*token == 'M' || *token == 'm')) {
230 /*
231 * The key type is unused, but is required to be 'M' or
232 * 'm' for compatibility.
233 */
234 if (!(*token == 'M' || *token == 'm')) {
210 log_maybe(&nerr,
235 log_maybe(NULL,
211 "authreadkeys: invalid type for key %d",
212 keyno);
236 "authreadkeys: invalid type for key %d",
237 keyno);
213 continue;
238 keytype = 0;
239 } else {
240 keytype = KEY_TYPE_MD5;
214 }
241 }
215 keytype = KEY_TYPE_MD5;
216#endif /* !OPENSSL */
217
218 /*
219 * Finally, get key and insert it. If it is longer than 20
220 * characters, it is a binary string encoded in hex;
221 * otherwise, it is a text string of printable ASCII
222 * characters.
223 */

--- 40 unchanged lines hidden (view full) ---

264 next->keyacclist = NULL;
265 next->keyid = keyno;
266 next->keytype = keytype;
267 next->seclen = len;
268 memcpy(next->secbuf, keystr, len);
269 }
270
271 token = nexttok(&line);
242#endif /* !OPENSSL */
243
244 /*
245 * Finally, get key and insert it. If it is longer than 20
246 * characters, it is a binary string encoded in hex;
247 * otherwise, it is a text string of printable ASCII
248 * characters.
249 */

--- 40 unchanged lines hidden (view full) ---

290 next->keyacclist = NULL;
291 next->keyid = keyno;
292 next->keytype = keytype;
293 next->seclen = len;
294 memcpy(next->secbuf, keystr, len);
295 }
296
297 token = nexttok(&line);
272DPRINTF(0, ("authreadkeys: full access list <%s>\n", (token) ? token : "NULL"));
298 DPRINTF(0, ("authreadkeys: full access list <%s>\n", (token) ? token : "NULL"));
273 if (token != NULL) { /* A comma-separated IP access list */
274 char *tp = token;
275
276 while (tp) {
277 char *i;
299 if (token != NULL) { /* A comma-separated IP access list */
300 char *tp = token;
301
302 while (tp) {
303 char *i;
278 KeyAccT ka;
304 sockaddr_u addr;
279
280 i = strchr(tp, (int)',');
281 if (i)
282 *i = '\0';
305
306 i = strchr(tp, (int)',');
307 if (i)
308 *i = '\0';
283DPRINTF(0, ("authreadkeys: access list: <%s>\n", tp));
309 DPRINTF(0, ("authreadkeys: access list: <%s>\n", tp));
284
310
285 if (is_ip_address(tp, AF_UNSPEC, &ka.addr)) {
286 KeyAccT *kap;
287
288 kap = emalloc(sizeof(KeyAccT));
289 memcpy(kap, &ka, sizeof ka);
290 kap->next = next->keyacclist;
291 next->keyacclist = kap;
311 if (is_ip_address(tp, AF_UNSPEC, &addr)) {
312 next->keyacclist = keyacc_new_push(
313 next->keyacclist, &addr);
292 } else {
293 log_maybe(&nerr,
294 "authreadkeys: invalid IP address <%s> for key %d",
295 tp, keyno);
296 }
297
298 if (i) {
299 tp = i + 1;
300 } else {
301 tp = 0;
302 }
303 }
304 }
305
314 } else {
315 log_maybe(&nerr,
316 "authreadkeys: invalid IP address <%s> for key %d",
317 tp, keyno);
318 }
319
320 if (i) {
321 tp = i + 1;
322 } else {
323 tp = 0;
324 }
325 }
326 }
327
328 /* check if this has to be weeded out... */
329 if (0 == keytype) {
330 free_keydata(next);
331 next = NULL;
332 continue;
333 }
334
306 INSIST(NULL != next);
307 next->next = list;
308 list = next;
309 }
310 fclose(fp);
335 INSIST(NULL != next);
336 next->next = list;
337 list = next;
338 }
339 fclose(fp);
311 if (nerr > nerr_maxlimit) {
312 msyslog(LOG_ERR,
313 "authreadkeys: rejecting file '%s' after %u errors (emergency break)",
314 file, nerr);
315 goto onerror;
316 }
317 if (nerr > 0) {
340 if (nerr > 0) {
341 const char * why = "";
342 if (nerr > nerr_maxlimit)
343 why = " (emergency break)";
318 msyslog(LOG_ERR,
344 msyslog(LOG_ERR,
319 "authreadkeys: rejecting file '%s' after %u error(s)",
320 file, nerr);
345 "authreadkeys: rejecting file '%s' after %u error(s)%s",
346 file, nerr, why);
321 goto onerror;
322 }
323
324 /* first remove old file-based keys */
325 auth_delkeys();
326 /* insert the new key material */
327 while (NULL != (next = list)) {
328 list = next->next;
329 MD5auth_setkey(next->keyid, next->keytype,
330 next->secbuf, next->seclen, next->keyacclist);
347 goto onerror;
348 }
349
350 /* first remove old file-based keys */
351 auth_delkeys();
352 /* insert the new key material */
353 while (NULL != (next = list)) {
354 list = next->next;
355 MD5auth_setkey(next->keyid, next->keytype,
356 next->secbuf, next->seclen, next->keyacclist);
331 /* purge secrets from memory before free()ing it */
332 memset(next, 0, sizeof(*next) + next->seclen);
333 free(next);
357 next->keyacclist = NULL; /* consumed by MD5auth_setkey */
358 free_keydata(next);
334 }
335 return (1);
336
337 onerror:
338 /* Mop up temporary storage before bailing out. */
339 while (NULL != (next = list)) {
340 list = next->next;
359 }
360 return (1);
361
362 onerror:
363 /* Mop up temporary storage before bailing out. */
364 while (NULL != (next = list)) {
365 list = next->next;
341
342 while (next->keyacclist) {
343 KeyAccT *kap = next->keyacclist;
344
345 next->keyacclist = kap->next;
346 free(kap);
347 }
348
349 /* purge secrets from memory before free()ing it */
350 memset(next, 0, sizeof(*next) + next->seclen);
351 free(next);
366 free_keydata(next);
352 }
353 return (0);
354}
367 }
368 return (0);
369}