1 /* $OpenBSD: httpd.c,v 1.70 2020/08/03 11:05:24 benno Exp $ */ 2 3 /* 4 * Copyright (c) 2014 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/types.h> 20 #include <sys/queue.h> 21 #include <sys/socket.h> 22 #include <sys/stat.h> 23 #include <sys/resource.h> 24 25 #include <netinet/in.h> 26 #include <arpa/inet.h> 27 28 #include <stdio.h> 29 #include <stdlib.h> 30 #include <stdarg.h> 31 #include <string.h> 32 #include <signal.h> 33 #include <getopt.h> 34 #include <netdb.h> 35 #include <fnmatch.h> 36 #include <err.h> 37 #include <errno.h> 38 #include <event.h> 39 #include <syslog.h> 40 #include <unistd.h> 41 #include <ctype.h> 42 #include <pwd.h> 43 44 #include "httpd.h" 45 46 #define MAXIMUM(a, b) (((a) > (b)) ? (a) : (b)) 47 48 __dead void usage(void); 49 50 int parent_configure(struct httpd *); 51 void parent_configure_done(struct httpd *); 52 void parent_reload(struct httpd *, unsigned int, const char *); 53 void parent_reopen(struct httpd *); 54 void parent_sig_handler(int, short, void *); 55 void parent_shutdown(struct httpd *); 56 int parent_dispatch_server(int, struct privsep_proc *, 57 struct imsg *); 58 int parent_dispatch_logger(int, struct privsep_proc *, 59 struct imsg *); 60 void parent_tls_ticket_rekey_start(struct server *); 61 void parent_tls_ticket_rekey(int, short, void *); 62 63 struct httpd *httpd_env; 64 65 static struct privsep_proc procs[] = { 66 { "server", PROC_SERVER, parent_dispatch_server, server }, 67 { "logger", PROC_LOGGER, parent_dispatch_logger, logger } 68 }; 69 70 void 71 parent_sig_handler(int sig, short event, void *arg) 72 { 73 struct privsep *ps = arg; 74 75 switch (sig) { 76 case SIGTERM: 77 case SIGINT: 78 parent_shutdown(ps->ps_env); 79 break; 80 case SIGHUP: 81 log_info("%s: reload requested with SIGHUP", __func__); 82 83 /* 84 * This is safe because libevent uses async signal handlers 85 * that run in the event loop and not in signal context. 86 */ 87 parent_reload(ps->ps_env, CONFIG_RELOAD, NULL); 88 break; 89 case SIGPIPE: 90 /* ignore */ 91 break; 92 case SIGUSR1: 93 log_info("%s: reopen requested with SIGUSR1", __func__); 94 95 parent_reopen(ps->ps_env); 96 break; 97 default: 98 fatalx("unexpected signal"); 99 } 100 } 101 102 __dead void 103 usage(void) 104 { 105 extern char *__progname; 106 107 fprintf(stderr, "usage: %s [-dnv] [-D macro=value] [-f file]\n", 108 __progname); 109 exit(1); 110 } 111 112 int 113 main(int argc, char *argv[]) 114 { 115 int c; 116 unsigned int proc; 117 int debug = 0, verbose = 0; 118 uint32_t opts = 0; 119 struct httpd *env; 120 struct privsep *ps; 121 const char *conffile = CONF_FILE; 122 enum privsep_procid proc_id = PROC_PARENT; 123 int proc_instance = 0; 124 const char *errp, *title = NULL; 125 int argc0 = argc; 126 127 while ((c = getopt(argc, argv, "dD:nf:I:P:v")) != -1) { 128 switch (c) { 129 case 'd': 130 debug = 2; 131 break; 132 case 'D': 133 if (cmdline_symset(optarg) < 0) 134 log_warnx("could not parse macro definition %s", 135 optarg); 136 break; 137 case 'n': 138 debug = 2; 139 opts |= HTTPD_OPT_NOACTION; 140 break; 141 case 'f': 142 conffile = optarg; 143 break; 144 case 'v': 145 verbose++; 146 opts |= HTTPD_OPT_VERBOSE; 147 break; 148 case 'P': 149 title = optarg; 150 proc_id = proc_getid(procs, nitems(procs), title); 151 if (proc_id == PROC_MAX) 152 fatalx("invalid process name"); 153 break; 154 case 'I': 155 proc_instance = strtonum(optarg, 0, 156 PROC_MAX_INSTANCES, &errp); 157 if (errp) 158 fatalx("invalid process instance"); 159 break; 160 default: 161 usage(); 162 } 163 } 164 165 /* log to stderr until daemonized */ 166 log_init(debug ? debug : 1, LOG_DAEMON); 167 168 argc -= optind; 169 if (argc > 0) 170 usage(); 171 172 if ((env = calloc(1, sizeof(*env))) == NULL || 173 (ps = calloc(1, sizeof(*ps))) == NULL) 174 exit(1); 175 176 httpd_env = env; 177 env->sc_ps = ps; 178 ps->ps_env = env; 179 TAILQ_INIT(&ps->ps_rcsocks); 180 env->sc_conffile = conffile; 181 env->sc_opts = opts; 182 183 if (parse_config(env->sc_conffile, env) == -1) 184 exit(1); 185 186 if (geteuid()) 187 errx(1, "need root privileges"); 188 189 if ((ps->ps_pw = getpwnam(HTTPD_USER)) == NULL) 190 errx(1, "unknown user %s", HTTPD_USER); 191 192 /* Configure the control socket */ 193 ps->ps_csock.cs_name = NULL; 194 195 log_init(debug, LOG_DAEMON); 196 log_setverbose(verbose); 197 198 if (env->sc_opts & HTTPD_OPT_NOACTION) 199 ps->ps_noaction = 1; 200 201 ps->ps_instances[PROC_SERVER] = env->sc_prefork_server; 202 ps->ps_instance = proc_instance; 203 if (title != NULL) 204 ps->ps_title[proc_id] = title; 205 206 if (env->sc_chroot == NULL) 207 env->sc_chroot = ps->ps_pw->pw_dir; 208 for (proc = 0; proc < nitems(procs); proc++) 209 procs[proc].p_chroot = env->sc_chroot; 210 211 if (env->sc_logdir == NULL) { 212 if (asprintf(&env->sc_logdir, "%s%s", env->sc_chroot, 213 HTTPD_LOGROOT) == -1) 214 errx(1, "malloc failed"); 215 } 216 217 /* only the parent returns */ 218 proc_init(ps, procs, nitems(procs), debug, argc0, argv, proc_id); 219 220 log_procinit("parent"); 221 if (!debug && daemon(1, 0) == -1) 222 err(1, "failed to daemonize"); 223 224 if (ps->ps_noaction == 0) 225 log_info("startup"); 226 227 if (pledge("stdio rpath wpath cpath inet dns sendfd", NULL) == -1) 228 fatal("pledge"); 229 230 event_init(); 231 232 signal_set(&ps->ps_evsigint, SIGINT, parent_sig_handler, ps); 233 signal_set(&ps->ps_evsigterm, SIGTERM, parent_sig_handler, ps); 234 signal_set(&ps->ps_evsighup, SIGHUP, parent_sig_handler, ps); 235 signal_set(&ps->ps_evsigpipe, SIGPIPE, parent_sig_handler, ps); 236 signal_set(&ps->ps_evsigusr1, SIGUSR1, parent_sig_handler, ps); 237 238 signal_add(&ps->ps_evsigint, NULL); 239 signal_add(&ps->ps_evsigterm, NULL); 240 signal_add(&ps->ps_evsighup, NULL); 241 signal_add(&ps->ps_evsigpipe, NULL); 242 signal_add(&ps->ps_evsigusr1, NULL); 243 244 proc_connect(ps); 245 246 if (load_config(env->sc_conffile, env) == -1) { 247 proc_kill(env->sc_ps); 248 exit(1); 249 } 250 251 if (env->sc_opts & HTTPD_OPT_NOACTION) { 252 fprintf(stderr, "configuration OK\n"); 253 proc_kill(env->sc_ps); 254 exit(0); 255 } 256 257 /* initialize the TLS session id to a random key for all procs */ 258 arc4random_buf(env->sc_tls_sid, sizeof(env->sc_tls_sid)); 259 260 if (parent_configure(env) == -1) 261 fatalx("configuration failed"); 262 263 event_dispatch(); 264 265 parent_shutdown(env); 266 /* NOTREACHED */ 267 268 return (0); 269 } 270 271 int 272 parent_configure(struct httpd *env) 273 { 274 int id; 275 struct ctl_flags cf; 276 int ret = -1; 277 struct server *srv; 278 struct media_type *media; 279 struct auth *auth; 280 281 RB_FOREACH(media, mediatypes, env->sc_mediatypes) { 282 if (config_setmedia(env, media) == -1) 283 fatal("send media"); 284 } 285 286 TAILQ_FOREACH(auth, env->sc_auth, auth_entry) { 287 if (config_setauth(env, auth) == -1) 288 fatal("send auth"); 289 } 290 291 /* First send the servers... */ 292 TAILQ_FOREACH(srv, env->sc_servers, srv_entry) { 293 if (srv->srv_conf.flags & SRVFLAG_LOCATION) 294 continue; 295 /* start the rekey of the tls ticket keys */ 296 if (srv->srv_conf.flags & SRVFLAG_TLS && 297 srv->srv_conf.tls_ticket_lifetime) 298 parent_tls_ticket_rekey_start(srv); 299 if (config_setserver(env, srv) == -1) 300 fatal("send server"); 301 } 302 /* ...and now send the locations */ 303 TAILQ_FOREACH(srv, env->sc_servers, srv_entry) { 304 if ((srv->srv_conf.flags & SRVFLAG_LOCATION) == 0) 305 continue; 306 if (config_setserver(env, srv) == -1) 307 fatal("send location"); 308 } 309 310 /* The servers need to reload their config. */ 311 env->sc_reload = env->sc_prefork_server + 1; 312 313 for (id = 0; id < PROC_MAX; id++) { 314 if (id == privsep_process) 315 continue; 316 cf.cf_opts = env->sc_opts; 317 cf.cf_flags = env->sc_flags; 318 memcpy(cf.cf_tls_sid, env->sc_tls_sid, sizeof(cf.cf_tls_sid)); 319 320 proc_compose(env->sc_ps, id, IMSG_CFG_DONE, &cf, sizeof(cf)); 321 } 322 323 ret = 0; 324 325 config_purge(env, CONFIG_ALL & ~CONFIG_SERVERS); 326 return (ret); 327 } 328 329 void 330 parent_reload(struct httpd *env, unsigned int reset, const char *filename) 331 { 332 if (env->sc_reload) { 333 log_debug("%s: already in progress: %d pending", 334 __func__, env->sc_reload); 335 return; 336 } 337 338 /* Switch back to the default config file */ 339 if (filename == NULL || *filename == '\0') 340 filename = env->sc_conffile; 341 342 log_debug("%s: level %d config file %s", __func__, reset, filename); 343 344 config_purge(env, CONFIG_ALL); 345 346 if (reset == CONFIG_RELOAD) { 347 if (load_config(filename, env) == -1) { 348 log_debug("%s: failed to load config file %s", 349 __func__, filename); 350 } 351 352 config_setreset(env, CONFIG_ALL); 353 354 if (parent_configure(env) == -1) { 355 log_debug("%s: failed to commit config from %s", 356 __func__, filename); 357 } 358 } else 359 config_setreset(env, reset); 360 } 361 362 void 363 parent_reopen(struct httpd *env) 364 { 365 proc_compose(env->sc_ps, PROC_LOGGER, IMSG_CTL_REOPEN, NULL, 0); 366 } 367 368 void 369 parent_configure_done(struct httpd *env) 370 { 371 int id; 372 373 if (env->sc_reload == 0) { 374 log_warnx("%s: configuration already finished", __func__); 375 return; 376 } 377 378 env->sc_reload--; 379 if (env->sc_reload == 0) { 380 for (id = 0; id < PROC_MAX; id++) { 381 if (id == privsep_process) 382 continue; 383 384 proc_compose(env->sc_ps, id, IMSG_CTL_START, NULL, 0); 385 } 386 } 387 } 388 389 void 390 parent_shutdown(struct httpd *env) 391 { 392 config_purge(env, CONFIG_ALL); 393 394 proc_kill(env->sc_ps); 395 control_cleanup(&env->sc_ps->ps_csock); 396 if (env->sc_ps->ps_csock.cs_name != NULL) 397 (void)unlink(env->sc_ps->ps_csock.cs_name); 398 399 free(env->sc_ps); 400 free(env); 401 402 log_info("parent terminating, pid %d", getpid()); 403 404 exit(0); 405 } 406 407 int 408 parent_dispatch_server(int fd, struct privsep_proc *p, struct imsg *imsg) 409 { 410 struct privsep *ps = p->p_ps; 411 struct httpd *env = ps->ps_env; 412 413 switch (imsg->hdr.type) { 414 case IMSG_CFG_DONE: 415 parent_configure_done(env); 416 break; 417 default: 418 return (-1); 419 } 420 421 return (0); 422 } 423 424 int 425 parent_dispatch_logger(int fd, struct privsep_proc *p, struct imsg *imsg) 426 { 427 struct privsep *ps = p->p_ps; 428 struct httpd *env = ps->ps_env; 429 unsigned int v; 430 char *str = NULL; 431 432 switch (imsg->hdr.type) { 433 case IMSG_CTL_RESET: 434 IMSG_SIZE_CHECK(imsg, &v); 435 memcpy(&v, imsg->data, sizeof(v)); 436 parent_reload(env, v, NULL); 437 break; 438 case IMSG_CTL_RELOAD: 439 if (IMSG_DATA_SIZE(imsg) > 0) 440 str = get_string(imsg->data, IMSG_DATA_SIZE(imsg)); 441 parent_reload(env, CONFIG_RELOAD, str); 442 free(str); 443 break; 444 case IMSG_CTL_SHUTDOWN: 445 parent_shutdown(env); 446 break; 447 case IMSG_CTL_REOPEN: 448 parent_reopen(env); 449 break; 450 case IMSG_CFG_DONE: 451 parent_configure_done(env); 452 break; 453 case IMSG_LOG_OPEN: 454 if (logger_open_priv(imsg) == -1) 455 fatalx("failed to open log file"); 456 break; 457 default: 458 return (-1); 459 } 460 461 return (0); 462 } 463 464 void 465 parent_tls_ticket_rekey_start(struct server *srv) 466 { 467 struct timeval tv; 468 469 server_generate_ticket_key(&srv->srv_conf); 470 471 evtimer_set(&srv->srv_evt, parent_tls_ticket_rekey, srv); 472 timerclear(&tv); 473 tv.tv_sec = srv->srv_conf.tls_ticket_lifetime / 4; 474 evtimer_add(&srv->srv_evt, &tv); 475 } 476 477 void 478 parent_tls_ticket_rekey(int fd, short events, void *arg) 479 { 480 struct server *srv = arg; 481 struct timeval tv; 482 483 server_generate_ticket_key(&srv->srv_conf); 484 proc_compose_imsg(httpd_env->sc_ps, PROC_SERVER, -1, 485 IMSG_TLSTICKET_REKEY, -1, -1, &srv->srv_conf.tls_ticket_key, 486 sizeof(srv->srv_conf.tls_ticket_key)); 487 explicit_bzero(&srv->srv_conf.tls_ticket_key, 488 sizeof(srv->srv_conf.tls_ticket_key)); 489 490 evtimer_set(&srv->srv_evt, parent_tls_ticket_rekey, srv); 491 timerclear(&tv); 492 tv.tv_sec = srv->srv_conf.tls_ticket_lifetime / 4; 493 evtimer_add(&srv->srv_evt, &tv); 494 } 495 496 /* 497 * Utility functions 498 */ 499 500 void 501 event_again(struct event *ev, int fd, short event, 502 void (*fn)(int, short, void *), 503 struct timeval *start, struct timeval *end, void *arg) 504 { 505 struct timeval tv_next, tv_now, tv; 506 507 getmonotime(&tv_now); 508 memcpy(&tv_next, end, sizeof(tv_next)); 509 timersub(&tv_now, start, &tv_now); 510 timersub(&tv_next, &tv_now, &tv_next); 511 512 memset(&tv, 0, sizeof(tv)); 513 if (timercmp(&tv_next, &tv, >)) 514 memcpy(&tv, &tv_next, sizeof(tv)); 515 516 event_del(ev); 517 event_set(ev, fd, event, fn, arg); 518 event_add(ev, &tv); 519 } 520 521 int 522 expand_string(char *label, size_t len, const char *srch, const char *repl) 523 { 524 char *tmp; 525 char *p, *q; 526 527 if ((tmp = calloc(1, len)) == NULL) { 528 log_debug("%s: calloc", __func__); 529 return (-1); 530 } 531 p = q = label; 532 while ((q = strstr(p, srch)) != NULL) { 533 *q = '\0'; 534 if ((strlcat(tmp, p, len) >= len) || 535 (strlcat(tmp, repl, len) >= len)) { 536 log_debug("%s: string too long", __func__); 537 free(tmp); 538 return (-1); 539 } 540 q += strlen(srch); 541 p = q; 542 } 543 if (strlcat(tmp, p, len) >= len) { 544 log_debug("%s: string too long", __func__); 545 free(tmp); 546 return (-1); 547 } 548 (void)strlcpy(label, tmp, len); /* always fits */ 549 free(tmp); 550 551 return (0); 552 } 553 554 const char * 555 url_decode(char *url) 556 { 557 char *p, *q; 558 char hex[3]; 559 unsigned long x; 560 561 hex[2] = '\0'; 562 p = q = url; 563 564 while (*p != '\0') { 565 switch (*p) { 566 case '%': 567 /* Encoding character is followed by two hex chars */ 568 if (!(isxdigit((unsigned char)p[1]) && 569 isxdigit((unsigned char)p[2]))) 570 return (NULL); 571 572 hex[0] = p[1]; 573 hex[1] = p[2]; 574 575 /* 576 * We don't have to validate "hex" because it is 577 * guaranteed to include two hex chars followed by nul. 578 */ 579 x = strtoul(hex, NULL, 16); 580 *q = (char)x; 581 p += 2; 582 break; 583 default: 584 *q = *p; 585 break; 586 } 587 p++; 588 q++; 589 } 590 *q = '\0'; 591 592 return (url); 593 } 594 595 const char * 596 canonicalize_path(const char *input, char *path, size_t len) 597 { 598 const char *i; 599 char *p, *start, *end; 600 601 /* assuming input starts with '/' and is nul-terminated */ 602 i = input; 603 p = path; 604 605 if (*input != '/' || len < 3) 606 return (NULL); 607 608 start = p; 609 end = p + (len - 1); 610 611 while (*i != '\0') { 612 /* Detect truncation */ 613 if (p >= end) 614 return (NULL); 615 616 /* 1. check for special path elements */ 617 if (i[0] == '/') { 618 if (i[1] == '/') { 619 /* a) skip repeating '//' slashes */ 620 while (i[1] == '/') 621 i++; 622 continue; 623 } else if (i[1] == '.' && i[2] == '.' && 624 (i[3] == '/' || i[3] == '\0')) { 625 /* b) revert '..' to previous directory */ 626 i += 3; 627 while (p > start && *p != '/') 628 p--; 629 *p = '\0'; 630 continue; 631 } else if (i[1] == '.' && 632 (i[2] == '/' || i[2] == '\0')) { 633 /* c) skip unnecessary '.' current dir */ 634 i += 2; 635 continue; 636 } 637 } 638 639 /* 2. copy any other characters */ 640 *p++ = *i; 641 i++; 642 } 643 if (p == start) 644 *p++ = '/'; 645 *p++ = '\0'; 646 647 return (path); 648 } 649 650 size_t 651 path_info(char *path) 652 { 653 char *p, *start, *end, ch; 654 struct stat st; 655 int ret; 656 657 start = path; 658 end = start + strlen(path); 659 660 for (p = end; p > start; p--) { 661 /* Scan every path component from the end and at each '/' */ 662 if (p < end && *p != '/') 663 continue; 664 665 /* Temporarily cut the path component out */ 666 ch = *p; 667 *p = '\0'; 668 ret = stat(path, &st); 669 *p = ch; 670 671 /* Break if the initial path component was found */ 672 if (ret == 0) 673 break; 674 } 675 676 return (p - start); 677 } 678 679 char * 680 url_encode(const char *src) 681 { 682 static char hex[] = "0123456789ABCDEF"; 683 char *dp, *dst; 684 unsigned char c; 685 686 /* We need 3 times the memory if every letter is encoded. */ 687 if ((dst = calloc(3, strlen(src) + 1)) == NULL) 688 return (NULL); 689 690 for (dp = dst; *src != 0; src++) { 691 c = (unsigned char) *src; 692 if (c == ' ' || c == '#' || c == '%' || c == '?' || c == '"' || 693 c == '&' || c == '<' || c <= 0x1f || c >= 0x7f) { 694 *dp++ = '%'; 695 *dp++ = hex[c >> 4]; 696 *dp++ = hex[c & 0x0f]; 697 } else 698 *dp++ = *src; 699 } 700 return (dst); 701 } 702 703 char* 704 escape_html(const char* src) 705 { 706 char *dp, *dst; 707 708 /* We need 5 times the memory if every letter is "&" */ 709 if ((dst = calloc(5, strlen(src) + 1)) == NULL) 710 return NULL; 711 712 for (dp = dst; *src != 0; src++) { 713 if (*src == '<') { 714 *dp++ = '&'; 715 *dp++ = 'l'; 716 *dp++ = 't'; 717 *dp++ = ';'; 718 } else if (*src == '>') { 719 *dp++ = '&'; 720 *dp++ = 'g'; 721 *dp++ = 't'; 722 *dp++ = ';'; 723 } else if (*src == '&') { 724 *dp++ = '&'; 725 *dp++ = 'a'; 726 *dp++ = 'm'; 727 *dp++ = 'p'; 728 *dp++ = ';'; 729 } else 730 *dp++ = *src; 731 } 732 return (dst); 733 } 734 735 void 736 socket_rlimit(int maxfd) 737 { 738 struct rlimit rl; 739 740 if (getrlimit(RLIMIT_NOFILE, &rl) == -1) 741 fatal("%s: failed to get resource limit", __func__); 742 log_debug("%s: max open files %llu", __func__, rl.rlim_max); 743 744 /* 745 * Allow the maximum number of open file descriptors for this 746 * login class (which should be the class "daemon" by default). 747 */ 748 if (maxfd == -1) 749 rl.rlim_cur = rl.rlim_max; 750 else 751 rl.rlim_cur = MAXIMUM(rl.rlim_max, (rlim_t)maxfd); 752 if (setrlimit(RLIMIT_NOFILE, &rl) == -1) 753 fatal("%s: failed to set resource limit", __func__); 754 } 755 756 char * 757 evbuffer_getline(struct evbuffer *evb) 758 { 759 uint8_t *ptr = EVBUFFER_DATA(evb); 760 size_t len = EVBUFFER_LENGTH(evb); 761 char *str; 762 size_t i; 763 764 /* Safe version of evbuffer_readline() */ 765 if ((str = get_string(ptr, len)) == NULL) 766 return (NULL); 767 768 for (i = 0; str[i] != '\0'; i++) { 769 if (str[i] == '\r' || str[i] == '\n') 770 break; 771 } 772 773 if (i == len) { 774 free(str); 775 return (NULL); 776 } 777 778 str[i] = '\0'; 779 780 if ((i + 1) < len) { 781 if (ptr[i] == '\r' && ptr[i + 1] == '\n') 782 i++; 783 } 784 785 evbuffer_drain(evb, ++i); 786 787 return (str); 788 } 789 790 char * 791 get_string(uint8_t *ptr, size_t len) 792 { 793 size_t i; 794 795 for (i = 0; i < len; i++) 796 if (!(isprint((unsigned char)ptr[i]) || 797 isspace((unsigned char)ptr[i]))) 798 break; 799 800 return strndup(ptr, i); 801 } 802 803 void * 804 get_data(uint8_t *ptr, size_t len) 805 { 806 uint8_t *data; 807 808 if ((data = malloc(len)) == NULL) 809 return (NULL); 810 memcpy(data, ptr, len); 811 812 return (data); 813 } 814 815 int 816 sockaddr_cmp(struct sockaddr *a, struct sockaddr *b, int prefixlen) 817 { 818 struct sockaddr_in *a4, *b4; 819 struct sockaddr_in6 *a6, *b6; 820 uint32_t av[4], bv[4], mv[4]; 821 822 if (a->sa_family == AF_UNSPEC || b->sa_family == AF_UNSPEC) 823 return (0); 824 else if (a->sa_family > b->sa_family) 825 return (1); 826 else if (a->sa_family < b->sa_family) 827 return (-1); 828 829 if (prefixlen == -1) 830 memset(&mv, 0xff, sizeof(mv)); 831 832 switch (a->sa_family) { 833 case AF_INET: 834 a4 = (struct sockaddr_in *)a; 835 b4 = (struct sockaddr_in *)b; 836 837 av[0] = a4->sin_addr.s_addr; 838 bv[0] = b4->sin_addr.s_addr; 839 if (prefixlen != -1) 840 mv[0] = prefixlen2mask(prefixlen); 841 842 if ((av[0] & mv[0]) > (bv[0] & mv[0])) 843 return (1); 844 if ((av[0] & mv[0]) < (bv[0] & mv[0])) 845 return (-1); 846 break; 847 case AF_INET6: 848 a6 = (struct sockaddr_in6 *)a; 849 b6 = (struct sockaddr_in6 *)b; 850 851 memcpy(&av, &a6->sin6_addr.s6_addr, 16); 852 memcpy(&bv, &b6->sin6_addr.s6_addr, 16); 853 if (prefixlen != -1) 854 prefixlen2mask6(prefixlen, mv); 855 856 if ((av[3] & mv[3]) > (bv[3] & mv[3])) 857 return (1); 858 if ((av[3] & mv[3]) < (bv[3] & mv[3])) 859 return (-1); 860 if ((av[2] & mv[2]) > (bv[2] & mv[2])) 861 return (1); 862 if ((av[2] & mv[2]) < (bv[2] & mv[2])) 863 return (-1); 864 if ((av[1] & mv[1]) > (bv[1] & mv[1])) 865 return (1); 866 if ((av[1] & mv[1]) < (bv[1] & mv[1])) 867 return (-1); 868 if ((av[0] & mv[0]) > (bv[0] & mv[0])) 869 return (1); 870 if ((av[0] & mv[0]) < (bv[0] & mv[0])) 871 return (-1); 872 break; 873 } 874 875 return (0); 876 } 877 878 uint32_t 879 prefixlen2mask(uint8_t prefixlen) 880 { 881 if (prefixlen == 0) 882 return (0); 883 884 if (prefixlen > 32) 885 prefixlen = 32; 886 887 return (htonl(0xffffffff << (32 - prefixlen))); 888 } 889 890 struct in6_addr * 891 prefixlen2mask6(uint8_t prefixlen, uint32_t *mask) 892 { 893 static struct in6_addr s6; 894 int i; 895 896 if (prefixlen > 128) 897 prefixlen = 128; 898 899 memset(&s6, 0, sizeof(s6)); 900 for (i = 0; i < prefixlen / 8; i++) 901 s6.s6_addr[i] = 0xff; 902 i = prefixlen % 8; 903 if (i) 904 s6.s6_addr[prefixlen / 8] = 0xff00 >> i; 905 906 memcpy(mask, &s6, sizeof(s6)); 907 908 return (&s6); 909 } 910 911 int 912 accept_reserve(int sockfd, struct sockaddr *addr, socklen_t *addrlen, 913 int reserve, volatile int *counter) 914 { 915 int ret; 916 if (getdtablecount() + reserve + 917 *counter >= getdtablesize()) { 918 errno = EMFILE; 919 return (-1); 920 } 921 922 if ((ret = accept4(sockfd, addr, addrlen, SOCK_NONBLOCK)) > -1) { 923 (*counter)++; 924 DPRINTF("%s: inflight incremented, now %d",__func__, *counter); 925 } 926 return (ret); 927 } 928 929 struct kv * 930 kv_add(struct kvtree *keys, char *key, char *value) 931 { 932 struct kv *kv, *oldkv; 933 934 if (key == NULL) 935 return (NULL); 936 if ((kv = calloc(1, sizeof(*kv))) == NULL) 937 return (NULL); 938 if ((kv->kv_key = strdup(key)) == NULL) { 939 free(kv); 940 return (NULL); 941 } 942 if (value != NULL && 943 (kv->kv_value = strdup(value)) == NULL) { 944 free(kv->kv_key); 945 free(kv); 946 return (NULL); 947 } 948 TAILQ_INIT(&kv->kv_children); 949 950 if ((oldkv = RB_INSERT(kvtree, keys, kv)) != NULL) { 951 TAILQ_INSERT_TAIL(&oldkv->kv_children, kv, kv_entry); 952 kv->kv_parent = oldkv; 953 } 954 955 return (kv); 956 } 957 958 int 959 kv_set(struct kv *kv, char *fmt, ...) 960 { 961 va_list ap; 962 char *value = NULL; 963 struct kv *ckv; 964 int ret; 965 966 va_start(ap, fmt); 967 ret = vasprintf(&value, fmt, ap); 968 va_end(ap); 969 if (ret == -1) 970 return (-1); 971 972 /* Remove all children */ 973 while ((ckv = TAILQ_FIRST(&kv->kv_children)) != NULL) { 974 TAILQ_REMOVE(&kv->kv_children, ckv, kv_entry); 975 kv_free(ckv); 976 free(ckv); 977 } 978 979 /* Set the new value */ 980 free(kv->kv_value); 981 kv->kv_value = value; 982 983 return (0); 984 } 985 986 int 987 kv_setkey(struct kv *kv, char *fmt, ...) 988 { 989 va_list ap; 990 char *key = NULL; 991 int ret; 992 993 va_start(ap, fmt); 994 ret = vasprintf(&key, fmt, ap); 995 va_end(ap); 996 if (ret == -1) 997 return (-1); 998 999 free(kv->kv_key); 1000 kv->kv_key = key; 1001 1002 return (0); 1003 } 1004 1005 void 1006 kv_delete(struct kvtree *keys, struct kv *kv) 1007 { 1008 struct kv *ckv; 1009 1010 RB_REMOVE(kvtree, keys, kv); 1011 1012 /* Remove all children */ 1013 while ((ckv = TAILQ_FIRST(&kv->kv_children)) != NULL) { 1014 TAILQ_REMOVE(&kv->kv_children, ckv, kv_entry); 1015 kv_free(ckv); 1016 free(ckv); 1017 } 1018 1019 kv_free(kv); 1020 free(kv); 1021 } 1022 1023 struct kv * 1024 kv_extend(struct kvtree *keys, struct kv *kv, char *value) 1025 { 1026 char *newvalue; 1027 1028 if (kv == NULL) { 1029 return (NULL); 1030 } else if (kv->kv_value != NULL) { 1031 if (asprintf(&newvalue, "%s%s", kv->kv_value, value) == -1) 1032 return (NULL); 1033 1034 free(kv->kv_value); 1035 kv->kv_value = newvalue; 1036 } else if ((kv->kv_value = strdup(value)) == NULL) 1037 return (NULL); 1038 1039 return (kv); 1040 } 1041 1042 void 1043 kv_purge(struct kvtree *keys) 1044 { 1045 struct kv *kv; 1046 1047 while ((kv = RB_MIN(kvtree, keys)) != NULL) 1048 kv_delete(keys, kv); 1049 } 1050 1051 void 1052 kv_free(struct kv *kv) 1053 { 1054 free(kv->kv_key); 1055 kv->kv_key = NULL; 1056 free(kv->kv_value); 1057 kv->kv_value = NULL; 1058 memset(kv, 0, sizeof(*kv)); 1059 } 1060 1061 struct kv * 1062 kv_find(struct kvtree *keys, struct kv *kv) 1063 { 1064 struct kv *match; 1065 const char *key; 1066 1067 if (kv->kv_flags & KV_FLAG_GLOBBING) { 1068 /* Test header key using shell globbing rules */ 1069 key = kv->kv_key == NULL ? "" : kv->kv_key; 1070 RB_FOREACH(match, kvtree, keys) { 1071 if (fnmatch(key, match->kv_key, FNM_CASEFOLD) == 0) 1072 break; 1073 } 1074 } else { 1075 /* Fast tree-based lookup only works without globbing */ 1076 match = RB_FIND(kvtree, keys, kv); 1077 } 1078 1079 return (match); 1080 } 1081 1082 int 1083 kv_cmp(struct kv *a, struct kv *b) 1084 { 1085 return (strcasecmp(a->kv_key, b->kv_key)); 1086 } 1087 1088 RB_GENERATE(kvtree, kv, kv_node, kv_cmp); 1089 1090 struct media_type * 1091 media_add(struct mediatypes *types, struct media_type *media) 1092 { 1093 struct media_type *entry; 1094 1095 if ((entry = RB_FIND(mediatypes, types, media)) != NULL) { 1096 log_debug("%s: duplicated entry for \"%s\"", __func__, 1097 media->media_name); 1098 return (NULL); 1099 } 1100 1101 if ((entry = malloc(sizeof(*media))) == NULL) 1102 return (NULL); 1103 1104 memcpy(entry, media, sizeof(*entry)); 1105 if (media->media_encoding != NULL && 1106 (entry->media_encoding = strdup(media->media_encoding)) == NULL) { 1107 free(entry); 1108 return (NULL); 1109 } 1110 RB_INSERT(mediatypes, types, entry); 1111 1112 return (entry); 1113 } 1114 1115 void 1116 media_delete(struct mediatypes *types, struct media_type *media) 1117 { 1118 RB_REMOVE(mediatypes, types, media); 1119 1120 free(media->media_encoding); 1121 free(media); 1122 } 1123 1124 void 1125 media_purge(struct mediatypes *types) 1126 { 1127 struct media_type *media; 1128 1129 while ((media = RB_MIN(mediatypes, types)) != NULL) 1130 media_delete(types, media); 1131 } 1132 1133 struct media_type * 1134 media_find(struct mediatypes *types, const char *file) 1135 { 1136 struct media_type *match, media; 1137 char *p; 1138 1139 /* Last component of the file name */ 1140 p = strchr(file, '\0'); 1141 while (p > file && p[-1] != '.' && p[-1] != '/') 1142 p--; 1143 if (*p == '\0') 1144 return (NULL); 1145 1146 if (strlcpy(media.media_name, p, 1147 sizeof(media.media_name)) >= 1148 sizeof(media.media_name)) { 1149 return (NULL); 1150 } 1151 1152 /* Find media type by extension name */ 1153 match = RB_FIND(mediatypes, types, &media); 1154 1155 return (match); 1156 } 1157 1158 struct media_type * 1159 media_find_config(struct httpd *env, struct server_config *srv_conf, 1160 const char *file) 1161 { 1162 struct media_type *match; 1163 1164 if ((match = media_find(env->sc_mediatypes, file)) != NULL) 1165 return (match); 1166 else if (srv_conf->flags & SRVFLAG_DEFAULT_TYPE) 1167 return (&srv_conf->default_type); 1168 1169 /* fallback to the global default type */ 1170 return (&env->sc_default_type); 1171 } 1172 1173 int 1174 media_cmp(struct media_type *a, struct media_type *b) 1175 { 1176 return (strcasecmp(a->media_name, b->media_name)); 1177 } 1178 1179 RB_GENERATE(mediatypes, media_type, media_entry, media_cmp); 1180 1181 struct auth * 1182 auth_add(struct serverauth *serverauth, struct auth *auth) 1183 { 1184 struct auth *entry; 1185 1186 TAILQ_FOREACH(entry, serverauth, auth_entry) { 1187 if (strcmp(entry->auth_htpasswd, auth->auth_htpasswd) == 0) 1188 return (entry); 1189 } 1190 1191 if ((entry = calloc(1, sizeof(*entry))) == NULL) 1192 return (NULL); 1193 1194 memcpy(entry, auth, sizeof(*entry)); 1195 1196 TAILQ_INSERT_TAIL(serverauth, entry, auth_entry); 1197 1198 return (entry); 1199 } 1200 1201 struct auth * 1202 auth_byid(struct serverauth *serverauth, uint32_t id) 1203 { 1204 struct auth *auth; 1205 1206 TAILQ_FOREACH(auth, serverauth, auth_entry) { 1207 if (auth->auth_id == id) 1208 return (auth); 1209 } 1210 1211 return (NULL); 1212 } 1213 1214 void 1215 auth_free(struct serverauth *serverauth, struct auth *auth) 1216 { 1217 TAILQ_REMOVE(serverauth, auth, auth_entry); 1218 } 1219 1220 1221 const char * 1222 print_host(struct sockaddr_storage *ss, char *buf, size_t len) 1223 { 1224 if (getnameinfo((struct sockaddr *)ss, ss->ss_len, 1225 buf, len, NULL, 0, NI_NUMERICHOST) != 0) { 1226 buf[0] = '\0'; 1227 return (NULL); 1228 } 1229 return (buf); 1230 } 1231 1232 const char * 1233 printb_flags(const uint32_t v, const char *bits) 1234 { 1235 static char buf[2][BUFSIZ]; 1236 static int idx = 0; 1237 int i, any = 0; 1238 char c, *p, *r; 1239 1240 p = r = buf[++idx % 2]; 1241 memset(p, 0, BUFSIZ); 1242 1243 if (bits) { 1244 bits++; 1245 while ((i = *bits++)) { 1246 if (v & (1 << (i - 1))) { 1247 if (any) { 1248 *p++ = ','; 1249 *p++ = ' '; 1250 } 1251 any = 1; 1252 for (; (c = *bits) > 32; bits++) { 1253 if (c == '_') 1254 *p++ = ' '; 1255 else 1256 *p++ = 1257 tolower((unsigned char)c); 1258 } 1259 } else 1260 for (; *bits > 32; bits++) 1261 ; 1262 } 1263 } 1264 1265 return (r); 1266 } 1267 1268 void 1269 getmonotime(struct timeval *tv) 1270 { 1271 struct timespec ts; 1272 1273 if (clock_gettime(CLOCK_MONOTONIC, &ts)) 1274 fatal("clock_gettime"); 1275 1276 TIMESPEC_TO_TIMEVAL(tv, &ts); 1277 } 1278