#include "xalloc.h"
#include "version.h"
#include "random.h"
+#include "sandbox.h"
+#include "watchdog.h"
+#include "fs.h"
/* If nonzero, display usage information and exit. */
static bool show_help = false;
fprintf(stderr, "Try `%s --help\' for more information.\n",
program_name);
else {
- static const char *message =
+ fprintf(stdout,
"Usage: %s [option]...\n"
"\n"
" -c, --config=DIR Read configuration options from DIR.\n"
" --help Display this help and exit.\n"
" --version Output version information and exit.\n"
"\n"
- "Report bugs to tinc@tinc-vpn.org.\n";
+ "Report bugs to tinc@tinc-vpn.org.\n",
+ program_name);
+ }
+}
- printf(message, program_name);
+// Try to resolve path to absolute, return a copy of the argument if this fails.
+static char *get_path_arg(char *arg) {
+ char *result = absolute_path(arg);
+
+ if(!result) {
+ result = xstrdup(arg);
}
+
+ return result;
}
static bool parse_options(int argc, char **argv) {
goto exit_fail;
case OPT_CONFIG_FILE:
+ assert(optarg);
free(confbase);
- confbase = xstrdup(optarg);
+ confbase = get_path_arg(optarg);
break;
case OPT_NO_DETACH:
break;
case OPT_NETNAME:
+ assert(optarg);
free(netname);
netname = xstrdup(optarg);
break;
if(optarg) {
free(logfilename);
- logfilename = xstrdup(optarg);
+ logfilename = get_path_arg(optarg);
}
break;
case OPT_PIDFILE:
+ assert(optarg);
free(pidfilename);
- pidfilename = xstrdup(optarg);
+ pidfilename = get_path_arg(optarg);
break;
default:
return false;
}
+static bool read_sandbox_level(void) {
+ sandbox_level_t level;
+ char *value = NULL;
+
+ if(get_config_string(lookup_config(&config_tree, "Sandbox"), &value)) {
+ if(!strcasecmp("off", value)) {
+ level = SANDBOX_NONE;
+ } else if(!strcasecmp("normal", value)) {
+ level = SANDBOX_NORMAL;
+ } else if(!strcasecmp("high", value)) {
+ level = SANDBOX_HIGH;
+ } else {
+ logger(DEBUG_ALWAYS, LOG_ERR, "Bad sandbox value %s!", value);
+ free(value);
+ return false;
+ }
+
+ free(value);
+ } else {
+#ifdef HAVE_SANDBOX
+ level = SANDBOX_NORMAL;
+#else
+ level = SANDBOX_NONE;
+#endif
+ }
+
+#ifndef HAVE_SANDBOX
+
+ if(level > SANDBOX_NONE) {
+ logger(DEBUG_ALWAYS, LOG_ERR, "Sandbox is used but is not supported on this platform");
+ return false;
+ }
+
+#endif
+ sandbox_set_level(level);
+ return true;
+}
+
static bool drop_privs(void) {
#ifndef HAVE_WINDOWS
uid_t uid = 0;
return false;
}
-#endif
- return true;
+#endif // HAVE_WINDOWS
+
+ makedirs(DIR_CACHE | DIR_HOSTS | DIR_INVITATIONS);
+
+ return sandbox_enter();
}
#ifdef HAVE_WINDOWS
}
if(show_version) {
- static const char *message =
+ fprintf(stdout,
"%s version %s (built %s %s, protocol %d.%d)\n"
"Features:"
#ifdef HAVE_OPENSSL
#ifdef HAVE_MINIUPNPC
" miniupnpc"
#endif
+#ifdef HAVE_SANDBOX
+ " sandbox"
+#endif
#ifdef ENABLE_UML
" uml"
#endif
#ifdef ENABLE_VDE
" vde"
+#endif
+#ifdef HAVE_WATCHDOG
+ " watchdog"
#endif
"\n\n"
"Copyright (C) 1998-2021 Ivo Timmermans, Guus Sliepen and others.\n"
"\n"
"tinc comes with ABSOLUTELY NO WARRANTY. This is free software,\n"
"and you are welcome to redistribute it under certain conditions;\n"
- "see the file COPYING for details.\n";
-
- printf(message, PACKAGE, BUILD_VERSION, BUILD_DATE, BUILD_TIME, PROT_MAJOR, PROT_MINOR);
+ "see the file COPYING for details.\n",
+ PACKAGE, BUILD_VERSION, BUILD_DATE, BUILD_TIME, PROT_MAJOR, PROT_MINOR);
return 0;
}
g_argv = argv;
- if(getenv("LISTEN_PID") && atoi(getenv("LISTEN_PID")) == getpid()) {
+ const char *listen_pid = getenv("LISTEN_PID");
+
+ if(listen_pid && atoi(listen_pid) == getpid()) {
do_detach = false;
}
return 1;
}
+ if(!read_sandbox_level()) {
+ return 1;
+ }
+
if(debug_level == DEBUG_NOTHING) {
int level = 0;
try_outgoing_connections();
+#ifdef HAVE_WATCHDOG
+ watchdog_start();
+#endif
+
status = main_loop();
+#ifdef HAVE_WATCHDOG
+ watchdog_stop();
+#endif
+
/* Shutdown properly. */
end: