1 /* $OpenBSD: httpd.c,v 1.67 2017/05/28 10:37:26 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), 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 canonicalize_host(const char *host, char *name, size_t len) 556 { 557 struct sockaddr_in sin4; 558 struct sockaddr_in6 sin6; 559 size_t i, j; 560 size_t plen; 561 char c; 562 563 if (len < 2) 564 goto fail; 565 566 /* 567 * Canonicalize an IPv4/6 address 568 */ 569 if (inet_pton(AF_INET, host, &sin4) == 1) 570 return (inet_ntop(AF_INET, &sin4, name, len)); 571 if (inet_pton(AF_INET6, host, &sin6) == 1) 572 return (inet_ntop(AF_INET6, &sin6, name, len)); 573 574 /* 575 * Canonicalize a hostname 576 */ 577 578 /* 1. remove repeated dots and convert upper case to lower case */ 579 plen = strlen(host); 580 memset(name, 0, len); 581 for (i = j = 0; i < plen; i++) { 582 if (j >= (len - 1)) 583 goto fail; 584 c = tolower((unsigned char)host[i]); 585 if ((c == '.') && (j == 0 || name[j - 1] == '.')) 586 continue; 587 name[j++] = c; 588 } 589 590 /* 2. remove trailing dots */ 591 for (i = j; i > 0; i--) { 592 if (name[i - 1] != '.') 593 break; 594 name[i - 1] = '\0'; 595 j--; 596 } 597 if (j <= 0) 598 goto fail; 599 600 return (name); 601 602 fail: 603 errno = EINVAL; 604 return (NULL); 605 } 606 607 const char * 608 url_decode(char *url) 609 { 610 char *p, *q; 611 char hex[3]; 612 unsigned long x; 613 614 hex[2] = '\0'; 615 p = q = url; 616 617 while (*p != '\0') { 618 switch (*p) { 619 case '%': 620 /* Encoding character is followed by two hex chars */ 621 if (!(isxdigit((unsigned char)p[1]) && 622 isxdigit((unsigned char)p[2]))) 623 return (NULL); 624 625 hex[0] = p[1]; 626 hex[1] = p[2]; 627 628 /* 629 * We don't have to validate "hex" because it is 630 * guaranteed to include two hex chars followed by nul. 631 */ 632 x = strtoul(hex, NULL, 16); 633 *q = (char)x; 634 p += 2; 635 break; 636 default: 637 *q = *p; 638 break; 639 } 640 p++; 641 q++; 642 } 643 *q = '\0'; 644 645 return (url); 646 } 647 648 const char * 649 canonicalize_path(const char *input, char *path, size_t len) 650 { 651 const char *i; 652 char *p, *start, *end; 653 654 /* assuming input starts with '/' and is nul-terminated */ 655 i = input; 656 p = path; 657 658 if (*input != '/' || len < 3) 659 return (NULL); 660 661 start = p; 662 end = p + (len - 1); 663 664 while (*i != '\0') { 665 /* Detect truncation */ 666 if (p >= end) 667 return (NULL); 668 669 /* 1. check for special path elements */ 670 if (i[0] == '/') { 671 if (i[1] == '/') { 672 /* a) skip repeating '//' slashes */ 673 while (i[1] == '/') 674 i++; 675 continue; 676 } else if (i[1] == '.' && i[2] == '.' && 677 (i[3] == '/' || i[3] == '\0')) { 678 /* b) revert '..' to previous directory */ 679 i += 3; 680 while (p > start && *p != '/') 681 p--; 682 *p = '\0'; 683 continue; 684 } else if (i[1] == '.' && 685 (i[2] == '/' || i[2] == '\0')) { 686 /* c) skip unnecessary '.' current dir */ 687 i += 2; 688 continue; 689 } 690 } 691 692 /* 2. copy any other characters */ 693 *p++ = *i; 694 i++; 695 } 696 if (p == start) 697 *p++ = '/'; 698 *p++ = '\0'; 699 700 return (path); 701 } 702 703 size_t 704 path_info(char *path) 705 { 706 char *p, *start, *end, ch; 707 struct stat st; 708 int ret; 709 710 start = path; 711 end = start + strlen(path); 712 713 for (p = end; p > start; p--) { 714 /* Scan every path component from the end and at each '/' */ 715 if (p < end && *p != '/') 716 continue; 717 718 /* Temporarily cut the path component out */ 719 ch = *p; 720 *p = '\0'; 721 ret = stat(path, &st); 722 *p = ch; 723 724 /* Break if the initial path component was found */ 725 if (ret == 0) 726 break; 727 } 728 729 return (p - start); 730 } 731 732 char * 733 url_encode(const char *src) 734 { 735 static char hex[] = "0123456789ABCDEF"; 736 char *dp, *dst; 737 unsigned char c; 738 739 /* We need 3 times the memory if every letter is encoded. */ 740 if ((dst = calloc(3, strlen(src) + 1)) == NULL) 741 return (NULL); 742 743 for (dp = dst; *src != 0; src++) { 744 c = (unsigned char) *src; 745 if (c == ' ' || c == '#' || c == '%' || c == '?' || c == '"' || 746 c == '&' || c == '<' || c <= 0x1f || c >= 0x7f) { 747 *dp++ = '%'; 748 *dp++ = hex[c >> 4]; 749 *dp++ = hex[c & 0x0f]; 750 } else 751 *dp++ = *src; 752 } 753 return (dst); 754 } 755 756 char* 757 escape_html(const char* src) 758 { 759 char *dp, *dst; 760 761 /* We need 5 times the memory if every letter is "&" */ 762 if ((dst = calloc(5, strlen(src) + 1)) == NULL) 763 return NULL; 764 765 for (dp = dst; *src != 0; src++) { 766 if (*src == '<') { 767 *dp++ = '&'; 768 *dp++ = 'l'; 769 *dp++ = 't'; 770 *dp++ = ';'; 771 } else if (*src == '>') { 772 *dp++ = '&'; 773 *dp++ = 'g'; 774 *dp++ = 't'; 775 *dp++ = ';'; 776 } else if (*src == '&') { 777 *dp++ = '&'; 778 *dp++ = 'a'; 779 *dp++ = 'm'; 780 *dp++ = 'p'; 781 *dp++ = ';'; 782 } else 783 *dp++ = *src; 784 } 785 return (dst); 786 } 787 788 void 789 socket_rlimit(int maxfd) 790 { 791 struct rlimit rl; 792 793 if (getrlimit(RLIMIT_NOFILE, &rl) == -1) 794 fatal("%s: failed to get resource limit", __func__); 795 log_debug("%s: max open files %llu", __func__, rl.rlim_max); 796 797 /* 798 * Allow the maximum number of open file descriptors for this 799 * login class (which should be the class "daemon" by default). 800 */ 801 if (maxfd == -1) 802 rl.rlim_cur = rl.rlim_max; 803 else 804 rl.rlim_cur = MAXIMUM(rl.rlim_max, (rlim_t)maxfd); 805 if (setrlimit(RLIMIT_NOFILE, &rl) == -1) 806 fatal("%s: failed to set resource limit", __func__); 807 } 808 809 char * 810 evbuffer_getline(struct evbuffer *evb) 811 { 812 uint8_t *ptr = EVBUFFER_DATA(evb); 813 size_t len = EVBUFFER_LENGTH(evb); 814 char *str; 815 size_t i; 816 817 /* Safe version of evbuffer_readline() */ 818 if ((str = get_string(ptr, len)) == NULL) 819 return (NULL); 820 821 for (i = 0; str[i] != '\0'; i++) { 822 if (str[i] == '\r' || str[i] == '\n') 823 break; 824 } 825 826 if (i == len) { 827 free(str); 828 return (NULL); 829 } 830 831 str[i] = '\0'; 832 833 if ((i + 1) < len) { 834 if (ptr[i] == '\r' && ptr[i + 1] == '\n') 835 i++; 836 } 837 838 evbuffer_drain(evb, ++i); 839 840 return (str); 841 } 842 843 char * 844 get_string(uint8_t *ptr, size_t len) 845 { 846 size_t i; 847 848 for (i = 0; i < len; i++) 849 if (!(isprint((unsigned char)ptr[i]) || 850 isspace((unsigned char)ptr[i]))) 851 break; 852 853 return strndup(ptr, i); 854 } 855 856 void * 857 get_data(uint8_t *ptr, size_t len) 858 { 859 uint8_t *data; 860 861 if ((data = malloc(len)) == NULL) 862 return (NULL); 863 memcpy(data, ptr, len); 864 865 return (data); 866 } 867 868 int 869 sockaddr_cmp(struct sockaddr *a, struct sockaddr *b, int prefixlen) 870 { 871 struct sockaddr_in *a4, *b4; 872 struct sockaddr_in6 *a6, *b6; 873 uint32_t av[4], bv[4], mv[4]; 874 875 if (a->sa_family == AF_UNSPEC || b->sa_family == AF_UNSPEC) 876 return (0); 877 else if (a->sa_family > b->sa_family) 878 return (1); 879 else if (a->sa_family < b->sa_family) 880 return (-1); 881 882 if (prefixlen == -1) 883 memset(&mv, 0xff, sizeof(mv)); 884 885 switch (a->sa_family) { 886 case AF_INET: 887 a4 = (struct sockaddr_in *)a; 888 b4 = (struct sockaddr_in *)b; 889 890 av[0] = a4->sin_addr.s_addr; 891 bv[0] = b4->sin_addr.s_addr; 892 if (prefixlen != -1) 893 mv[0] = prefixlen2mask(prefixlen); 894 895 if ((av[0] & mv[0]) > (bv[0] & mv[0])) 896 return (1); 897 if ((av[0] & mv[0]) < (bv[0] & mv[0])) 898 return (-1); 899 break; 900 case AF_INET6: 901 a6 = (struct sockaddr_in6 *)a; 902 b6 = (struct sockaddr_in6 *)b; 903 904 memcpy(&av, &a6->sin6_addr.s6_addr, 16); 905 memcpy(&bv, &b6->sin6_addr.s6_addr, 16); 906 if (prefixlen != -1) 907 prefixlen2mask6(prefixlen, mv); 908 909 if ((av[3] & mv[3]) > (bv[3] & mv[3])) 910 return (1); 911 if ((av[3] & mv[3]) < (bv[3] & mv[3])) 912 return (-1); 913 if ((av[2] & mv[2]) > (bv[2] & mv[2])) 914 return (1); 915 if ((av[2] & mv[2]) < (bv[2] & mv[2])) 916 return (-1); 917 if ((av[1] & mv[1]) > (bv[1] & mv[1])) 918 return (1); 919 if ((av[1] & mv[1]) < (bv[1] & mv[1])) 920 return (-1); 921 if ((av[0] & mv[0]) > (bv[0] & mv[0])) 922 return (1); 923 if ((av[0] & mv[0]) < (bv[0] & mv[0])) 924 return (-1); 925 break; 926 } 927 928 return (0); 929 } 930 931 uint32_t 932 prefixlen2mask(uint8_t prefixlen) 933 { 934 if (prefixlen == 0) 935 return (0); 936 937 if (prefixlen > 32) 938 prefixlen = 32; 939 940 return (htonl(0xffffffff << (32 - prefixlen))); 941 } 942 943 struct in6_addr * 944 prefixlen2mask6(uint8_t prefixlen, uint32_t *mask) 945 { 946 static struct in6_addr s6; 947 int i; 948 949 if (prefixlen > 128) 950 prefixlen = 128; 951 952 memset(&s6, 0, sizeof(s6)); 953 for (i = 0; i < prefixlen / 8; i++) 954 s6.s6_addr[i] = 0xff; 955 i = prefixlen % 8; 956 if (i) 957 s6.s6_addr[prefixlen / 8] = 0xff00 >> i; 958 959 memcpy(mask, &s6, sizeof(s6)); 960 961 return (&s6); 962 } 963 964 int 965 accept_reserve(int sockfd, struct sockaddr *addr, socklen_t *addrlen, 966 int reserve, volatile int *counter) 967 { 968 int ret; 969 if (getdtablecount() + reserve + 970 *counter >= getdtablesize()) { 971 errno = EMFILE; 972 return (-1); 973 } 974 975 if ((ret = accept4(sockfd, addr, addrlen, SOCK_NONBLOCK)) > -1) { 976 (*counter)++; 977 DPRINTF("%s: inflight incremented, now %d",__func__, *counter); 978 } 979 return (ret); 980 } 981 982 struct kv * 983 kv_add(struct kvtree *keys, char *key, char *value) 984 { 985 struct kv *kv, *oldkv; 986 987 if (key == NULL) 988 return (NULL); 989 if ((kv = calloc(1, sizeof(*kv))) == NULL) 990 return (NULL); 991 if ((kv->kv_key = strdup(key)) == NULL) { 992 free(kv); 993 return (NULL); 994 } 995 if (value != NULL && 996 (kv->kv_value = strdup(value)) == NULL) { 997 free(kv->kv_key); 998 free(kv); 999 return (NULL); 1000 } 1001 TAILQ_INIT(&kv->kv_children); 1002 1003 if ((oldkv = RB_INSERT(kvtree, keys, kv)) != NULL) { 1004 TAILQ_INSERT_TAIL(&oldkv->kv_children, kv, kv_entry); 1005 kv->kv_parent = oldkv; 1006 } 1007 1008 return (kv); 1009 } 1010 1011 int 1012 kv_set(struct kv *kv, char *fmt, ...) 1013 { 1014 va_list ap; 1015 char *value = NULL; 1016 struct kv *ckv; 1017 int ret; 1018 1019 va_start(ap, fmt); 1020 ret = vasprintf(&value, fmt, ap); 1021 va_end(ap); 1022 if (ret == -1) 1023 return (-1); 1024 1025 /* Remove all children */ 1026 while ((ckv = TAILQ_FIRST(&kv->kv_children)) != NULL) { 1027 TAILQ_REMOVE(&kv->kv_children, ckv, kv_entry); 1028 kv_free(ckv); 1029 free(ckv); 1030 } 1031 1032 /* Set the new value */ 1033 free(kv->kv_value); 1034 kv->kv_value = value; 1035 1036 return (0); 1037 } 1038 1039 int 1040 kv_setkey(struct kv *kv, char *fmt, ...) 1041 { 1042 va_list ap; 1043 char *key = NULL; 1044 int ret; 1045 1046 va_start(ap, fmt); 1047 ret = vasprintf(&key, fmt, ap); 1048 va_end(ap); 1049 if (ret == -1) 1050 return (-1); 1051 1052 free(kv->kv_key); 1053 kv->kv_key = key; 1054 1055 return (0); 1056 } 1057 1058 void 1059 kv_delete(struct kvtree *keys, struct kv *kv) 1060 { 1061 struct kv *ckv; 1062 1063 RB_REMOVE(kvtree, keys, kv); 1064 1065 /* Remove all children */ 1066 while ((ckv = TAILQ_FIRST(&kv->kv_children)) != NULL) { 1067 TAILQ_REMOVE(&kv->kv_children, ckv, kv_entry); 1068 kv_free(ckv); 1069 free(ckv); 1070 } 1071 1072 kv_free(kv); 1073 free(kv); 1074 } 1075 1076 struct kv * 1077 kv_extend(struct kvtree *keys, struct kv *kv, char *value) 1078 { 1079 char *newvalue; 1080 1081 if (kv == NULL) { 1082 return (NULL); 1083 } else if (kv->kv_value != NULL) { 1084 if (asprintf(&newvalue, "%s%s", kv->kv_value, value) == -1) 1085 return (NULL); 1086 1087 free(kv->kv_value); 1088 kv->kv_value = newvalue; 1089 } else if ((kv->kv_value = strdup(value)) == NULL) 1090 return (NULL); 1091 1092 return (kv); 1093 } 1094 1095 void 1096 kv_purge(struct kvtree *keys) 1097 { 1098 struct kv *kv; 1099 1100 while ((kv = RB_MIN(kvtree, keys)) != NULL) 1101 kv_delete(keys, kv); 1102 } 1103 1104 void 1105 kv_free(struct kv *kv) 1106 { 1107 free(kv->kv_key); 1108 kv->kv_key = NULL; 1109 free(kv->kv_value); 1110 kv->kv_value = NULL; 1111 memset(kv, 0, sizeof(*kv)); 1112 } 1113 1114 struct kv * 1115 kv_inherit(struct kv *dst, struct kv *src) 1116 { 1117 memset(dst, 0, sizeof(*dst)); 1118 memcpy(dst, src, sizeof(*dst)); 1119 TAILQ_INIT(&dst->kv_children); 1120 1121 if (src->kv_key != NULL) { 1122 if ((dst->kv_key = strdup(src->kv_key)) == NULL) { 1123 kv_free(dst); 1124 return (NULL); 1125 } 1126 } 1127 if (src->kv_value != NULL) { 1128 if ((dst->kv_value = strdup(src->kv_value)) == NULL) { 1129 kv_free(dst); 1130 return (NULL); 1131 } 1132 } 1133 1134 return (dst); 1135 } 1136 1137 int 1138 kv_log(struct evbuffer *log, struct kv *kv) 1139 { 1140 char *msg; 1141 1142 if (log == NULL) 1143 return (0); 1144 if (asprintf(&msg, " [%s%s%s]", 1145 kv->kv_key == NULL ? "(unknown)" : kv->kv_key, 1146 kv->kv_value == NULL ? "" : ": ", 1147 kv->kv_value == NULL ? "" : kv->kv_value) == -1) 1148 return (-1); 1149 if (evbuffer_add(log, msg, strlen(msg)) == -1) { 1150 free(msg); 1151 return (-1); 1152 } 1153 free(msg); 1154 1155 return (0); 1156 } 1157 1158 struct kv * 1159 kv_find(struct kvtree *keys, struct kv *kv) 1160 { 1161 struct kv *match; 1162 const char *key; 1163 1164 if (kv->kv_flags & KV_FLAG_GLOBBING) { 1165 /* Test header key using shell globbing rules */ 1166 key = kv->kv_key == NULL ? "" : kv->kv_key; 1167 RB_FOREACH(match, kvtree, keys) { 1168 if (fnmatch(key, match->kv_key, FNM_CASEFOLD) == 0) 1169 break; 1170 } 1171 } else { 1172 /* Fast tree-based lookup only works without globbing */ 1173 match = RB_FIND(kvtree, keys, kv); 1174 } 1175 1176 return (match); 1177 } 1178 1179 int 1180 kv_cmp(struct kv *a, struct kv *b) 1181 { 1182 return (strcasecmp(a->kv_key, b->kv_key)); 1183 } 1184 1185 RB_GENERATE(kvtree, kv, kv_node, kv_cmp); 1186 1187 struct media_type * 1188 media_add(struct mediatypes *types, struct media_type *media) 1189 { 1190 struct media_type *entry; 1191 1192 if ((entry = RB_FIND(mediatypes, types, media)) != NULL) { 1193 log_debug("%s: duplicated entry for \"%s\"", __func__, 1194 media->media_name); 1195 return (NULL); 1196 } 1197 1198 if ((entry = malloc(sizeof(*media))) == NULL) 1199 return (NULL); 1200 1201 memcpy(entry, media, sizeof(*entry)); 1202 if (media->media_encoding != NULL && 1203 (entry->media_encoding = strdup(media->media_encoding)) == NULL) { 1204 free(entry); 1205 return (NULL); 1206 } 1207 RB_INSERT(mediatypes, types, entry); 1208 1209 return (entry); 1210 } 1211 1212 void 1213 media_delete(struct mediatypes *types, struct media_type *media) 1214 { 1215 RB_REMOVE(mediatypes, types, media); 1216 1217 free(media->media_encoding); 1218 free(media); 1219 } 1220 1221 void 1222 media_purge(struct mediatypes *types) 1223 { 1224 struct media_type *media; 1225 1226 while ((media = RB_MIN(mediatypes, types)) != NULL) 1227 media_delete(types, media); 1228 } 1229 1230 struct media_type * 1231 media_find(struct mediatypes *types, const char *file) 1232 { 1233 struct media_type *match, media; 1234 char *p; 1235 1236 /* Last component of the file name */ 1237 p = strchr(file, '\0'); 1238 while (p > file && p[-1] != '.' && p[-1] != '/') 1239 p--; 1240 if (*p == '\0') 1241 return (NULL); 1242 1243 if (strlcpy(media.media_name, p, 1244 sizeof(media.media_name)) >= 1245 sizeof(media.media_name)) { 1246 return (NULL); 1247 } 1248 1249 /* Find media type by extension name */ 1250 match = RB_FIND(mediatypes, types, &media); 1251 1252 return (match); 1253 } 1254 1255 struct media_type * 1256 media_find_config(struct httpd *env, struct server_config *srv_conf, 1257 const char *file) 1258 { 1259 struct media_type *match; 1260 1261 if ((match = media_find(env->sc_mediatypes, file)) != NULL) 1262 return (match); 1263 else if (srv_conf->flags & SRVFLAG_DEFAULT_TYPE) 1264 return (&srv_conf->default_type); 1265 1266 /* fallback to the global default type */ 1267 return (&env->sc_default_type); 1268 } 1269 1270 int 1271 media_cmp(struct media_type *a, struct media_type *b) 1272 { 1273 return (strcasecmp(a->media_name, b->media_name)); 1274 } 1275 1276 RB_GENERATE(mediatypes, media_type, media_entry, media_cmp); 1277 1278 struct auth * 1279 auth_add(struct serverauth *serverauth, struct auth *auth) 1280 { 1281 struct auth *entry; 1282 1283 TAILQ_FOREACH(entry, serverauth, auth_entry) { 1284 if (strcmp(entry->auth_htpasswd, auth->auth_htpasswd) == 0) 1285 return (entry); 1286 } 1287 1288 if ((entry = calloc(1, sizeof(*entry))) == NULL) 1289 return (NULL); 1290 1291 memcpy(entry, auth, sizeof(*entry)); 1292 1293 TAILQ_INSERT_TAIL(serverauth, entry, auth_entry); 1294 1295 return (entry); 1296 } 1297 1298 struct auth * 1299 auth_byid(struct serverauth *serverauth, uint32_t id) 1300 { 1301 struct auth *auth; 1302 1303 TAILQ_FOREACH(auth, serverauth, auth_entry) { 1304 if (auth->auth_id == id) 1305 return (auth); 1306 } 1307 1308 return (NULL); 1309 } 1310 1311 void 1312 auth_free(struct serverauth *serverauth, struct auth *auth) 1313 { 1314 TAILQ_REMOVE(serverauth, auth, auth_entry); 1315 } 1316 1317 1318 const char * 1319 print_host(struct sockaddr_storage *ss, char *buf, size_t len) 1320 { 1321 if (getnameinfo((struct sockaddr *)ss, ss->ss_len, 1322 buf, len, NULL, 0, NI_NUMERICHOST) != 0) { 1323 buf[0] = '\0'; 1324 return (NULL); 1325 } 1326 return (buf); 1327 } 1328 1329 const char * 1330 print_time(struct timeval *a, struct timeval *b, char *buf, size_t len) 1331 { 1332 struct timeval tv; 1333 unsigned long h, sec, min; 1334 1335 timerclear(&tv); 1336 timersub(a, b, &tv); 1337 sec = tv.tv_sec % 60; 1338 min = tv.tv_sec / 60 % 60; 1339 h = tv.tv_sec / 60 / 60; 1340 1341 snprintf(buf, len, "%.2lu:%.2lu:%.2lu", h, min, sec); 1342 return (buf); 1343 } 1344 1345 const char * 1346 printb_flags(const uint32_t v, const char *bits) 1347 { 1348 static char buf[2][BUFSIZ]; 1349 static int idx = 0; 1350 int i, any = 0; 1351 char c, *p, *r; 1352 1353 p = r = buf[++idx % 2]; 1354 memset(p, 0, BUFSIZ); 1355 1356 if (bits) { 1357 bits++; 1358 while ((i = *bits++)) { 1359 if (v & (1 << (i - 1))) { 1360 if (any) { 1361 *p++ = ','; 1362 *p++ = ' '; 1363 } 1364 any = 1; 1365 for (; (c = *bits) > 32; bits++) { 1366 if (c == '_') 1367 *p++ = ' '; 1368 else 1369 *p++ = 1370 tolower((unsigned char)c); 1371 } 1372 } else 1373 for (; *bits > 32; bits++) 1374 ; 1375 } 1376 } 1377 1378 return (r); 1379 } 1380 1381 void 1382 getmonotime(struct timeval *tv) 1383 { 1384 struct timespec ts; 1385 1386 if (clock_gettime(CLOCK_MONOTONIC, &ts)) 1387 fatal("clock_gettime"); 1388 1389 TIMESPEC_TO_TIMEVAL(tv, &ts); 1390 } 1391