From 4bea9934cf59f9f0214f510b323fe5ac9cd044bb Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Tue, 21 Aug 2018 10:53:33 +0200 Subject: [PATCH 1/3] Added patch from #4697 --- libfreerdp/core/proxy.c | 106 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 105 insertions(+), 1 deletion(-) diff --git a/libfreerdp/core/proxy.c b/libfreerdp/core/proxy.c index 34e8363d5..b0b610f80 100644 --- a/libfreerdp/core/proxy.c +++ b/libfreerdp/core/proxy.c @@ -82,6 +82,12 @@ BOOL proxy_prepare(rdpSettings* settings, const char** lpPeerHostname, UINT16* l if (!settings->ProxyType) proxy_read_environment(settings, "HTTPS_PROXY"); + if (settings->ProxyType) + proxy_read_environment(settings, "no_proxy"); + + if (settings->ProxyType) + proxy_read_environment(settings, "NO_PROXY"); + if (settings->ProxyType) { *lpPeerHostname = settings->ProxyHostname; @@ -94,6 +100,91 @@ BOOL proxy_prepare(rdpSettings* settings, const char** lpPeerHostname, UINT16* l return FALSE; } +static BOOL check_no_proxy(rdpSettings* settings, const char* no_proxy) +{ + const char* delimiter = ","; + BOOL result = FALSE; + char* current; + char* copy; + size_t host_len; + + if (!no_proxy || !settings) + return FALSE; + + host_len = strlen(settings->ServerHostname); + copy = _strdup(no_proxy); + + if (!copy) + return FALSE; + + current = strtok(copy, delimiter); + + while (current && !result) + { + const size_t currentlen = strlen(current); + + if (currentlen > 0) + { + WLog_DBG(TAG, "%s => %s (%"PRIdz")", settings->ServerHostname, current, currentlen); + + /* detect left and right "*" wildcard */ + if (current[0] == '*') + { + if (host_len >= currentlen) + { + const size_t offset = host_len + 1 - currentlen; + + if (strncmp(current + 1, settings->ServerHostname + offset, currentlen - 1) == 0) + result = TRUE; + } + } + else if (current[currentlen - 1] == '*') + { + if (strncmp(current, settings->ServerHostname, currentlen - 1) == 0) + result = TRUE; + } + else + { + if (strcmp(current, settings->ServerHostname) == 0) + result = TRUE; /* exact match */ + else + { + struct sockaddr_in sa4; + struct sockaddr_in6 sa6; + BOOL is_ip = FALSE; + + if (inet_pton(AF_INET, settings->ServerHostname, &sa4.sin_addr) == 1) + is_ip = TRUE; + else if (inet_pton(AF_INET6, settings->ServerHostname, &sa6.sin6_addr) == 1) + is_ip = TRUE; + + if (is_ip) + { + if (!strncmp(current, settings->ServerHostname, currentlen)) + result = TRUE; /* left-aligned match for IPs */ + } + else if (current[0] == '.') /* Only compare if the no_proxy variable contains a whole domain. */ + { + if (host_len >= currentlen) + { + const size_t offset = host_len - currentlen; + + if (!strncmp(current, settings->ServerHostname + offset, + currentlen)) + result = TRUE; /* right-aligned match for host names */ + } + } + } + } + } + + current = strtok(NULL, delimiter); + } + + free(copy); + return result; +} + void proxy_read_environment(rdpSettings* settings, char* envname) { DWORD envlen; @@ -112,7 +203,20 @@ void proxy_read_environment(rdpSettings* settings, char* envname) } if (GetEnvironmentVariableA(envname, env, envlen) == envlen - 1) - proxy_parse_uri(settings, env); + { + if (_strnicmp("NO_PROXY", envname, 9) == 0) + { + if (check_no_proxy(settings, env)) + { + WLog_INFO(TAG, "deactivating proxy: %s [%s=%s]", settings->ServerHostname, envname, env); + settings->ProxyType = PROXY_TYPE_NONE; + } + } + else + { + proxy_parse_uri(settings, env); + } + } free(env); } From a0facc329f7abdb3fb9d5c74f87926857aa06929 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Tue, 21 Aug 2018 10:57:44 +0200 Subject: [PATCH 2/3] Added option to deactivate proxy. --- client/common/cmdline.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/client/common/cmdline.c b/client/common/cmdline.c index f1ab367cd..a9740cab6 100644 --- a/client/common/cmdline.c +++ b/client/common/cmdline.c @@ -1875,14 +1875,13 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings, { *p = '\0'; - if (!strcmp("http", arg->Value)) - { + if (_stricmp("no_proxy", arg->Value) == 0) + settings->ProxyType = PROXY_TYPE_NONE; + + if (_stricmp("http", arg->Value) == 0) settings->ProxyType = PROXY_TYPE_HTTP; - } - else if (!strcmp("socks5", arg->Value)) - { + else if (_stricmp("socks5", arg->Value) == 0) settings->ProxyType = PROXY_TYPE_SOCKS; - } else { WLog_ERR(TAG, "Only HTTP and SOCKS5 proxies supported by now"); From b5df39756d325ac0e27c0d991c0920667973379a Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Tue, 21 Aug 2018 11:01:54 +0200 Subject: [PATCH 3/3] Added option to ignore proxy env. --- client/common/cmdline.c | 2 +- include/freerdp/settings.h | 1 + libfreerdp/core/proxy.c | 18 +++++++++++------- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/client/common/cmdline.c b/client/common/cmdline.c index a9740cab6..28bfc3e2d 100644 --- a/client/common/cmdline.c +++ b/client/common/cmdline.c @@ -1876,7 +1876,7 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings, *p = '\0'; if (_stricmp("no_proxy", arg->Value) == 0) - settings->ProxyType = PROXY_TYPE_NONE; + settings->ProxyType = PROXY_TYPE_IGNORE; if (_stricmp("http", arg->Value) == 0) settings->ProxyType = PROXY_TYPE_HTTP; diff --git a/include/freerdp/settings.h b/include/freerdp/settings.h index 0a548e778..6d4adee26 100644 --- a/include/freerdp/settings.h +++ b/include/freerdp/settings.h @@ -475,6 +475,7 @@ typedef struct _RDPDR_PARALLEL RDPDR_PARALLEL; #define PROXY_TYPE_NONE 0 #define PROXY_TYPE_HTTP 1 #define PROXY_TYPE_SOCKS 2 +#define PROXY_TYPE_IGNORE 0xFFFF /* Settings */ diff --git a/libfreerdp/core/proxy.c b/libfreerdp/core/proxy.c index b0b610f80..f849010eb 100644 --- a/libfreerdp/core/proxy.c +++ b/libfreerdp/core/proxy.c @@ -75,20 +75,23 @@ void proxy_read_environment(rdpSettings* settings, char* envname); BOOL proxy_prepare(rdpSettings* settings, const char** lpPeerHostname, UINT16* lpPeerPort, const char** lpProxyUsername, const char** lpProxyPassword) { + if (settings->ProxyType == PROXY_TYPE_IGNORE) + return FALSE; + /* For TSGateway, find the system HTTPS proxy automatically */ - if (!settings->ProxyType) + if (settings->ProxyType == PROXY_TYPE_NONE) proxy_read_environment(settings, "https_proxy"); - if (!settings->ProxyType) + if (settings->ProxyType == PROXY_TYPE_NONE) proxy_read_environment(settings, "HTTPS_PROXY"); - if (settings->ProxyType) + if (settings->ProxyType != PROXY_TYPE_NONE) proxy_read_environment(settings, "no_proxy"); - if (settings->ProxyType) + if (settings->ProxyType != PROXY_TYPE_NONE) proxy_read_environment(settings, "NO_PROXY"); - if (settings->ProxyType) + if (settings->ProxyType != PROXY_TYPE_NONE) { *lpPeerHostname = settings->ProxyHostname; *lpPeerPort = settings->ProxyPort; @@ -163,7 +166,7 @@ static BOOL check_no_proxy(rdpSettings* settings, const char* no_proxy) if (!strncmp(current, settings->ServerHostname, currentlen)) result = TRUE; /* left-aligned match for IPs */ } - else if (current[0] == '.') /* Only compare if the no_proxy variable contains a whole domain. */ + else if (current[0] == '.') /* Only compare if the no_proxy variable contains a whole domain. */ { if (host_len >= currentlen) { @@ -204,7 +207,7 @@ void proxy_read_environment(rdpSettings* settings, char* envname) if (GetEnvironmentVariableA(envname, env, envlen) == envlen - 1) { - if (_strnicmp("NO_PROXY", envname, 9) == 0) + if (_strnicmp("NO_PROXY", envname, 9) == 0) { if (check_no_proxy(settings, env)) { @@ -303,6 +306,7 @@ BOOL proxy_connect(rdpSettings* settings, BIO* bufferedBio, const char* proxyUse switch (settings->ProxyType) { case PROXY_TYPE_NONE: + case PROXY_TYPE_IGNORE: return TRUE; case PROXY_TYPE_HTTP: