Add tests for some device & address variables
[tinc] / src / tincd.c
index 06e6713..4c33dc0 100644 (file)
@@ -55,6 +55,9 @@
 #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;
@@ -130,7 +133,7 @@ static void usage(bool status) {
                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"
@@ -152,9 +155,8 @@ static void usage(bool status) {
                        "      --help                    Display this help and exit.\n"
                        "      --version                 Output version information and exit.\n"
                        "\n"
-                       "Report bugs to tinc@tinc-vpn.org.\n";
-
-               printf(message, program_name);
+                       "Report bugs to tinc@tinc-vpn.org.\n",
+                       program_name);
        }
 }
 
@@ -185,6 +187,7 @@ static bool parse_options(int argc, char **argv) {
                        goto exit_fail;
 
                case OPT_CONFIG_FILE:
+                       assert(optarg);
                        free(confbase);
                        confbase = get_path_arg(optarg);
                        break;
@@ -216,6 +219,7 @@ static bool parse_options(int argc, char **argv) {
                        break;
 
                case OPT_NETNAME:
+                       assert(optarg);
                        free(netname);
                        netname = xstrdup(optarg);
                        break;
@@ -280,6 +284,7 @@ static bool parse_options(int argc, char **argv) {
                        break;
 
                case OPT_PIDFILE:
+                       assert(optarg);
                        free(pidfilename);
                        pidfilename = get_path_arg(optarg);
                        break;
@@ -323,6 +328,44 @@ exit_fail:
        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;
@@ -373,8 +416,11 @@ static bool drop_privs(void) {
                        return false;
                }
 
-#endif
-       return true;
+#endif // HAVE_WINDOWS
+
+       makedirs(DIR_CACHE | DIR_HOSTS | DIR_INVITATIONS);
+
+       return sandbox_enter();
 }
 
 #ifdef HAVE_WINDOWS
@@ -419,7 +465,7 @@ int main(int argc, char **argv) {
        }
 
        if(show_version) {
-               static const char *message =
+               fprintf(stdout,
                        "%s version %s (built %s %s, protocol %d.%d)\n"
                        "Features:"
 #ifdef HAVE_OPENSSL
@@ -449,11 +495,17 @@ int main(int argc, char **argv) {
 #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"
@@ -461,9 +513,8 @@ int main(int argc, char **argv) {
                        "\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;
        }
 
@@ -515,7 +566,9 @@ int main(int argc, char **argv) {
 
        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;
        }
 
@@ -532,6 +585,10 @@ int main(int argc, char **argv) {
                return 1;
        }
 
+       if(!read_sandbox_level()) {
+               return 1;
+       }
+
        if(debug_level == DEBUG_NOTHING) {
                int level = 0;
 
@@ -646,8 +703,16 @@ int main2(int argc, char **argv) {
 
        try_outgoing_connections();
 
+#ifdef HAVE_WATCHDOG
+       watchdog_start();
+#endif
+
        status = main_loop();
 
+#ifdef HAVE_WATCHDOG
+       watchdog_stop();
+#endif
+
        /* Shutdown properly. */
 
 end: