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