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