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