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