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 35e8e4920e68c20efa472803f1fae58abc55e809..08afe7853fd9ebebadb5b3aa6aa4a97e8f208045 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 3bc17e233fd34f69c77dc094f1c91499a0ccd938..72bd8f3134b65cf3baee793449b885bee866dab3 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 c374eb5d85e0fadead7bbf2b870d78af3d4b1f54..fadfd05fd7d96946fe77a8118d45ca4a7b451efb 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 c3364ced9200028f6727ff309ee624fcb94f1406..5c387bdb8fe333d6272f02049d6b672eb7105e8a 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__ */