GitHub CI: update list of container images
[tinc] / src / tincctl.c
index b2d98f6..3af0f1f 100644 (file)
 #include "subnet.h"
 #include "keys.h"
 #include "random.h"
+#include "sandbox.h"
 #include "pidfile.h"
 #include "console.h"
+#include "fs.h"
 
 #ifndef MSG_NOSIGNAL
 #define MSG_NOSIGNAL 0
@@ -78,7 +80,7 @@ char *scriptextension = defaultextension;
 static char *prompt;
 char *device = NULL;
 char *iface = NULL;
-int debug_level = -1;
+debug_t debug_level = -1;
 
 typedef enum option_t {
        OPT_BAD_OPTION  = '?',
@@ -108,7 +110,7 @@ static struct option const long_options[] = {
 };
 
 static void version(void) {
-       static const char *message =
+       fprintf(stdout,
                "%s version %s (built %s %s, protocol %d.%d)\n"
                "Features:"
 #ifdef HAVE_READLINE
@@ -119,6 +121,9 @@ static void version(void) {
 #endif
 #ifndef DISABLE_LEGACY
                " legacy_protocol"
+#endif
+#ifdef HAVE_SANDBOX
+               " sandbox"
 #endif
                "\n\n"
                "Copyright (C) 1998-2018 Ivo Timmermans, Guus Sliepen and others.\n"
@@ -126,16 +131,15 @@ static void version(void) {
                "\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);
 }
 
 static void usage(bool status) {
        if(status) {
                fprintf(stderr, "Try `%s --help\' for more information.\n", program_name);
        } else {
-               static const char *message =
+               fprintf(stdout,
                        "Usage: %s [options] command\n"
                        "\n"
                        "Valid options are:\n"
@@ -194,9 +198,8 @@ static void usage(bool status) {
                        "  sign [FILE]                Generate a signed version of a file.\n"
                        "  verify NODE [FILE]         Verify that a file was signed by the given NODE.\n"
                        "\n"
-                       "Report bugs to tinc@tinc-vpn.org.\n";
-
-               printf(message, program_name);
+                       "Report bugs to tinc@tinc-vpn.org.\n",
+                       program_name);
        }
 }
 
@@ -492,6 +495,10 @@ bool recvline(int fd, char *line, size_t len) {
        }
 
        while(!(newline = memchr(buffer, '\n', blen))) {
+               if(!wait_socket_recv(fd)) {
+                       return false;
+               }
+
                ssize_t nrecv = recv(fd, buffer + blen, sizeof(buffer) - blen, 0);
 
                if(nrecv == -1 && sockerrno == EINTR) {
@@ -1517,7 +1524,10 @@ static int cmd_pcap(int argc, char *argv[]) {
 static void sigint_handler(int sig) {
        (void)sig;
 
-       fprintf(stderr, "\n");
+       if(write(2, "\n", 1) < 0) {
+               // nothing we can do
+       }
+
        shutdown(fd, SHUT_RDWR);
 }
 #endif
@@ -1697,6 +1707,7 @@ const var_t variables[] = {
        {"ProcessPriority", VAR_SERVER},
        {"Proxy", VAR_SERVER},
        {"ReplayWindow", VAR_SERVER | VAR_SAFE},
+       {"Sandbox", VAR_SERVER},
        {"ScriptsExtension", VAR_SERVER},
        {"ScriptsInterpreter", VAR_SERVER},
        {"StrictSubnets", VAR_SERVER | VAR_SAFE},
@@ -1928,16 +1939,18 @@ static int cmd_config(int argc, char *argv[]) {
        char filename[PATH_MAX];
 
        if(node) {
-               if((size_t)snprintf(filename, sizeof(filename), "%s" SLASH "%s", hosts_dir, node) >= sizeof(filename)) {
-                       fprintf(stderr, "Filename too long: %s" SLASH "%s\n", hosts_dir, node);
-                       free(node);
-                       return 1;
-               }
+               size_t wrote = (size_t)snprintf(filename, sizeof(filename), "%s" SLASH "%s", hosts_dir, node);
 
                if(node != line) {
                        free(node);
                        node = NULL;
                }
+
+               if(wrote >= sizeof(filename)) {
+                       fprintf(stderr, "Filename too long: %s" SLASH "%s\n", hosts_dir, node);
+                       return 1;
+               }
+
        } else {
                snprintf(filename, sizeof(filename), "%s", tinc_conf);
        }
@@ -2226,19 +2239,8 @@ static int cmd_init(int argc, char *argv[]) {
                return 1;
        }
 
-       if(!confbase_given && mkdir(confdir, 0755) && errno != EEXIST) {
-               fprintf(stderr, "Could not create directory %s: %s\n", confdir, strerror(errno));
-               return 1;
-       }
-
-       if(mkdir(confbase, 0777) && errno != EEXIST) {
-               fprintf(stderr, "Could not create directory %s: %s\n", confbase, strerror(errno));
-               return 1;
-       }
-
-       if(mkdir(hosts_dir, 0777) && errno != EEXIST) {
-               fprintf(stderr, "Could not create directory %s: %s\n", hosts_dir, strerror(errno));
-               return 1;
+       if(!makedirs(DIR_HOSTS | DIR_CONFBASE | DIR_CONFDIR | DIR_CACHE)) {
+               return false;
        }
 
        FILE *f = fopen(tinc_conf, "w");
@@ -2537,7 +2539,7 @@ static int cmd_export_all(int argc, char *argv[]) {
                if(first) {
                        first = false;
                } else {
-                       printf("#---------------------------------------------------------------#\n");
+                       printf("\n#---------------------------------------------------------------#\n");
                }
 
                result |= export(ent->d_name, stdout);
@@ -3352,6 +3354,9 @@ int main(int argc, char *argv[]) {
        crypto_init();
        prng_init();
 
+       sandbox_set_level(SANDBOX_NORMAL);
+       sandbox_enter();
+
        int result = run_command(argc, argv);
 
        random_exit();