diff --git a/client/common/cmdline.c b/client/common/cmdline.c index ce6df4a05..25f60bd20 100644 --- a/client/common/cmdline.c +++ b/client/common/cmdline.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include diff --git a/include/freerdp/settings.h b/include/freerdp/settings.h index 5d69e0159..2ef6a1227 100644 --- a/include/freerdp/settings.h +++ b/include/freerdp/settings.h @@ -1697,7 +1697,6 @@ 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); diff --git a/include/freerdp/utils/proxy_utils.h b/include/freerdp/utils/proxy_utils.h new file mode 100644 index 000000000..0bd510e9e --- /dev/null +++ b/include/freerdp/utils/proxy_utils.h @@ -0,0 +1,37 @@ +/** + * FreeRDP: A Remote Desktop Protocol Implementation + * RDP Proxy Utils + * + * Copyright 2016 Armin Novak + * Copyright 2022 Adrian Vollmer + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FREERDP_PROXY_UTILS_H +#define FREERDP_PROXY_UTILS_H + +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + + FREERDP_API BOOL proxy_parse_uri(rdpSettings* settings, const char* uri_in); + +#ifdef __cplusplus +} +#endif + +#endif /* FREERDP_PROXY_UTILS_H */ diff --git a/libfreerdp/common/settings.c b/libfreerdp/common/settings.c index 7406ef579..357864471 100644 --- a/libfreerdp/common/settings.c +++ b/libfreerdp/common/settings.c @@ -1415,151 +1415,3 @@ 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; -} diff --git a/libfreerdp/core/proxy.c b/libfreerdp/core/proxy.c index 62b18478d..31fc99eff 100644 --- a/libfreerdp/core/proxy.c +++ b/libfreerdp/core/proxy.c @@ -22,6 +22,7 @@ #include "proxy.h" #include +#include #include #include "tcp.h" @@ -648,3 +649,171 @@ static BOOL socks_proxy_connect(BIO* bufferedBio, const char* proxyUsername, return FALSE; } + +static BOOL value_to_int(const char* value, LONGLONG* result, LONGLONG min, LONGLONG max) +{ + long long rc; + + if (!value || !result) + return FALSE; + + errno = 0; + rc = _strtoi64(value, NULL, 0); + + if (errno != 0) + return FALSE; + + if ((rc < min) || (rc > max)) + return FALSE; + + *result = rc; + 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) + goto fail; + + 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; +}