mirror of https://github.com/FreeRDP/FreeRDP
Fixed parsing of https_proxy environment variable
A proxy URI was parsed both in the function `proxy_read_environment()` in `libfreerdp/core/proxy.c` and in the function `freerdp_client_settings_parse_command_line_arguments()` in `client/common/cmdline.c`. But only the latter was taking into account that the URI can contain a user and password, which made it impossible to use a proxy with authentication by just using an environment variable like `https_proxy`. The function `proxy_parse_uri()` in `libfreerdp/core/proxy.c` was clearly not parsing the optional username and password. This commit moves the code from `client/common/cmdline.c` to `libfreerdp/common/settings.c` into a function `proxy_parse_uri()` so redundant code is avoided. This function is then called in both instances where a proxy URI is parsed. Some minor adjustment were made to the code, so the `WLog_INFO()` statement at the end works in both cases, where credentials were either provided or not. Also, some error messages were added or clarified. If the parsing of the environment variable fails, we ignore it entirely (with a warning) and proceed.
This commit is contained in:
parent
6c0938f752
commit
28923ddd75
|
@ -2162,105 +2162,13 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
|
|||
|
||||
if (arg->Flags & COMMAND_LINE_VALUE_PRESENT)
|
||||
{
|
||||
char* p;
|
||||
char* atPtr;
|
||||
const char* cur = arg->Value;
|
||||
|
||||
if (!cur)
|
||||
return COMMAND_LINE_ERROR_UNEXPECTED_VALUE;
|
||||
/* value is [scheme://][user:password@]hostname:port */
|
||||
p = strstr(cur, "://");
|
||||
|
||||
if (p)
|
||||
{
|
||||
*p = '\0';
|
||||
|
||||
if (_stricmp("no_proxy", cur) == 0)
|
||||
{
|
||||
if (!freerdp_settings_set_uint32(settings, FreeRDP_ProxyType,
|
||||
PROXY_TYPE_IGNORE))
|
||||
return COMMAND_LINE_ERROR_MEMORY;
|
||||
}
|
||||
if (_stricmp("http", cur) == 0)
|
||||
{
|
||||
if (!freerdp_settings_set_uint32(settings, FreeRDP_ProxyType,
|
||||
PROXY_TYPE_HTTP))
|
||||
return COMMAND_LINE_ERROR_MEMORY;
|
||||
}
|
||||
else if (_stricmp("socks5", cur) == 0)
|
||||
{
|
||||
if (!freerdp_settings_set_uint32(settings, FreeRDP_ProxyType,
|
||||
PROXY_TYPE_SOCKS))
|
||||
return COMMAND_LINE_ERROR_MEMORY;
|
||||
}
|
||||
else
|
||||
{
|
||||
WLog_ERR(TAG, "Only HTTP and SOCKS5 proxies supported by now");
|
||||
return COMMAND_LINE_ERROR_UNEXPECTED_VALUE;
|
||||
}
|
||||
|
||||
cur = p + 3;
|
||||
}
|
||||
|
||||
/* cur is now [user:password@]hostname:port */
|
||||
atPtr = strrchr(cur, '@');
|
||||
|
||||
if (atPtr)
|
||||
{
|
||||
/* got a login / password,
|
||||
* atPtr
|
||||
* v
|
||||
* [user:password@]hostname:port
|
||||
* ^
|
||||
* colonPtr
|
||||
*/
|
||||
char* colonPtr = strchr(cur, ':');
|
||||
|
||||
if (!colonPtr || (colonPtr > atPtr))
|
||||
{
|
||||
WLog_ERR(
|
||||
TAG,
|
||||
"invalid syntax for proxy, expected syntax is user:password@host:port");
|
||||
return COMMAND_LINE_ERROR_UNEXPECTED_VALUE;
|
||||
}
|
||||
|
||||
*colonPtr = '\0';
|
||||
if (!freerdp_settings_set_string(settings, FreeRDP_ProxyUsername, cur))
|
||||
{
|
||||
WLog_ERR(TAG, "unable to allocate proxy username");
|
||||
return COMMAND_LINE_ERROR_MEMORY;
|
||||
}
|
||||
|
||||
*atPtr = '\0';
|
||||
|
||||
if (!freerdp_settings_set_string(settings, FreeRDP_ProxyPassword, colonPtr + 1))
|
||||
{
|
||||
WLog_ERR(TAG, "unable to allocate proxy password");
|
||||
return COMMAND_LINE_ERROR_MEMORY;
|
||||
}
|
||||
|
||||
cur = atPtr + 1;
|
||||
}
|
||||
|
||||
p = strchr(cur, ':');
|
||||
|
||||
if (p)
|
||||
{
|
||||
LONGLONG val;
|
||||
|
||||
if (!value_to_int(&p[1], &val, 0, UINT16_MAX))
|
||||
return COMMAND_LINE_ERROR_UNEXPECTED_VALUE;
|
||||
|
||||
if (!freerdp_settings_set_uint16(settings, FreeRDP_ProxyPort, (UINT16)val))
|
||||
return FALSE;
|
||||
*p = '\0';
|
||||
}
|
||||
|
||||
p = strchr(cur, '/');
|
||||
if (p)
|
||||
*p = '\0';
|
||||
if (!freerdp_settings_set_string(settings, FreeRDP_ProxyHostname, cur))
|
||||
return FALSE;
|
||||
if (!proxy_parse_uri(settings, cur))
|
||||
return COMMAND_LINE_ERROR_UNEXPECTED_VALUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -1697,6 +1697,7 @@ extern "C"
|
|||
FREERDP_API void freerdp_target_net_addresses_free(rdpSettings* settings);
|
||||
FREERDP_API BOOL freerdp_target_net_addresses_copy(rdpSettings* settings, char** addresses,
|
||||
UINT32 count);
|
||||
FREERDP_API BOOL proxy_parse_uri(rdpSettings* settings, const char* uri_in);
|
||||
|
||||
FREERDP_API void freerdp_performance_flags_make(rdpSettings* settings);
|
||||
FREERDP_API void freerdp_performance_flags_split(rdpSettings* settings);
|
||||
|
|
|
@ -1415,3 +1415,151 @@ BOOL freerdp_target_net_addresses_copy(rdpSettings* settings, char** addresses,
|
|||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL proxy_parse_uri(rdpSettings* settings, const char* uri_in)
|
||||
{
|
||||
BOOL rc = FALSE;
|
||||
const char* protocol = "";
|
||||
char* p;
|
||||
char* atPtr;
|
||||
char* uri_copy = _strdup(uri_in);
|
||||
char* uri = uri_copy;
|
||||
if (!uri)
|
||||
return FALSE;
|
||||
|
||||
p = strstr(uri, "://");
|
||||
|
||||
if (p)
|
||||
{
|
||||
*p = '\0';
|
||||
|
||||
if (_stricmp("no_proxy", uri) == 0)
|
||||
{
|
||||
if (!freerdp_settings_set_uint32(settings, FreeRDP_ProxyType, PROXY_TYPE_IGNORE))
|
||||
goto fail;
|
||||
}
|
||||
if (_stricmp("http", uri) == 0)
|
||||
{
|
||||
if (!freerdp_settings_set_uint32(settings, FreeRDP_ProxyType, PROXY_TYPE_HTTP))
|
||||
goto fail;
|
||||
protocol = "http";
|
||||
}
|
||||
else if (_stricmp("socks5", uri) == 0)
|
||||
{
|
||||
if (!freerdp_settings_set_uint32(settings, FreeRDP_ProxyType, PROXY_TYPE_SOCKS))
|
||||
goto fail;
|
||||
protocol = "socks5";
|
||||
}
|
||||
else
|
||||
{
|
||||
WLog_ERR(TAG, "Only HTTP and SOCKS5 proxies supported by now");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
uri = p + 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* default proxy protocol is http */
|
||||
if (!freerdp_settings_set_uint32(settings, FreeRDP_ProxyType, PROXY_TYPE_HTTP))
|
||||
goto fail;
|
||||
protocol = "http";
|
||||
}
|
||||
|
||||
/* uri is now [user:password@]hostname:port */
|
||||
atPtr = strrchr(uri, '@');
|
||||
|
||||
if (atPtr)
|
||||
{
|
||||
/* got a login / password,
|
||||
* atPtr
|
||||
* v
|
||||
* [user:password@]hostname:port
|
||||
* ^
|
||||
* colonPtr
|
||||
*/
|
||||
char* colonPtr = strchr(uri, ':');
|
||||
|
||||
if (!colonPtr || (colonPtr > atPtr))
|
||||
{
|
||||
WLog_ERR(TAG, "invalid syntax for proxy (contains no password)");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
*colonPtr = '\0';
|
||||
if (!freerdp_settings_set_string(settings, FreeRDP_ProxyUsername, uri))
|
||||
{
|
||||
WLog_ERR(TAG, "unable to allocate proxy username");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
*atPtr = '\0';
|
||||
|
||||
if (!freerdp_settings_set_string(settings, FreeRDP_ProxyPassword, colonPtr + 1))
|
||||
{
|
||||
WLog_ERR(TAG, "unable to allocate proxy password");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
uri = atPtr + 1;
|
||||
}
|
||||
|
||||
p = strchr(uri, ':');
|
||||
|
||||
if (p)
|
||||
{
|
||||
LONGLONG val;
|
||||
|
||||
if (!value_to_int(&p[1], &val, 0, UINT16_MAX))
|
||||
{
|
||||
WLog_ERR(TAG, "invalid syntax for proxy (invalid port)");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (val == 0)
|
||||
{
|
||||
WLog_ERR(TAG, "invalid syntax for proxy (port missing)");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!freerdp_settings_set_uint16(settings, FreeRDP_ProxyPort, (UINT16)val))
|
||||
goto fail;
|
||||
*p = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
WLog_ERR(TAG, "invalid syntax for proxy (port missing)");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
p = strchr(uri, '/');
|
||||
if (p)
|
||||
*p = '\0';
|
||||
if (!freerdp_settings_set_string(settings, FreeRDP_ProxyHostname, uri))
|
||||
goto fail;
|
||||
|
||||
if (_stricmp("", uri) == 0)
|
||||
{
|
||||
WLog_ERR(TAG, "invalid syntax for proxy (hostname missing)");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (freerdp_settings_get_string(settings, FreeRDP_ProxyUsername))
|
||||
{
|
||||
WLog_INFO(TAG, "Parsed proxy configuration: %s://%s:%s@%s:%d", protocol,
|
||||
freerdp_settings_get_string(settings, FreeRDP_ProxyUsername), "******",
|
||||
freerdp_settings_get_string(settings, FreeRDP_ProxyHostname),
|
||||
freerdp_settings_get_uint16(settings, FreeRDP_ProxyPort));
|
||||
}
|
||||
else
|
||||
{
|
||||
WLog_INFO(TAG, "Parsed proxy configuration: %s://%s:%d", protocol,
|
||||
freerdp_settings_get_string(settings, FreeRDP_ProxyHostname),
|
||||
freerdp_settings_get_uint16(settings, FreeRDP_ProxyPort));
|
||||
}
|
||||
rc = TRUE;
|
||||
|
||||
fail:
|
||||
free(uri_copy);
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -69,7 +69,6 @@ static BOOL http_proxy_connect(BIO* bufferedBio, const char* proxyUsername,
|
|||
static BOOL socks_proxy_connect(BIO* bufferedBio, const char* proxyUsername,
|
||||
const char* proxyPassword, const char* hostname, UINT16 port);
|
||||
static void proxy_read_environment(rdpSettings* settings, char* envname);
|
||||
static BOOL proxy_parse_uri(rdpSettings* settings, const char* uri);
|
||||
|
||||
BOOL proxy_prepare(rdpSettings* settings, const char** lpPeerHostname, UINT16* lpPeerPort,
|
||||
const char** lpProxyUsername, const char** lpProxyPassword)
|
||||
|
@ -285,95 +284,17 @@ void proxy_read_environment(rdpSettings* settings, char* envname)
|
|||
}
|
||||
else
|
||||
{
|
||||
proxy_parse_uri(settings, env);
|
||||
if (!proxy_parse_uri(settings, env))
|
||||
{
|
||||
WLog_WARN(
|
||||
TAG, "Error while parsing proxy URI from environment variable; ignoring proxy");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(env);
|
||||
}
|
||||
|
||||
BOOL proxy_parse_uri(rdpSettings* settings, const char* uri_in)
|
||||
{
|
||||
BOOL rc = FALSE;
|
||||
char *hostname, *pport;
|
||||
const char* protocol;
|
||||
char* p;
|
||||
UINT16 port;
|
||||
char* uri_copy = _strdup(uri_in);
|
||||
char* uri = uri_copy;
|
||||
if (!uri)
|
||||
return FALSE;
|
||||
p = strstr(uri, "://");
|
||||
|
||||
if (p)
|
||||
{
|
||||
if (p == uri + 4 && !strncmp("http", uri, 4))
|
||||
{
|
||||
if (!freerdp_settings_set_uint32(settings, FreeRDP_ProxyType, PROXY_TYPE_HTTP))
|
||||
goto fail;
|
||||
|
||||
protocol = "http";
|
||||
}
|
||||
else if (p == uri + 6 && !strncmp("socks5", uri, 6))
|
||||
{
|
||||
if (!freerdp_settings_set_uint32(settings, FreeRDP_ProxyType, PROXY_TYPE_SOCKS))
|
||||
goto fail;
|
||||
protocol = "socks5";
|
||||
}
|
||||
else
|
||||
{
|
||||
WLog_ERR(TAG, "Only HTTP and SOCKS5 proxies supported by now");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
uri = p + 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
WLog_ERR(TAG, "No scheme in proxy URI");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
hostname = uri;
|
||||
pport = strchr(hostname, ':');
|
||||
|
||||
if (pport)
|
||||
{
|
||||
long val;
|
||||
errno = 0;
|
||||
val = strtol(pport + 1, NULL, 0);
|
||||
|
||||
if ((errno != 0) || (val <= 0) || (val > UINT16_MAX))
|
||||
return FALSE;
|
||||
|
||||
port = (UINT16)val;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The default is 80. Also for Proxys. */
|
||||
port = 80;
|
||||
pport = strchr(hostname, '/');
|
||||
}
|
||||
|
||||
if (pport)
|
||||
*pport = '\0';
|
||||
|
||||
if (!freerdp_settings_set_string(settings, FreeRDP_ProxyHostname, hostname))
|
||||
goto fail;
|
||||
|
||||
if (!freerdp_settings_set_uint16(settings, FreeRDP_ProxyPort, port))
|
||||
goto fail;
|
||||
|
||||
WLog_INFO(TAG, "Parsed proxy configuration: %s://%s:%d", protocol,
|
||||
freerdp_settings_get_string(settings, FreeRDP_ProxyHostname),
|
||||
freerdp_settings_get_uint16(settings, FreeRDP_ProxyPort));
|
||||
rc = TRUE;
|
||||
|
||||
fail:
|
||||
free(uri_copy);
|
||||
return rc;
|
||||
}
|
||||
|
||||
BOOL proxy_connect(rdpSettings* settings, BIO* bufferedBio, const char* proxyUsername,
|
||||
const char* proxyPassword, const char* hostname, UINT16 port)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue