xref: /openbsd-src/usr.sbin/ntpd/constraint.c (revision fb8aa7497fded39583f40e800732f9c046411717)
1 /*	$OpenBSD: constraint.c,v 1.29 2016/06/01 16:35:58 deraadt 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_child(struct constraint *, struct ntp_addr_msg *,
61 	    u_int8_t *, int[2], const char *, uid_t, gid_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,
214     const char *pw_dir, uid_t pw_uid, gid_t pw_gid)
215 {
216 	struct ntp_addr_msg	 am;
217 	struct ntp_addr		*h;
218 	struct constraint	*cstr;
219 	int			 pipes[2];
220 
221 	if ((cstr = constraint_byid(id)) != NULL) {
222 		log_warnx("IMSG_CONSTRAINT_QUERY repeated for id %d", id);
223 		return;
224 	}
225 
226 	if (len < sizeof(am)) {
227 		log_warnx("invalid IMSG_CONSTRAINT_QUERY received");
228 		return;
229 	}
230 	memcpy(&am, data, sizeof(am));
231 	if (len != (sizeof(am) + am.namelen + am.pathlen)) {
232 		log_warnx("invalid IMSG_CONSTRAINT_QUERY received");
233 		return;
234 	}
235 	/* Additional imsg data is obtained in the unpriv child */
236 
237 	if ((h = calloc(1, sizeof(*h))) == NULL)
238 		fatal("calloc ntp_addr");
239 	memcpy(h, &am.a, sizeof(*h));
240 	h->next = NULL;
241 
242 	cstr = new_constraint();
243 	cstr->id = id;
244 	cstr->addr = h;
245 	cstr->addr_head.a = h;
246 	constraint_add(cstr);
247 	constraint_cnt++;
248 
249 	if (socketpair(AF_UNIX, SOCK_DGRAM, AF_UNSPEC, pipes) == -1)
250 		fatal("%s pipes", __func__);
251 
252 	/*
253 	 * Fork child handlers and make sure to do any sensitive work in the
254 	 * the (unprivileged) child.  The parent should not do any parsing,
255 	 * certificate loading etc.
256 	 */
257 	switch (cstr->pid = fork()) {
258 	case -1:
259 		cstr->senderrors++;
260 		close(pipes[0]);
261 		close(pipes[1]);
262 		return;
263 	case 0:
264 		priv_constraint_child(cstr, &am, data + sizeof(am), pipes,
265 		    pw_dir, pw_uid, pw_gid);
266 
267 		_exit(0);
268 		/* NOTREACHED */
269 	default:
270 		/* Parent */
271 		close(pipes[1]);
272 		cstr->fd = pipes[0];
273 
274 		imsg_init(&cstr->ibuf, cstr->fd);
275 		break;
276 	}
277 }
278 
279 void
280 priv_constraint_child(struct constraint *cstr, struct ntp_addr_msg *am,
281     u_int8_t *data, int pipes[2], const char *pw_dir, uid_t pw_uid, gid_t pw_gid)
282 {
283 	static char		 addr[NI_MAXHOST];
284 	struct timeval		 rectv, xmttv;
285 	struct sigaction	 sa;
286 	void			*ctx;
287 	struct iovec		 iov[2];
288 	int			 i;
289 
290 	log_procinit("constraint");
291 
292 	if (setpriority(PRIO_PROCESS, 0, 0) == -1)
293 		log_warn("could not set priority");
294 
295 	/* Init TLS and load CA certs before chroot() */
296 	if (tls_init() == -1)
297 		fatalx("tls_init");
298 	if ((conf->ca = tls_load_file(CONSTRAINT_CA,
299 	    &conf->ca_len, NULL)) == NULL)
300 		fatalx("failed to load constraint ca");
301 
302 	if (chroot(pw_dir) == -1)
303 		fatal("chroot");
304 	if (chdir("/") == -1)
305 		fatal("chdir(\"/\")");
306 
307 	if (setgroups(1, &pw_gid) ||
308 	    setresgid(pw_gid, pw_gid, pw_gid) ||
309 	    setresuid(pw_uid, pw_uid, pw_uid))
310 		fatal("can't drop privileges");
311 
312 	/* Reset all signal handlers */
313 	memset(&sa, 0, sizeof(sa));
314 	sigemptyset(&sa.sa_mask);
315 	sa.sa_flags = SA_RESTART;
316 	sa.sa_handler = SIG_DFL;
317 	for (i = 1; i < _NSIG; i++)
318 		sigaction(i, &sa, NULL);
319 
320 	if (pledge("stdio inet", NULL) == -1)
321 		fatal("pledge");
322 
323 	/* Get name and set process title */
324 	if (getnameinfo((struct sockaddr *)&cstr->addr->ss,
325 	    SA_LEN((struct sockaddr *)&cstr->addr->ss),
326 	    addr, sizeof(addr), NULL, 0,
327 	    NI_NUMERICHOST) != 0)
328 		fatalx("%s getnameinfo", __func__);
329 
330 	log_debug("constraint request to %s", addr);
331 	setproctitle("constraint from %s", addr);
332 
333 	/* Set file descriptors */
334 	if (dup2(pipes[1], CONSTRAINT_PASSFD) == -1)
335 		fatal("%s dup2 CONSTRAINT_PASSFD", __func__);
336 	if (pipes[0] != CONSTRAINT_PASSFD)
337 		close(pipes[0]);
338 	if (pipes[1] != CONSTRAINT_PASSFD)
339 		close(pipes[1]);
340 	(void)closefrom(CONSTRAINT_PASSFD + 1);
341 
342 	if (fcntl(CONSTRAINT_PASSFD, F_SETFD, FD_CLOEXEC) == -1)
343 		fatal("%s fcntl F_SETFD", __func__);
344 
345 	cstr->fd = CONSTRAINT_PASSFD;
346 	imsg_init(&cstr->ibuf, cstr->fd);
347 
348 	/* Get remaining data from imsg in the unpriv child */
349 	if (am->namelen) {
350 		if ((cstr->addr_head.name =
351 		    get_string(data, am->namelen)) == NULL)
352 			fatalx("invalid IMSG_CONSTRAINT_QUERY name");
353 		data += am->namelen;
354 	}
355 	if (am->pathlen) {
356 		if ((cstr->addr_head.path =
357 		    get_string(data, am->pathlen)) == NULL)
358 			fatalx("invalid IMSG_CONSTRAINT_QUERY path");
359 	}
360 
361 	/* Run! */
362 	if ((ctx = httpsdate_query(addr,
363 	    CONSTRAINT_PORT, cstr->addr_head.name, cstr->addr_head.path,
364 	    conf->ca, conf->ca_len, &rectv, &xmttv)) == NULL) {
365 		/* Abort with failure but without warning */
366 		exit(1);
367 	}
368 
369 	iov[0].iov_base = &rectv;
370 	iov[0].iov_len = sizeof(rectv);
371 	iov[1].iov_base = &xmttv;
372 	iov[1].iov_len = sizeof(xmttv);
373 	imsg_composev(&cstr->ibuf,
374 	    IMSG_CONSTRAINT_RESULT, 0, 0, -1, iov, 2);
375 	imsg_flush(&cstr->ibuf);
376 
377 	/* Tear down the TLS connection after sending the result */
378 	httpsdate_free(ctx);
379 }
380 
381 void
382 priv_constraint_check_child(pid_t pid, int status)
383 {
384 	struct constraint	*cstr;
385 	int			 fail, sig;
386 	char			*signame;
387 
388 	fail = sig = 0;
389 	if (WIFSIGNALED(status)) {
390 		sig = WTERMSIG(status);
391 	} else if (WIFEXITED(status)) {
392 		if (WEXITSTATUS(status) != 0)
393 			fail = 1;
394 	} else
395 		fatalx("unexpected cause of SIGCHLD");
396 
397 	if ((cstr = constraint_bypid(pid)) != NULL) {
398 		if (sig) {
399 			if (sig != SIGTERM) {
400 				signame = strsignal(sig) ?
401 				    strsignal(sig) : "unknown";
402 				log_warnx("constraint %s; "
403 				    "terminated with signal %d (%s)",
404 				    log_sockaddr((struct sockaddr *)
405 				    &cstr->addr->ss), sig, signame);
406 			}
407 			fail = 1;
408 		}
409 
410 		priv_constraint_close(cstr->fd, fail);
411 	}
412 }
413 
414 void
415 priv_constraint_kill(u_int32_t id)
416 {
417 	struct constraint	*cstr;
418 
419 	if ((cstr = constraint_byid(id)) == NULL) {
420 		log_warnx("IMSG_CONSTRAINT_KILL for invalid id %d", id);
421 		return;
422 	}
423 
424 	kill(cstr->pid, SIGTERM);
425 }
426 
427 struct constraint *
428 constraint_byid(u_int32_t id)
429 {
430 	struct constraint	*cstr;
431 
432 	TAILQ_FOREACH(cstr, &conf->constraints, entry) {
433 		if (cstr->id == id)
434 			return (cstr);
435 	}
436 
437 	return (NULL);
438 }
439 
440 struct constraint *
441 constraint_byfd(int fd)
442 {
443 	struct constraint	*cstr;
444 
445 	TAILQ_FOREACH(cstr, &conf->constraints, entry) {
446 		if (cstr->fd == fd)
447 			return (cstr);
448 	}
449 
450 	return (NULL);
451 }
452 
453 struct constraint *
454 constraint_bypid(pid_t pid)
455 {
456 	struct constraint	*cstr;
457 
458 	TAILQ_FOREACH(cstr, &conf->constraints, entry) {
459 		if (cstr->pid == pid)
460 			return (cstr);
461 	}
462 
463 	return (NULL);
464 }
465 
466 int
467 constraint_close(u_int32_t id)
468 {
469 	struct constraint	*cstr;
470 
471 	if ((cstr = constraint_byid(id)) == NULL) {
472 		log_warn("%s: id %d: not found", __func__, id);
473 		return (0);
474 	}
475 
476 	cstr->last = getmonotime();
477 
478 	if (cstr->addr == NULL || (cstr->addr = cstr->addr->next) == NULL) {
479 		/* Either a pool or all addresses have been tried */
480 		cstr->addr = cstr->addr_head.a;
481 		if (cstr->senderrors)
482 			cstr->state = STATE_INVALID;
483 		else if (cstr->state >= STATE_QUERY_SENT)
484 			cstr->state = STATE_DNS_DONE;
485 
486 		return (1);
487 	}
488 
489 	/* Go on and try the next resolved address for this constraint */
490 	return (constraint_init(cstr));
491 }
492 
493 void
494 priv_constraint_close(int fd, int fail)
495 {
496 	struct constraint	*cstr;
497 	u_int32_t		 id;
498 
499 	if ((cstr = constraint_byfd(fd)) == NULL) {
500 		log_warn("%s: fd %d: not found", __func__, fd);
501 		return;
502 	}
503 
504 	id = cstr->id;
505 	constraint_remove(cstr);
506 	constraint_cnt--;
507 
508 	imsg_compose(ibuf, IMSG_CONSTRAINT_CLOSE, id, 0, -1,
509 	    &fail, sizeof(fail));
510 }
511 
512 void
513 constraint_add(struct constraint *cstr)
514 {
515 	TAILQ_INSERT_TAIL(&conf->constraints, cstr, entry);
516 }
517 
518 void
519 constraint_remove(struct constraint *cstr)
520 {
521 	TAILQ_REMOVE(&conf->constraints, cstr, entry);
522 
523 	msgbuf_clear(&cstr->ibuf.w);
524 	if (cstr->fd != -1)
525 		close(cstr->fd);
526 	free(cstr->addr_head.name);
527 	free(cstr->addr_head.path);
528 	free(cstr->addr);
529 	free(cstr);
530 }
531 
532 void
533 constraint_purge(void)
534 {
535 	struct constraint	*cstr, *ncstr;
536 
537 	TAILQ_FOREACH_SAFE(cstr, &conf->constraints, entry, ncstr)
538 		constraint_remove(cstr);
539 }
540 
541 int
542 priv_constraint_dispatch(struct pollfd *pfd)
543 {
544 	struct imsg		 imsg;
545 	struct constraint	*cstr;
546 	ssize_t			 n;
547 	struct timeval		 tv[2];
548 
549 	if ((cstr = constraint_byfd(pfd->fd)) == NULL)
550 		return (0);
551 
552 	if (!(pfd->revents & POLLIN))
553 		return (0);
554 
555 	if (((n = imsg_read(&cstr->ibuf)) == -1 && errno != EAGAIN) || n == 0) {
556 		priv_constraint_close(pfd->fd, 1);
557 		return (1);
558 	}
559 
560 	for (;;) {
561 		if ((n = imsg_get(&cstr->ibuf, &imsg)) == -1) {
562 			priv_constraint_close(pfd->fd, 1);
563 			return (1);
564 		}
565 		if (n == 0)
566 			break;
567 
568 		switch (imsg.hdr.type) {
569 		case IMSG_CONSTRAINT_RESULT:
570 			 if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(tv))
571 				fatalx("invalid IMSG_CONSTRAINT received");
572 
573 			/* forward imsg to ntp child, don't parse it here */
574 			imsg_compose(ibuf, imsg.hdr.type,
575 			    cstr->id, 0, -1, imsg.data, sizeof(tv));
576 			break;
577 		default:
578 			break;
579 		}
580 		imsg_free(&imsg);
581 	}
582 
583 	return (0);
584 }
585 
586 void
587 constraint_msg_result(u_int32_t id, u_int8_t *data, size_t len)
588 {
589 	struct constraint	*cstr;
590 	struct timeval		 tv[2];
591 	double			 offset;
592 
593 	if ((cstr = constraint_byid(id)) == NULL) {
594 		log_warnx("IMSG_CONSTRAINT_CLOSE with invalid constraint id");
595 		return;
596 	}
597 
598 	if (len != sizeof(tv)) {
599 		log_warnx("invalid IMSG_CONSTRAINT received");
600 		return;
601 	}
602 
603 	memcpy(tv, data, len);
604 
605 	offset = gettime_from_timeval(&tv[0]) -
606 	    gettime_from_timeval(&tv[1]);
607 
608 	log_info("constraint reply from %s: offset %f",
609 	    log_sockaddr((struct sockaddr *)&cstr->addr->ss),
610 	    offset);
611 
612 	cstr->state = STATE_REPLY_RECEIVED;
613 	cstr->last = getmonotime();
614 	cstr->constraint = tv[0].tv_sec;
615 
616 	constraint_update();
617 }
618 
619 void
620 constraint_msg_close(u_int32_t id, u_int8_t *data, size_t len)
621 {
622 	struct constraint	*cstr;
623 	int			 fail;
624 
625 	if ((cstr = constraint_byid(id)) == NULL) {
626 		log_warnx("IMSG_CONSTRAINT_CLOSE with invalid constraint id");
627 		return;
628 	}
629 
630 	if (len != sizeof(int)) {
631 		log_warnx("invalid IMSG_CONSTRAINT_CLOSE received");
632 		return;
633 	}
634 
635 	memcpy(&fail, data, len);
636 
637 	if (fail) {
638 		log_debug("no constraint reply from %s"
639 		    " received in time, next query %ds",
640 		    log_sockaddr((struct sockaddr *)
641 		    &cstr->addr->ss), CONSTRAINT_SCAN_INTERVAL);
642 	}
643 
644 	if (fail || cstr->state < STATE_QUERY_SENT) {
645 		cstr->senderrors++;
646 		constraint_close(cstr->id);
647 	}
648 }
649 
650 void
651 constraint_msg_dns(u_int32_t id, u_int8_t *data, size_t len)
652 {
653 	struct constraint	*cstr, *ncstr = NULL;
654 	u_int8_t		*p;
655 	struct ntp_addr		*h;
656 
657 	if ((cstr = constraint_byid(id)) == NULL) {
658 		log_warnx("IMSG_CONSTRAINT_DNS with invalid constraint id");
659 		return;
660 	}
661 	if (cstr->addr != NULL) {
662 		log_warnx("IMSG_CONSTRAINT_DNS but addr != NULL!");
663 		return;
664 	}
665 	if (len == 0) {
666 		log_debug("%s FAILED", __func__);
667 		cstr->state = STATE_DNS_TEMPFAIL;
668 		return;
669 	}
670 
671 	if ((len % sizeof(struct sockaddr_storage)) != 0)
672 		fatalx("IMSG_CONSTRAINT_DNS len");
673 
674 	p = data;
675 	do {
676 		if ((h = calloc(1, sizeof(*h))) == NULL)
677 			fatal("calloc ntp_addr");
678 		memcpy(&h->ss, p, sizeof(h->ss));
679 		p += sizeof(h->ss);
680 		len -= sizeof(h->ss);
681 
682 		if (ncstr == NULL || cstr->addr_head.pool) {
683 			ncstr = new_constraint();
684 			ncstr->addr = h;
685 			ncstr->addr_head.a = h;
686 			ncstr->addr_head.name = strdup(cstr->addr_head.name);
687 			ncstr->addr_head.path = strdup(cstr->addr_head.path);
688 			if (ncstr->addr_head.name == NULL ||
689 			    ncstr->addr_head.path == NULL)
690 				fatal("calloc name");
691 			ncstr->addr_head.pool = cstr->addr_head.pool;
692 			ncstr->state = STATE_DNS_DONE;
693 			constraint_add(ncstr);
694 			constraint_cnt += constraint_init(ncstr);
695 		} else {
696 			h->next = ncstr->addr;
697 			ncstr->addr = h;
698 			ncstr->addr_head.a = h;
699 		}
700 	} while (len);
701 
702 	constraint_remove(cstr);
703 }
704 
705 int
706 constraint_cmp(const void *a, const void *b)
707 {
708 	return (*(const time_t *)a - *(const time_t *)b);
709 }
710 
711 void
712 constraint_update(void)
713 {
714 	struct constraint *cstr;
715 	int	 cnt, i;
716 	time_t	*sum;
717 	time_t	 now;
718 
719 	now = getmonotime();
720 
721 	cnt = 0;
722 	TAILQ_FOREACH(cstr, &conf->constraints, entry) {
723 		if (cstr->state != STATE_REPLY_RECEIVED)
724 			continue;
725 		cnt++;
726 	}
727 
728 	if ((sum = calloc(cnt, sizeof(time_t))) == NULL)
729 		fatal("calloc");
730 
731 	i = 0;
732 	TAILQ_FOREACH(cstr, &conf->constraints, entry) {
733 		if (cstr->state != STATE_REPLY_RECEIVED)
734 			continue;
735 		sum[i++] = cstr->constraint + (now - cstr->last);
736 	}
737 
738 	qsort(sum, cnt, sizeof(time_t), constraint_cmp);
739 
740 	/* calculate median */
741 	i = cnt / 2;
742 	if (cnt % 2 == 0)
743 		if (sum[i - 1] < sum[i])
744 			i -= 1;
745 
746 	conf->constraint_last = now;
747 	conf->constraint_median = sum[i];
748 
749 	free(sum);
750 }
751 
752 void
753 constraint_reset(void)
754 {
755 	struct constraint *cstr;
756 
757 	TAILQ_FOREACH(cstr, &conf->constraints, entry) {
758 		if (cstr->state == STATE_QUERY_SENT)
759 			continue;
760 		constraint_close(cstr->id);
761 	}
762 	conf->constraint_errors = 0;
763 }
764 
765 int
766 constraint_check(double val)
767 {
768 	struct timeval	tv;
769 	double		constraint;
770 	time_t		now;
771 
772 	if (conf->constraint_median == 0)
773 		return (0);
774 
775 	/* Calculate the constraint with the current offset */
776 	now = getmonotime();
777 	tv.tv_sec = conf->constraint_median + (now - conf->constraint_last);
778 	tv.tv_usec = 0;
779 	constraint = gettime_from_timeval(&tv);
780 
781 	if (((val - constraint) > CONSTRAINT_MARGIN) ||
782 	    ((constraint - val) > CONSTRAINT_MARGIN)) {
783 		/* XXX get new constraint if too many errors happened */
784 		if (conf->constraint_errors++ >
785 		    (CONSTRAINT_ERROR_MARGIN * peer_cnt)) {
786 			constraint_reset();
787 		}
788 
789 		return (-1);
790 	}
791 
792 	return (0);
793 }
794 
795 struct httpsdate *
796 httpsdate_init(const char *addr, const char *port, const char *hostname,
797     const char *path, const u_int8_t *ca, size_t ca_len)
798 {
799 	struct httpsdate	*httpsdate = NULL;
800 
801 	if ((httpsdate = calloc(1, sizeof(*httpsdate))) == NULL)
802 		goto fail;
803 
804 	if (hostname == NULL)
805 		hostname = addr;
806 
807 	if ((httpsdate->tls_addr = strdup(addr)) == NULL ||
808 	    (httpsdate->tls_port = strdup(port)) == NULL ||
809 	    (httpsdate->tls_hostname = strdup(hostname)) == NULL ||
810 	    (httpsdate->tls_path = strdup(path)) == NULL)
811 		goto fail;
812 
813 	if (asprintf(&httpsdate->tls_request,
814 	    "HEAD %s HTTP/1.1\r\nHost: %s\r\nConnection: close\r\n\r\n",
815 	    httpsdate->tls_path, httpsdate->tls_hostname) == -1)
816 		goto fail;
817 
818 	if ((httpsdate->tls_config = tls_config_new()) == NULL)
819 		goto fail;
820 
821 	if (tls_config_set_ciphers(httpsdate->tls_config, "compat") != 0)
822 		goto fail;
823 
824 	if (ca == NULL || ca_len == 0)
825 		tls_config_insecure_noverifycert(httpsdate->tls_config);
826 	else
827 		tls_config_set_ca_mem(httpsdate->tls_config, ca, ca_len);
828 
829 	return (httpsdate);
830 
831  fail:
832 	httpsdate_free(httpsdate);
833 	return (NULL);
834 }
835 
836 void
837 httpsdate_free(void *arg)
838 {
839 	struct httpsdate *httpsdate = arg;
840 	if (httpsdate == NULL)
841 		return;
842 	if (httpsdate->tls_ctx)
843 		tls_close(httpsdate->tls_ctx);
844 	tls_free(httpsdate->tls_ctx);
845 	tls_config_free(httpsdate->tls_config);
846 	free(httpsdate->tls_addr);
847 	free(httpsdate->tls_port);
848 	free(httpsdate->tls_hostname);
849 	free(httpsdate->tls_path);
850 	free(httpsdate->tls_request);
851 	free(httpsdate);
852 }
853 
854 int
855 httpsdate_request(struct httpsdate *httpsdate, struct timeval *when)
856 {
857 	size_t	 outlen = 0, maxlength = CONSTRAINT_MAXHEADERLENGTH, len;
858 	char	*line, *p, *buf;
859 	ssize_t	 ret;
860 
861 	if ((httpsdate->tls_ctx = tls_client()) == NULL)
862 		goto fail;
863 
864 	if (tls_configure(httpsdate->tls_ctx, httpsdate->tls_config) == -1)
865 		goto fail;
866 
867 	if (tls_connect_servername(httpsdate->tls_ctx, httpsdate->tls_addr,
868 	    httpsdate->tls_port, httpsdate->tls_hostname) == -1) {
869 		log_debug("tls connect failed: %s (%s): %s",
870 		    httpsdate->tls_addr, httpsdate->tls_hostname,
871 		    tls_error(httpsdate->tls_ctx));
872 		goto fail;
873 	}
874 
875 	buf = httpsdate->tls_request;
876 	len = strlen(httpsdate->tls_request);
877 	while (len > 0) {
878 		ret = tls_write(httpsdate->tls_ctx, buf, len);
879 		if (ret == TLS_WANT_POLLIN || ret == TLS_WANT_POLLOUT)
880 			continue;
881 		if (ret < 0) {
882 			log_warnx("tls write failed: %s (%s): %s",
883 			    httpsdate->tls_addr, httpsdate->tls_hostname,
884 			    tls_error(httpsdate->tls_ctx));
885 			goto fail;
886 		}
887 		buf += ret;
888 		len -= ret;
889 	}
890 
891 	while ((line = tls_readline(httpsdate->tls_ctx, &outlen,
892 	    &maxlength, when)) != NULL) {
893 		line[strcspn(line, "\r\n")] = '\0';
894 
895 		if ((p = strchr(line, ' ')) == NULL || *p == '\0')
896 			goto next;
897 		*p++ = '\0';
898 		if (strcasecmp("Date:", line) != 0)
899 			goto next;
900 
901 		/*
902 		 * Expect the date/time format as IMF-fixdate which is
903 		 * mandated by HTTP/1.1 in the new RFC 7231 and was
904 		 * preferred by RFC 2616.  Other formats would be RFC 850
905 		 * or ANSI C's asctime() - the latter doesn't include
906 		 * the timezone which is required here.
907 		 */
908 		if (strptime(p, "%a, %d %h %Y %T GMT",
909 		    &httpsdate->tls_tm) == NULL) {
910 			log_warnx("unsupported date format");
911 			free(line);
912 			return (-1);
913 		}
914 
915 		free(line);
916 		break;
917  next:
918 		free(line);
919 	}
920 
921 	return (0);
922 
923  fail:
924 	httpsdate_free(httpsdate);
925 	return (-1);
926 }
927 
928 void *
929 httpsdate_query(const char *addr, const char *port, const char *hostname,
930     const char *path, const u_int8_t *ca, size_t ca_len,
931     struct timeval *rectv, struct timeval *xmttv)
932 {
933 	struct httpsdate	*httpsdate;
934 	struct timeval		 when;
935 	time_t			 t;
936 
937 	if ((httpsdate = httpsdate_init(addr, port, hostname, path,
938 	    ca, ca_len)) == NULL)
939 		return (NULL);
940 
941 	if (httpsdate_request(httpsdate, &when) == -1)
942 		return (NULL);
943 
944 	/* Return parsed date as local time */
945 	t = timegm(&httpsdate->tls_tm);
946 
947 	/* Report parsed Date: as "received time" */
948 	rectv->tv_sec = t;
949 	rectv->tv_usec = 0;
950 
951 	/* And add delay as "transmit time" */
952 	xmttv->tv_sec = when.tv_sec;
953 	xmttv->tv_usec = when.tv_usec;
954 
955 	return (httpsdate);
956 }
957 
958 /* Based on SSL_readline in ftp/fetch.c */
959 char *
960 tls_readline(struct tls *tls, size_t *lenp, size_t *maxlength,
961     struct timeval *when)
962 {
963 	size_t i, len;
964 	char *buf, *q, c;
965 	ssize_t ret;
966 
967 	len = 128;
968 	if ((buf = malloc(len)) == NULL)
969 		fatal("Can't allocate memory for transfer buffer");
970 	for (i = 0; ; i++) {
971 		if (i >= len - 1) {
972 			if ((q = reallocarray(buf, len, 2)) == NULL)
973 				fatal("Can't expand transfer buffer");
974 			buf = q;
975 			len *= 2;
976 		}
977  again:
978 		ret = tls_read(tls, &c, 1);
979 		if (ret == TLS_WANT_POLLIN || ret == TLS_WANT_POLLOUT)
980 			goto again;
981 		if (ret < 0) {
982 			/* SSL read error, ignore */
983 			free(buf);
984 			return (NULL);
985 		}
986 
987 		if (maxlength != NULL && (*maxlength)-- == 0) {
988 			log_warnx("maximum length exceeded");
989 			free(buf);
990 			return (NULL);
991 		}
992 
993 		buf[i] = c;
994 		if (c == '\n')
995 			break;
996 	}
997 	*lenp = i;
998 	if (gettimeofday(when, NULL) == -1)
999 		fatal("gettimeofday");
1000 	return (buf);
1001 }
1002 
1003 char *
1004 get_string(u_int8_t *ptr, size_t len)
1005 {
1006 	size_t	 i;
1007 
1008 	for (i = 0; i < len; i++)
1009 		if (!(isprint(ptr[i]) || isspace(ptr[i])))
1010 			break;
1011 
1012 	return strndup(ptr, i);
1013 }
1014