xref: /openbsd/usr.sbin/ntpd/constraint.c (revision b7e9bd4f)
1 /*	$OpenBSD: constraint.c,v 1.42 2019/01/21 11:08:37 jsing Exp $	*/
2 
3 /*
4  * Copyright (c) 2015 Reyk Floeter <reyk@openbsd.org>
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #include <sys/queue.h>
20 #include <sys/socket.h>
21 #include <sys/time.h>
22 #include <sys/types.h>
23 #include <sys/wait.h>
24 #include <sys/resource.h>
25 #include <sys/uio.h>
26 
27 #include <netinet/in.h>
28 #include <arpa/inet.h>
29 
30 #include <errno.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <fcntl.h>
34 #include <imsg.h>
35 #include <netdb.h>
36 #include <poll.h>
37 #include <signal.h>
38 #include <string.h>
39 #include <unistd.h>
40 #include <time.h>
41 #include <ctype.h>
42 #include <tls.h>
43 #include <pwd.h>
44 
45 #include "ntpd.h"
46 
47 #define	IMF_FIXDATE	"%a, %d %h %Y %T GMT"
48 #define	X509_DATE	"%Y-%m-%d %T UTC"
49 
50 int	 constraint_addr_init(struct constraint *);
51 struct constraint *
52 	 constraint_byid(u_int32_t);
53 struct constraint *
54 	 constraint_byfd(int);
55 struct constraint *
56 	 constraint_bypid(pid_t);
57 int	 constraint_close(u_int32_t);
58 void	 constraint_update(void);
59 void	 constraint_reset(void);
60 int	 constraint_cmp(const void *, const void *);
61 
62 void	 priv_constraint_close(int, int);
63 void	 priv_constraint_readquery(struct constraint *, struct ntp_addr_msg *,
64 	    uint8_t **);
65 
66 struct httpsdate *
67 	 httpsdate_init(const char *, const char *, const char *,
68 	    const char *, const u_int8_t *, size_t);
69 void	 httpsdate_free(void *);
70 int	 httpsdate_request(struct httpsdate *, struct timeval *);
71 void	*httpsdate_query(const char *, const char *, const char *,
72 	    const char *, const u_int8_t *, size_t,
73 	    struct timeval *, struct timeval *);
74 
75 char	*tls_readline(struct tls *, size_t *, size_t *, struct timeval *);
76 
77 u_int constraint_cnt;
78 extern u_int peer_cnt;
79 extern struct imsgbuf *ibuf;		/* priv */
80 extern struct imsgbuf *ibuf_main;	/* chld */
81 
82 struct httpsdate {
83 	char			*tls_addr;
84 	char			*tls_port;
85 	char			*tls_hostname;
86 	char			*tls_path;
87 	char			*tls_request;
88 	struct tls_config	*tls_config;
89 	struct tls		*tls_ctx;
90 	struct tm		 tls_tm;
91 };
92 
93 int
94 constraint_init(struct constraint *cstr)
95 {
96 	cstr->state = STATE_NONE;
97 	cstr->fd = -1;
98 	cstr->last = getmonotime();
99 	cstr->constraint = 0;
100 	cstr->senderrors = 0;
101 
102 	return (constraint_addr_init(cstr));
103 }
104 
105 int
106 constraint_addr_init(struct constraint *cstr)
107 {
108 	struct sockaddr_in	*sa_in;
109 	struct sockaddr_in6	*sa_in6;
110 	struct ntp_addr		*h;
111 
112 	if (cstr->state == STATE_DNS_INPROGRESS)
113 		return (0);
114 
115 	if (cstr->addr_head.a == NULL) {
116 		priv_dns(IMSG_CONSTRAINT_DNS, cstr->addr_head.name, cstr->id);
117 		cstr->state = STATE_DNS_INPROGRESS;
118 		return (0);
119 	}
120 
121 	h = cstr->addr;
122 	switch (h->ss.ss_family) {
123 	case AF_INET:
124 		sa_in = (struct sockaddr_in *)&h->ss;
125 		if (ntohs(sa_in->sin_port) == 0)
126 			sa_in->sin_port = htons(443);
127 		cstr->state = STATE_DNS_DONE;
128 		break;
129 	case AF_INET6:
130 		sa_in6 = (struct sockaddr_in6 *)&h->ss;
131 		if (ntohs(sa_in6->sin6_port) == 0)
132 			sa_in6->sin6_port = htons(443);
133 		cstr->state = STATE_DNS_DONE;
134 		break;
135 	default:
136 		/* XXX king bula sez it? */
137 		fatalx("wrong AF in constraint_addr_init");
138 		/* NOTREACHED */
139 	}
140 
141 	return (1);
142 }
143 
144 int
145 constraint_query(struct constraint *cstr)
146 {
147 	time_t			 now;
148 	struct ntp_addr_msg	 am;
149 	struct iovec		 iov[3];
150 	int			 iov_cnt = 0;
151 
152 	now = getmonotime();
153 
154 	switch (cstr->state) {
155 	case STATE_DNS_DONE:
156 		/* Proceed and query the time */
157 		break;
158 	case STATE_DNS_TEMPFAIL:
159 		/* Retry resolving the address */
160 		constraint_init(cstr);
161 		return (-1);
162 	case STATE_QUERY_SENT:
163 		if (cstr->last + CONSTRAINT_SCAN_TIMEOUT > now) {
164 			/* The caller should expect a reply */
165 			return (0);
166 		}
167 
168 		/* Timeout, just kill the process to reset it. */
169 		imsg_compose(ibuf_main, IMSG_CONSTRAINT_KILL,
170 		    cstr->id, 0, -1, NULL, 0);
171 
172 		cstr->state = STATE_TIMEOUT;
173 		return (-1);
174 	case STATE_INVALID:
175 		if (cstr->last + CONSTRAINT_SCAN_INTERVAL > now) {
176 			/* Nothing to do */
177 			return (-1);
178 		}
179 
180 		/* Reset and retry */
181 		cstr->senderrors = 0;
182 		constraint_close(cstr->id);
183 		break;
184 	case STATE_REPLY_RECEIVED:
185 	default:
186 		/* Nothing to do */
187 		return (-1);
188 	}
189 
190 	cstr->last = now;
191 	cstr->state = STATE_QUERY_SENT;
192 
193 	memset(&am, 0, sizeof(am));
194 	memcpy(&am.a, cstr->addr, sizeof(am.a));
195 
196 	iov[iov_cnt].iov_base = &am;
197 	iov[iov_cnt++].iov_len = sizeof(am);
198 	if (cstr->addr_head.name) {
199 		am.namelen = strlen(cstr->addr_head.name) + 1;
200 		iov[iov_cnt].iov_base = cstr->addr_head.name;
201 		iov[iov_cnt++].iov_len = am.namelen;
202 	}
203 	if (cstr->addr_head.path) {
204 		am.pathlen = strlen(cstr->addr_head.path) + 1;
205 		iov[iov_cnt].iov_base = cstr->addr_head.path;
206 		iov[iov_cnt++].iov_len = am.pathlen;
207 	}
208 
209 	imsg_composev(ibuf_main, IMSG_CONSTRAINT_QUERY,
210 	    cstr->id, 0, -1, iov, iov_cnt);
211 
212 	return (0);
213 }
214 
215 void
216 priv_constraint_msg(u_int32_t id, u_int8_t *data, size_t len, int argc,
217     char **argv)
218 {
219 	struct ntp_addr_msg	 am;
220 	struct ntp_addr		*h;
221 	struct constraint	*cstr;
222 	int			 pipes[2];
223 	int			 rv;
224 
225 	if ((cstr = constraint_byid(id)) != NULL) {
226 		log_warnx("IMSG_CONSTRAINT_QUERY repeated for id %d", id);
227 		return;
228 	}
229 
230 	if (len < sizeof(am)) {
231 		log_warnx("invalid IMSG_CONSTRAINT_QUERY received");
232 		return;
233 	}
234 	memcpy(&am, data, sizeof(am));
235 	if (len != (sizeof(am) + am.namelen + am.pathlen)) {
236 		log_warnx("invalid IMSG_CONSTRAINT_QUERY received");
237 		return;
238 	}
239 	/* Additional imsg data is obtained in the unpriv child */
240 
241 	if ((h = calloc(1, sizeof(*h))) == NULL)
242 		fatal("calloc ntp_addr");
243 	memcpy(h, &am.a, sizeof(*h));
244 	h->next = NULL;
245 
246 	cstr = new_constraint();
247 	cstr->id = id;
248 	cstr->addr = h;
249 	cstr->addr_head.a = h;
250 	constraint_add(cstr);
251 	constraint_cnt++;
252 
253 	if (socketpair(AF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, AF_UNSPEC,
254 	    pipes) == -1)
255 		fatal("%s pipes", __func__);
256 
257 	/* Prepare and send constraint data to child. */
258 	cstr->fd = pipes[0];
259 	imsg_init(&cstr->ibuf, cstr->fd);
260 	if (imsg_compose(&cstr->ibuf, IMSG_CONSTRAINT_QUERY, id, 0, -1,
261 	    data, len) == -1)
262 		fatal("%s: imsg_compose", __func__);
263 	do {
264 		rv = imsg_flush(&cstr->ibuf);
265 	} while (rv == -1 && errno == EAGAIN);
266 	if (rv == -1)
267 		fatal("imsg_flush");
268 
269 	/*
270 	 * Fork child handlers and make sure to do any sensitive work in the
271 	 * the (unprivileged) child.  The parent should not do any parsing,
272 	 * certificate loading etc.
273 	 */
274 	cstr->pid = start_child(CONSTRAINT_PROC_NAME, pipes[1], argc, argv);
275 }
276 
277 void
278 priv_constraint_readquery(struct constraint *cstr, struct ntp_addr_msg *am,
279     uint8_t **data)
280 {
281 	struct ntp_addr		*h;
282 	uint8_t			*dptr;
283 	int			 n;
284 	struct imsg		 imsg;
285 	size_t			 mlen;
286 
287 	/* Read the message our parent left us. */
288 	if (((n = imsg_read(&cstr->ibuf)) == -1 && errno != EAGAIN) || n == 0)
289 		fatal("%s: imsg_read", __func__);
290 	if (((n = imsg_get(&cstr->ibuf, &imsg)) == -1) || n == 0)
291 		fatal("%s: imsg_get", __func__);
292 	if (imsg.hdr.type != IMSG_CONSTRAINT_QUERY)
293 		fatalx("%s: invalid message type", __func__);
294 
295 	/*
296 	 * Copy the message contents just like our father:
297 	 * priv_constraint_msg().
298 	 */
299 	mlen = imsg.hdr.len - IMSG_HEADER_SIZE;
300 	if (mlen < sizeof(*am))
301 		fatalx("%s: mlen < sizeof(*am)", __func__);
302 
303 	memcpy(am, imsg.data, sizeof(*am));
304 	if (mlen != (sizeof(*am) + am->namelen + am->pathlen))
305 		fatalx("%s: mlen < sizeof(*am) + am->namelen + am->pathlen",
306 		    __func__);
307 
308 	if ((h = calloc(1, sizeof(*h))) == NULL ||
309 	    (*data = calloc(1, mlen)) == NULL)
310 		fatal("%s: calloc", __func__);
311 
312 	memcpy(h, &am->a, sizeof(*h));
313 	h->next = NULL;
314 
315 	cstr->id = imsg.hdr.peerid;
316 	cstr->addr = h;
317 	cstr->addr_head.a = h;
318 
319 	dptr = imsg.data;
320 	memcpy(*data, dptr + sizeof(*am), mlen - sizeof(*am));
321 	imsg_free(&imsg);
322 }
323 
324 void
325 priv_constraint_child(const char *pw_dir, uid_t pw_uid, gid_t pw_gid)
326 {
327 	struct constraint	 cstr;
328 	struct ntp_addr_msg	 am;
329 	uint8_t			*data;
330 	static char		 addr[NI_MAXHOST];
331 	struct timeval		 rectv, xmttv;
332 	struct sigaction	 sa;
333 	void			*ctx;
334 	struct iovec		 iov[2];
335 	int			 i, rv;
336 
337 	log_procinit("constraint");
338 
339 	if (setpriority(PRIO_PROCESS, 0, 0) == -1)
340 		log_warn("could not set priority");
341 
342 	/* Init TLS and load CA certs before chroot() */
343 	if (tls_init() == -1)
344 		fatalx("tls_init");
345 	if ((conf->ca = tls_load_file(tls_default_ca_cert_file(),
346 	    &conf->ca_len, NULL)) == NULL)
347 		fatalx("failed to load constraint ca");
348 
349 	if (chroot(pw_dir) == -1)
350 		fatal("chroot");
351 	if (chdir("/") == -1)
352 		fatal("chdir(\"/\")");
353 
354 	if (setgroups(1, &pw_gid) ||
355 	    setresgid(pw_gid, pw_gid, pw_gid) ||
356 	    setresuid(pw_uid, pw_uid, pw_uid))
357 		fatal("can't drop privileges");
358 
359 	/* Reset all signal handlers */
360 	memset(&sa, 0, sizeof(sa));
361 	sigemptyset(&sa.sa_mask);
362 	sa.sa_flags = SA_RESTART;
363 	sa.sa_handler = SIG_DFL;
364 	for (i = 1; i < _NSIG; i++)
365 		sigaction(i, &sa, NULL);
366 
367 	if (pledge("stdio inet", NULL) == -1)
368 		fatal("pledge");
369 
370 	cstr.fd = CONSTRAINT_PASSFD;
371 	imsg_init(&cstr.ibuf, cstr.fd);
372 	priv_constraint_readquery(&cstr, &am, &data);
373 
374 	/*
375 	 * Get the IP address as name and set the process title accordingly.
376 	 * This only converts an address into a string and does not trigger
377 	 * any DNS operation, so it is safe to be called without the dns
378 	 * pledge.
379 	 */
380 	if (getnameinfo((struct sockaddr *)&cstr.addr->ss,
381 	    SA_LEN((struct sockaddr *)&cstr.addr->ss),
382 	    addr, sizeof(addr), NULL, 0,
383 	    NI_NUMERICHOST) != 0)
384 		fatalx("%s getnameinfo", __func__);
385 
386 	log_debug("constraint request to %s", addr);
387 	setproctitle("constraint from %s", addr);
388 	(void)closefrom(CONSTRAINT_PASSFD + 1);
389 
390 	/*
391 	 * Set the close-on-exec flag to prevent leaking the communication
392 	 * channel to any exec'ed child.  In theory this could never happen,
393 	 * constraints don't exec children and pledge() prevents it,
394 	 * but we keep it as a safety belt; especially for portability.
395 	 */
396 	if (fcntl(CONSTRAINT_PASSFD, F_SETFD, FD_CLOEXEC) == -1)
397 		fatal("%s fcntl F_SETFD", __func__);
398 
399 	/* Get remaining data from imsg in the unpriv child */
400 	if (am.namelen) {
401 		if ((cstr.addr_head.name =
402 		    get_string(data, am.namelen)) == NULL)
403 			fatalx("invalid IMSG_CONSTRAINT_QUERY name");
404 		data += am.namelen;
405 	}
406 	if (am.pathlen) {
407 		if ((cstr.addr_head.path =
408 		    get_string(data, am.pathlen)) == NULL)
409 			fatalx("invalid IMSG_CONSTRAINT_QUERY path");
410 	}
411 
412 	/* Run! */
413 	if ((ctx = httpsdate_query(addr,
414 	    CONSTRAINT_PORT, cstr.addr_head.name, cstr.addr_head.path,
415 	    conf->ca, conf->ca_len, &rectv, &xmttv)) == NULL) {
416 		/* Abort with failure but without warning */
417 		exit(1);
418 	}
419 
420 	iov[0].iov_base = &rectv;
421 	iov[0].iov_len = sizeof(rectv);
422 	iov[1].iov_base = &xmttv;
423 	iov[1].iov_len = sizeof(xmttv);
424 	imsg_composev(&cstr.ibuf,
425 	    IMSG_CONSTRAINT_RESULT, 0, 0, -1, iov, 2);
426 	do {
427 		rv = imsg_flush(&cstr.ibuf);
428 	} while (rv == -1 && errno == EAGAIN);
429 
430 	/* Tear down the TLS connection after sending the result */
431 	httpsdate_free(ctx);
432 
433 	exit(0);
434 }
435 
436 void
437 priv_constraint_check_child(pid_t pid, int status)
438 {
439 	struct constraint	*cstr;
440 	int			 fail, sig;
441 	char			*signame;
442 
443 	fail = sig = 0;
444 	if (WIFSIGNALED(status)) {
445 		sig = WTERMSIG(status);
446 	} else if (WIFEXITED(status)) {
447 		if (WEXITSTATUS(status) != 0)
448 			fail = 1;
449 	} else
450 		fatalx("unexpected cause of SIGCHLD");
451 
452 	if ((cstr = constraint_bypid(pid)) != NULL) {
453 		if (sig) {
454 			if (sig != SIGTERM) {
455 				signame = strsignal(sig) ?
456 				    strsignal(sig) : "unknown";
457 				log_warnx("constraint %s; "
458 				    "terminated with signal %d (%s)",
459 				    log_sockaddr((struct sockaddr *)
460 				    &cstr->addr->ss), sig, signame);
461 			}
462 			fail = 1;
463 		}
464 
465 		priv_constraint_close(cstr->fd, fail);
466 	}
467 }
468 
469 void
470 priv_constraint_kill(u_int32_t id)
471 {
472 	struct constraint	*cstr;
473 
474 	if ((cstr = constraint_byid(id)) == NULL) {
475 		log_warnx("IMSG_CONSTRAINT_KILL for invalid id %d", id);
476 		return;
477 	}
478 
479 	kill(cstr->pid, SIGTERM);
480 }
481 
482 struct constraint *
483 constraint_byid(u_int32_t id)
484 {
485 	struct constraint	*cstr;
486 
487 	TAILQ_FOREACH(cstr, &conf->constraints, entry) {
488 		if (cstr->id == id)
489 			return (cstr);
490 	}
491 
492 	return (NULL);
493 }
494 
495 struct constraint *
496 constraint_byfd(int fd)
497 {
498 	struct constraint	*cstr;
499 
500 	TAILQ_FOREACH(cstr, &conf->constraints, entry) {
501 		if (cstr->fd == fd)
502 			return (cstr);
503 	}
504 
505 	return (NULL);
506 }
507 
508 struct constraint *
509 constraint_bypid(pid_t pid)
510 {
511 	struct constraint	*cstr;
512 
513 	TAILQ_FOREACH(cstr, &conf->constraints, entry) {
514 		if (cstr->pid == pid)
515 			return (cstr);
516 	}
517 
518 	return (NULL);
519 }
520 
521 int
522 constraint_close(u_int32_t id)
523 {
524 	struct constraint	*cstr;
525 
526 	if ((cstr = constraint_byid(id)) == NULL) {
527 		log_warn("%s: id %d: not found", __func__, id);
528 		return (0);
529 	}
530 
531 	cstr->last = getmonotime();
532 
533 	if (cstr->addr == NULL || (cstr->addr = cstr->addr->next) == NULL) {
534 		/* Either a pool or all addresses have been tried */
535 		cstr->addr = cstr->addr_head.a;
536 		if (cstr->senderrors)
537 			cstr->state = STATE_INVALID;
538 		else if (cstr->state >= STATE_QUERY_SENT)
539 			cstr->state = STATE_DNS_DONE;
540 
541 		return (1);
542 	}
543 
544 	/* Go on and try the next resolved address for this constraint */
545 	return (constraint_init(cstr));
546 }
547 
548 void
549 priv_constraint_close(int fd, int fail)
550 {
551 	struct constraint	*cstr;
552 	u_int32_t		 id;
553 
554 	if ((cstr = constraint_byfd(fd)) == NULL) {
555 		log_warn("%s: fd %d: not found", __func__, fd);
556 		return;
557 	}
558 
559 	id = cstr->id;
560 	constraint_remove(cstr);
561 	constraint_cnt--;
562 
563 	imsg_compose(ibuf, IMSG_CONSTRAINT_CLOSE, id, 0, -1,
564 	    &fail, sizeof(fail));
565 }
566 
567 void
568 constraint_add(struct constraint *cstr)
569 {
570 	TAILQ_INSERT_TAIL(&conf->constraints, cstr, entry);
571 }
572 
573 void
574 constraint_remove(struct constraint *cstr)
575 {
576 	TAILQ_REMOVE(&conf->constraints, cstr, entry);
577 
578 	msgbuf_clear(&cstr->ibuf.w);
579 	if (cstr->fd != -1)
580 		close(cstr->fd);
581 	free(cstr->addr_head.name);
582 	free(cstr->addr_head.path);
583 	free(cstr->addr);
584 	free(cstr);
585 }
586 
587 void
588 constraint_purge(void)
589 {
590 	struct constraint	*cstr, *ncstr;
591 
592 	TAILQ_FOREACH_SAFE(cstr, &conf->constraints, entry, ncstr)
593 		constraint_remove(cstr);
594 }
595 
596 int
597 priv_constraint_dispatch(struct pollfd *pfd)
598 {
599 	struct imsg		 imsg;
600 	struct constraint	*cstr;
601 	ssize_t			 n;
602 	struct timeval		 tv[2];
603 
604 	if ((cstr = constraint_byfd(pfd->fd)) == NULL)
605 		return (0);
606 
607 	if (!(pfd->revents & POLLIN))
608 		return (0);
609 
610 	if (((n = imsg_read(&cstr->ibuf)) == -1 && errno != EAGAIN) || n == 0) {
611 		priv_constraint_close(pfd->fd, 1);
612 		return (1);
613 	}
614 
615 	for (;;) {
616 		if ((n = imsg_get(&cstr->ibuf, &imsg)) == -1) {
617 			priv_constraint_close(pfd->fd, 1);
618 			return (1);
619 		}
620 		if (n == 0)
621 			break;
622 
623 		switch (imsg.hdr.type) {
624 		case IMSG_CONSTRAINT_RESULT:
625 			 if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(tv))
626 				fatalx("invalid IMSG_CONSTRAINT received");
627 
628 			/* forward imsg to ntp child, don't parse it here */
629 			imsg_compose(ibuf, imsg.hdr.type,
630 			    cstr->id, 0, -1, imsg.data, sizeof(tv));
631 			break;
632 		default:
633 			break;
634 		}
635 		imsg_free(&imsg);
636 	}
637 
638 	return (0);
639 }
640 
641 void
642 constraint_msg_result(u_int32_t id, u_int8_t *data, size_t len)
643 {
644 	struct constraint	*cstr;
645 	struct timeval		 tv[2];
646 	double			 offset;
647 
648 	if ((cstr = constraint_byid(id)) == NULL) {
649 		log_warnx("IMSG_CONSTRAINT_CLOSE with invalid constraint id");
650 		return;
651 	}
652 
653 	if (len != sizeof(tv)) {
654 		log_warnx("invalid IMSG_CONSTRAINT received");
655 		return;
656 	}
657 
658 	memcpy(tv, data, len);
659 
660 	offset = gettime_from_timeval(&tv[0]) -
661 	    gettime_from_timeval(&tv[1]);
662 
663 	log_info("constraint reply from %s: offset %f",
664 	    log_sockaddr((struct sockaddr *)&cstr->addr->ss),
665 	    offset);
666 
667 	cstr->state = STATE_REPLY_RECEIVED;
668 	cstr->last = getmonotime();
669 	cstr->constraint = tv[0].tv_sec;
670 
671 	constraint_update();
672 }
673 
674 void
675 constraint_msg_close(u_int32_t id, u_int8_t *data, size_t len)
676 {
677 	struct constraint	*cstr;
678 	int			 fail;
679 
680 	if ((cstr = constraint_byid(id)) == NULL) {
681 		log_warnx("IMSG_CONSTRAINT_CLOSE with invalid constraint id");
682 		return;
683 	}
684 
685 	if (len != sizeof(int)) {
686 		log_warnx("invalid IMSG_CONSTRAINT_CLOSE received");
687 		return;
688 	}
689 
690 	memcpy(&fail, data, len);
691 
692 	if (fail) {
693 		log_debug("no constraint reply from %s"
694 		    " received in time, next query %ds",
695 		    log_sockaddr((struct sockaddr *)
696 		    &cstr->addr->ss), CONSTRAINT_SCAN_INTERVAL);
697 	}
698 
699 	if (fail || cstr->state < STATE_QUERY_SENT) {
700 		cstr->senderrors++;
701 		constraint_close(cstr->id);
702 	}
703 }
704 
705 void
706 constraint_msg_dns(u_int32_t id, u_int8_t *data, size_t len)
707 {
708 	struct constraint	*cstr, *ncstr = NULL;
709 	u_int8_t		*p;
710 	struct ntp_addr		*h;
711 
712 	if ((cstr = constraint_byid(id)) == NULL) {
713 		log_warnx("IMSG_CONSTRAINT_DNS with invalid constraint id");
714 		return;
715 	}
716 	if (cstr->addr != NULL) {
717 		log_warnx("IMSG_CONSTRAINT_DNS but addr != NULL!");
718 		return;
719 	}
720 	if (len == 0) {
721 		log_debug("%s FAILED", __func__);
722 		cstr->state = STATE_DNS_TEMPFAIL;
723 		return;
724 	}
725 
726 	if ((len % sizeof(struct sockaddr_storage)) != 0)
727 		fatalx("IMSG_CONSTRAINT_DNS len");
728 
729 	p = data;
730 	do {
731 		if ((h = calloc(1, sizeof(*h))) == NULL)
732 			fatal("calloc ntp_addr");
733 		memcpy(&h->ss, p, sizeof(h->ss));
734 		p += sizeof(h->ss);
735 		len -= sizeof(h->ss);
736 
737 		if (ncstr == NULL || cstr->addr_head.pool) {
738 			ncstr = new_constraint();
739 			ncstr->addr = h;
740 			ncstr->addr_head.a = h;
741 			ncstr->addr_head.name = strdup(cstr->addr_head.name);
742 			ncstr->addr_head.path = strdup(cstr->addr_head.path);
743 			if (ncstr->addr_head.name == NULL ||
744 			    ncstr->addr_head.path == NULL)
745 				fatal("calloc name");
746 			ncstr->addr_head.pool = cstr->addr_head.pool;
747 			ncstr->state = STATE_DNS_DONE;
748 			constraint_add(ncstr);
749 			constraint_cnt += constraint_init(ncstr);
750 		} else {
751 			h->next = ncstr->addr;
752 			ncstr->addr = h;
753 			ncstr->addr_head.a = h;
754 		}
755 	} while (len);
756 
757 	constraint_remove(cstr);
758 }
759 
760 int
761 constraint_cmp(const void *a, const void *b)
762 {
763 	time_t at = *(const time_t *)a;
764 	time_t bt = *(const time_t *)b;
765 	return at < bt ? -1 : (at > bt ? 1 : 0);
766 }
767 
768 void
769 constraint_update(void)
770 {
771 	struct constraint *cstr;
772 	int	 cnt, i;
773 	time_t	*sum;
774 	time_t	 now;
775 
776 	now = getmonotime();
777 
778 	cnt = 0;
779 	TAILQ_FOREACH(cstr, &conf->constraints, entry) {
780 		if (cstr->state != STATE_REPLY_RECEIVED)
781 			continue;
782 		cnt++;
783 	}
784 
785 	if ((sum = calloc(cnt, sizeof(time_t))) == NULL)
786 		fatal("calloc");
787 
788 	i = 0;
789 	TAILQ_FOREACH(cstr, &conf->constraints, entry) {
790 		if (cstr->state != STATE_REPLY_RECEIVED)
791 			continue;
792 		sum[i++] = cstr->constraint + (now - cstr->last);
793 	}
794 
795 	qsort(sum, cnt, sizeof(time_t), constraint_cmp);
796 
797 	/* calculate median */
798 	i = cnt / 2;
799 	if (cnt % 2 == 0)
800 		if (sum[i - 1] < sum[i])
801 			i -= 1;
802 
803 	conf->constraint_last = now;
804 	conf->constraint_median = sum[i];
805 
806 	free(sum);
807 }
808 
809 void
810 constraint_reset(void)
811 {
812 	struct constraint *cstr;
813 
814 	TAILQ_FOREACH(cstr, &conf->constraints, entry) {
815 		if (cstr->state == STATE_QUERY_SENT)
816 			continue;
817 		constraint_close(cstr->id);
818 	}
819 	conf->constraint_errors = 0;
820 }
821 
822 int
823 constraint_check(double val)
824 {
825 	struct timeval	tv;
826 	double		constraint;
827 	time_t		now;
828 
829 	if (conf->constraint_median == 0)
830 		return (0);
831 
832 	/* Calculate the constraint with the current offset */
833 	now = getmonotime();
834 	tv.tv_sec = conf->constraint_median + (now - conf->constraint_last);
835 	tv.tv_usec = 0;
836 	constraint = gettime_from_timeval(&tv);
837 
838 	if (((val - constraint) > CONSTRAINT_MARGIN) ||
839 	    ((constraint - val) > CONSTRAINT_MARGIN)) {
840 		/* XXX get new constraint if too many errors happened */
841 		if (conf->constraint_errors++ >
842 		    (CONSTRAINT_ERROR_MARGIN * peer_cnt)) {
843 			constraint_reset();
844 		}
845 
846 		return (-1);
847 	}
848 
849 	return (0);
850 }
851 
852 struct httpsdate *
853 httpsdate_init(const char *addr, const char *port, const char *hostname,
854     const char *path, const u_int8_t *ca, size_t ca_len)
855 {
856 	struct httpsdate	*httpsdate = NULL;
857 
858 	if ((httpsdate = calloc(1, sizeof(*httpsdate))) == NULL)
859 		goto fail;
860 
861 	if (hostname == NULL)
862 		hostname = addr;
863 
864 	if ((httpsdate->tls_addr = strdup(addr)) == NULL ||
865 	    (httpsdate->tls_port = strdup(port)) == NULL ||
866 	    (httpsdate->tls_hostname = strdup(hostname)) == NULL ||
867 	    (httpsdate->tls_path = strdup(path)) == NULL)
868 		goto fail;
869 
870 	if (asprintf(&httpsdate->tls_request,
871 	    "HEAD %s HTTP/1.1\r\nHost: %s\r\nConnection: close\r\n\r\n",
872 	    httpsdate->tls_path, httpsdate->tls_hostname) == -1)
873 		goto fail;
874 
875 	if ((httpsdate->tls_config = tls_config_new()) == NULL)
876 		goto fail;
877 	if (tls_config_set_ca_mem(httpsdate->tls_config, ca, ca_len) == -1)
878 		goto fail;
879 
880 	/*
881 	 * Due to the fact that we're trying to determine a constraint for time
882 	 * we do our own certificate validity checking, since the automatic
883 	 * version is based on our wallclock, which may well be inaccurate...
884 	 */
885 	tls_config_insecure_noverifytime(httpsdate->tls_config);
886 
887 	return (httpsdate);
888 
889  fail:
890 	httpsdate_free(httpsdate);
891 	return (NULL);
892 }
893 
894 void
895 httpsdate_free(void *arg)
896 {
897 	struct httpsdate *httpsdate = arg;
898 	if (httpsdate == NULL)
899 		return;
900 	if (httpsdate->tls_ctx)
901 		tls_close(httpsdate->tls_ctx);
902 	tls_free(httpsdate->tls_ctx);
903 	tls_config_free(httpsdate->tls_config);
904 	free(httpsdate->tls_addr);
905 	free(httpsdate->tls_port);
906 	free(httpsdate->tls_hostname);
907 	free(httpsdate->tls_path);
908 	free(httpsdate->tls_request);
909 	free(httpsdate);
910 }
911 
912 int
913 httpsdate_request(struct httpsdate *httpsdate, struct timeval *when)
914 {
915 	char	 timebuf1[32], timebuf2[32];
916 	size_t	 outlen = 0, maxlength = CONSTRAINT_MAXHEADERLENGTH, len;
917 	char	*line, *p, *buf;
918 	time_t	 httptime, notbefore, notafter;
919 	struct tm *tm;
920 	ssize_t	 ret;
921 
922 	if ((httpsdate->tls_ctx = tls_client()) == NULL)
923 		goto fail;
924 
925 	if (tls_configure(httpsdate->tls_ctx, httpsdate->tls_config) == -1)
926 		goto fail;
927 
928 	/*
929 	 * libtls expects an address string, which can also be a DNS name,
930 	 * but we pass a pre-resolved IP address string in tls_addr so it
931 	 * does not trigger any DNS operation and is safe to be called
932 	 * without the dns pledge.
933 	 */
934 	if (tls_connect_servername(httpsdate->tls_ctx, httpsdate->tls_addr,
935 	    httpsdate->tls_port, httpsdate->tls_hostname) == -1) {
936 		log_debug("tls connect failed: %s (%s): %s",
937 		    httpsdate->tls_addr, httpsdate->tls_hostname,
938 		    tls_error(httpsdate->tls_ctx));
939 		goto fail;
940 	}
941 
942 	buf = httpsdate->tls_request;
943 	len = strlen(httpsdate->tls_request);
944 	while (len > 0) {
945 		ret = tls_write(httpsdate->tls_ctx, buf, len);
946 		if (ret == TLS_WANT_POLLIN || ret == TLS_WANT_POLLOUT)
947 			continue;
948 		if (ret < 0) {
949 			log_warnx("tls write failed: %s (%s): %s",
950 			    httpsdate->tls_addr, httpsdate->tls_hostname,
951 			    tls_error(httpsdate->tls_ctx));
952 			goto fail;
953 		}
954 		buf += ret;
955 		len -= ret;
956 	}
957 
958 	while ((line = tls_readline(httpsdate->tls_ctx, &outlen,
959 	    &maxlength, when)) != NULL) {
960 		line[strcspn(line, "\r\n")] = '\0';
961 
962 		if ((p = strchr(line, ' ')) == NULL || *p == '\0')
963 			goto next;
964 		*p++ = '\0';
965 		if (strcasecmp("Date:", line) != 0)
966 			goto next;
967 
968 		/*
969 		 * Expect the date/time format as IMF-fixdate which is
970 		 * mandated by HTTP/1.1 in the new RFC 7231 and was
971 		 * preferred by RFC 2616.  Other formats would be RFC 850
972 		 * or ANSI C's asctime() - the latter doesn't include
973 		 * the timezone which is required here.
974 		 */
975 		if (strptime(p, IMF_FIXDATE,
976 		    &httpsdate->tls_tm) == NULL) {
977 			log_warnx("unsupported date format");
978 			free(line);
979 			return (-1);
980 		}
981 
982 		free(line);
983 		break;
984  next:
985 		free(line);
986 	}
987 
988 	/*
989 	 * Now manually check the validity of the certificate presented in the
990 	 * TLS handshake, based on the time specified by the server's HTTP Date:
991 	 * header.
992 	 */
993 	notbefore = tls_peer_cert_notbefore(httpsdate->tls_ctx);
994 	notafter = tls_peer_cert_notafter(httpsdate->tls_ctx);
995 	if ((httptime = timegm(&httpsdate->tls_tm)) == -1)
996 		goto fail;
997 	if (httptime <= notbefore) {
998 		if ((tm = gmtime(&notbefore)) == NULL)
999 			goto fail;
1000 		if (strftime(timebuf1, sizeof(timebuf1), X509_DATE, tm) == 0)
1001 			goto fail;
1002 		if (strftime(timebuf2, sizeof(timebuf2), X509_DATE,
1003 		    &httpsdate->tls_tm) == 0)
1004 			goto fail;
1005 		log_warnx("tls certificate not yet valid: %s (%s): "
1006 		    "not before %s, now %s", httpsdate->tls_addr,
1007 		    httpsdate->tls_hostname, timebuf1, timebuf2);
1008 		goto fail;
1009 	}
1010 	if (httptime >= notafter) {
1011 		if ((tm = gmtime(&notafter)) == NULL)
1012 			goto fail;
1013 		if (strftime(timebuf1, sizeof(timebuf1), X509_DATE, tm) == 0)
1014 			goto fail;
1015 		if (strftime(timebuf2, sizeof(timebuf2), X509_DATE,
1016 		    &httpsdate->tls_tm) == 0)
1017 			goto fail;
1018 		log_warnx("tls certificate expired: %s (%s): "
1019 		    "not after %s, now %s", httpsdate->tls_addr,
1020 		    httpsdate->tls_hostname, timebuf1, timebuf2);
1021 		goto fail;
1022 	}
1023 
1024 	return (0);
1025 
1026  fail:
1027 	httpsdate_free(httpsdate);
1028 	return (-1);
1029 }
1030 
1031 void *
1032 httpsdate_query(const char *addr, const char *port, const char *hostname,
1033     const char *path, const u_int8_t *ca, size_t ca_len,
1034     struct timeval *rectv, struct timeval *xmttv)
1035 {
1036 	struct httpsdate	*httpsdate;
1037 	struct timeval		 when;
1038 	time_t			 t;
1039 
1040 	if ((httpsdate = httpsdate_init(addr, port, hostname, path,
1041 	    ca, ca_len)) == NULL)
1042 		return (NULL);
1043 
1044 	if (httpsdate_request(httpsdate, &when) == -1)
1045 		return (NULL);
1046 
1047 	/* Return parsed date as local time */
1048 	t = timegm(&httpsdate->tls_tm);
1049 
1050 	/* Report parsed Date: as "received time" */
1051 	rectv->tv_sec = t;
1052 	rectv->tv_usec = 0;
1053 
1054 	/* And add delay as "transmit time" */
1055 	xmttv->tv_sec = when.tv_sec;
1056 	xmttv->tv_usec = when.tv_usec;
1057 
1058 	return (httpsdate);
1059 }
1060 
1061 /* Based on SSL_readline in ftp/fetch.c */
1062 char *
1063 tls_readline(struct tls *tls, size_t *lenp, size_t *maxlength,
1064     struct timeval *when)
1065 {
1066 	size_t i, len;
1067 	char *buf, *q, c;
1068 	ssize_t ret;
1069 
1070 	len = 128;
1071 	if ((buf = malloc(len)) == NULL)
1072 		fatal("Can't allocate memory for transfer buffer");
1073 	for (i = 0; ; i++) {
1074 		if (i >= len - 1) {
1075 			if ((q = reallocarray(buf, len, 2)) == NULL)
1076 				fatal("Can't expand transfer buffer");
1077 			buf = q;
1078 			len *= 2;
1079 		}
1080  again:
1081 		ret = tls_read(tls, &c, 1);
1082 		if (ret == TLS_WANT_POLLIN || ret == TLS_WANT_POLLOUT)
1083 			goto again;
1084 		if (ret < 0) {
1085 			/* SSL read error, ignore */
1086 			free(buf);
1087 			return (NULL);
1088 		}
1089 
1090 		if (maxlength != NULL && (*maxlength)-- == 0) {
1091 			log_warnx("maximum length exceeded");
1092 			free(buf);
1093 			return (NULL);
1094 		}
1095 
1096 		buf[i] = c;
1097 		if (c == '\n')
1098 			break;
1099 	}
1100 	*lenp = i;
1101 	if (gettimeofday(when, NULL) == -1)
1102 		fatal("gettimeofday");
1103 	return (buf);
1104 }
1105 
1106 char *
1107 get_string(u_int8_t *ptr, size_t len)
1108 {
1109 	size_t	 i;
1110 
1111 	for (i = 0; i < len; i++)
1112 		if (!(isprint(ptr[i]) || isspace(ptr[i])))
1113 			break;
1114 
1115 	return strndup(ptr, i);
1116 }
1117