From 013c65096cd313176380194cb9b2867bfa50e3b9 Mon Sep 17 00:00:00 2001 From: Max Moser Date: Fri, 23 Feb 2018 16:23:02 +0100 Subject: [PATCH] Add FQDN support in the Connection Editor Make the Connection Editor accept things that basically look like FQDNs Add quotation around the connection ID for wg-quick up/down Move the is_empty function to shared/ --- properties/nm-wireguard-editor.c | 20 +----- shared/utils.c | 101 +++++++++++++++++++++++++++++++ shared/utils.h | 4 ++ src/nm-wireguard-service.c | 4 +- 4 files changed, 108 insertions(+), 21 deletions(-) diff --git a/properties/nm-wireguard-editor.c b/properties/nm-wireguard-editor.c index 23b393f..011766a 100644 --- a/properties/nm-wireguard-editor.c +++ b/properties/nm-wireguard-editor.c @@ -54,24 +54,6 @@ typedef struct { gboolean new_connection; } WireguardEditorPrivate; -/*****************************************************************************/ - -// check if the given string is NULL or empty -static gboolean -is_empty(const char *str) -{ - gboolean empty = FALSE; - gchar *tmp = g_strdup(str); - tmp = g_strstrip(tmp); - - if(!tmp || !tmp[0]){ - empty = TRUE; - } - - g_free(tmp); - return empty; -} - /*****************************************************************************/ // functions for checking the contents of the input fields in the GUI @@ -174,7 +156,7 @@ check_peer_allowed_ips(const char *str) static gboolean check_peer_endpoint(const char *str) { - return is_ip4((char *)str) || is_ip6((char *)str); + return is_ip4((char *)str) || is_ip6((char *)str) || is_fqdn((char *)str); } // used in 'check()', matches the functions above diff --git a/shared/utils.c b/shared/utils.c index 34af0c5..76576a3 100644 --- a/shared/utils.c +++ b/shared/utils.c @@ -249,6 +249,22 @@ out_fail: /*****************************************************************************/ +// check if the given string is NULL or empty +gboolean +is_empty(const char *str) +{ + gboolean empty = FALSE; + gchar *tmp = g_strdup(str); + tmp = g_strstrip(tmp); + + if(!tmp || !tmp[0]){ + empty = TRUE; + } + + g_free(tmp); + return empty; +} + // check if the given string looks like an IPv4 address // that is, four segments of numbers (0-255), separated by dots // additionally, there may be a port suffix (separated from the address by a colon; 0 - 65535) @@ -443,4 +459,89 @@ is_ip6(char *addr) ip6end: g_strfreev(parts); return success; +} + +// check if the address looks like a valid FQDN +gboolean is_fqdn(char *addr) +{ + int idx = 0; + int idx2 = 0; + int dots = 0; + gchar **parts; + gchar **tmp; + gchar *lastpart; + gboolean success = TRUE; + gboolean contains_alpha = FALSE; + + if(!addr){ + return FALSE; + } + + while(addr && addr[idx]){ + if(addr[idx] == '.'){ + dots++; + } + idx++; + } + + parts = g_strsplit_set(addr, ".", 0); + lastpart = parts[dots]; + + // iterate over all parts of the name + for(idx = 0; idx <= dots; idx++){ + contains_alpha = FALSE; + + // if the part is empty + if(is_empty(parts[idx])){ + success = FALSE; + goto fqdn_end; + } + + idx2 = 0; + while(parts[idx] && parts[idx][idx2]){ + char c = parts[idx][idx2]; + + // we have arrived at the last part and found the beginning of the port + if((idx == dots) && (c == ':')){ + break; + } + + if(!g_ascii_isalnum(c) && (c != '-')){ + // if there's a character other than something alphanumeric or a hyphen, + // reject it + // TODO: cover more than just ASCII, check length, etc. + success = FALSE; + goto fqdn_end; + } + + if(g_ascii_isalpha(c)){ + contains_alpha = TRUE; + } + + idx2++; + } + + // names consisting of only numbers are not legitimate + if(!contains_alpha){ + success = FALSE; + goto fqdn_end; + } + } + + // might have a port suffix after a colon (e.g. tuwien.ac.at:8080) + if(g_strrstr(lastpart, ":")){ + tmp = g_strsplit(lastpart, ":", 2); + + // the last part has been checked in the loop above, so we only need + // to check the port + if(!g_ascii_string_to_unsigned(tmp[1], 10, 0, 65535, NULL, NULL)){ + success = FALSE; + } + + g_strfreev(tmp); + } + +fqdn_end: + g_strfreev(parts); + return success; } \ No newline at end of file diff --git a/shared/utils.h b/shared/utils.h index 5370087..30402c7 100644 --- a/shared/utils.h +++ b/shared/utils.h @@ -96,10 +96,14 @@ gboolean is_pkcs12 (const char *filepath); gboolean is_encrypted (const char *filename); +gboolean is_empty(const char *str); + gboolean is_ip4 (char *addr); gboolean is_ip6 (char *addr); +gboolean is_fqdn(char *addr); + #define NMOVPN_PROTCOL_TYPES \ "udp", \ "udp4", \ diff --git a/src/nm-wireguard-service.c b/src/nm-wireguard-service.c index db720c6..64fbff1 100644 --- a/src/nm-wireguard-service.c +++ b/src/nm-wireguard-service.c @@ -186,7 +186,7 @@ wg_disconnect(NMVpnServicePlugin *plugin, g_chmod(filename, 0400); // join together our command - command = g_strdup_printf("%s down %s", wg_quick_path, filename); + command = g_strdup_printf("%s down '%s'", wg_quick_path, filename); if(!g_spawn_command_line_sync(command, NULL, NULL, &retcode, error)){ _LOGW("An error occured while spawning wg-quick! (Error: %s)", (*error)->message); @@ -474,7 +474,7 @@ connect_common(NMVpnServicePlugin *plugin, g_chmod(filename, 0400); // join together our command - command = g_strdup_printf("%s up %s", wg_quick_path, filename); + command = g_strdup_printf("%s up '%s'", wg_quick_path, filename); if(!g_spawn_command_line_sync(command, NULL, NULL, &retcode, error)){ _LOGW("An error occured while spawning wg-quick! (Error: %s)", (*error)->message);