1 /*
2  * Copyright (c) 2020 Omar Polo <op@omarpolo.com>
3  *
4  * Permission to use, copy, modify, and distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16 
17 #include "gmid.h"
18 
19 #include <sys/stat.h>
20 
21 #include <errno.h>
22 #include <fcntl.h>
23 #include <getopt.h>
24 #include <libgen.h>
25 #include <limits.h>
26 #include <pwd.h>
27 #include <signal.h>
28 #include <string.h>
29 
30 static const char	*opts = "6c:D:d:fH:hnP:p:Vvx:";
31 
32 static struct option longopts[] = {
33 	{"help",	no_argument,		NULL,	'h'},
34 	{"version",	no_argument,		NULL,	'V'},
35 	{NULL,		0,			NULL,	0},
36 };
37 
38 struct fcgi fcgi[FCGI_MAX];
39 
40 struct vhosthead hosts;
41 
42 int sock4, sock6;
43 
44 struct imsgbuf logibuf, exibuf, servibuf[PROC_MAX];
45 
46 const char *config_path, *certs_dir, *hostname, *pidfile, *cgi;
47 
48 struct conf conf;
49 
50 struct tls_config *tlsconf;
51 struct tls *ctx;
52 
53 static void
dummy_handler(int signo)54 dummy_handler(int signo)
55 {
56 	return;
57 }
58 
59 /* wrapper around dirname(3).  dn must be PATH_MAX+1 at least. */
60 static void
pdirname(const char * path,char * dn)61 pdirname(const char *path, char *dn)
62 {
63 	char	 p[PATH_MAX+1];
64 	char	*t;
65 
66 	strlcpy(p, path, sizeof(p));
67 	t = dirname(p);
68 	memmove(dn, t, strlen(t)+1);
69 }
70 
71 static void
mkdirs(const char * path,mode_t mode)72 mkdirs(const char *path, mode_t mode)
73 {
74 	char	dname[PATH_MAX+1];
75 
76 	pdirname(path, dname);
77 	if (!strcmp(dname, "/"))
78 		return;
79 	mkdirs(dname, mode);
80 	if (mkdir(path, mode) != 0 && errno != EEXIST)
81 		fatal("can't mkdir %s: %s", path, strerror(errno));
82 }
83 
84 /* $XDG_DATA_HOME/gmid */
85 char *
data_dir(void)86 data_dir(void)
87 {
88 	const char *home, *xdg;
89 	char *t;
90 
91 	if ((xdg = getenv("XDG_DATA_HOME")) == NULL) {
92 		if ((home = getenv("HOME")) == NULL)
93 			errx(1, "XDG_DATA_HOME and HOME both empty");
94 		if (asprintf(&t, "%s/.local/share/gmid", home) == -1)
95 			err(1, "asprintf");
96 	} else {
97 		if (asprintf(&t, "%s/gmid", xdg) == -1)
98 			err(1, "asprintf");
99 	}
100 
101 	mkdirs(t, 0755);
102 	return t;
103 }
104 
105 void
load_local_cert(const char * hostname,const char * dir)106 load_local_cert(const char *hostname, const char *dir)
107 {
108 	char *cert, *key;
109 	struct vhost *h;
110 
111 	if (asprintf(&cert, "%s/%s.cert.pem", dir, hostname) == -1)
112 		errx(1, "asprintf");
113 	if (asprintf(&key, "%s/%s.key.pem", dir, hostname) == -1)
114 		errx(1, "asprintf");
115 
116 	if (access(cert, R_OK) == -1 || access(key, R_OK) == -1)
117 		gen_certificate(hostname, cert, key);
118 
119 	h = TAILQ_FIRST(&hosts);
120 	h->cert = cert;
121 	h->key = key;
122 	h->domain = hostname;
123 }
124 
125 void
load_vhosts(void)126 load_vhosts(void)
127 {
128 	struct vhost	*h;
129 	struct location	*l;
130 
131 	TAILQ_FOREACH(h, &hosts, vhosts) {
132 		TAILQ_FOREACH(l, &h->locations, locations) {
133 			if (l->dir == NULL)
134 				continue;
135 			if ((l->dirfd = open(l->dir, O_RDONLY | O_DIRECTORY)) == -1)
136 				fatal("open %s for domain %s", l->dir, h->domain);
137 		}
138 	}
139 }
140 
141 int
make_socket(int port,int family)142 make_socket(int port, int family)
143 {
144 	int sock, v;
145 	struct sockaddr_in addr4;
146 	struct sockaddr_in6 addr6;
147 	struct sockaddr *addr;
148 	socklen_t len;
149 
150         switch (family) {
151 	case AF_INET:
152 		bzero(&addr4, sizeof(addr4));
153 		addr4.sin_family = family;
154 		addr4.sin_port = htons(port);
155 		addr4.sin_addr.s_addr = INADDR_ANY;
156 		addr = (struct sockaddr*)&addr4;
157 		len = sizeof(addr4);
158 		break;
159 
160 	case AF_INET6:
161 		bzero(&addr6, sizeof(addr6));
162 		addr6.sin6_family = AF_INET6;
163 		addr6.sin6_port = htons(port);
164 		addr6.sin6_addr = in6addr_any;
165 		addr = (struct sockaddr*)&addr6;
166 		len = sizeof(addr6);
167 		break;
168 
169 	default:
170 		/* unreachable */
171 		abort();
172 	}
173 
174 	if ((sock = socket(family, SOCK_STREAM, 0)) == -1)
175 		fatal("socket: %s", strerror(errno));
176 
177 	v = 1;
178 	if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &v, sizeof(v)) == -1)
179 		fatal("setsockopt(SO_REUSEADDR): %s", strerror(errno));
180 
181 	v = 1;
182 	if (setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, &v, sizeof(v)) == -1)
183 		fatal("setsockopt(SO_REUSEPORT): %s", strerror(errno));
184 
185 	mark_nonblock(sock);
186 
187 	if (bind(sock, addr, len) == -1)
188 		fatal("bind: %s", strerror(errno));
189 
190 	if (listen(sock, 16) == -1)
191 		fatal("listen: %s", strerror(errno));
192 
193 	return sock;
194 }
195 
196 void
setup_tls(void)197 setup_tls(void)
198 {
199 	struct vhost *h;
200 
201 	if ((tlsconf = tls_config_new()) == NULL)
202 		fatal("tls_config_new");
203 
204 	/* optionally accept client certs, but don't try to verify them */
205 	tls_config_verify_client_optional(tlsconf);
206 	tls_config_insecure_noverifycert(tlsconf);
207 
208 	if (tls_config_set_protocols(tlsconf, conf.protos) == -1)
209 		fatal("tls_config_set_protocols");
210 
211 	if ((ctx = tls_server()) == NULL)
212 		fatal("tls_server failure");
213 
214 	h = TAILQ_FIRST(&hosts);
215 
216 	/* we need to set something, then we can add how many key we want */
217 	if (tls_config_set_keypair_file(tlsconf, h->cert, h->key))
218 		fatal("tls_config_set_keypair_file failed for (%s, %s)",
219 		    h->cert, h->key);
220 
221 	while ((h = TAILQ_NEXT(h, vhosts)) != NULL) {
222 		if (tls_config_add_keypair_file(tlsconf, h->cert, h->key) == -1)
223 			fatal("failed to load the keypair (%s, %s)",
224 			    h->cert, h->key);
225 	}
226 
227 	if (tls_configure(ctx, tlsconf) == -1)
228 		fatal("tls_configure: %s", tls_error(ctx));
229 }
230 
231 static int
listener_main(struct imsgbuf * ibuf)232 listener_main(struct imsgbuf *ibuf)
233 {
234 	drop_priv();
235 	load_default_mime(&conf.mime);
236 	load_vhosts();
237 	loop(ctx, sock4, sock6, ibuf);
238 	return 0;
239 }
240 
241 void
init_config(void)242 init_config(void)
243 {
244 	TAILQ_INIT(&hosts);
245 
246 	conf.port = 1965;
247 	conf.ipv6 = 0;
248 	conf.protos = TLS_PROTOCOL_TLSv1_2 | TLS_PROTOCOL_TLSv1_3;
249 
250 	init_mime(&conf.mime);
251 
252 	conf.chroot = NULL;
253 	conf.user = NULL;
254 
255 	conf.prefork = 3;
256 }
257 
258 void
free_config(void)259 free_config(void)
260 {
261 	struct vhost *h, *th;
262 	struct location *l, *tl;
263 	struct envlist *e, *te;
264 	struct alist *a, *ta;
265 	int v, i;
266 
267 	v = conf.verbose;
268 
269 	free(conf.chroot);
270 	free(conf.user);
271 	memset(&conf, 0, sizeof(conf));
272 
273 	conf.verbose = v;
274 
275 	TAILQ_FOREACH_SAFE(h, &hosts, vhosts, th) {
276 		TAILQ_FOREACH_SAFE(l, &h->locations, locations, tl) {
277 			TAILQ_REMOVE(&h->locations, l, locations);
278 
279 			free((char*)l->match);
280 			free((char*)l->lang);
281 			free((char*)l->default_mime);
282 			free((char*)l->index);
283 			free((char*)l->block_fmt);
284 			free((char*)l->dir);
285 
286 			if (l->dirfd != -1)
287 				close(l->dirfd);
288 
289 			free(l);
290 		}
291 
292 		TAILQ_FOREACH_SAFE(e, &h->env, envs, te) {
293 			TAILQ_REMOVE(&h->env, e, envs);
294 
295 			free(e->name);
296 			free(e->value);
297 			free(e);
298 		}
299 
300 		TAILQ_FOREACH_SAFE(e, &h->params, envs, te) {
301 			TAILQ_REMOVE(&h->params, e, envs);
302 
303 			free(e->name);
304 			free(e->value);
305 			free(e);
306 		}
307 
308 		TAILQ_FOREACH_SAFE(a, &h->aliases, aliases, ta) {
309 			TAILQ_REMOVE(&h->aliases, a, aliases);
310 
311 			free(a->alias);
312 			free(a);
313 		}
314 
315 		free((char*)h->domain);
316 		free((char*)h->cert);
317 		free((char*)h->key);
318 		free((char*)h->cgi);
319 		free((char*)h->entrypoint);
320 
321 		TAILQ_REMOVE(&hosts, h, vhosts);
322 		free(h);
323 	}
324 
325 	for (i = 0; i < FCGI_MAX; ++i) {
326 		if (fcgi[i].path == NULL && fcgi[i].prog == NULL)
327 			break;
328 		free(fcgi[i].path);
329 		free(fcgi[i].port);
330 		free(fcgi[i].prog);
331 
332 		fcgi[i].path = NULL;
333 		fcgi[i].port = NULL;
334 		fcgi[i].prog = NULL;
335 
336 		fcgi[i].pending = 0;
337 		fcgi[i].s = FCGI_OFF;
338 	}
339 
340 	tls_free(ctx);
341 	tls_config_free(tlsconf);
342 }
343 
344 static int
wait_signal(void)345 wait_signal(void)
346 {
347 	sigset_t mask;
348 	int signo;
349 
350 	sigemptyset(&mask);
351 	sigaddset(&mask, SIGHUP);
352 	sigaddset(&mask, SIGINT);
353 	sigaddset(&mask, SIGTERM);
354 	sigwait(&mask, &signo);
355 
356 	return signo == SIGHUP;
357 }
358 
359 void
drop_priv(void)360 drop_priv(void)
361 {
362 	struct passwd *pw = NULL;
363 
364 	if (conf.chroot != NULL && conf.user == NULL)
365 		fatal("can't chroot without an user to switch to after.");
366 
367 	if (conf.user != NULL) {
368 		if ((pw = getpwnam(conf.user)) == NULL)
369 			fatal("can't find user %s", conf.user);
370 	}
371 
372 	if (conf.chroot != NULL) {
373 		if (chroot(conf.chroot) != 0 || chdir("/") != 0)
374 			fatal("%s: %s", conf.chroot, strerror(errno));
375 	}
376 
377 	if (pw != NULL) {
378 		if (setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) == -1)
379 			fatal("setresuid(%d): %s", pw->pw_uid,
380 			    strerror(errno));
381 	}
382 
383 	if (getuid() == 0)
384 		log_warn(NULL, "not a good idea to run a network daemon as root");
385 }
386 
387 static void
usage(void)388 usage(void)
389 {
390 	fprintf(stderr,
391 	    "Version: " GMID_STRING "\n"
392 	    "Usage: %s [-fnv] [-c config] [-D macro=value] [-P pidfile]\n"
393 	    "       %s [-6hVv] [-d certs-dir] [-H hostname] [-p port] [-x cgi] [dir]\n",
394 	    getprogname(),
395 	    getprogname());
396 }
397 
398 static void
logger_init(void)399 logger_init(void)
400 {
401 	int p[2];
402 
403 	if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, p) == -1)
404 		err(1, "socketpair");
405 
406 	switch (fork()) {
407 	case -1:
408 		err(1, "fork");
409 	case 0:
410 		signal(SIGHUP, SIG_IGN);
411 		close(p[0]);
412 		setproctitle("logger");
413 		imsg_init(&logibuf, p[1]);
414 		drop_priv();
415 		_exit(logger_main(p[1], &logibuf));
416 	default:
417 		close(p[1]);
418 		imsg_init(&logibuf, p[0]);
419 		return;
420 	}
421 }
422 
423 static int
serve(int argc,char ** argv,struct imsgbuf * ibuf)424 serve(int argc, char **argv, struct imsgbuf *ibuf)
425 {
426 	char		 path[PATH_MAX];
427 	int		 i, p[2];
428 	struct vhost	*h;
429 	struct location	*l;
430 
431         if (config_path == NULL) {
432 		if (hostname == NULL)
433 			hostname = "localhost";
434 		if (certs_dir == NULL)
435 			certs_dir = data_dir();
436 		load_local_cert(hostname, certs_dir);
437 
438 		h = TAILQ_FIRST(&hosts);
439 		h->domain = "*";
440 
441 		l = TAILQ_FIRST(&h->locations);
442 		l->auto_index = 1;
443 		l->match = "*";
444 
445 		switch (argc) {
446 		case 0:
447 			l->dir = getcwd(path, sizeof(path));
448 			break;
449 		case 1:
450 			l->dir = absolutify_path(argv[0]);
451 			break;
452 		default:
453 			usage();
454 			return 1;
455 		}
456 
457 		log_notice(NULL, "serving %s on port %d", l->dir, conf.port);
458 	}
459 
460 	/* setup tls before dropping privileges: we don't want user
461 	 * to put private certs inside the chroot. */
462 	setup_tls();
463 
464 	for (i = 0; i < conf.prefork; ++i) {
465 		if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC,
466 		    PF_UNSPEC, p) == -1)
467 			fatal("socketpair: %s", strerror(errno));
468 
469 		switch (fork()) {
470 		case -1:
471 			fatal("fork: %s", strerror(errno));
472 		case 0:		/* child */
473 			close(p[0]);
474 			imsg_init(&exibuf, p[1]);
475 			setproctitle("server");
476 			_exit(listener_main(&exibuf));
477 		default:
478 			close(p[1]);
479 			imsg_init(&servibuf[i], p[0]);
480 		}
481 	}
482 
483 	setproctitle("executor");
484 	drop_priv();
485 	_exit(executor_main(ibuf));
486 }
487 
488 static int
write_pidfile(const char * pidfile)489 write_pidfile(const char *pidfile)
490 {
491 	struct flock	lock;
492 	int		fd;
493 
494 	if (pidfile == NULL)
495 		return -1;
496 
497 	if ((fd = open(pidfile, O_WRONLY|O_CREAT|O_CLOEXEC, 0600)) == -1)
498 		fatal("can't open pidfile %s: %s", pidfile, strerror(errno));
499 
500 	lock.l_start = 0;
501 	lock.l_len = 0;
502 	lock.l_type = F_WRLCK;
503 	lock.l_whence = SEEK_SET;
504 
505 	if (fcntl(fd, F_SETLK, &lock) == -1)
506 		fatal("can't lock %s, gmid is already running?", pidfile);
507 
508 	if (ftruncate(fd, 0) == -1)
509 		fatal("ftruncate: %s: %s", pidfile, strerror(errno));
510 
511 	dprintf(fd, "%d\n", getpid());
512 
513 	return fd;
514 }
515 
516 static void
setup_configless(int argc,char ** argv,const char * cgi)517 setup_configless(int argc, char **argv, const char *cgi)
518 {
519 	struct vhost	*host;
520 	struct location	*loc;
521 
522 	host = xcalloc(1, sizeof(*host));
523 	host->cgi = cgi;
524 	TAILQ_INSERT_HEAD(&hosts, host, vhosts);
525 
526 	loc = xcalloc(1, sizeof(*loc));
527 	loc->fcgi = -1;
528 	TAILQ_INSERT_HEAD(&host->locations, loc, locations);
529 
530 	serve(argc, argv, NULL);
531 
532 	imsg_compose(&logibuf, IMSG_QUIT, 0, 0, -1, NULL, 0);
533 	imsg_flush(&logibuf);
534 }
535 
536 static int
parse_portno(const char * p)537 parse_portno(const char *p)
538 {
539 	const char *errstr;
540 	int n;
541 
542 	n = strtonum(p, 0, UINT16_MAX, &errstr);
543 	if (errstr != NULL)
544 		yyerror("port number is %s: %s", errstr, p);
545 	return n;
546 }
547 
548 int
main(int argc,char ** argv)549 main(int argc, char **argv)
550 {
551 	struct imsgbuf exibuf;
552 	int ch, conftest = 0, configless = 0;
553 	int pidfd, old_ipv6, old_port;
554 
555 	logger_init();
556 	init_config();
557 
558 	while ((ch = getopt_long(argc, argv, opts, longopts, NULL)) != -1) {
559 		switch (ch) {
560 		case '6':
561 			conf.ipv6 = 1;
562 			configless = 1;
563 			break;
564 
565 		case 'c':
566 			config_path = absolutify_path(optarg);
567 			break;
568 
569 		case 'D':
570 			if (cmdline_symset(optarg) == -1)
571 				fatal("could not parse macro definition: %s",
572 				    optarg);
573 			break;
574 
575 		case 'd':
576 			certs_dir = optarg;
577 			configless = 1;
578 			break;
579 
580 		case 'f':
581 			conf.foreground = 1;
582 			break;
583 
584 		case 'H':
585 			hostname = optarg;
586 			configless = 1;
587 			break;
588 
589 		case 'h':
590 			usage();
591 			return 0;
592 
593 		case 'n':
594 			conftest = 1;
595 			break;
596 
597 		case 'P':
598 			pidfile = optarg;
599 			break;
600 
601 		case 'p':
602 			conf.port = parse_portno(optarg);
603 			configless = 1;
604 			break;
605 
606 		case 'V':
607 			puts("Version: " GMID_STRING);
608 			return 0;
609 
610 		case 'v':
611 			conf.verbose++;
612 			break;
613 
614 		case 'x':
615 			/* drop the starting / (if any) */
616 			if (*optarg == '/')
617 				optarg++;
618 			cgi = optarg;
619 			configless = 1;
620 			break;
621 
622 		default:
623 			usage();
624 			return 1;
625 		}
626 	}
627 	argc -= optind;
628 	argv += optind;
629 
630 	if (config_path == NULL) {
631 		configless = 1;
632 		conf.foreground = 1;
633 		conf.prefork = 1;
634 		conf.verbose++;
635 	}
636 
637 	if (config_path != NULL && (argc > 0 || configless))
638 		fatal("can't specify options in config mode.");
639 
640 	if (conftest) {
641 		if (config_path == NULL)
642 			fatal("missing configuration");
643 		parse_conf(config_path);
644 		puts("config OK");
645 		return 0;
646 	}
647 
648 	if (!conf.foreground && !configless) {
649 		/* log to syslog */
650 		imsg_compose(&logibuf, IMSG_LOG_TYPE, 0, 0, -1, NULL, 0);
651 		imsg_flush(&logibuf);
652 
653 		if (daemon(1, 1) == -1)
654 			fatal("daemon: %s", strerror(errno));
655 	}
656 
657 	if (config_path != NULL)
658 		parse_conf(config_path);
659 
660 	sock4 = make_socket(conf.port, AF_INET);
661 	sock6 = -1;
662 	if (conf.ipv6)
663 		sock6 = make_socket(conf.port, AF_INET6);
664 
665 	signal(SIGPIPE, SIG_IGN);
666 	signal(SIGCHLD, SIG_IGN);
667 
668 	if (configless) {
669 		setup_configless(argc, argv, cgi);
670 		return 0;
671 	}
672 
673 	pidfd = write_pidfile(pidfile);
674 
675 	/*
676 	 * Linux seems to call the event handlers even when we're
677 	 * doing a sigwait.  These dummy handlers are here to avoid
678 	 * being terminated on SIGHUP, SIGINT or SIGTERM.
679 	 */
680 	signal(SIGHUP, dummy_handler);
681 	signal(SIGINT, dummy_handler);
682 	signal(SIGTERM, dummy_handler);
683 
684 	/* wait a sighup and reload the daemon */
685 	for (;;) {
686 		int p[2];
687 
688 		if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC,
689 		    PF_UNSPEC, p) == -1)
690 			fatal("socketpair: %s", strerror(errno));
691 
692 		switch (fork()) {
693 		case -1:
694 			fatal("fork: %s", strerror(errno));
695 		case 0:
696 			close(p[0]);
697 			imsg_init(&exibuf, p[1]);
698 			_exit(serve(argc, argv, &exibuf));
699 		}
700 
701 		close(p[1]);
702 		imsg_init(&exibuf, p[0]);
703 
704 		if (!wait_signal())
705 			break;
706 
707 		log_info(NULL, "reloading configuration %s", config_path);
708 
709 		/* close the executor (it'll close the servers too) */
710 		imsg_compose(&exibuf, IMSG_QUIT, 0, 0, -1, NULL, 0);
711 		imsg_flush(&exibuf);
712 		close(p[0]);
713 
714 		old_ipv6 = conf.ipv6;
715 		old_port = conf.port;
716 
717 		free_config();
718 		init_config();
719 		parse_conf(config_path);
720 
721 		if (old_port != conf.port) {
722 			close(sock4);
723 			close(sock6);
724 			sock4 = -1;
725 			sock6 = -1;
726 		}
727 
728 		if (sock6 != -1 && old_ipv6 != conf.ipv6) {
729 			close(sock6);
730 			sock6 = -1;
731 		}
732 
733 		if (sock4 == -1)
734 			sock4 = make_socket(conf.port, AF_INET);
735 		if (sock6 == -1 && conf.ipv6)
736 			sock6 = make_socket(conf.port, AF_INET6);
737 	}
738 
739 	imsg_compose(&exibuf, IMSG_QUIT, 0, 0, -1, NULL, 0);
740 	imsg_flush(&exibuf);
741 
742 	imsg_compose(&logibuf, IMSG_QUIT, 0, 0, -1, NULL, 0);
743 	imsg_flush(&logibuf);
744 
745 	if (pidfd != -1)
746 		close(pidfd);
747 
748 	return 0;
749 }
750