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