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