1 /*
2  *	aprsc
3  *
4  *	(c) Heikki Hannikainen, OH7LZB <hessu@hes.iki.fi>
5  *
6  *	This program is licensed under the BSD license, which can be found
7  *	in the file LICENSE.
8  *
9  */
10 
11 #define HELPS	"Usage: aprsc [-t <chrootdir>] [-u <setuid user>] [-c <cfgfile>] [-f (fork)]\n" \
12 	" [-n <logname>] [-e <loglevel>] [-o <logdest>] [-r <logdir>] [-p <pidfile>]\n" \
13 	" [-y (try config)] [-h (help)]\n"
14 
15 #include <pthread.h>
16 #include <semaphore.h>
17 
18 #include <string.h>
19 #include <errno.h>
20 #include <stdarg.h>
21 #include <stdlib.h>
22 #include <unistd.h>
23 #include <signal.h>
24 #include <sys/types.h>
25 #include <sys/stat.h>
26 #include <fcntl.h>
27 #include <pwd.h>
28 #include <time.h>
29 #include <sys/time.h>
30 #ifdef __linux__ /* Very Linux-specific code.. */
31 #include <sys/syscall.h>
32 #endif
33 #include <sys/resource.h>
34 #include <locale.h>
35 #include <ctype.h>
36 
37 #include "hmalloc.h"
38 #include "hlog.h"
39 #include "config.h"
40 #include "ssl.h"
41 #include "accept.h"
42 #include "uplink.h"
43 #include "worker.h"
44 #include "status.h"
45 #include "http.h"
46 #include "version.h"
47 
48 #include "dupecheck.h"
49 #include "filter.h"
50 #include "historydb.h"
51 #include "client_heard.h"
52 #include "keyhash.h"
53 
54 #ifdef USE_POSIX_CAP
55 #include <sys/capability.h>
56 #include <sys/prctl.h>
57 #endif
58 
59 struct itimerval itv; // Linux profiling timer does not pass over to pthreads..
60 
61 int shutting_down;		// are we shutting down now?
62 int reopen_logs;		// should we reopen log files now?
63 int reconfiguring;		// should we reconfigure now?
64 int fileno_limit = -1;
65 int dbdump_at_exit;
66 int quit_after_config;
67 int liveupgrade_startup;
68 int liveupgrade_fired;
69 int want_dbdump;
70 
71 /* random instance ID, alphanumeric low-case */
72 #define INSTANCE_ID_LEN 8
73 char instance_id[INSTANCE_ID_LEN+1];
74 
75 pthread_attr_t pthr_attrs;
76 
77 /*
78  *	Parse arguments
79  */
80 
parse_cmdline(int argc,char * argv[])81 void parse_cmdline(int argc, char *argv[])
82 {
83 	int s, i;
84 	int failed = 0;
85 
86 	while ((s = getopt(argc, argv, "c:ft:u:n:r:d:DyZe:o:p:?h")) != -1) {
87 	switch (s) {
88 		case 'c':
89 			if (cfgfile && cfgfile != def_cfgfile)
90 				hfree(cfgfile);
91 			cfgfile = hstrdup(optarg);
92 			break;
93 		case 'f':
94 			fork_a_daemon = 1;
95 			break;
96 		case 't':
97 			if (chrootdir)
98 				hfree(chrootdir);
99 			chrootdir = hstrdup(optarg);
100 			break;
101 		case 'u':
102 			if (setuid_s)
103 				hfree(setuid_s);
104 			setuid_s = hstrdup(optarg);
105 			break;
106 		case 'n':
107 			if (logname && logname != def_logname)
108 				hfree(logname);
109 			logname = hstrdup(optarg);
110 			break;
111 		case 'r':
112 			if (log_dir)
113 				hfree(log_dir);
114 			log_dir = hstrdup(optarg);
115 			break;
116 		case 'd':
117 			if (!strcasecmp(optarg, "requests")) {
118 				//dump_requests = 1;
119 			} else if (!strcasecmp(optarg, "splay")) {
120 				dump_splay = 1;
121 			} else {
122 				fprintf(stderr, "Unknown -d parameter: %s\n", optarg);
123 				failed = 1;
124 			}
125 			break;
126 		case 'D':
127 			dbdump_at_exit = 1;
128 			break;
129 		case 'y':
130 			quit_after_config = 1;
131 			break;
132 		case 'Z': /* Can be removed in 2.2 or so, switched to an env var */
133 			liveupgrade_startup = 1;
134 			break;
135 		case 'e':
136 			i = pick_loglevel(optarg, log_levelnames);
137 			if (i > -1)
138 				log_level = i;
139 			else {
140 				fprintf(stderr, "Log level unknown: \"%s\"\n", optarg);
141 				failed = 1;
142 			}
143 			break;
144 		case 'o':
145 			i = pick_loglevel(optarg, log_destnames);
146 			if (i > -1)
147 				if (i == 0)
148 					log_dest = 0;
149 				else
150 					log_dest = 1 << (i-1);
151 			else {
152 				fprintf(stderr, "Log destination unknown: \"%s\"\n", optarg);
153 				failed = 1;
154 			}
155 			break;
156 		case 'p':
157 			if (pidfile)
158 				hfree(pidfile);
159 			pidfile= hstrdup(optarg);
160 			break;
161 		case '?':
162 		case 'h':
163 			fprintf(stderr, "%s\nBuilt at %s by %s\nBuilt with:%s\n",
164 				verstr, verstr_build_time, verstr_build_user, verstr_features);
165 			failed = 1;
166 	}
167 	}
168 
169 	/* when doing a live upgrade, we're already with the right user */
170 	if (liveupgrade_startup && setuid_s) {
171 		hfree(setuid_s);
172 		setuid_s = NULL;
173 	}
174 
175 	if (!log_dir)
176 		log_dir = hstrdup("logs");
177 
178 	if (failed) {
179 		fputs(HELPS, stderr);
180 		exit(failed);
181 	}
182 
183 	if (quit_after_config) {
184 		fork_a_daemon = 0;
185 	}
186 }
187 
188 /*
189  *	signal handler
190  */
191 
sighandler(int signum)192 int sighandler(int signum)
193 {
194 	switch (signum) {
195 
196 	case SIGINT:
197 	case SIGTERM:
198 	case SIGQUIT:
199 		hlog(LOG_NOTICE, "Shutting down on signal %d", signum);
200 		shutting_down = 1;
201 		return 0;
202 
203 	case SIGHUP:
204 		hlog(LOG_INFO, "SIGHUP received: reopening logs");
205 		reopen_logs = 1;
206 		break;
207 
208 	case SIGUSR1:
209 		hlog(LOG_INFO, "SIGUSR1 received: reconfiguring");
210 		reconfiguring = 1;
211 		break;
212 
213 	case SIGUSR2:
214 		hlog(LOG_INFO, "SIGUSR2 received: performing live upgrade");
215 		liveupgrade_fired = 1;
216 		shutting_down = 1;
217 		break;
218 
219 	default:
220 		hlog(LOG_WARNING, "* SIG %d ignored", signum);
221 		break;
222 	}
223 
224 	signal(signum, (void *)sighandler);	/* restore handler */
225 	return 0;
226 
227 }
228 
229 /*
230  *	A very Linux specific thing, as there the pthreads are a special variation
231  *	of fork(), and per POSIX the profiling timers are not kept over fork()...
232  */
pthreads_profiling_reset(const char * name)233 void pthreads_profiling_reset(const char *name)
234 {
235 #ifdef __linux__ /* Very Linux-specific code.. */
236 	int tid;
237 	if (itv.it_interval.tv_usec || itv.it_interval.tv_sec) {
238 	  setitimer(ITIMER_PROF, &itv, NULL);
239 	}
240 
241 	tid = syscall(SYS_gettid);
242 	hlog(LOG_DEBUG, "Thread %s: Linux ThreadId: %d", name, tid);
243 #endif
244 }
245 
246 #define PATHLEN 500
dbdump_historydb(void)247 static int dbdump_historydb(void)
248 {
249 	FILE *fp;
250 	char path[PATHLEN+1];
251 	int ret = 0;
252 
253 	snprintf(path, PATHLEN, "%s/historydb.json", rundir);
254 	fp = fopen(path,"w");
255 	if (!fp) {
256 		hlog(LOG_ERR, "dbdump historydb failed to open %s for writing: %s", path, strerror(errno));
257 		return -1;
258 	}
259 
260 	if (historydb_dump(fp)) {
261 		ret = -1;
262 	}
263 
264 	if (fclose(fp)) {
265 		hlog(LOG_ERR, "dbdump historydb failed to close %s after writing: %s", path, strerror(errno));
266 		return -1;
267 	}
268 
269 	return ret;
270 }
271 
dbdump_all(void)272 static void dbdump_all(void)
273 {
274 	FILE *fp;
275 	char path[PATHLEN+1];
276 
277 	/*
278 	 *    As a general rule, dumping of databases is not a Good Idea in
279 	 *    operational system.  Development time debugging on other hand..
280 	 */
281 
282 	dbdump_historydb();
283 
284 	snprintf(path, PATHLEN, "%s/filter.wx.dump", rundir);
285 	fp = fopen(path,"w");
286 	if (fp) {
287 		filter_wx_dump(fp);
288 		fclose(fp);
289 	}
290 	snprintf(path, PATHLEN, "%s/filter.entry.dump", rundir);
291 	fp = fopen(path,"w");
292 	if (fp) {
293 		filter_entrycall_dump(fp);
294 		fclose(fp);
295 	}
296 	snprintf(path, PATHLEN, "%s/pbuf.dump", rundir);
297 	fp = fopen(path,"w");
298 	if (fp) {
299 		pbuf_dump(fp);
300 		fclose(fp);
301 	}
302 	snprintf(path, PATHLEN, "%s/pbuf.dupe.dump", rundir);
303 	fp = fopen(path,"w");
304 	if (fp) {
305 		pbuf_dupe_dump(fp);
306 		fclose(fp);
307 	}
308 }
309 
dbload_all(void)310 static void dbload_all(void)
311 {
312 	FILE *fp;
313 	char path[PATHLEN+1];
314 	char path_renamed[PATHLEN+1];
315 
316 	snprintf(path, PATHLEN, "%s/historydb.json", rundir);
317 	fp = fopen(path,"r");
318 	if (fp) {
319 		hlog(LOG_INFO, "Live upgrade: Loading historydb from %s ...", path);
320 		snprintf(path_renamed, PATHLEN, "%s/historydb.json.old", rundir);
321 		if (rename(path, path_renamed) < 0) {
322 			hlog(LOG_ERR, "Failed to rename historydb dump file %s to %s: %s",
323 				path, path_renamed, strerror(errno));
324 			unlink(path);
325 		}
326 
327 		historydb_load(fp);
328 		fclose(fp);
329 	}
330 }
331 
332 /*
333  *	switch uid
334  */
335 struct passwd pwbuf;
336 char *pw_buf_s;
337 
338 /* Look up the target UID/GID from passwd/group */
find_uid(const char * uid_s)339 static void find_uid(const char *uid_s)
340 {
341 	struct passwd *pwbufp;
342 	int buflen;
343 
344 	buflen = sysconf(_SC_GETPW_R_SIZE_MAX);
345 	if (buflen < 10)
346 		buflen = 1024;
347 
348 	pw_buf_s = hmalloc(buflen);
349 
350 #ifdef sun
351 	pwbufp = getpwnam_r(uid_s, &pwbuf, pw_buf_s, buflen);
352 #else
353 	int e = getpwnam_r(uid_s, &pwbuf, pw_buf_s, buflen, &pwbufp);
354 
355 	if (e) {
356 		fprintf(stderr, "aprsc: getpwnam(%s) failed, can not set UID: %s\n", uid_s, strerror(e));
357 		exit(1);
358 	}
359 #endif
360 
361 	if (pwbufp == NULL) {
362 		fprintf(stderr, "aprsc: getpwnam(%s) failed, can not set UID: user not found\n", uid_s);
363 		exit(1);
364 	}
365 }
366 
367 /* set effective UID, for startup time */
set_euid(void)368 static void set_euid(void)
369 {
370 	if (setegid(pwbuf.pw_gid)) {
371 		fprintf(stderr, "aprsc: Failed to set effective GID %d: %s\n", pwbuf.pw_gid, strerror(errno));
372 		exit(1);
373 	}
374 
375 	if (seteuid(pwbuf.pw_uid)) {
376 		fprintf(stderr, "aprsc: Failed to set effective UID %d: %s\n", pwbuf.pw_uid, strerror(errno));
377 		exit(1);
378 	}
379 }
380 
381 /* switch back to uid 0 for post-config setup as root */
set_euid_0(void)382 static void set_euid_0(void)
383 {
384 	if (seteuid(0)) {
385 		fprintf(stderr, "aprsc: Failed to set effective UID back to 0: %s\n", strerror(errno));
386 		exit(1);
387 	}
388 }
389 
check_caps(char * when)390 static void check_caps(char *when)
391 {
392 #ifdef USE_POSIX_CAP
393 	cap_t caps = cap_get_proc();
394 
395 	if (caps == NULL) {
396 		hlog(LOG_ERR, "check_caps: Failed to get current POSIX capabilities: %s", strerror(errno));
397 		return;
398 	}
399 
400 	char *s = cap_to_text(caps, NULL);
401 
402 	if (s) {
403 		hlog(LOG_DEBUG, "aprsc: capabilities %s: %s", when, s);
404 	}
405 
406 	cap_free(caps);
407 #endif
408 }
409 
set_initial_capabilities(void)410 static int set_initial_capabilities(void)
411 {
412 #ifdef USE_POSIX_CAP
413 	int ret = -1;
414 
415 	cap_t caps = cap_init();
416 
417 	/* list of capabilities needed at startup - less than what root has */
418 #define NCAPS 5
419 	cap_value_t cap_list[NCAPS];
420 	cap_list[0] = CAP_NET_BIND_SERVICE;
421 	cap_list[1] = CAP_SETUID;
422 	cap_list[2] = CAP_SETGID;
423 	cap_list[3] = CAP_SYS_RESOURCE;
424 	cap_list[4] = CAP_SYS_CHROOT;
425 
426 	if (cap_set_flag(caps, CAP_PERMITTED, NCAPS, cap_list, CAP_SET) == -1) {
427 		fprintf(stderr, "aprsc: Failed to set initial POSIX capability flags: %s\n", strerror(errno));
428 		goto end_caps;
429 	}
430 
431 	if (cap_set_flag(caps, CAP_EFFECTIVE, NCAPS, cap_list, CAP_SET) == -1) {
432 		fprintf(stderr, "aprsc: Failed to set initial POSIX capability flags: %s\n", strerror(errno));
433 		goto end_caps;
434 	}
435 
436 	//fprintf(stderr, "aprsc: going to set: %s\n", cap_to_text(caps, NULL));
437 
438 	if (cap_set_proc(caps) == -1) {
439 		fprintf(stderr, "aprsc: Failed to apply initial POSIX capabilities: %s\n", strerror(errno));
440 		goto end_caps;
441 	}
442 
443 	if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) == -1) {
444 		fprintf(stderr, "aprsc: Failed to set PR_SET_KEEPCAPS: %s\n", strerror(errno));
445 		goto end_caps;
446 	}
447 
448 	//fprintf(stderr, "aprsc: Successfully enabled initial POSIX capabilities\n");
449 	ret = 0;
450 
451 end_caps:
452 	if (caps) {
453 		if (cap_free(caps) == -1)
454 			fprintf(stderr, "aprsc: Failed to free capabilities: %s\n", strerror(errno));
455 		caps = NULL;
456 	}
457 
458 	return ret;
459 #else
460 	return 0;
461 #endif
462 }
463 
set_final_capabilities(void)464 static int set_final_capabilities(void)
465 {
466 #ifdef USE_POSIX_CAP
467 	int ret = -1;
468 	cap_t caps = cap_init();
469 
470 #define NCAPS_FINAL 1
471 	if (listen_low_ports) {
472 		cap_value_t cap_list[NCAPS_FINAL];
473 		cap_list[0] = CAP_NET_BIND_SERVICE;
474 
475 		if (cap_set_flag(caps, CAP_PERMITTED, NCAPS_FINAL, cap_list, CAP_SET) == -1) {
476 			hlog(LOG_ERR, "aprsc: Failed to set final permitted POSIX capability flags: %s", strerror(errno));
477 			goto end_caps;
478 		}
479 
480 		if (cap_set_flag(caps, CAP_EFFECTIVE, NCAPS_FINAL, cap_list, CAP_SET) == -1) {
481 			hlog(LOG_ERR, "aprsc: Failed to set final effective POSIX capability flags: %s", strerror(errno));
482 			goto end_caps;
483 		}
484 
485 		/* when we exec() myself in live upgrade, these capabilities are also
486 		 * needed by the new process. INHERITABLE FTW!
487 		 */
488 		if (cap_set_flag(caps, CAP_INHERITABLE, NCAPS_FINAL, cap_list, CAP_SET) == -1) {
489 			hlog(LOG_ERR, "aprsc: Failed to set final inheritable POSIX capability flags: %s", strerror(errno));
490 			goto end_caps;
491 		}
492 
493 		//fprintf(stderr, "aprsc: going to set: %s\n", cap_to_text(caps, NULL));
494 		ret = 1;
495 	} else {
496 		ret = 0;
497 	}
498 
499 	if (cap_set_proc(caps) == -1) {
500 		hlog(LOG_ERR, "aprsc: Failed to apply final POSIX capabilities: %s", strerror(errno));
501 		ret = -1;
502 		goto end_caps;
503 	}
504 
505 	//fprintf(stderr, "aprsc: Successfully enabled final POSIX capabilities\n");
506 
507 end_caps:
508 	if (caps) {
509 		if (cap_free(caps) == -1)
510 			hlog(LOG_ERR, "aprsc: Failed to free capabilities: %s", strerror(errno));
511 		caps = NULL;
512 	}
513 
514 	return ret;
515 #else
516 	return -1;
517 #endif
518 }
519 
520 /* set real UID to non-root, cannot be reversed */
set_uid(void)521 static void set_uid(void)
522 {
523 	//check_caps("before set_uid");
524 
525 	if (setgid(pwbuf.pw_gid)) {
526 		fprintf(stderr, "aprsc: Failed to set GID %d: %s\n", pwbuf.pw_gid, strerror(errno));
527 		exit(1);
528 	}
529 
530 	if (setuid(pwbuf.pw_uid)) {
531 		fprintf(stderr, "aprsc: Failed to set UID %d: %s\n", pwbuf.pw_uid, strerror(errno));
532 		exit(1);
533 	}
534 
535 }
536 
537 /*
538  *	Check that we're not running as root. Bail out if we are
539  */
540 
check_uid(void)541 static void check_uid(void)
542 {
543 	if (getuid() == 0 || geteuid() == 0) {
544 		fprintf(stderr,
545 			"aprsc: Security incident about to happen: running as root.\n"
546 			"Use the -u <username> switch to run as unprivileged user 'aprsc', or start\n"
547 			"it up as such an user.\n");
548 		exit(1);
549 	}
550 }
551 
552 /*
553  *	Generate a pseudorandom instance ID by reading the pseudorandom
554  *	source and converting the binary data to lower-case alphanumeric
555  */
556 
generate_instance_id(void)557 static void generate_instance_id(void)
558 {
559 	unsigned char s[INSTANCE_ID_LEN];
560 	int fd, l;
561 	char c;
562 	unsigned seed;
563 	struct timeval tv;
564 
565 	if ((fd = open("/dev/urandom", O_RDONLY)) == -1) {
566 		hlog(LOG_ERR, "open(/dev/urandom) failed: %s", strerror(errno));
567 		fd = -1;
568 	}
569 
570 	/* seed the prng */
571 	if (fd >= 0) {
572 		l = read(fd, &seed, sizeof(seed));
573 		if (l != sizeof(seed)) {
574 			hlog(LOG_ERR, "read(/dev/urandom, %d) for seed failed: %s", sizeof(seed), strerror(errno));
575 			close(fd);
576 			fd = -1;
577 		}
578 	}
579 
580 	if (fd < 0) {
581 		/* not very strong, but we're not doing cryptography here */
582 		gettimeofday(&tv, NULL);
583 		seed = tv.tv_sec + tv.tv_usec + getpid();
584 	}
585 
586 	srandom(seed);
587 
588 	if (fd >= 0) {
589 		/* generate instance id */
590 		l = read(fd, s, INSTANCE_ID_LEN);
591 		if (l != INSTANCE_ID_LEN) {
592 			hlog(LOG_ERR, "read(/dev/urandom, %d) failed: %s", INSTANCE_ID_LEN, strerror(errno));
593 			close(fd);
594 			fd = -1;
595 		}
596 	}
597 
598 	if (fd < 0) {
599 		/* urandom failed for us, use something inferior */
600 		for (l = 0; l < INSTANCE_ID_LEN; l++) {
601 			// coverity[dont_call]  // squelch warning: not security sensitive use of random()
602 			s[l] = random() % 256;
603 		}
604 	}
605 
606 	for (l = 0; l < INSTANCE_ID_LEN; l++) {
607 		/* 256 is not divisible by 36, the distribution is slightly skewed,
608 		 * but that's not serious.
609 		 */
610 		c = s[l] % (26 + 10); /* letters and numbers */
611 		if (c < 10)
612 			c += 48; /* number */
613 		else
614 			c = c - 10 + 97; /* letter */
615 		instance_id[l] = c;
616 	}
617 	instance_id[INSTANCE_ID_LEN] = 0;
618 
619 	if (fd >= 0)
620 		close(fd);
621 }
622 
623 /*
624  *	DNS lookup which phones home with version information.
625  *
626  *	Tin foil hats off. Version information and instance statistics
627  *	make developers happy.
628  */
629 
version_report(const char * state)630 void version_report(const char *state)
631 {
632 #ifdef VERSION_REPORT_OVER_DNS
633 	struct addrinfo hints;
634 	struct addrinfo *ai;
635 	char v[80];
636 	char n[32];
637 	char s[300];
638 	int i, l;
639 
640 	/* don't send version reports during testing */
641 	if (getenv("APRSC_NO_VERSION_REPORT"))
642 		return;
643 
644 	/* normalize version string to fit in a DNS label */
645 	strncpy(v, version_build, sizeof(v));
646 	l = strlen(v);
647 	for (i = 0; i < sizeof(v) && i < l; i++)
648 		if (!isalnum(v[i]))
649 			v[i] = '-';
650 
651 	if (serverid) {
652 		/* we're configured, include serverid and normalize it */
653 		strncpy(n, serverid, sizeof(n));
654 		n[sizeof(n)-1] = 0;
655 		l = strlen(n);
656 		for (i = 0; i < sizeof(n) && i < l; i++)
657 			if (!isalnum(n[i]))
658 				n[i] = '-';
659 		snprintf(s, 300, "%s.%s.%s.%s.aprsc.he.fi", n, v, instance_id, state);
660 	} else {
661 		snprintf(s, 300, "%s.%s.%s.aprsc.he.fi", v, instance_id, state);
662 	}
663 
664 	/* reduce the amount of lookups in case of a failure, don't do
665 	 * separate AAAA + A lookups
666 	 */
667 	memset(&hints, 0, sizeof(hints));
668 	hints.ai_family = AF_INET;
669 
670 	ai = NULL;
671 	i = getaddrinfo(s, NULL, &hints, &ai);
672 	if (i != 0)
673 		hlog(LOG_DEBUG, "DNS lookup of aprsc.he.fi failed: %s", gai_strerror(i));
674 	if (ai)
675 		freeaddrinfo(ai);
676 #endif
677 }
678 
679 /*
680  *	Execute a new myself to perform a live upgrade
681  */
682 
liveupgrade_exec(int argc,char ** argv)683 static void liveupgrade_exec(int argc, char **argv)
684 {
685 	char **nargv;
686 	int i;
687 	char *bin = argv[0];
688 
689 	i = strlen(argv[0]);
690 	if (chrootdir && strncmp(argv[0], chrootdir, strlen(chrootdir)) == 0) {
691 		bin = hmalloc(i+1);
692 		strncpy(bin, argv[0] + strlen(chrootdir), i);
693 	}
694 
695 	hlog(LOG_NOTICE, "Live upgrade: Executing the new me: %s", bin);
696 
697 	/* generate argument list for the new executable */
698 	nargv = hmalloc(sizeof(char *) * (argc+1));
699 
700 	nargv[0] = bin;
701 	for (i = 1; i < argc; i++)
702 		nargv[i] = argv[i];
703 
704 	nargv[i++] = NULL;
705 
706 	/* new method of signalling live upgrade, less confusion */
707 #ifdef HAVE_SETENV
708 	if (setenv("APRSC_LIVE_UPGRADE", "1", 1) != 0) {
709 		hlog(LOG_CRIT, "Live upgrade: setenv(APRSC_LIVE_UPGRADE) failed: %s", strerror(errno));
710 		goto err;
711 	}
712 #else
713 #ifdef HAVE_PUTENV
714 	if (putenv("APRSC_LIVE_UPGRADE=1") != 0) {
715 		hlog(LOG_CRIT, "Live upgrade: putenv(APRSC_LIVE_UPGRADE) failed: %s", strerror(errno));
716 		goto err;
717 	}
718 #else
719 	hlog(LOG_CRIT, "Live upgrade: no putenv/setenv available, live upgrade does not work");
720 	goto err;
721 #endif
722 #endif
723 
724 	/* close pid file and free the lock on it */
725 	closepid();
726 
727 	/* close log file so that we don't leak the file descriptor */
728 	close_log(0);
729 
730 	/* execute new binary, should not return if all goes fine */
731 	execv(bin, nargv);
732 
733 	hlog(LOG_CRIT, "liveupgrade: exec failed, I'm still here! %s", strerror(errno));
734 
735 err:
736 	/* free resources in case we'd decide to continue anyway */
737 	if (bin != argv[0])
738 		hfree(bin);
739 	hfree(nargv);
740 }
741 
742 
743 /*
744  *	Time-keeping thread
745  */
746 
747 #ifdef USE_CLOCK_GETTIME
timeval_diff(struct timespec start,struct timespec end)748 static double timeval_diff(struct timespec start, struct timespec end)
749 {
750 	double diff;
751 
752 	diff = (end.tv_sec - start.tv_sec)
753 		+ ((end.tv_nsec - start.tv_nsec) / 1000000000.0);
754 
755 	return diff;
756 }
757 #else
timeval_diff(struct timeval start,struct timeval end)758 static double timeval_diff(struct timeval start, struct timeval end)
759 {
760 	double diff;
761 
762 	diff = (end.tv_sec - start.tv_sec)
763 		+ ((end.tv_usec - start.tv_usec) / 1000000.0);
764 
765 	return diff;
766 }
767 #endif
768 
time_set_tick_and_now(void)769 void time_set_tick_and_now(void)
770 {
771 #ifdef USE_CLOCK_GETTIME
772 	struct timespec ts;
773 	clock_gettime(CLOCK_MONOTONIC, &ts);
774 	tick = ts.tv_sec;
775 	clock_gettime(CLOCK_REALTIME, &ts);
776 	now = ts.tv_sec;
777 #else
778 	struct timeval tv;
779 	gettimeofday(&tv, NULL);
780 	tick = tv.tv_sec;
781 	now = tv.tv_sec;
782 #endif
783 }
784 
time_thread(void * asdf)785 void time_thread(void *asdf)
786 {
787 	sigset_t sigs_to_block;
788 	time_t previous_tick;
789 	struct timespec sleep_req;
790 #ifdef USE_CLOCK_GETTIME
791 	struct timespec sleep_start, sleep_end;
792 	struct timespec ts;
793 	hlog(LOG_INFO, "Time thread starting: using clock_gettime");
794 #else
795 	struct timeval sleep_start, sleep_end;
796 	hlog(LOG_INFO, "Time thread starting: using gettimeofday");
797 #endif
798 
799 	pthreads_profiling_reset("time");
800 
801 	sigemptyset(&sigs_to_block);
802 	sigaddset(&sigs_to_block, SIGALRM);
803 	sigaddset(&sigs_to_block, SIGINT);
804 	sigaddset(&sigs_to_block, SIGTERM);
805 	sigaddset(&sigs_to_block, SIGQUIT);
806 	sigaddset(&sigs_to_block, SIGHUP);
807 	sigaddset(&sigs_to_block, SIGURG);
808 	sigaddset(&sigs_to_block, SIGPIPE);
809 	sigaddset(&sigs_to_block, SIGUSR1);
810 	sigaddset(&sigs_to_block, SIGUSR2);
811 	pthread_sigmask(SIG_BLOCK, &sigs_to_block, NULL);
812 
813 	time_set_tick_and_now();
814 	previous_tick = tick;
815 
816 	sleep_req.tv_sec = 0;
817 	sleep_req.tv_nsec = 210 * 1000 * 1000; /* 210 ms */
818 
819 	while (!accept_shutting_down) {
820 #ifdef USE_CLOCK_GETTIME
821 		clock_gettime(CLOCK_MONOTONIC, &sleep_start);
822 		nanosleep(&sleep_req, NULL);
823 		clock_gettime(CLOCK_MONOTONIC, &sleep_end);
824 		tick = sleep_end.tv_sec;
825 		clock_gettime(CLOCK_REALTIME, &ts);
826 		now = ts.tv_sec;
827 #else
828 		gettimeofday(&sleep_start, NULL);
829 		nanosleep(&sleep_req, NULL);
830 		gettimeofday(&sleep_end, NULL);
831 		tick = sleep_end.tv_sec;
832 		now = tick;
833 #endif
834 
835 		double slept = timeval_diff(sleep_start, sleep_end);
836 		if (slept > 0.90)
837 			hlog(LOG_WARNING, "time keeping: sleep of %d ms took %.6f s!", sleep_req.tv_nsec / 1000 / 1000, slept);
838 
839 		/* catch some oddities with time keeping */
840 		if (tick != previous_tick) {
841 			if (previous_tick > tick) {
842 				hlog(LOG_WARNING, "time keeping: Time jumped backward by %d seconds!", previous_tick - tick);
843 			} else if (previous_tick < tick-1) {
844 				hlog(LOG_WARNING, "time keeping: Time jumped forward by %d seconds!", tick - previous_tick);
845 			}
846 
847 			previous_tick = tick;
848 		}
849 
850 	}
851 
852 }
853 
init_reopen_stdio(void)854 static void init_reopen_stdio(void)
855 {
856 	/* close stdin and stdout, and any other FDs that might be left open */
857 	/* closing stderr masks error logs between this point and opening the logs... suboptimal. */
858 	{
859 		int i;
860 		close(0);
861 		close(1);
862 		for (i = 3; i < 100; i++)
863 			close(i);
864 	}
865 
866 	/* all of this fails in chroot, so do it before */
867 	if (open("/dev/null", O_RDWR) == -1) /* stdin */
868 		hlog(LOG_ERR, "open(/dev/null) failed for stdin: %s", strerror(errno));
869 	if (dup(0) == -1) /* stdout */
870 		hlog(LOG_ERR, "dup(0) failed for stdout: %s", strerror(errno));
871 }
872 
873 /*
874  *	Main
875  */
876 
main(int argc,char ** argv)877 int main(int argc, char **argv)
878 {
879 	pthread_t accept_th;
880 	pthread_t http_th;
881 	pthread_t time_th;
882 	int e;
883 	struct rlimit rlim;
884 	time_t cleanup_tick = 0;
885 	time_t version_tick = 0;
886 	int have_low_ports = 0;
887 
888 	if (getuid() == 0)
889 		set_initial_capabilities();
890 
891 	time_set_tick_and_now();
892 	cleanup_tick = tick;
893 	// coverity[dont_call]  // squelch warning: not security sensitive use of random()
894 	version_tick = tick + random() % 60; /* some load distribution */
895 	startup_tick = tick;
896 	startup_time = now;
897 	setlinebuf(stderr);
898 
899 	/* set locale to C so that isalnum(), isupper() etc don't do anything
900 	 * unexpected if the environment is unexpected.
901 	 */
902 	if (!setlocale(LC_COLLATE, "C")) {
903 		hlog(LOG_CRIT, "Failed to set locale C for LC_COLLATE.");
904 		exit(1);
905 	}
906 	if (!setlocale(LC_CTYPE, "C")) {
907 		hlog(LOG_CRIT, "Failed to set locale C for LC_CTYPE.");
908 		exit(1);
909 	}
910 	if (!setlocale(LC_MESSAGES, "C")) {
911 		hlog(LOG_CRIT, "Failed to set locale C for LC_MESSAGES.");
912 		exit(1);
913 	}
914 	if (!setlocale(LC_NUMERIC, "C")) {
915 		hlog(LOG_CRIT, "Failed to set locale C for LC_NUMERIC.");
916 		exit(1);
917 	}
918 
919 	/* Adjust process global fileno limit to match the maximum available
920 	 * at this time
921 	 */
922 	e = getrlimit(RLIMIT_NOFILE, &rlim);
923 	if (e < 0) {
924 		hlog(LOG_ERR, "Failed to get initial file number resource limit: %s", strerror(errno));
925 	} else {
926 		rlim.rlim_cur = rlim.rlim_max;
927 		e = setrlimit(RLIMIT_NOFILE, &rlim);
928 		if (e < 0) {
929 			hlog(LOG_ERR, "Failed to set file number resource limit: %s", strerror(errno));
930 		}
931 		e = getrlimit(RLIMIT_NOFILE, &rlim);
932 		if (e < 0) {
933 			hlog(LOG_ERR, "Failed to verify modified file number resource limit: %s", strerror(errno));
934 		}
935 		fileno_limit = rlim.rlim_cur;
936 	}
937 
938 	getitimer(ITIMER_PROF, &itv);
939 
940 	/* check if we're doing a live upgrade - need to know this in the
941 	 * command line parser already
942 	 */
943 	if (getenv("APRSC_LIVE_UPGRADE"))
944 		liveupgrade_startup = 1;
945 
946 	/* command line */
947 	parse_cmdline(argc, argv);
948 
949 	/* if setuid is needed, find the user UID */
950 	if (setuid_s)
951 		find_uid(setuid_s);
952 
953 	/* fork a daemon */
954 	if (fork_a_daemon) {
955 		hlog(LOG_INFO, "Forking...");
956 		int i = fork();
957 		if (i < 0) {
958 			hlog(LOG_CRIT, "Fork to background failed: %s", strerror(errno));
959 			fprintf(stderr, "Fork to background failed: %s\n", strerror(errno));
960 			exit(1);
961 		} else if (i == 0) {
962 			/* child */
963 			hlog(LOG_INFO, "Child started...");
964 			if (setsid() == -1) {
965 				fprintf(stderr, "setsid() failed: %s\n", strerror(errno));
966 				//exit(1);
967 			}
968 		} else {
969 			/* parent, quitting */
970 			hlog(LOG_DEBUG, "Forked daemon process %d, parent quitting", i);
971 			exit(0);
972 		}
973 	}
974 
975 	/* close stdin and stdout, and any other FDs that might be left open */
976 	if (!liveupgrade_startup)
977 		init_reopen_stdio();
978 
979 	/* prepare for a possible chroot, force loading of
980 	 * resolver libraries at this point, so that we don't
981 	 * need a copy of the shared libs within the chroot dir
982 	 */
983 	generate_instance_id();
984 	version_report("startup");
985 
986 	/* do a chroot if required */
987 	if (chrootdir && !liveupgrade_startup) {
988 		if ((!setuid_s) || pwbuf.pw_uid == 0) {
989 			fprintf(stderr, "aprsc: chroot requested but not setuid to non-root user - insecure\n"
990 				"configuration detected. Using -u <username> and start as root required.\n");
991 			exit(1);
992 		}
993 		if (chdir(chrootdir) != 0) {
994 			fprintf(stderr, "aprsc: chdir(%s) failed before chroot: %s\n", chrootdir, strerror(errno));
995 			exit(1);
996 		}
997 		if (chroot(chrootdir)) {
998 			fprintf(stderr, "aprsc: chroot(%s) failed: %s\n", chrootdir, strerror(errno));
999 			exit(1);
1000 		}
1001 		if (chdir("/") != 0) { /* maybe redundant after the first chdir() */
1002 			fprintf(stderr, "aprsc: chdir(/) failed after chroot: %s\n", strerror(errno));
1003 			exit(1);
1004 		}
1005 	}
1006 
1007 	/* set effective UID to non-root before opening files */
1008 	if (setuid_s && !liveupgrade_startup)
1009 		set_euid();
1010 
1011 	/* open syslog, write an initial log message and read configuration */
1012 	open_log(logname, 0);
1013 	if (!quit_after_config)
1014 		hlog(LOG_NOTICE, "Starting up version %s, instance id %s %s...",
1015 			version_build, instance_id, (liveupgrade_startup) ? "- LIVE UPGRADE " : "");
1016 
1017 	int orig_log_dest = log_dest;
1018 	log_dest |= L_STDERR;
1019 
1020 	if (read_config()) {
1021 		hlog(LOG_CRIT, "Initial configuration failed.");
1022 		exit(1);
1023 	}
1024 
1025 	if (quit_after_config)
1026 		exit(0);
1027 
1028 	/* adjust file limits as requested, not after every reconfigure
1029 	 * but only at startup - we won't have root privileges available
1030 	 * later.
1031 	 */
1032 	if (setuid_s)
1033 		set_euid_0();
1034 
1035 	if (new_fileno_limit > 0 && new_fileno_limit != fileno_limit && !liveupgrade_startup) {
1036 		/* Adjust process global fileno limit */
1037 		struct rlimit rlim;
1038 		if (getrlimit(RLIMIT_NOFILE, &rlim) < 0)
1039 			hlog(LOG_WARNING, "Configuration: getrlimit(RLIMIT_NOFILE) failed: %s", strerror(errno));
1040 		rlim.rlim_cur = rlim.rlim_max = new_fileno_limit;
1041 		if (setrlimit(RLIMIT_NOFILE, &rlim) < 0)
1042 			hlog(LOG_WARNING, "Configuration: setrlimit(RLIMIT_NOFILE) failed: %s", strerror(errno));
1043 		if (getrlimit(RLIMIT_NOFILE, &rlim) == 0) {
1044 			fileno_limit = rlim.rlim_cur;
1045 			if (fileno_limit < new_fileno_limit)
1046 				hlog(LOG_WARNING, "Configuration could not raise FileLimit%s, it is now %d", (getuid() != 0) ? " (not running as root)" : "", fileno_limit);
1047 		}
1048 	}
1049 
1050 	/* if setuid is needed, do so */
1051 	if (setuid_s) {
1052 		set_uid();
1053 		//check_caps("after set_uid");
1054 		if (set_final_capabilities() >= 0)
1055 			have_low_ports = 1;
1056 		check_caps("after set_final_capabilities");
1057 	}
1058 
1059 	/* check that we're not root - it would be insecure and really not required */
1060 	check_uid();
1061 
1062 	/* if we're not logging on stderr, we close the stderr FD after we have read configuration
1063 	 * and opened the log file or syslog - initial config errors should go to stderr.
1064 	 */
1065 	if (!(log_dest & L_STDERR)) {
1066 		close(2);
1067 		if (dup(0) == -1) /* stderr */
1068 			hlog(LOG_ERR, "dup(0) failed for stderr: %s", strerror(errno));
1069 	}
1070 
1071 	/* Write pid file, now that we have our final pid... might fail, which is critical.
1072 	 * writepid locks the pid file and leaves the file descriptor open, so that
1073 	 * reopening and re-locking the file will fail, protecting us from multiple
1074 	 * processes running accidentally.
1075 	 */
1076 	if (!writepid(pidfile))
1077 		exit(1);
1078 
1079 	log_dest = orig_log_dest;
1080 
1081 	/* log these only to the final log, after stderr is closed, so that
1082 	 * a normal, successful startup does not print out informative stuff
1083 	 * on the console
1084 	 */
1085 	if (have_low_ports)
1086 		hlog(LOG_INFO, "POSIX capabilities available: can bind low ports");
1087 
1088 	hlog(LOG_INFO, "After configuration FileLimit is %d, MaxClients is %d, xpoll using %s",
1089 		fileno_limit, maxclients, xpoll_implementation);
1090 
1091 	/* validate maxclients vs fileno_limit, now when it's determined */
1092 	if (fileno_limit < maxclients + 50) {
1093 		hlog(LOG_ERR, "FileLimit is smaller than MaxClients + 50: Server may run out of file descriptors and break badly");
1094 	}
1095 
1096 	/* catch signals */
1097 	signal(SIGINT, (void *)sighandler);
1098 	signal(SIGTERM, (void *)sighandler);
1099 	signal(SIGQUIT, (void *)sighandler);
1100 	signal(SIGHUP, (void *)sighandler);
1101 	signal(SIGUSR1, (void *)sighandler);
1102 	signal(SIGUSR2, (void *)sighandler);
1103 	signal(SIGPIPE, SIG_IGN);
1104 	signal(SIGURG, SIG_IGN);
1105 
1106 	/* Early inits in single-thread mode */
1107 	keyhash_init();
1108 	filter_init();
1109 	pbuf_init();
1110 	dupecheck_init();
1111 	historydb_init();
1112 	client_heard_init();
1113 	client_init();
1114 	xpoll_init();
1115 	status_init();
1116 	ssl_init();
1117 
1118 	/* if live upgrading, load status file and database dumps */
1119 	if (liveupgrade_startup) {
1120 		dbload_all();
1121 		/* historydb must be loaded before applying filters, so do dbload_all first */
1122 		status_read_liveupgrade();
1123 	}
1124 
1125 	pthread_attr_init(&pthr_attrs);
1126 	/* 128 kB stack is enough for each thread,
1127 	   default of 10 MB is way too much...*/
1128 	pthread_attr_setstacksize(&pthr_attrs, 128*1024);
1129 
1130 	/* start the time thread, which will update the current time */
1131 	if (pthread_create(&time_th, &pthr_attrs, (void *)time_thread, NULL))
1132 		perror("pthread_create failed for time_thread");
1133 
1134 	/* start the accept thread, which will start server threads */
1135 	if (pthread_create(&accept_th, &pthr_attrs, (void *)accept_thread, NULL))
1136 		perror("pthread_create failed for accept_thread");
1137 
1138 	/* start the HTTP thread, which runs libevent's HTTP server */
1139 	if (pthread_create(&http_th, &pthr_attrs, (void *)http_thread, NULL))
1140 		perror("pthread_create failed for http_thread");
1141 
1142 	/* act as statistics and housekeeping thread from now on */
1143 	while (!shutting_down) {
1144 		if (poll(NULL, 0, 300) == -1 && errno != EINTR)
1145 			hlog(LOG_WARNING, "main: poll sleep failed: %s", strerror(errno));
1146 
1147 		if (want_dbdump) {
1148 			dbdump_all();
1149 			want_dbdump = 0;
1150 		}
1151 
1152 		if (reopen_logs) {
1153 			reopen_logs = 0;
1154 			close_log(1);
1155 		}
1156 
1157 
1158 		if (reconfiguring) {
1159 			reconfiguring = 0;
1160 			if (read_config()) {
1161 				hlog(LOG_ERR, "New configuration was not successfully read.");
1162 			} else {
1163 				hlog(LOG_INFO, "New configuration read successfully. Applying....");
1164 				accept_reconfiguring = 1;
1165 				http_reconfiguring = 1;
1166 			}
1167 		}
1168 
1169 		if (cleanup_tick < tick || cleanup_tick > tick + 80) {
1170 			cleanup_tick = tick + 60;
1171 
1172 			status_dump_file();
1173 			historydb_cleanup();
1174 			filter_wx_cleanup();
1175 			filter_entrycall_cleanup();
1176 		}
1177 
1178 		if (version_tick < tick || version_tick > tick + 86500) {
1179 			version_tick = tick + 86400;
1180 			version_report("run");
1181 		}
1182 	}
1183 
1184 	if (liveupgrade_fired)
1185 		hlog(LOG_INFO, "Shutdown for LIVE UPGRADE!");
1186 
1187 	hlog(LOG_INFO, "Signalling threads to shut down...");
1188 	accept_shutting_down = (liveupgrade_fired) ? 2 : 1;
1189 
1190 	if ((e = pthread_join(http_th, NULL)))
1191 		hlog(LOG_ERR, "Could not pthread_join http_th: %s", strerror(e));
1192 	else
1193 		hlog(LOG_INFO, "HTTP thread has terminated.");
1194 
1195 	if ((e = pthread_join(accept_th, NULL)))
1196 		hlog(LOG_ERR, "Could not pthread_join accept_th: %s", strerror(e));
1197 	else
1198 		hlog(LOG_INFO, "Accept thread has terminated.");
1199 
1200 	if ((e = pthread_join(time_th, NULL)))
1201 		hlog(LOG_ERR, "Could not pthread_join time_th: %s", strerror(e));
1202 
1203 	if (dbdump_at_exit) {
1204 		dbdump_all();
1205 	}
1206 
1207 	if (liveupgrade_fired) {
1208 		hlog(LOG_INFO, "Live upgrade: Dumping state to files...");
1209 		if (dbdump_historydb() || status_dump_liveupgrade()) {
1210 			hlog(LOG_ERR, "Live upgrade: Dumps failed - cannot continue!");
1211 			return 1;
1212 		}
1213 		hlog(LOG_INFO, "Live upgrade: Dumps completed.");
1214 		liveupgrade_exec(argc, argv);
1215 	}
1216 
1217 	free_config();
1218 	dupecheck_atend();
1219 	historydb_atend();
1220 	filter_wx_atend();
1221 	filter_entrycall_atend();
1222 	status_atend();
1223 	ssl_atend();
1224 
1225 	hlog(LOG_NOTICE, "Shut down.");
1226 	close_log(0);
1227 
1228 	return 0;
1229 }
1230 
1231