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