GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.sbin/ntpd/constraint.c Lines: 0 476 0.0 %
Date: 2017-11-07 Branches: 0 298 0.0 %

Line Branch Exec Source
1
/*	$OpenBSD: constraint.c,v 1.35 2016/12/05 10:41:33 rzalamena 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(CONSTRAINT_CA,
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 flock rpath cpath wpath", 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
	return (*(const time_t *)a - *(const time_t *)b);
761
}
762
763
void
764
constraint_update(void)
765
{
766
	struct constraint *cstr;
767
	int	 cnt, i;
768
	time_t	*sum;
769
	time_t	 now;
770
771
	now = getmonotime();
772
773
	cnt = 0;
774
	TAILQ_FOREACH(cstr, &conf->constraints, entry) {
775
		if (cstr->state != STATE_REPLY_RECEIVED)
776
			continue;
777
		cnt++;
778
	}
779
780
	if ((sum = calloc(cnt, sizeof(time_t))) == NULL)
781
		fatal("calloc");
782
783
	i = 0;
784
	TAILQ_FOREACH(cstr, &conf->constraints, entry) {
785
		if (cstr->state != STATE_REPLY_RECEIVED)
786
			continue;
787
		sum[i++] = cstr->constraint + (now - cstr->last);
788
	}
789
790
	qsort(sum, cnt, sizeof(time_t), constraint_cmp);
791
792
	/* calculate median */
793
	i = cnt / 2;
794
	if (cnt % 2 == 0)
795
		if (sum[i - 1] < sum[i])
796
			i -= 1;
797
798
	conf->constraint_last = now;
799
	conf->constraint_median = sum[i];
800
801
	free(sum);
802
}
803
804
void
805
constraint_reset(void)
806
{
807
	struct constraint *cstr;
808
809
	TAILQ_FOREACH(cstr, &conf->constraints, entry) {
810
		if (cstr->state == STATE_QUERY_SENT)
811
			continue;
812
		constraint_close(cstr->id);
813
	}
814
	conf->constraint_errors = 0;
815
}
816
817
int
818
constraint_check(double val)
819
{
820
	struct timeval	tv;
821
	double		constraint;
822
	time_t		now;
823
824
	if (conf->constraint_median == 0)
825
		return (0);
826
827
	/* Calculate the constraint with the current offset */
828
	now = getmonotime();
829
	tv.tv_sec = conf->constraint_median + (now - conf->constraint_last);
830
	tv.tv_usec = 0;
831
	constraint = gettime_from_timeval(&tv);
832
833
	if (((val - constraint) > CONSTRAINT_MARGIN) ||
834
	    ((constraint - val) > CONSTRAINT_MARGIN)) {
835
		/* XXX get new constraint if too many errors happened */
836
		if (conf->constraint_errors++ >
837
		    (CONSTRAINT_ERROR_MARGIN * peer_cnt)) {
838
			constraint_reset();
839
		}
840
841
		return (-1);
842
	}
843
844
	return (0);
845
}
846
847
struct httpsdate *
848
httpsdate_init(const char *addr, const char *port, const char *hostname,
849
    const char *path, const u_int8_t *ca, size_t ca_len)
