Add stricter checks for netnames.

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.
This commit is contained in:
Guus Sliepen 2016-04-17 14:38:37 +02:00
parent 097c69fc6a
commit c2dc3784f1
4 changed files with 29 additions and 4 deletions

View file

@ -392,7 +392,7 @@ int cmd_invite(int argc, char *argv[]) {
// Fill in the details. // Fill in the details.
fprintf(f, "Name = %s\n", argv[1]); fprintf(f, "Name = %s\n", argv[1]);
if(netname) if(check_netname(netname, true))
fprintf(f, "NetName = %s\n", netname); fprintf(f, "NetName = %s\n", netname);
fprintf(f, "ConnectTo = %s\n", myname); fprintf(f, "ConnectTo = %s\n", myname);
@ -541,12 +541,17 @@ static bool finalize_join(void) {
} }
if(!check_id(name)) { if(!check_id(name)) {
fprintf(stderr, "Invalid Name found in invitation: %s!\n", name); fprintf(stderr, "Invalid Name found in invitation!\n");
return false; return false;
} }
if(!netname) if(!netname) {
netname = grep(data, "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; bool ask_netname = false;
char temp_netname[32]; char temp_netname[32];

View file

@ -261,11 +261,14 @@ static bool parse_options(int argc, char **argv) {
netname = NULL; netname = NULL;
} }
if(netname && (strpbrk(netname, "\\/") || *netname == '.')) { if(netname && !check_netname(netname, false)) {
fprintf(stderr, "Invalid character in netname!\n"); fprintf(stderr, "Invalid character in netname!\n");
return false; return false;
} }
if(netname && !check_netname(netname, true))
fprintf(stderr, "Warning: unsafe character in netname!\n");
return true; return true;
} }

View file

@ -191,6 +191,22 @@ bool check_id(const char *id) {
return true; 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. */ /* Windows doesn't define HOST_NAME_MAX. */
#ifndef HOST_NAME_MAX #ifndef HOST_NAME_MAX
#define HOST_NAME_MAX 255 #define HOST_NAME_MAX 255

View file

@ -51,6 +51,7 @@ extern const char *winerror(int);
extern unsigned int bitfield_to_int(const void *bitfield, size_t size); extern unsigned int bitfield_to_int(const void *bitfield, size_t size);
extern bool check_id(const char *); extern bool check_id(const char *);
extern bool check_netname(const char *, bool strict);
char *replace_name(const char *name); char *replace_name(const char *name);
#endif /* __TINC_UTILS_H__ */ #endif /* __TINC_UTILS_H__ */