Stricter checks for netname and node names.
[tinc] / src / tincctl.c
index 1cdcf58..39bd326 100644 (file)
@@ -111,6 +111,7 @@ static void usage(bool status) {
                                "Valid commands are:\n"
                                "  init [name]                Create initial configuration files.\n"
                                "  config                     Change configuration:\n"
+                               "    [get] VARIABLE           - print current value of VARIABLE\n"
                                "    [set] VARIABLE VALUE     - set VARIABLE to VALUE\n"
                                "    add VARIABLE VALUE       - add VARIABLE with the given VALUE\n"
                                "    del VARIABLE [VALUE]     - remove VARIABLE [only ones with watching VALUE]\n"
@@ -193,11 +194,16 @@ static bool parse_options(int argc, char **argv) {
 
         /* netname "." is special: a "top-level name" */
 
-        if(netname && !strcmp(netname, ".")) {
+        if(netname && (!*netname || !strcmp(netname, "."))) {
                 free(netname);
                 netname = NULL;
         }
 
+       if(netname && (strpbrk(netname, "\\/") || *netname == '.')) {
+               fprintf(stderr, "Invalid character in netname!\n");
+               return false;
+       }
+
        return true;
 }
 
@@ -738,7 +744,8 @@ static int cmd_stop(int argc, char *argv[]) {
 }
 
 static int cmd_restart(int argc, char *argv[]) {
-       return cmd_stop(argc, argv) ?: cmd_start(argc, argv);
+       cmd_stop(argc, argv);
+       return cmd_start(argc, argv);
 }
 
 static int cmd_reload(int argc, char *argv[]) {
@@ -941,7 +948,7 @@ static int cmd_log(int argc, char *argv[]) {
 }
 
 static int cmd_pid(int argc, char *argv[]) {
-       if(!connect_tincd())
+       if(!connect_tincd() && !pid)
                return 1;
 
        printf("%d\n", pid);
@@ -1017,6 +1024,7 @@ static struct {
        {"KeyExpire", VAR_SERVER},
        {"LocalDiscovery", VAR_SERVER},
        {"MACExpire", VAR_SERVER},
+       {"MaxOutputBufferSize", VAR_SERVER},
        {"MaxTimeout", VAR_SERVER},
        {"Mode", VAR_SERVER},
        {"Name", VAR_SERVER},
@@ -1026,26 +1034,32 @@ static struct {
        {"PrivateKey", VAR_SERVER | VAR_OBSOLETE},
        {"PrivateKeyFile", VAR_SERVER},
        {"ProcessPriority", VAR_SERVER},
+       {"Proxy", VAR_SERVER},
        {"ReplayWindow", VAR_SERVER},
        {"StrictSubnets", VAR_SERVER},
        {"TunnelServer", VAR_SERVER},
        {"UDPRcvBuf", VAR_SERVER},
        {"UDPSndBuf", VAR_SERVER},
+       {"VDEGroup", VAR_SERVER},
+       {"VDEPort", VAR_SERVER},
        /* Host configuration */
        {"Address", VAR_HOST | VAR_MULTIPLE},
        {"Cipher", VAR_SERVER | VAR_HOST},
        {"ClampMSS", VAR_SERVER | VAR_HOST},
        {"Compression", VAR_SERVER | VAR_HOST},
        {"Digest", VAR_SERVER | VAR_HOST},
+       {"ECDSAPublicKey", VAR_HOST},
+       {"ECDSAPublicKeyFile", VAR_SERVER | VAR_HOST},
        {"IndirectData", VAR_SERVER | VAR_HOST},
        {"MACLength", VAR_SERVER | VAR_HOST},
        {"PMTU", VAR_SERVER | VAR_HOST},
        {"PMTUDiscovery", VAR_SERVER | VAR_HOST},
        {"Port", VAR_HOST},
-       {"PublicKey", VAR_SERVER | VAR_HOST | VAR_OBSOLETE},
+       {"PublicKey", VAR_HOST | VAR_OBSOLETE},
        {"PublicKeyFile", VAR_SERVER | VAR_HOST | VAR_OBSOLETE},
        {"Subnet", VAR_HOST | VAR_MULTIPLE},
        {"TCPOnly", VAR_SERVER | VAR_HOST},
+       {"Weight", VAR_HOST},
        {NULL, 0}
 };
 
@@ -1055,8 +1069,10 @@ static int cmd_config(int argc, char *argv[]) {
                return 1;
        }
 
-       int action = 0;
-       if(!strcasecmp(argv[1], "add")) {
+       int action = -2;
+       if(!strcasecmp(argv[1], "get")) {
+               argv++, argc--;
+       } else if(!strcasecmp(argv[1], "add")) {
                argv++, argc--, action = 1;
        } else if(!strcasecmp(argv[1], "del")) {
                argv++, argc--, action = -1;
@@ -1108,6 +1124,9 @@ static int cmd_config(int argc, char *argv[]) {
                return 1;
        }
 
+       if(action < -1 && *value)
+               action = 0;
+
        /* Some simple checks. */
        bool found = false;
 
@@ -1156,8 +1175,8 @@ static int cmd_config(int argc, char *argv[]) {
                return 1;
        }
 
-       if(!found && action >= 0) {
-               if(force) {
+       if(!found) {
+               if(force || action < 0) {
                        fprintf(stderr, "Warning: %s is not a known configuration variable!\n", variable);
                } else {
                        fprintf(stderr, "%s: is not a known configuration variable! Use --force to use it anyway.\n", variable);
@@ -1189,19 +1208,24 @@ static int cmd_config(int argc, char *argv[]) {
                }
        }
 
-       char *tmpfile;
-       xasprintf(&tmpfile, "%s.config.tmp", filename);
-       FILE *tf = fopen(tmpfile, "w");
-       if(!tf) {
-               fprintf(stderr, "Could not open temporary file %s: %s\n", tmpfile, strerror(errno));
-               return 1;
+       char *tmpfile = NULL;
+       FILE *tf = NULL;
+
+       if(action >= -1) {
+               xasprintf(&tmpfile, "%s.config.tmp", filename);
+               tf = fopen(tmpfile, "w");
+               if(!tf) {
+                       fprintf(stderr, "Could not open temporary file %s: %s\n", tmpfile, strerror(errno));
+                       return 1;
+               }
        }
 
-       // Copy the file, making modifications on the fly.
+       // Copy the file, making modifications on the fly, unless we are just getting a value.
        char buf1[4096];
        char buf2[4096];
        bool set = false;
        bool removed = false;
+       found = false;
 
        while(fgets(buf1, sizeof buf1, f)) {
                buf1[sizeof buf1 - 1] = 0;
@@ -1223,8 +1247,12 @@ static int cmd_config(int argc, char *argv[]) {
 
                // Did it match?
                if(!strcasecmp(buf2, variable)) {
+                       // Get
+                       if(action < -1) {
+                               found = true;
+                               printf("%s\n", bvalue);
                        // Del
-                       if(action < 0) {
+                       } else if(action == -1) {
                                if(!*value || !strcasecmp(bvalue, value)) {
                                        removed = true;
                                        continue;
@@ -1244,18 +1272,20 @@ static int cmd_config(int argc, char *argv[]) {
                        }
                }
 
-               // Copy original line...
-               if(fputs(buf1, tf) < 0) {
-                       fprintf(stderr, "Error writing to temporary file %s: %s\n", tmpfile, strerror(errno));
-                       return 1;
-               }
-
-               // Add newline if it is missing...
-               if(*buf1 && buf1[strlen(buf1) - 1] != '\n') {
-                       if(fputc('\n', tf) < 0) {
+               if(action >= -1) {
+                       // Copy original line...
+                       if(fputs(buf1, tf) < 0) {
                                fprintf(stderr, "Error writing to temporary file %s: %s\n", tmpfile, strerror(errno));
                                return 1;
                        }
+
+                       // Add newline if it is missing...
+                       if(*buf1 && buf1[strlen(buf1) - 1] != '\n') {
+                               if(fputc('\n', tf) < 0) {
+                                       fprintf(stderr, "Error writing to temporary file %s: %s\n", tmpfile, strerror(errno));
+                                       return 1;
+                               }
+                       }
                }
        }
 
@@ -1278,6 +1308,12 @@ static int cmd_config(int argc, char *argv[]) {
                }
        }
 
+       if(action < -1) {
+               if(!found)
+                       fprintf(stderr, "No matching configuration variables found.\n");
+               return 0;
+       }
+
        // Make sure we wrote everything...
        if(fclose(tf)) {
                fprintf(stderr, "Error closing temporary file %s: %s\n", tmpfile, strerror(errno));
@@ -1313,6 +1349,9 @@ static int cmd_config(int argc, char *argv[]) {
 }
 
 bool check_id(const char *name) {
+       if(!name || !*name)
+               return false;
+
        for(int i = 0; i < strlen(name); i++) {
                if(!isalnum(name[i]) && name[i] != '_')
                        return false;