#include "config.h"
#endif
+#include <ctype.h>
#include <assert.h>
#include <winpr/crt.h>
{ "gd", COMMAND_LINE_VALUE_REQUIRED, "<domain>", NULL, NULL, -1, NULL, "Gateway domain" },
{ "gt", COMMAND_LINE_VALUE_REQUIRED, "<rpc|http|auto>", NULL, NULL, -1, NULL, "Gateway transport type" },
{ "gateway-usage-method", COMMAND_LINE_VALUE_REQUIRED, "<direct|detect>", NULL, NULL, -1, "gum", "Gateway usage method" },
- { "http-proxy", COMMAND_LINE_VALUE_REQUIRED, "<host>:<port>", NULL, NULL, -1, NULL, "HTTP Proxy" },
+ { "proxy", COMMAND_LINE_VALUE_REQUIRED, "[<protocol>://]<host>:<port>", NULL, NULL, -1, NULL, "Proxy (see also environment variable below)" },
{ "load-balance-info", COMMAND_LINE_VALUE_REQUIRED, "<info string>", NULL, NULL, -1, NULL, "Load balance info" },
{ "app", COMMAND_LINE_VALUE_REQUIRED, "<executable path> or <||alias>", NULL, NULL, -1, NULL, "Remote application program" },
{ "app-name", COMMAND_LINE_VALUE_REQUIRED, "<app name>", NULL, NULL, -1, NULL, "Remote application name for user interface" },
settings->GatewayUseSameCredentials = TRUE;
freerdp_set_gateway_usage_method(settings, TSC_PROXY_MODE_DIRECT);
}
- CommandLineSwitchCase(arg, "http-proxy")
+ CommandLineSwitchCase(arg, "proxy")
{
if (arg->Flags & COMMAND_LINE_VALUE_PRESENT)
{
+ p = strstr(arg->Value, "://");
+ if (p) {
+ *p = '\0';
+ if (!strcmp("http", arg->Value)) {
+ settings->ProxyType = PROXY_TYPE_HTTP;
+ } else {
+ WLog_ERR(TAG, "Only HTTP proxys supported by now");
+ return COMMAND_LINE_ERROR_UNEXPECTED_VALUE;
+ }
+ arg->Value = p + 3;
+ }
+
p = strchr(arg->Value, ':');
if (p)
{
length = (int) (p - arg->Value);
- settings->HTTPProxyPort = atoi(&p[1]);
- settings->HTTPProxyHostname = (char*) malloc(length + 1);
- strncpy(settings->HTTPProxyHostname, arg->Value, length);
- settings->HTTPProxyHostname[length] = '\0';
-
- settings->HTTPProxyEnabled = TRUE;
- }
- else
- {
- /* TODO parse encironment variable here? */
- fprintf(stderr, "Option http-proxy needs argument. Ignored.\n");
+ if (!isdigit(p[1])) {
+ WLog_ERR(TAG, "Could not parse proxy port");
+ return COMMAND_LINE_ERROR_UNEXPECTED_VALUE;
+ }
+ settings->ProxyPort = atoi(&p[1]);
+ settings->ProxyHostname = (char*) malloc(length + 1);
+ strncpy(settings->ProxyHostname, arg->Value, length);
+ settings->ProxyHostname[length] = '\0';
+
+ settings->ProxyType = PROXY_TYPE_HTTP;
}
}
+ else
+ {
+ WLog_ERR(TAG, "Option http-proxy needs argument.");
+ return COMMAND_LINE_ERROR_UNEXPECTED_VALUE;
+ }
}
CommandLineSwitchCase(arg, "gu")
{
};
typedef struct _RDPDR_PARALLEL RDPDR_PARALLEL;
+#define PROXY_TYPE_NONE 0
+#define PROXY_TYPE_HTTP 1
+
/* Settings */
#ifdef __GNUC__
#define FreeRDP_GatewayRpcTransport 1994
#define FreeRDP_GatewayHttpTransport 1995
#define FreeRDP_GatewayUdpTransport 1996
-#define FreeRDP_HTTPProxyEnabled 2015
-#define FreeRDP_HTTPProxyHostname 2016
-#define FreeRDP_HTTPProxyPort 2017
+#define FreeRDP_ProxyType 2015
+#define FreeRDP_ProxyHostname 2016
+#define FreeRDP_ProxyPort 2017
#define FreeRDP_RemoteApplicationMode 2112
#define FreeRDP_RemoteApplicationName 2113
#define FreeRDP_RemoteApplicationIcon 2114
ALIGN64 BOOL GatewayRpcTransport; /* 1994 */
ALIGN64 BOOL GatewayHttpTransport; /* 1995 */
ALIGN64 BOOL GatewayUdpTransport; /* 1996 */
- UINT64 padding2048[2048 - 1997]; /* 1997 */
- UINT64 padding2112[2112 - 2048]; /* 2048 */
+ UINT64 padding2048[2015 - 1997]; /* 1997 */
- /* HTTP Proxy */
- ALIGN64 BOOL HTTPProxyEnabled; /* 1995 */
- ALIGN64 char* HTTPProxyHostname; /* 1996 */
- ALIGN64 UINT32 HTTPProxyPort; /* 1997 */
+ /* Proxy */
+ ALIGN64 UINT32 ProxyType; /* 2015 */
+ ALIGN64 char* ProxyHostname; /* 2016 */
+ ALIGN64 UINT16 ProxyPort; /* 2017 */
+ UINT64 padding2112[2112 - 2018]; /* 2018 */
/**
* RemoteApp
case FreeRDP_GatewayUdpTransport:
return settings->GatewayUdpTransport;
- case FreeRDP_HTTPProxyEnabled:
- return settings->HTTPProxyEnabled;
-
case FreeRDP_RemoteApplicationMode:
return settings->RemoteApplicationMode;
settings->GatewayUdpTransport = param;
break;
- case FreeRDP_HTTPProxyEnabled:
- settings->HTTPProxyEnabled = param;
- break;
-
case FreeRDP_RemoteApplicationMode:
settings->RemoteApplicationMode = param;
break;
case FreeRDP_GatewayCredentialsSource:
return settings->GatewayCredentialsSource;
+ case FreeRDP_ProxyType:
+ return settings->ProxyType;
+
+ case FreeRDP_ProxyPort:
+ return settings->ProxyPort;
+
case FreeRDP_RemoteAppNumIconCaches:
return settings->RemoteAppNumIconCaches;
settings->GatewayCredentialsSource = param;
break;
+ case FreeRDP_ProxyType:
+ settings->ProxyType = param;
+ break;
+
+ case FreeRDP_ProxyPort:
+ settings->ProxyPort = param;
+ break;
+
case FreeRDP_RemoteAppNumIconCaches:
settings->RemoteAppNumIconCaches = param;
break;
case FreeRDP_GatewayDomain:
return settings->GatewayDomain;
+ case FreeRDP_ProxyHostname:
+ return settings->ProxyHostname;
+
case FreeRDP_RemoteApplicationName:
return settings->RemoteApplicationName;
tmp = &settings->GatewayDomain;
break;
- case FreeRDP_HTTPProxyHostname:
- tmp = &settings->HTTPProxyHostname;
+ case FreeRDP_ProxyHostname:
+ tmp = &settings->ProxyHostname;
break;
case FreeRDP_RemoteApplicationName:
BIO* bufferedBio = NULL;
rdpSettings* settings = rdg->settings;
const char *peerHostname = settings->GatewayHostname;
- int peerPort = settings->GatewayPort;
- BOOL isProxyConnection = FALSE;
+ UINT16 peerPort = settings->GatewayPort;
+ BOOL isProxyConnection = proxy_prepare(settings, &peerHostname, &peerPort, TRUE);
assert(hostname != NULL);
- if (settings->HTTPProxyEnabled) {
- peerHostname = settings->HTTPProxyHostname;
- peerPort = settings->HTTPProxyPort;
- isProxyConnection = TRUE;
- }
-
sockfd = freerdp_tcp_connect(rdg->context, settings, peerHostname,
peerPort, timeout);
status = BIO_set_nonblock(bufferedBio, TRUE);
if (isProxyConnection) {
- if (!http_proxy_connect(bufferedBio, settings->GatewayHostname, settings->GatewayPort))
- return -1;
+ if (!proxy_connect(settings, bufferedBio, settings->GatewayHostname, settings->GatewayPort))
+ return FALSE;
}
if (!status)
assert(hostname != NULL);
- if (settings->HTTPProxyEnabled) {
- peerHostname = settings->HTTPProxyHostname;
- peerPort = settings->HTTPProxyPort;
+ if (settings->ProxyType) {
+ peerHostname = settings->ProxyHostname;
+ peerPort = settings->ProxyPort;
isProxyConnection = TRUE;
}
rdpContext* context = rpc->context;
rdpSettings* settings = context->settings;
const char *peerHostname = settings->GatewayHostname;
- int peerPort = settings->GatewayPort;
- BOOL isProxyConnection = FALSE;
-
- if (settings->HTTPProxyEnabled) {
- peerHostname = settings->HTTPProxyHostname;
- peerPort = settings->HTTPProxyPort;
- isProxyConnection = TRUE;
- }
+ UINT16 peerPort = settings->GatewayPort;
+ BOOL isProxyConnection = proxy_prepare(settings, &peerHostname, &peerPort, TRUE);
sockfd = freerdp_tcp_connect(context, settings, peerHostname,
peerPort, timeout);
return -1;
if (isProxyConnection) {
- if (!http_proxy_connect(bufferedBio, settings->GatewayHostname, settings->GatewayPort))
+ if (!proxy_connect(settings, bufferedBio, settings->GatewayHostname, settings->GatewayPort))
return -1;
}
* limitations under the License.
*/
+#include <ctype.h>
#include "proxy.h"
#include "freerdp/settings.h"
#define CRLF "\r\n"
#define TAG FREERDP_TAG("core.proxy")
-void http_proxy_read_environment(rdpSettings *settings, char *envname)
+BOOL http_proxy_connect(BIO* bufferedBio, const char* hostname, UINT16 port);
+void proxy_read_environment(rdpSettings *settings, char *envname);
+
+BOOL proxy_prepare(rdpSettings *settings, const char **lpPeerHostname, UINT16 *lpPeerPort, BOOL isHTTPS)
+{
+ /* For TSGateway, find the system HTTPS proxy automatically */
+ if (!settings->ProxyType)
+ proxy_read_environment(settings, "https_proxy");
+
+ if (!settings->ProxyType)
+ proxy_read_environment(settings, "HTTPS_PROXY");
+
+ if (settings->ProxyType) {
+ *lpPeerHostname = settings->ProxyHostname;
+ *lpPeerPort = settings->ProxyPort;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+void proxy_read_environment(rdpSettings *settings, char *envname)
{
char env[256];
DWORD envlen;
- char *hostname, *pport;
- envlen = GetEnvironmentVariableA(envname, env, sizeof(env));
+ envlen = GetEnvironmentVariableA(envname, env, sizeof(env)-1);
if(!envlen)
return;
- if (strncmp(env, "http://", 7)) {
- WLog_ERR(TAG, "Proxy url must have scheme http. Ignoring.");
- return;
- }
+ env[envlen] = '\0';
- settings->HTTPProxyEnabled = TRUE;
+ proxy_parse_uri(settings, env);
+}
- hostname = env + 7;
+BOOL proxy_parse_uri(rdpSettings *settings, const char *uri)
+{
+ const char *hostname, *pport;
+ const char *protocol;
+ const char *p;
+ int hostnamelen;
+
+ p = strstr(uri, "://");
+ if (p) {
+ protocol = uri;
+ if (p == uri+4 && !strncmp("http", uri, 4)) {
+ settings->ProxyType = PROXY_TYPE_HTTP;
+ } else {
+ WLog_ERR(TAG, "Only HTTP proxys supported by now");
+ return FALSE;
+ }
+ uri = p + 3;
+ } else {
+ WLog_ERR(TAG, "No scheme in proxy URI");
+ return FALSE;
+ }
+
+ hostname = uri;
pport = strchr(hostname, ':');
if (pport) {
- *pport = '\0';
- settings->HTTPProxyPort = atoi(pport+1);
+ if (!isdigit(*(pport+1))) {
+ WLog_ERR(TAG, "Could not parse proxy port");
+ return FALSE;
+ }
+ settings->ProxyPort = atoi(pport+1);
}
else {
/* The default is 80. Also for Proxys. */
- settings->HTTPProxyPort = 80;
+ settings->ProxyPort = 80;
pport = strchr(hostname, '/');
- if(pport)
- *pport = '\0';
}
- freerdp_set_param_string(settings, FreeRDP_HTTPProxyHostname, hostname);
- WLog_INFO(TAG, "Parsed proxy configuration: %s:%d", settings->HTTPProxyHostname, settings->HTTPProxyPort);
+ if(pport) {
+ hostnamelen = pport - hostname;
+ } else {
+ hostnamelen = strlen(hostname);
+ }
+
+ settings->ProxyHostname = strndup(hostname, hostnamelen);
+ WLog_INFO(TAG, "Parsed proxy configuration: %s://%s:%d", protocol, settings->ProxyHostname, settings->ProxyPort);
+ return TRUE;
+}
+
+BOOL proxy_connect(rdpSettings *settings, BIO *bufferedBio, const char *hostname, UINT16 port)
+{
+ switch (settings->ProxyType) {
+ case PROXY_TYPE_NONE:
+ return TRUE;
+ case PROXY_TYPE_HTTP:
+ return http_proxy_connect(bufferedBio, hostname, port);
+ default:
+ WLog_ERR(TAG, "Invalid internal proxy configuration");
+ return FALSE;
+ }
}
BOOL http_proxy_connect(BIO* bufferedBio, const char* hostname, UINT16 port)
#include "freerdp/settings.h"
#include <openssl/bio.h>
-void http_proxy_read_environment(rdpSettings *settings, char *envname);
-BOOL http_proxy_connect(BIO *bio, const char* hostname, UINT16 port);
+BOOL proxy_prepare(rdpSettings *settings, const char **lpPeerHostname, UINT16 *lpPeerPort, BOOL isHTTPS);
+BOOL proxy_parse_uri(rdpSettings *settings, const char *uri);
+BOOL proxy_connect(rdpSettings *settings, BIO *bio, const char* hostname, UINT16 port);
#endif
CHECKED_STRDUP(GatewayUsername); /* 1987 */
CHECKED_STRDUP(GatewayPassword); /* 1988 */
CHECKED_STRDUP(GatewayDomain); /* 1989 */
- CHECKED_STRDUP(HTTPProxyHostname); /* 2016 */
+ CHECKED_STRDUP(ProxyHostname); /* 2016 */
CHECKED_STRDUP(RemoteApplicationName); /* 2113 */
CHECKED_STRDUP(RemoteApplicationIcon); /* 2114 */
CHECKED_STRDUP(RemoteApplicationProgram); /* 2115 */
#include "fastpath.h"
#include "transport.h"
#include "rdp.h"
-#include "proxy.h"
#define TAG FREERDP_TAG("core.transport")
if (transport->GatewayEnabled)
{
- /* For TSGateway, find the system HTTPS proxy automatically */
- if (!transport->settings->HTTPProxyEnabled)
- http_proxy_read_environment(settings, "https_proxy");
-
- if (!transport->settings->HTTPProxyEnabled)
- http_proxy_read_environment(settings, "HTTPS_PROXY");
-
if (!status && settings->GatewayHttpTransport)
{
transport->rdg = rdg_new(transport);