Add stricter checks for netnames.
authorGuus Sliepen <guus@tinc-vpn.org>
Sun, 17 Apr 2016 12:38:37 +0000 (14:38 +0200)
committerGuus Sliepen <guus@tinc-vpn.org>
Sun, 17 Apr 2016 12:38:37 +0000 (14:38 +0200)
When passing a NetName via an invitation, we don't allow any characters
that are unsafe (either because they could cause shells to expand things,
or because they are not allowed on some filesystems).

Also, warn when tinc is started with unsafe netnames.

src/invitation.c
src/tincd.c
src/utils.c
src/utils.h

index 35e8e49..08afe78 100644 (file)
@@ -392,7 +392,7 @@ int cmd_invite(int argc, char *argv[]) {
 
        // Fill in the details.
        fprintf(f, "Name = %s\n", argv[1]);
-       if(netname)
+       if(check_netname(netname, true))
                fprintf(f, "NetName = %s\n", netname);
        fprintf(f, "ConnectTo = %s\n", myname);
 
@@ -541,12 +541,17 @@ static bool finalize_join(void) {
        }
 
        if(!check_id(name)) {
-               fprintf(stderr, "Invalid Name found in invitation: %s!\n", name);
+               fprintf(stderr, "Invalid Name found in invitation!\n");
                return false;
        }
 
-       if(!netname)
+       if(!netname) {
                netname = grep(data, "NetName");
+               if(netname && !check_netname(netname, true)) {
+                       fprintf(stderr, "Unsafe NetName found in invitation!\n");
+                       return false;
+               }
+       }
 
        bool ask_netname = false;
        char temp_netname[32];
index 3bc17e2..72bd8f3 100644 (file)
@@ -261,11 +261,14 @@ static bool parse_options(int argc, char **argv) {
                netname = NULL;
        }
 
-       if(netname && (strpbrk(netname, "\\/") || *netname == '.')) {
+       if(netname && !check_netname(netname, false)) {
                fprintf(stderr, "Invalid character in netname!\n");
                return false;
        }
 
+       if(netname && !check_netname(netname, true))
+               fprintf(stderr, "Warning: unsafe character in netname!\n");
+
        return true;
 }
 
index c374eb5..fadfd05 100644 (file)
@@ -191,6 +191,22 @@ bool check_id(const char *id) {
        return true;
 }
 
+bool check_netname(const char *netname, bool strict) {
+       if(!netname || !*netname || *netname == '.')
+               return false;
+
+       for(const char *c = netname; *c; c++) {
+               if(iscntrl(*c))
+                       return false;
+               if(*c == '/' || *c == '\\')
+                       return false;
+               if(strict && strchr(" $%<>:`\"|?*", *c))
+                       return false;
+       }
+
+       return true;
+}
+
 /* Windows doesn't define HOST_NAME_MAX. */
 #ifndef HOST_NAME_MAX
 #define HOST_NAME_MAX 255
index c3364ce..5c387bd 100644 (file)
@@ -51,6 +51,7 @@ extern const char *winerror(int);
 extern unsigned int bitfield_to_int(const void *bitfield, size_t size);
 
 extern bool check_id(const char *);
+extern bool check_netname(const char *, bool strict);
 char *replace_name(const char *name);
 
 #endif /* __TINC_UTILS_H__ */