Start support for HTTP Proxy. Does almost work; need to fully read and parse HTTP Proxy response.
This commit is contained in:
parent
14208dcb8d
commit
996f8ccb94
@ -504,6 +504,10 @@ if(ANDROID)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WITH_HTTP_PROXY)
|
||||
add_definitions(-DWITH_HTTP_PROXY)
|
||||
endif()
|
||||
|
||||
# Unit Tests
|
||||
|
||||
include(CTest)
|
||||
|
@ -72,6 +72,9 @@ COMMAND_LINE_ARGUMENT_A args[] =
|
||||
{ "gu", COMMAND_LINE_VALUE_REQUIRED, "[<domain>\\]<user> or <user>[@<domain>]", NULL, NULL, -1, NULL, "Gateway username" },
|
||||
{ "gp", COMMAND_LINE_VALUE_REQUIRED, "<password>", NULL, NULL, -1, NULL, "Gateway password" },
|
||||
{ "gd", COMMAND_LINE_VALUE_REQUIRED, "<domain>", NULL, NULL, -1, NULL, "Gateway domain" },
|
||||
#ifdef WITH_HTTP_PROXY
|
||||
{ "http-proxy", COMMAND_LINE_VALUE_REQUIRED, "<host>:<port>", NULL, NULL, -1, NULL, "HTTP Proxy" },
|
||||
#endif
|
||||
{ "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" },
|
||||
@ -1349,6 +1352,32 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
|
||||
settings->GatewayUseSameCredentials = TRUE;
|
||||
settings->GatewayEnabled = TRUE;
|
||||
}
|
||||
#ifdef WITH_HTTP_PROXY
|
||||
CommandLineSwitchCase(arg, "http-proxy")
|
||||
{
|
||||
if (arg->Flags & COMMAND_LINE_VALUE_PRESENT)
|
||||
{
|
||||
/* TODO: parse "http://" URL? */
|
||||
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");
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
CommandLineSwitchCase(arg, "gu")
|
||||
{
|
||||
char* user;
|
||||
|
@ -68,6 +68,8 @@ option(STATIC_CHANNELS "Build channels statically" ON)
|
||||
|
||||
option(WITH_CHANNELS "Build virtual channel plugins" ON)
|
||||
|
||||
option(WITH_HTTP_PROXY "Build HTTP proxy support" OFF)
|
||||
|
||||
if(WITH_CLIENT AND WITH_CHANNELS)
|
||||
option(WITH_CLIENT_CHANNELS "Build virtual channel plugins" ON)
|
||||
endif()
|
||||
|
@ -669,6 +669,11 @@ typedef struct _RDPDR_PARALLEL RDPDR_PARALLEL;
|
||||
#define FreeRDP_GatewayCredentialsSource 1990
|
||||
#define FreeRDP_GatewayUseSameCredentials 1991
|
||||
#define FreeRDP_GatewayEnabled 1992
|
||||
#ifdef WITH_HTTP_PROXY
|
||||
#define FreeRDP_HTTPProxyEnabled 2995
|
||||
#define FreeRDP_HTTPProxyHostname 2996
|
||||
#define FreeRDP_HTTPProxyPort 2997
|
||||
#endif
|
||||
#define FreeRDP_RemoteApplicationMode 2112
|
||||
#define FreeRDP_RemoteApplicationName 2113
|
||||
#define FreeRDP_RemoteApplicationIcon 2114
|
||||
@ -1076,6 +1081,13 @@ struct rdp_settings
|
||||
UINT64 padding2048[2048 - 1993]; /* 1993 */
|
||||
UINT64 padding2112[2112 - 2048]; /* 2048 */
|
||||
|
||||
#ifdef WITH_HTTP_PROXY
|
||||
/* HTTP Proxy */
|
||||
ALIGN64 BOOL HTTPProxyEnabled; /* 1995 */
|
||||
ALIGN64 char* HTTPProxyHostname; /* 1996 */
|
||||
ALIGN64 UINT32 HTTPProxyPort; /* 1997 */
|
||||
#endif
|
||||
|
||||
/**
|
||||
* RemoteApp
|
||||
*/
|
||||
|
@ -746,6 +746,12 @@ BOOL freerdp_get_param_bool(rdpSettings* settings, int id)
|
||||
return settings->GatewayEnabled;
|
||||
break;
|
||||
|
||||
#ifdef WITH_HTTP_PROXY
|
||||
case FreeRDP_HTTPProxyEnabled:
|
||||
return settings->HTTPProxyEnabled;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case FreeRDP_RemoteApplicationMode:
|
||||
return settings->RemoteApplicationMode;
|
||||
break;
|
||||
@ -1218,6 +1224,12 @@ int freerdp_set_param_bool(rdpSettings* settings, int id, BOOL param)
|
||||
settings->GatewayEnabled = param;
|
||||
break;
|
||||
|
||||
#ifdef WITH_HTTP_PROXY
|
||||
case FreeRDP_HTTPProxyEnabled:
|
||||
settings->HTTPProxyEnabled = param;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case FreeRDP_RemoteApplicationMode:
|
||||
settings->RemoteApplicationMode = param;
|
||||
break;
|
||||
@ -1603,6 +1615,12 @@ UINT32 freerdp_get_param_uint32(rdpSettings* settings, int id)
|
||||
return settings->GatewayCredentialsSource;
|
||||
break;
|
||||
|
||||
#ifdef WITH_HTTP_PROXY
|
||||
case FreeRDP_HTTPProxyPort:
|
||||
return settings->HTTPProxyPort;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case FreeRDP_RemoteAppNumIconCaches:
|
||||
return settings->RemoteAppNumIconCaches;
|
||||
break;
|
||||
@ -1911,6 +1929,12 @@ int freerdp_set_param_uint32(rdpSettings* settings, int id, UINT32 param)
|
||||
settings->GatewayCredentialsSource = param;
|
||||
break;
|
||||
|
||||
#ifdef WITH_HTTP_PROXY
|
||||
case FreeRDP_HTTPProxyPort:
|
||||
settings->HTTPProxyPort = param;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case FreeRDP_RemoteAppNumIconCaches:
|
||||
settings->RemoteAppNumIconCaches = param;
|
||||
break;
|
||||
@ -2233,6 +2257,12 @@ char* freerdp_get_param_string(rdpSettings* settings, int id)
|
||||
return settings->GatewayDomain;
|
||||
break;
|
||||
|
||||
#ifdef WITH_HTTP_PROXY
|
||||
case FreeRDP_HTTPProxyHostname:
|
||||
return settings->HTTPProxyHostname;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case FreeRDP_RemoteApplicationName:
|
||||
return settings->RemoteApplicationName;
|
||||
break;
|
||||
@ -2437,6 +2467,13 @@ int freerdp_set_param_string(rdpSettings* settings, int id, const char* param)
|
||||
settings->GatewayDomain = _strdup(param);
|
||||
break;
|
||||
|
||||
#ifdef WITH_HTTP_PROXY
|
||||
case FreeRDP_HTTPProxyHostname:
|
||||
free(settings->HTTPProxyHostname);
|
||||
settings->HTTPProxyHostname = _strdup(param);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case FreeRDP_RemoteApplicationName:
|
||||
free(settings->RemoteApplicationName);
|
||||
settings->RemoteApplicationName = _strdup(param);
|
||||
|
@ -481,6 +481,9 @@ rdpSettings* freerdp_settings_clone(rdpSettings* settings)
|
||||
_settings->GatewayUsername = _strdup(settings->GatewayUsername); /* 1987 */
|
||||
_settings->GatewayPassword = _strdup(settings->GatewayPassword); /* 1988 */
|
||||
_settings->GatewayDomain = _strdup(settings->GatewayDomain); /* 1989 */
|
||||
#ifdef WITH_HTTP_PROXY
|
||||
_settings->HTTPProxyHostname = settings->HTTPProxyHostname; /* 199x */
|
||||
#endif
|
||||
_settings->RemoteApplicationName = _strdup(settings->RemoteApplicationName); /* 2113 */
|
||||
_settings->RemoteApplicationIcon = _strdup(settings->RemoteApplicationIcon); /* 2114 */
|
||||
_settings->RemoteApplicationProgram = _strdup(settings->RemoteApplicationProgram); /* 2115 */
|
||||
@ -534,6 +537,9 @@ rdpSettings* freerdp_settings_clone(rdpSettings* settings)
|
||||
_settings->GatewayUsageMethod = settings->GatewayUsageMethod; /* 1984 */
|
||||
_settings->GatewayPort = settings->GatewayPort; /* 1985 */
|
||||
_settings->GatewayCredentialsSource = settings->GatewayCredentialsSource; /* 1990 */
|
||||
#ifdef WITH_HTTP_PROXY
|
||||
_settings->HTTPProxyPort = settings->HTTPProxyPort; /* 199x */
|
||||
#endif
|
||||
_settings->RemoteApplicationExpandCmdLine = settings->RemoteApplicationExpandCmdLine; /* 2119 */
|
||||
_settings->RemoteApplicationExpandWorkingDir = settings->RemoteApplicationExpandWorkingDir; /* 2120 */
|
||||
_settings->RemoteAppNumIconCaches = settings->RemoteAppNumIconCaches; /* 2122 */
|
||||
@ -651,6 +657,9 @@ rdpSettings* freerdp_settings_clone(rdpSettings* settings)
|
||||
_settings->PlayRemoteFx = settings->PlayRemoteFx; /* 1857 */
|
||||
_settings->GatewayUseSameCredentials = settings->GatewayUseSameCredentials; /* 1991 */
|
||||
_settings->GatewayEnabled = settings->GatewayEnabled; /* 1992 */
|
||||
#ifdef WITH_HTTP_PROXY
|
||||
_settings->HTTPProxyEnabled = settings->HTTPProxyEnabled; /* 1995 */
|
||||
#endif
|
||||
_settings->RemoteApplicationMode = settings->RemoteApplicationMode; /* 2112 */
|
||||
_settings->DisableRemoteAppCapsCheck = settings->DisableRemoteAppCapsCheck; /* 2121 */
|
||||
_settings->RemoteAppLanguageBarSupported = settings->RemoteAppLanguageBarSupported; /* 2124 */
|
||||
|
@ -327,6 +327,61 @@ BOOL transport_connect_nla(rdpTransport* transport)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#ifdef WITH_HTTP_PROXY
|
||||
/* TODO move into core/tcp.c? */
|
||||
|
||||
|
||||
BOOL transport_http_proxy_connect(rdpTransport* transport, const char* hostname, UINT16 port)
|
||||
{
|
||||
int status;
|
||||
wStream* s;
|
||||
char str[32];
|
||||
|
||||
_itoa_s(port, str, sizeof(str), 10);
|
||||
|
||||
s = Stream_New(NULL, 200);
|
||||
Stream_Write(s, "CONNECT ", 8);
|
||||
Stream_Write(s, hostname, strlen(hostname));
|
||||
Stream_Write_UINT8(s, ':');
|
||||
Stream_Write(s, str, strlen(str));
|
||||
Stream_Write(s, " HTTP/1.1\r\n\r\nHost: ", 19);
|
||||
Stream_Write(s, hostname, strlen(hostname));
|
||||
Stream_Write_UINT8(s, ':');
|
||||
Stream_Write(s, str, strlen(str));
|
||||
Stream_Write(s, "\r\n\r\n", 4);
|
||||
|
||||
// Send Host: header? (RFC2817)
|
||||
|
||||
//fprintf(stderr, "Sending CONNECT %.*s:%.*s\n", strlen(hostname), hostname, strlen(str), str);
|
||||
fprintf(stderr, "Sending \"%.*s\"...\n", (int)Stream_GetPosition(s), Stream_Buffer(s));
|
||||
|
||||
status = transport_write(transport, s);
|
||||
if (status < 0) {
|
||||
fprintf(stderr, "Error writing: status=%d\n", status);
|
||||
return status;
|
||||
}
|
||||
|
||||
fprintf(stderr, "Sent!\n");
|
||||
|
||||
// Read result...
|
||||
memset(str, 0, sizeof(str));
|
||||
status = tcp_read(transport->TcpIn, (BYTE*)str, sizeof(str)-1);
|
||||
if (status <= 0) {
|
||||
// Error?
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
fprintf(stderr, "Reply: \"%.*s\"\n", status, str);
|
||||
|
||||
// TODO read until "\r\n\r\n"
|
||||
if (strstr(str, "200") == NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
BOOL transport_tsg_connect(rdpTransport* transport, const char* hostname, UINT16 port)
|
||||
{
|
||||
rdpTsg* tsg = tsg_new(transport);
|
||||
@ -374,6 +429,50 @@ BOOL transport_connect(rdpTransport* transport, const char* hostname, UINT16 por
|
||||
|
||||
transport->async = settings->AsyncTransport;
|
||||
|
||||
#ifdef WITH_HTTP_PROXY
|
||||
if (transport->settings->HTTPProxyEnabled)
|
||||
{
|
||||
status = tcp_connect(transport->TcpIn, settings->HTTPProxyHostname, settings->HTTPProxyPort);
|
||||
|
||||
if (status) {
|
||||
if (transport->settings->GatewayEnabled) {
|
||||
transport->layer = TRANSPORT_LAYER_HTTP_PROXY_IN;
|
||||
status = transport_http_proxy_connect(transport, settings->GatewayHostname, settings->GatewayPort);
|
||||
|
||||
if (status) {
|
||||
// Connect second channel
|
||||
transport->TcpOut = tcp_new(settings);
|
||||
status = tcp_connect(transport->TcpOut, settings->HTTPProxyHostname, settings->HTTPProxyPort);
|
||||
}
|
||||
|
||||
if (status) {
|
||||
transport->layer = TRANSPORT_LAYER_HTTP_PROXY_OUT;
|
||||
status = transport_http_proxy_connect(transport, settings->GatewayHostname, settings->GatewayPort);
|
||||
}
|
||||
|
||||
if (status) {
|
||||
transport->layer = TRANSPORT_LAYER_TSG;
|
||||
transport->SplitInputOutput = TRUE;
|
||||
status = transport_tsg_connect(transport, hostname, port);
|
||||
}
|
||||
}
|
||||
else {
|
||||
transport->layer = TRANSPORT_LAYER_TCP;
|
||||
transport->SplitInputOutput = FALSE;
|
||||
transport->TcpOut = transport->TcpIn;
|
||||
|
||||
status = tcp_connect(transport->TcpIn, settings->HTTPProxyHostname, settings->HTTPProxyPort);
|
||||
|
||||
if (status) {
|
||||
status = transport_http_proxy_connect(transport, hostname, port);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
||||
if (transport->settings->GatewayEnabled)
|
||||
{
|
||||
transport->layer = TRANSPORT_LAYER_TSG;
|
||||
@ -555,6 +654,12 @@ int transport_read_layer(rdpTransport* transport, BYTE* data, int bytes)
|
||||
else if (transport->layer == TRANSPORT_LAYER_TSG_TLS) {
|
||||
status = tls_read(transport->TsgTls, data + read, bytes - read);
|
||||
}
|
||||
#ifdef WITH_HTTP_PROXY
|
||||
else if (transport->layer == TRANSPORT_LAYER_HTTP_PROXY_IN)
|
||||
status = tcp_read(transport->TcpIn, data + read, bytes - read);
|
||||
else if (transport->layer == TRANSPORT_LAYER_HTTP_PROXY_OUT)
|
||||
status = tcp_read(transport->TcpOut, data + read, bytes - read);
|
||||
#endif
|
||||
|
||||
/* blocking means that we can't continue until this is read */
|
||||
|
||||
@ -737,6 +842,12 @@ int transport_write(rdpTransport* transport, wStream* s)
|
||||
status = tsg_write(transport->tsg, Stream_Pointer(s), length);
|
||||
else if (transport->layer == TRANSPORT_LAYER_TSG_TLS)
|
||||
status = tls_write(transport->TsgTls, Stream_Pointer(s), length);
|
||||
#ifdef WITH_HTTP_PROXY
|
||||
else if (transport->layer == TRANSPORT_LAYER_HTTP_PROXY_IN)
|
||||
status = tcp_write(transport->TcpIn, Stream_Pointer(s), length);
|
||||
else if (transport->layer == TRANSPORT_LAYER_HTTP_PROXY_OUT)
|
||||
status = tcp_write(transport->TcpOut, Stream_Pointer(s), length);
|
||||
#endif
|
||||
|
||||
if (status < 0)
|
||||
break; /* error occurred */
|
||||
@ -757,6 +868,12 @@ int transport_write(rdpTransport* transport, wStream* s)
|
||||
tcp_wait_write(transport->TcpOut);
|
||||
else if (transport->layer == TRANSPORT_LAYER_TSG_TLS)
|
||||
tls_wait_write(transport->TsgTls);
|
||||
#ifdef WITH_HTTP_PROXY
|
||||
else if (transport->layer == TRANSPORT_LAYER_HTTP_PROXY_IN)
|
||||
tcp_wait_write(transport->TcpIn);
|
||||
else if (transport->layer == TRANSPORT_LAYER_HTTP_PROXY_OUT)
|
||||
tcp_wait_write(transport->TcpOut);
|
||||
#endif
|
||||
else
|
||||
USleep(transport->SleepInterval);
|
||||
}
|
||||
|
@ -26,7 +26,11 @@ typedef enum
|
||||
TRANSPORT_LAYER_TLS,
|
||||
TRANSPORT_LAYER_TSG,
|
||||
TRANSPORT_LAYER_TSG_TLS,
|
||||
TRANSPORT_LAYER_CLOSED
|
||||
TRANSPORT_LAYER_CLOSED,
|
||||
#ifdef WITH_HTTP_PROXY
|
||||
TRANSPORT_LAYER_HTTP_PROXY_IN,
|
||||
TRANSPORT_LAYER_HTTP_PROXY_OUT,
|
||||
#endif
|
||||
} TRANSPORT_LAYER;
|
||||
|
||||
typedef struct rdp_transport rdpTransport;
|
||||
|
Loading…
Reference in New Issue
Block a user