Refactor crypto RNG; add getrandom() support
[tinc] / src / tincctl.c
index a3978bc..fe00912 100644 (file)
@@ -19,8 +19,6 @@
 
 #include "system.h"
 
-#include <getopt.h>
-
 #ifdef HAVE_READLINE
 #include "readline/readline.h"
 #include "readline/history.h"
@@ -42,6 +40,7 @@
 #include "version.h"
 #include "subnet.h"
 #include "keys.h"
+#include "random.h"
 
 #ifndef MSG_NOSIGNAL
 #define MSG_NOSIGNAL 0
@@ -283,7 +282,7 @@ ask_filename:
                }
        }
 
-#ifdef HAVE_MINGW
+#ifdef HAVE_WINDOWS
 
        if(filename[0] != '\\' && filename[0] != '/' && !strchr(filename, ':')) {
 #else
@@ -646,14 +645,14 @@ static bool stop_tincd(void) {
                // wait for tincd to close the connection...
        }
 
-       close(fd);
+       closesocket(fd);
        pid = 0;
        fd = -1;
 
        return true;
 }
 
-#ifdef HAVE_MINGW
+#ifdef HAVE_WINDOWS
 static bool remove_service(void) {
        SC_HANDLE manager = NULL;
        SC_HANDLE service = NULL;
@@ -719,7 +718,7 @@ bool connect_tincd(bool verbose) {
 
                if(select(fd + 1, &r, NULL, NULL, &tv)) {
                        fprintf(stderr, "Previous connection to tincd lost, reconnecting.\n");
-                       close(fd);
+                       closesocket(fd);
                        fd = -1;
                } else {
                        return true;
@@ -750,7 +749,7 @@ bool connect_tincd(bool verbose) {
 
        fclose(f);
 
-#ifndef HAVE_MINGW
+#ifndef HAVE_WINDOWS
 
        if((pid == 0) || (kill(pid, 0) && (errno == ESRCH))) {
                fprintf(stderr, "Could not find tincd running at pid %d\n", pid);
@@ -786,7 +785,7 @@ bool connect_tincd(bool verbose) {
                        fprintf(stderr, "Cannot connect to UNIX socket %s: %s\n", unixsocketname, sockstrerror(sockerrno));
                }
 
-               close(fd);
+               closesocket(fd);
                fd = -1;
                return false;
        }
@@ -832,7 +831,7 @@ bool connect_tincd(bool verbose) {
                        fprintf(stderr, "Cannot connect to %s port %s: %s\n", host, port, sockstrerror(sockerrno));
                }
 
-               close(fd);
+               closesocket(fd);
                fd = -1;
                return false;
        }
@@ -855,7 +854,7 @@ bool connect_tincd(bool verbose) {
                        fprintf(stderr, "Cannot read greeting from control socket: %s\n", sockstrerror(sockerrno));
                }
 
-               close(fd);
+               closesocket(fd);
                fd = -1;
                return false;
        }
@@ -865,7 +864,7 @@ bool connect_tincd(bool verbose) {
                        fprintf(stderr, "Could not fully establish control socket connection\n");
                }
 
-               close(fd);
+               closesocket(fd);
                fd = -1;
                return false;
        }
@@ -888,7 +887,7 @@ static int cmd_start(int argc, char *argv[]) {
        char *c;
        char *slash = strrchr(program_name, '/');
 
-#ifdef HAVE_MINGW
+#ifdef HAVE_WINDOWS
 
        if((c = strrchr(program_name, '\\')) > slash) {
                slash = c;
@@ -906,7 +905,7 @@ static int cmd_start(int argc, char *argv[]) {
        char **nargv = xzalloc((optind + argc) * sizeof(*nargv));
 
        char *arg0 = c;
-#ifdef HAVE_MINGW
+#ifdef HAVE_WINDOWS
        /*
           Windows has no real concept of an "argv array". A command line is just one string.
           The CRT of the new process will decode the command line string to generate argv before calling main(), and (by convention)
@@ -927,7 +926,7 @@ static int cmd_start(int argc, char *argv[]) {
                nargv[nargc++] = argv[i];
        }
 
-#ifdef HAVE_MINGW
+#ifdef HAVE_WINDOWS
        int status = spawnvp(_P_WAIT, c, nargv);
 
        free(nargv);
@@ -1026,7 +1025,7 @@ static int cmd_stop(int argc, char *argv[]) {
                return 1;
        }
 
-#ifdef HAVE_MINGW
+#ifdef HAVE_WINDOWS
        return remove_service() ? EXIT_SUCCESS : EXIT_FAILURE;
 #else
 
@@ -1530,7 +1529,7 @@ static int cmd_log(int argc, char *argv[]) {
        signal(SIGINT, SIG_DFL);
 #endif
 
-       close(fd);
+       closesocket(fd);
        fd = -1;
        return 0;
 }
@@ -1894,7 +1893,11 @@ static int cmd_config(int argc, char *argv[]) {
        char filename[PATH_MAX];
 
        if(node) {
-               snprintf(filename, sizeof(filename), "%s" SLASH "%s", hosts_dir, 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;
+               }
 
                if(node != line) {
                        free(node);
@@ -2056,7 +2059,7 @@ static int cmd_config(int argc, char *argv[]) {
        }
 
        // Replace the configuration file with the new one
-#ifdef HAVE_MINGW
+#ifdef HAVE_WINDOWS
 
        if(remove(filename)) {
                fprintf(stderr, "Error replacing file %s: %s\n", filename, strerror(errno));
@@ -2232,7 +2235,7 @@ static int cmd_init(int argc, char *argv[]) {
 
        check_port(name);
 
-#ifndef HAVE_MINGW
+#ifndef HAVE_WINDOWS
        char filename[PATH_MAX];
        snprintf(filename, sizeof(filename), "%s" SLASH "tinc-up", confbase);
 
@@ -2394,7 +2397,7 @@ static int cmd_edit(int argc, char *argv[]) {
        }
 
        char *command;
-#ifndef HAVE_MINGW
+#ifndef HAVE_WINDOWS
        const char *editor = getenv("VISUAL");
 
        if(!editor) {
@@ -2621,7 +2624,7 @@ static int switch_network(char *name) {
        }
 
        if(fd >= 0) {
-               close(fd);
+               closesocket(fd);
                fd = -1;
        }
 
@@ -3264,6 +3267,22 @@ static void cleanup(void) {
        free_names();
 }
 
+static int run_command(int argc, char *argv[]) {
+       if(optind >= argc) {
+               return cmd_shell(argc, argv);
+       }
+
+       for(int i = 0; commands[i].command; i++) {
+               if(!strcasecmp(argv[optind], commands[i].command)) {
+                       return commands[i].function(argc - optind, argv + optind);
+               }
+       }
+
+       fprintf(stderr, "Unknown command `%s'.\n", argv[optind]);
+       usage(true);
+       return 1;
+}
+
 int main(int argc, char *argv[]) {
        program_name = argv[0];
        orig_argv = argv;
@@ -3288,7 +3307,7 @@ int main(int argc, char *argv[]) {
                return 0;
        }
 
-#ifdef HAVE_MINGW
+#ifdef HAVE_WINDOWS
        static struct WSAData wsa_state;
 
        if(WSAStartup(MAKEWORD(2, 2), &wsa_state)) {
@@ -3299,20 +3318,13 @@ int main(int argc, char *argv[]) {
 #endif
 
        gettimeofday(&now, NULL);
+       random_init();
        crypto_init();
        prng_init();
 
-       if(optind >= argc) {
-               return cmd_shell(argc, argv);
-       }
+       int result = run_command(argc, argv);
 
-       for(int i = 0; commands[i].command; i++) {
-               if(!strcasecmp(argv[optind], commands[i].command)) {
-                       return commands[i].function(argc - optind, argv + optind);
-               }
-       }
+       random_exit();
 
-       fprintf(stderr, "Unknown command `%s'.\n", argv[optind]);
-       usage(true);
-       return 1;
+       return result;
 }