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