850
{
851
	struct httpsdate	*httpsdate = NULL;
852
853
	if ((httpsdate = calloc(1, sizeof(*httpsdate))) == NULL)
854
		goto fail;
855
856
	if (hostname == NULL)
857
		hostname = addr;
858
859
	if ((httpsdate->tls_addr = strdup(addr)) == NULL ||
860
	    (httpsdate->tls_port = strdup(port)) == NULL ||
861
	    (httpsdate->tls_hostname = strdup(hostname)) == NULL ||
862
	    (httpsdate->tls_path = strdup(path)) == NULL)
863
		goto fail;
864
865
	if (asprintf(&httpsdate->tls_request,
866
	    "HEAD %s HTTP/1.1\r\nHost: %s\r\nConnection: close\r\n\r\n",
867
	    httpsdate->tls_path, httpsdate->tls_hostname) == -1)
868
		goto fail;
869
870
	if ((httpsdate->tls_config = tls_config_new()) == NULL)
871
		goto fail;
872
873
	if (tls_config_set_ciphers(httpsdate->tls_config, "all") != 0)
874
		goto fail;
875
876
	if (ca == NULL || ca_len == 0)
877
		tls_config_insecure_noverifycert(httpsdate->tls_config);
878
	else
879
		tls_config_set_ca_mem(httpsdate->tls_config, ca, ca_len);
880
881
	return (httpsdate);
882
883
 fail:
884
	httpsdate_free(httpsdate);
885
	return (NULL);
886
}
887
888
void
889
httpsdate_free(void *arg)
890
{
891
	struct httpsdate *httpsdate = arg;
892
	if (httpsdate == NULL)
893
		return;
894
	if (httpsdate->tls_ctx)
895
		tls_close(httpsdate->tls_ctx);
896
	tls_free(httpsdate->tls_ctx);
897
	tls_config_free(httpsdate->tls_config);
898
	free(httpsdate->tls_addr);
899
	free(httpsdate->tls_port);
900
	free(httpsdate->tls_hostname);
901
	free(httpsdate->tls_path);
902
	free(httpsdate->tls_request);
903
	free(httpsdate);
904
}
905
906
int
907
httpsdate_request(struct httpsdate *httpsdate, struct timeval *when)
908
{
909
	size_t	 outlen = 0, maxlength = CONSTRAINT_MAXHEADERLENGTH, len;
910
	char	*line, *p, *buf;
911
	ssize_t	 ret;
912
913
	if ((httpsdate->tls_ctx = tls_client()) == NULL)
914
		goto fail;
915
916
	if (tls_configure(httpsdate->tls_ctx, httpsdate->tls_config) == -1)
917
		goto fail;
918
919
	/*
920
	 * libtls expects an address string, which can also be a DNS name,
921
	 * but we pass a pre-resolved IP address string in tls_addr so it
922
	 * does not trigger any DNS operation and is safe to be called
923
	 * without the dns pledge.
924
	 */
925
	if (tls_connect_servername(httpsdate->tls_ctx, httpsdate->tls_addr,
926
	    httpsdate->tls_port, httpsdate->tls_hostname) == -1) {
927
		log_debug("tls connect failed: %s (%s): %s",
928
		    httpsdate->tls_addr, httpsdate->tls_hostname,
929
		    tls_error(httpsdate->tls_ctx));
930
		goto fail;
931
	}
932
933
	buf = httpsdate->tls_request;
934
	len = strlen(httpsdate->tls_request);
935
	while (len > 0) {
936
		ret = tls_write(httpsdate->tls_ctx, buf, len);
937
		if (ret == TLS_WANT_POLLIN || ret == TLS_WANT_POLLOUT)
938
			continue;
939
		if (ret < 0) {
940
			log_warnx("tls write failed: %s (%s): %s",
941
			    httpsdate->tls_addr, httpsdate->tls_hostname,
942
			    tls_error(httpsdate->tls_ctx));
943
			goto fail;
944
		}
945
		buf += ret;
946
		len -= ret;
947
	}
948
949
	while ((line = tls_readline(httpsdate->tls_ctx, &outlen,
950
	    &maxlength, when)) != NULL) {
951
		line[strcspn(line, "\r\n")] = '\0';
952
953
		if ((p = strchr(line, ' ')) == NULL || *p == '\0')
954
			goto next;
955
		*p++ = '\0';
956
		if (strcasecmp("Date:", line) != 0)
957
			goto next;
958
959
		/*
960
		 * Expect the date/time format as IMF-fixdate which is
961
		 * mandated by HTTP/1.1 in the new RFC 7231 and was
962
		 * preferred by RFC 2616.  Other formats would be RFC 850
963
		 * or ANSI C's asctime() - the latter doesn't include
964
		 * the timezone which is required here.
965
		 */
966
		if (strptime(p, "%a, %d %h %Y %T GMT",
967
		    &httpsdate->tls_tm) == NULL) {
968
			log_warnx("unsupported date format");
969
			free(line);
970
			return (-1);
971
		}
972
973
		free(line);
974
		break;
975
 next:
976
		free(line);
977
	}
978
979
	return (0);
980
981
 fail:
982
	httpsdate_free(httpsdate);
983
	return (-1);
984
}
985
986
void *
987
httpsdate_query(const char *addr, const char *port, const char *hostname,
988
    const char *path, const u_int8_t *ca, size_t ca_len,
989
    struct timeval *rectv, struct timeval *xmttv)
990
{
991
	struct httpsdate	*httpsdate;
992
	struct timeval		 when;
993
	time_t			 t;
994
995
	if ((httpsdate = httpsdate_init(addr, port, hostname, path,
996
	    ca, ca_len)) == NULL)
997
		return (NULL);
998
999
	if (httpsdate_request(httpsdate, &when) == -1)
1000
		return (NULL);
1001
1002
	/* Return parsed date as local time */
1003
	t = timegm(&httpsdate->tls_tm);
1004
1005
	/* Report parsed Date: as "received time" */
1006
	rectv->tv_sec = t;
1007
	rectv->tv_usec = 0;
1008
1009
	/* And add delay as "transmit time" */
1010
	xmttv->tv_sec = when.tv_sec;
1011
	xmttv->tv_usec = when.tv_usec;
1012
1013
	return (httpsdate);
1014
}
1015
1016
/* Based on SSL_readline in ftp/fetch.c */
1017
char *
1018
tls_readline(struct tls *tls, size_t *lenp, size_t *maxlength,
1019
    struct timeval *when)
1020
{
1021
	size_t i, len;
1022
	char *buf, *q, c;
1023
	ssize_t ret;
1024
1025
	len = 128;
1026
	if ((buf = malloc(len)) == NULL)
1027
		fatal("Can't allocate memory for transfer buffer");
1028
	for (i = 0; ; i++) {
1029
		if (i >= len - 1) {
1030
			if ((q = reallocarray(buf, len, 2)) == NULL)
1031
				fatal("Can't expand transfer buffer");
1032
			buf = q;
1033
			len *= 2;
1034
		}
1035
 again:
1036
		ret = tls_read(tls, &c, 1);
1037
		if (ret == TLS_WANT_POLLIN || ret == TLS_WANT_POLLOUT)
1038
			goto again;
1039
		if (ret < 0) {
1040
			/* SSL read error, ignore */
1041
			free(buf);
1042
			return (NULL);
1043
		}
1044
1045
		if (maxlength != NULL && (*maxlength)-- == 0) {
1046
			log_warnx("maximum length exceeded");
1047
			free(buf);
1048
			return (NULL);
1049
		}
1050
1051
		buf[i] = c;
1052
		if (c == '\n')
1053
			break;
1054
	}
1055
	*lenp = i;
1056
	if (gettimeofday(when, NULL) == -1)
1057
		fatal("gettimeofday");
1058
	return (buf);
1059
}
1060
1061
char *
1062
get_string(u_int8_t *ptr, size_t len)
1063
{
1064
	size_t	 i;
1065
1066
	for (i = 0; i < len; i++)
1067
		if (!(isprint(ptr[i]) || isspace(ptr[i])))
1068
			break;
1069
1070
	return strndup(ptr, i);
1071
}