xref: /openbsd-src/usr.sbin/httpd/httpd.c (revision f2da64fbbbf1b03f09f390ab01267c93dfd77c4c)
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