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