1 /*
2     process.c -- process management functions
3     Copyright (C) 1999-2005 Ivo Timmermans,
4                   2000-2015 Guus Sliepen <guus@tinc-vpn.org>
5 
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10 
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15 
16     You should have received a copy of the GNU General Public License along
17     with this program; if not, write to the Free Software Foundation, Inc.,
18     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20 
21 #include "system.h"
22 
23 #include "conf.h"
24 #include "connection.h"
25 #include "device.h"
26 #include "edge.h"
27 #include "logger.h"
28 #include "net.h"
29 #include "node.h"
30 #include "pidfile.h"
31 #include "process.h"
32 #include "subnet.h"
33 #include "utils.h"
34 #include "xalloc.h"
35 
36 /* If zero, don't detach from the terminal. */
37 bool do_detach = true;
38 bool sighup = false;
39 bool sigalrm = false;
40 
41 extern char *identname;
42 extern char *pidfilename;
43 extern char **g_argv;
44 extern bool use_logfile;
45 
46 #ifndef HAVE_MINGW
47 static sigset_t emptysigset;
48 #endif
49 
50 /* Some functions the less gifted operating systems might lack... */
51 
52 #ifdef HAVE_MINGW
53 extern char *identname;
54 extern char *program_name;
55 extern char **g_argv;
56 
57 static SC_HANDLE manager = NULL;
58 static SC_HANDLE service = NULL;
59 static SERVICE_STATUS status = {0};
60 static SERVICE_STATUS_HANDLE statushandle = 0;
61 
install_service(void)62 bool install_service(void) {
63 	char command[4096] = "\"";
64 	char **argp;
65 	bool space;
66 	SERVICE_DESCRIPTION description = {"Virtual Private Network daemon"};
67 
68 	manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
69 
70 	if(!manager) {
71 		logger(LOG_ERR, "Could not open service manager: %s", winerror(GetLastError()));
72 		return false;
73 	}
74 
75 	if(!strchr(program_name, '\\')) {
76 		GetCurrentDirectory(sizeof(command) - 1, command + 1);
77 		strncat(command, "\\", sizeof(command) - strlen(command));
78 	}
79 
80 	strncat(command, program_name, sizeof(command) - strlen(command));
81 
82 	strncat(command, "\"", sizeof(command) - strlen(command));
83 
84 	for(argp = g_argv + 1; *argp; argp++) {
85 		space = strchr(*argp, ' ');
86 		strncat(command, " ", sizeof(command) - strlen(command));
87 
88 		if(space) {
89 			strncat(command, "\"", sizeof(command) - strlen(command));
90 		}
91 
92 		strncat(command, *argp, sizeof(command) - strlen(command));
93 
94 		if(space) {
95 			strncat(command, "\"", sizeof(command) - strlen(command));
96 		}
97 	}
98 
99 	service = CreateService(manager, identname, identname,
100 	                        SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL,
101 	                        command, NULL, NULL, NULL, NULL, NULL);
102 
103 	if(!service) {
104 		DWORD lasterror = GetLastError();
105 		logger(LOG_ERR, "Could not create %s service: %s", identname, winerror(lasterror));
106 
107 		if(lasterror != ERROR_SERVICE_EXISTS) {
108 			return false;
109 		}
110 	}
111 
112 	if(service) {
113 		ChangeServiceConfig2(service, SERVICE_CONFIG_DESCRIPTION, &description);
114 		logger(LOG_INFO, "%s service installed", identname);
115 	} else {
116 		service = OpenService(manager, identname, SERVICE_ALL_ACCESS);
117 	}
118 
119 	if(!StartService(service, 0, NULL)) {
120 		logger(LOG_WARNING, "Could not start %s service: %s", identname, winerror(GetLastError()));
121 	} else {
122 		logger(LOG_INFO, "%s service started", identname);
123 	}
124 
125 	return true;
126 }
127 
remove_service(void)128 bool remove_service(void) {
129 	manager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
130 
131 	if(!manager) {
132 		logger(LOG_ERR, "Could not open service manager: %s", winerror(GetLastError()));
133 		return false;
134 	}
135 
136 	service = OpenService(manager, identname, SERVICE_ALL_ACCESS);
137 
138 	if(!service) {
139 		logger(LOG_ERR, "Could not open %s service: %s", identname, winerror(GetLastError()));
140 		return false;
141 	}
142 
143 	if(!ControlService(service, SERVICE_CONTROL_STOP, &status)) {
144 		logger(LOG_ERR, "Could not stop %s service: %s", identname, winerror(GetLastError()));
145 	} else {
146 		logger(LOG_INFO, "%s service stopped", identname);
147 	}
148 
149 	if(!DeleteService(service)) {
150 		logger(LOG_ERR, "Could not remove %s service: %s", identname, winerror(GetLastError()));
151 		return false;
152 	}
153 
154 	logger(LOG_INFO, "%s service removed", identname);
155 
156 	return true;
157 }
158 
controlhandler(DWORD request,DWORD type,LPVOID boe,LPVOID bah)159 DWORD WINAPI controlhandler(DWORD request, DWORD type, LPVOID boe, LPVOID bah) {
160 	switch(request) {
161 	case SERVICE_CONTROL_INTERROGATE:
162 		SetServiceStatus(statushandle, &status);
163 		return NO_ERROR;
164 
165 	case SERVICE_CONTROL_STOP:
166 		logger(LOG_NOTICE, "Got %s request", "SERVICE_CONTROL_STOP");
167 		break;
168 
169 	case SERVICE_CONTROL_SHUTDOWN:
170 		logger(LOG_NOTICE, "Got %s request", "SERVICE_CONTROL_SHUTDOWN");
171 		break;
172 
173 	default:
174 		logger(LOG_WARNING, "Got unexpected request %d", (int)request);
175 		return ERROR_CALL_NOT_IMPLEMENTED;
176 	}
177 
178 	if(running) {
179 		running = false;
180 		status.dwWaitHint = 30000;
181 		status.dwCurrentState = SERVICE_STOP_PENDING;
182 		SetServiceStatus(statushandle, &status);
183 		return NO_ERROR;
184 	} else {
185 		status.dwWaitHint = 0;
186 		status.dwCurrentState = SERVICE_STOPPED;
187 		SetServiceStatus(statushandle, &status);
188 		exit(1);
189 	}
190 
191 }
192 
run_service(DWORD argc,LPTSTR * argv)193 VOID WINAPI run_service(DWORD argc, LPTSTR *argv) {
194 	extern int main2(int argc, char **argv);
195 
196 	status.dwServiceType = SERVICE_WIN32;
197 	status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
198 	status.dwWin32ExitCode = 0;
199 	status.dwServiceSpecificExitCode = 0;
200 	status.dwCheckPoint = 0;
201 
202 	statushandle = RegisterServiceCtrlHandlerEx(identname, controlhandler, NULL);
203 
204 	if(!statushandle) {
205 		logger(LOG_ERR, "System call `%s' failed: %s", "RegisterServiceCtrlHandlerEx", winerror(GetLastError()));
206 	} else {
207 		status.dwWaitHint = 30000;
208 		status.dwCurrentState = SERVICE_START_PENDING;
209 		SetServiceStatus(statushandle, &status);
210 
211 		status.dwWaitHint = 0;
212 		status.dwCurrentState = SERVICE_RUNNING;
213 		SetServiceStatus(statushandle, &status);
214 
215 		main2(argc, argv);
216 
217 		status.dwWaitHint = 0;
218 		status.dwCurrentState = SERVICE_STOPPED;
219 		SetServiceStatus(statushandle, &status);
220 	}
221 
222 	return;
223 }
224 
init_service(void)225 bool init_service(void) {
226 	SERVICE_TABLE_ENTRY services[] = {
227 		{identname, run_service},
228 		{NULL, NULL}
229 	};
230 
231 	if(!StartServiceCtrlDispatcher(services)) {
232 		if(GetLastError() == ERROR_FAILED_SERVICE_CONTROLLER_CONNECT) {
233 			return false;
234 		} else {
235 			logger(LOG_ERR, "System call `%s' failed: %s", "StartServiceCtrlDispatcher", winerror(GetLastError()));
236 		}
237 	}
238 
239 	return true;
240 }
241 #endif
242 
243 #ifndef HAVE_MINGW
244 /*
245   check for an existing tinc for this net, and write pid to pidfile
246 */
write_pidfile(void)247 static bool write_pidfile(void) {
248 	pid_t pid;
249 
250 	pid = check_pid(pidfilename);
251 
252 	if(pid) {
253 		if(netname)
254 			fprintf(stderr, "A tincd is already running for net `%s' with pid %ld.\n",
255 			        netname, (long)pid);
256 		else {
257 			fprintf(stderr, "A tincd is already running with pid %ld.\n", (long)pid);
258 		}
259 
260 		return false;
261 	}
262 
263 	/* if it's locked, write-protected, or whatever */
264 	if(!write_pid(pidfilename)) {
265 		fprintf(stderr, "Couldn't write pid file %s: %s\n", pidfilename, strerror(errno));
266 		return false;
267 	}
268 
269 	return true;
270 }
271 #endif
272 
273 /*
274   kill older tincd for this net
275 */
kill_other(int signal)276 bool kill_other(int signal) {
277 #ifndef HAVE_MINGW
278 	pid_t pid;
279 
280 	pid = read_pid(pidfilename);
281 
282 	if(!pid) {
283 		if(netname)
284 			fprintf(stderr, "No other tincd is running for net `%s'.\n",
285 			        netname);
286 		else {
287 			fprintf(stderr, "No other tincd is running.\n");
288 		}
289 
290 		return false;
291 	}
292 
293 	errno = 0;                                      /* No error, sometimes errno is only changed on error */
294 
295 	/* ESRCH is returned when no process with that pid is found */
296 	if(kill(pid, signal) && errno == ESRCH) {
297 		if(netname)
298 			fprintf(stderr, "The tincd for net `%s' is no longer running. ",
299 			        netname);
300 		else {
301 			fprintf(stderr, "The tincd is no longer running. ");
302 		}
303 
304 		fprintf(stderr, "Removing stale lock file.\n");
305 		remove_pid(pidfilename);
306 	}
307 
308 	return true;
309 #else
310 	return remove_service();
311 #endif
312 }
313 
314 /*
315   Detach from current terminal, write pidfile, kill parent
316 */
detach(void)317 bool detach(void) {
318 	setup_signals();
319 
320 	/* First check if we can open a fresh new pidfile */
321 
322 #ifndef HAVE_MINGW
323 
324 	if(!write_pidfile()) {
325 		return false;
326 	}
327 
328 	/* If we succeeded in doing that, detach */
329 
330 	closelogger();
331 #endif
332 
333 	if(do_detach) {
334 #ifndef HAVE_MINGW
335 
336 		if(daemon(0, 0)) {
337 			fprintf(stderr, "Couldn't detach from terminal: %s",
338 			        strerror(errno));
339 			return false;
340 		}
341 
342 		/* Now UPDATE the pid in the pidfile, because we changed it... */
343 
344 		if(!write_pid(pidfilename)) {
345 			fprintf(stderr, "Could not write pid file %s: %s\n", pidfilename, strerror(errno));
346 			return false;
347 		}
348 
349 #else
350 
351 		if(!statushandle) {
352 			exit(install_service());
353 		}
354 
355 #endif
356 	}
357 
358 	openlogger(identname, use_logfile ? LOGMODE_FILE : (do_detach ? LOGMODE_SYSLOG : LOGMODE_STDERR));
359 
360 	logger(LOG_NOTICE, "tincd %s starting, debug level %d",
361 	       VERSION, debug_level);
362 
363 	return true;
364 }
365 
366 #ifdef HAVE_PUTENV
unputenv(char * p)367 void unputenv(char *p) {
368 	char *e = strchr(p, '=');
369 
370 	if(!e) {
371 		return;
372 	}
373 
374 	int len = e - p;
375 #ifndef HAVE_UNSETENV
376 #ifdef HAVE_MINGW
377 	// Windows requires putenv("FOO=") to unset %FOO%
378 	len++;
379 #endif
380 #endif
381 	char var[len + 1];
382 	memcpy(var, p, len);
383 	var[len] = 0;
384 #ifdef HAVE_UNSETENV
385 	unsetenv(var);
386 #else
387 	// We must keep what we putenv() around in memory.
388 	// To do this without memory leaks, keep things in a list and reuse if possible.
389 	static list_t list = {};
390 
391 	for(list_node_t *node = list.head; node; node = node->next) {
392 		char *data = node->data;
393 
394 		if(!strcmp(data, var)) {
395 			putenv(data);
396 			return;
397 		}
398 	}
399 
400 	char *data = xstrdup(var);
401 	list_insert_tail(&list, data);
402 	putenv(data);
403 #endif
404 }
405 #else
putenv(const char * p)406 void putenv(const char *p) {}
unputenv(const char * p)407 void unputenv(const char *p) {}
408 #endif
409 
execute_script(const char * name,char ** envp)410 bool execute_script(const char *name, char **envp) {
411 #ifdef HAVE_SYSTEM
412 	char *scriptname;
413 	char *interpreter = NULL;
414 	config_t *cfg_interpreter;
415 	int status, len, i;
416 
417 	cfg_interpreter = lookup_config(config_tree, "ScriptsInterpreter");
418 #ifndef HAVE_MINGW
419 	len = xasprintf(&scriptname, "\"%s/%s\"", confbase, name);
420 #else
421 
422 	if(cfg_interpreter) {
423 		len = xasprintf(&scriptname, "\"%s/%s\"", confbase, name);
424 	} else {
425 		len = xasprintf(&scriptname, "\"%s/%s.bat\"", confbase, name);
426 	}
427 
428 #endif
429 
430 	if(len < 0) {
431 		return false;
432 	}
433 
434 	scriptname[len - 1] = '\0';
435 
436 	/* First check if there is a script */
437 	if(access(scriptname + 1, F_OK)) {
438 		free(scriptname);
439 		return true;
440 	}
441 
442 	// Custom scripts interpreter
443 	if(get_config_string(cfg_interpreter, &interpreter)) {
444 		// Force custom scripts interpreter allowing execution of scripts on android without execution flag (such as on /sdcard)
445 		free(scriptname);
446 		len = xasprintf(&scriptname, "%s \"%s/%s\"", interpreter, confbase, name);
447 		free(interpreter);
448 
449 		if(len < 0) {
450 			return false;
451 		}
452 	}
453 
454 	ifdebug(STATUS) logger(LOG_INFO, "Executing script %s", name);
455 
456 	/* Set environment */
457 
458 	for(i = 0; envp[i]; i++) {
459 		putenv(envp[i]);
460 	}
461 
462 	scriptname[len - 1] = '\"';
463 	status = system(scriptname);
464 
465 	free(scriptname);
466 
467 	/* Unset environment */
468 
469 	for(i = 0; envp[i]; i++) {
470 		unputenv(envp[i]);
471 	}
472 
473 	if(status != -1) {
474 #ifdef WEXITSTATUS
475 
476 		if(WIFEXITED(status)) { /* Child exited by itself */
477 			if(WEXITSTATUS(status)) {
478 				logger(LOG_ERR, "Script %s exited with non-zero status %d",
479 				       name, WEXITSTATUS(status));
480 				return false;
481 			}
482 		} else if(WIFSIGNALED(status)) {        /* Child was killed by a signal */
483 			logger(LOG_ERR, "Script %s was killed by signal %d (%s)",
484 			       name, WTERMSIG(status), strsignal(WTERMSIG(status)));
485 			return false;
486 		} else {                        /* Something strange happened */
487 			logger(LOG_ERR, "Script %s terminated abnormally", name);
488 			return false;
489 		}
490 
491 #endif
492 	} else {
493 		logger(LOG_ERR, "System call `%s' failed: %s", "system", strerror(errno));
494 		return false;
495 	}
496 
497 #endif
498 	return true;
499 }
500 
501 
502 /*
503   Signal handlers.
504 */
505 
506 #ifndef HAVE_MINGW
sigterm_handler(int a)507 static RETSIGTYPE sigterm_handler(int a) {
508 	(void)a;
509 	logger(LOG_NOTICE, "Got %s signal", "TERM");
510 
511 	if(running) {
512 		running = false;
513 	} else {
514 		exit(1);
515 	}
516 }
517 
sigquit_handler(int a)518 static RETSIGTYPE sigquit_handler(int a) {
519 	(void)a;
520 	logger(LOG_NOTICE, "Got %s signal", "QUIT");
521 
522 	if(running) {
523 		running = false;
524 	} else {
525 		exit(1);
526 	}
527 }
528 
fatal_signal_square(int a)529 static RETSIGTYPE fatal_signal_square(int a) {
530 	logger(LOG_ERR, "Got another fatal signal %d (%s): not restarting.", a,
531 	       strsignal(a));
532 	exit(1);
533 }
534 
fatal_signal_handler(int a)535 static RETSIGTYPE fatal_signal_handler(int a) {
536 	struct sigaction act;
537 	logger(LOG_ERR, "Got fatal signal %d (%s)", a, strsignal(a));
538 
539 	if(do_detach) {
540 		logger(LOG_NOTICE, "Trying to re-execute in 5 seconds...");
541 
542 		act.sa_handler = fatal_signal_square;
543 		act.sa_mask = emptysigset;
544 		act.sa_flags = 0;
545 		sigaction(SIGSEGV, &act, NULL);
546 
547 		close_network_connections();
548 		sleep(5);
549 		remove_pid(pidfilename);
550 		execvp(g_argv[0], g_argv);
551 	} else {
552 		logger(LOG_NOTICE, "Not restarting.");
553 		exit(1);
554 	}
555 }
556 
sighup_handler(int a)557 static RETSIGTYPE sighup_handler(int a) {
558 	(void)a;
559 	logger(LOG_NOTICE, "Got %s signal", "HUP");
560 	sighup = true;
561 }
562 
sigint_handler(int a)563 static RETSIGTYPE sigint_handler(int a) {
564 	(void)a;
565 	static int saved_debug_level = -1;
566 
567 	logger(LOG_NOTICE, "Got %s signal", "INT");
568 
569 	if(saved_debug_level != -1) {
570 		logger(LOG_NOTICE, "Reverting to old debug level (%d)",
571 		       saved_debug_level);
572 		debug_level = saved_debug_level;
573 		saved_debug_level = -1;
574 	} else {
575 		logger(LOG_NOTICE,
576 		       "Temporarily setting debug level to 5.  Kill me with SIGINT again to go back to level %d.",
577 		       debug_level);
578 		saved_debug_level = debug_level;
579 		debug_level = 5;
580 	}
581 }
582 
sigalrm_handler(int a)583 static RETSIGTYPE sigalrm_handler(int a) {
584 	(void)a;
585 	logger(LOG_NOTICE, "Got %s signal", "ALRM");
586 	sigalrm = true;
587 }
588 
sigusr1_handler(int a)589 static RETSIGTYPE sigusr1_handler(int a) {
590 	(void)a;
591 	dump_connections();
592 }
593 
sigusr2_handler(int a)594 static RETSIGTYPE sigusr2_handler(int a) {
595 	(void)a;
596 	devops.dump_stats();
597 	dump_nodes();
598 	dump_edges();
599 	dump_subnets();
600 }
601 
sigwinch_handler(int a)602 static RETSIGTYPE sigwinch_handler(int a) {
603 	(void)a;
604 	do_purge = true;
605 }
606 
unexpected_signal_handler(int a)607 static RETSIGTYPE unexpected_signal_handler(int a) {
608 	(void)a;
609 	logger(LOG_WARNING, "Got unexpected signal %d (%s)", a, strsignal(a));
610 }
611 
ignore_signal_handler(int a)612 static RETSIGTYPE ignore_signal_handler(int a) {
613 	(void)a;
614 	ifdebug(SCARY_THINGS) logger(LOG_DEBUG, "Ignored signal %d (%s)", a, strsignal(a));
615 }
616 
617 static struct {
618 	int signal;
619 	void (*handler)(int);
620 } sighandlers[] = {
621 	{SIGHUP, sighup_handler},
622 	{SIGTERM, sigterm_handler},
623 	{SIGQUIT, sigquit_handler},
624 	{SIGSEGV, fatal_signal_handler},
625 	{SIGBUS, fatal_signal_handler},
626 	{SIGILL, fatal_signal_handler},
627 	{SIGPIPE, ignore_signal_handler},
628 	{SIGINT, sigint_handler},
629 	{SIGUSR1, sigusr1_handler},
630 	{SIGUSR2, sigusr2_handler},
631 	{SIGCHLD, ignore_signal_handler},
632 	{SIGALRM, sigalrm_handler},
633 	{SIGWINCH, sigwinch_handler},
634 	{SIGABRT, SIG_DFL},
635 	{0, NULL}
636 };
637 #endif
638 
setup_signals(void)639 void setup_signals(void) {
640 #ifndef HAVE_MINGW
641 	int i;
642 	struct sigaction act;
643 
644 	sigemptyset(&emptysigset);
645 	act.sa_handler = NULL;
646 	act.sa_mask = emptysigset;
647 	act.sa_flags = 0;
648 
649 	/* Set a default signal handler for every signal, errors will be
650 	   ignored. */
651 	for(i = 1; i < NSIG; i++) {
652 		if(!do_detach) {
653 			act.sa_handler = SIG_DFL;
654 		} else {
655 			act.sa_handler = unexpected_signal_handler;
656 		}
657 
658 		sigaction(i, &act, NULL);
659 	}
660 
661 	/* If we didn't detach, allow coredumps */
662 	if(!do_detach) {
663 		sighandlers[3].handler = SIG_DFL;
664 	}
665 
666 	/* Then, for each known signal that we want to catch, assign a
667 	   handler to the signal, with error checking this time. */
668 	for(i = 0; sighandlers[i].signal; i++) {
669 		act.sa_handler = sighandlers[i].handler;
670 
671 		if(sigaction(sighandlers[i].signal, &act, NULL) < 0)
672 			fprintf(stderr, "Installing signal handler for signal %d (%s) failed: %s\n",
673 			        sighandlers[i].signal, strsignal(sighandlers[i].signal),
674 			        strerror(errno));
675 	}
676 
677 #endif
678 }
679