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