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