libfreerdp-core: add 'Bypass RD Gateway server for local addresses' feature

This commit is contained in:
Marc-André Moreau 2014-03-24 14:44:18 -04:00
parent fb12998957
commit 4c920506ed
11 changed files with 90 additions and 13 deletions

View File

@ -1345,9 +1345,11 @@ int freerdp_client_settings_parse_command_line_arguments(rdpSettings* settings,
settings->GatewayHostname = _strdup(settings->ServerHostname);
}
settings->GatewayUsageMethod = TSC_PROXY_MODE_DIRECT;
settings->GatewayUseSameCredentials = TRUE;
settings->GatewayUsageMethod = TSC_PROXY_MODE_DETECT;
settings->GatewayEnabled = TRUE;
settings->GatewayBypassLocal = TRUE;
}
CommandLineSwitchCase(arg, "gu")
{

View File

@ -866,14 +866,36 @@ BOOL freerdp_client_populate_settings_from_rdp_file(rdpFile* file, rdpSettings*
{
freerdp_set_param_uint32(settings, FreeRDP_GatewayUsageMethod, file->GatewayUsageMethod);
if (file->GatewayUsageMethod == TSC_PROXY_MODE_DIRECT)
freerdp_set_param_bool(settings, FreeRDP_GatewayEnabled, TRUE);
else if (file->GatewayUsageMethod == TSC_PROXY_MODE_DETECT)
freerdp_set_param_bool(settings, FreeRDP_GatewayEnabled, TRUE);
else if (file->GatewayUsageMethod == TSC_PROXY_MODE_DEFAULT)
freerdp_set_param_bool(settings, FreeRDP_GatewayEnabled, TRUE);
else if (file->GatewayUsageMethod == TSC_PROXY_MODE_NONE_DETECT)
if (file->GatewayUsageMethod == TSC_PROXY_MODE_NONE_DIRECT)
{
freerdp_set_param_bool(settings, FreeRDP_GatewayEnabled, FALSE);
freerdp_set_param_bool(settings, FreeRDP_GatewayBypassLocal, FALSE);
}
else if (file->GatewayUsageMethod == TSC_PROXY_MODE_DIRECT)
{
freerdp_set_param_bool(settings, FreeRDP_GatewayEnabled, TRUE);
freerdp_set_param_bool(settings, FreeRDP_GatewayBypassLocal, FALSE);
}
else if (file->GatewayUsageMethod == TSC_PROXY_MODE_DETECT)
{
freerdp_set_param_bool(settings, FreeRDP_GatewayEnabled, TRUE);
freerdp_set_param_bool(settings, FreeRDP_GatewayBypassLocal, TRUE);
}
else if (file->GatewayUsageMethod == TSC_PROXY_MODE_DEFAULT)
{
/**
* This corresponds to "Automatically detect RD Gateway server settings",
* which means the client attempts to use gateway group policy settings
* http://technet.microsoft.com/en-us/library/cc770601.aspx
*/
freerdp_set_param_bool(settings, FreeRDP_GatewayEnabled, FALSE);
freerdp_set_param_bool(settings, FreeRDP_GatewayBypassLocal, FALSE);
}
else if (file->GatewayUsageMethod == TSC_PROXY_MODE_NONE_DETECT)
{
freerdp_set_param_bool(settings, FreeRDP_GatewayEnabled, FALSE);
freerdp_set_param_bool(settings, FreeRDP_GatewayBypassLocal, FALSE);
}
}
if (~file->PromptCredentialOnce)

View File

@ -669,6 +669,7 @@ typedef struct _RDPDR_PARALLEL RDPDR_PARALLEL;
#define FreeRDP_GatewayCredentialsSource 1990
#define FreeRDP_GatewayUseSameCredentials 1991
#define FreeRDP_GatewayEnabled 1992
#define FreeRDP_GatewayBypassLocal 1993
#define FreeRDP_RemoteApplicationMode 2112
#define FreeRDP_RemoteApplicationName 2113
#define FreeRDP_RemoteApplicationIcon 2114
@ -1073,7 +1074,8 @@ struct rdp_settings
ALIGN64 UINT32 GatewayCredentialsSource; /* 1990 */
ALIGN64 BOOL GatewayUseSameCredentials; /* 1991 */
ALIGN64 BOOL GatewayEnabled; /* 1992 */
UINT64 padding2048[2048 - 1993]; /* 1993 */
ALIGN64 BOOL GatewayBypassLocal; /* 1993 */
UINT64 padding2048[2048 - 1994]; /* 1994 */
UINT64 padding2112[2112 - 2048]; /* 2048 */
/**

View File

@ -746,6 +746,10 @@ BOOL freerdp_get_param_bool(rdpSettings* settings, int id)
return settings->GatewayEnabled;
break;
case FreeRDP_GatewayBypassLocal:
return settings->GatewayBypassLocal;
break;
case FreeRDP_RemoteApplicationMode:
return settings->RemoteApplicationMode;
break;
@ -1218,6 +1222,10 @@ int freerdp_set_param_bool(rdpSettings* settings, int id, BOOL param)
settings->GatewayEnabled = param;
break;
case FreeRDP_GatewayBypassLocal:
settings->GatewayBypassLocal = param;
break;
case FreeRDP_RemoteApplicationMode:
settings->RemoteApplicationMode = param;
break;

View File

@ -231,6 +231,9 @@ BOOL rdp_client_connect(rdpRdp* rdp)
nego_set_negotiation_enabled(rdp->nego, settings->NegotiateSecurityLayer);
nego_set_restricted_admin_mode_required(rdp->nego, settings->RestrictedAdminModeRequired);
nego_set_gateway_enabled(rdp->nego, settings->GatewayEnabled);
nego_set_gateway_bypass_local(rdp->nego, settings->GatewayBypassLocal);
nego_enable_rdp(rdp->nego, settings->RdpSecurity);
nego_enable_tls(rdp->nego, settings->TlsSecurity);
nego_enable_nla(rdp->nego, settings->NlaSecurity);

View File

@ -212,7 +212,25 @@ BOOL nego_security_connect(rdpNego* nego)
BOOL nego_tcp_connect(rdpNego* nego)
{
if (!nego->tcp_connected)
nego->tcp_connected = transport_connect(nego->transport, nego->hostname, nego->port);
{
if (nego->GatewayEnabled && nego->GatewayBypassLocal)
{
/* Attempt a direct connection first, and then fallback to using the gateway */
transport_set_gateway_enabled(nego->transport, FALSE);
nego->tcp_connected = transport_connect(nego->transport, nego->hostname, nego->port);
if (!nego->tcp_connected)
{
transport_set_gateway_enabled(nego->transport, TRUE);
nego->tcp_connected = transport_connect(nego->transport, nego->hostname, nego->port);
}
}
else
{
nego->tcp_connected = transport_connect(nego->transport, nego->hostname, nego->port);
}
}
return nego->tcp_connected;
}
@ -1034,6 +1052,16 @@ void nego_set_restricted_admin_mode_required(rdpNego* nego, BOOL RestrictedAdmin
nego->RestrictedAdminModeRequired = RestrictedAdminModeRequired;
}
void nego_set_gateway_enabled(rdpNego* nego, BOOL GatewayEnabled)
{
nego->GatewayEnabled = GatewayEnabled;
}
void nego_set_gateway_bypass_local(rdpNego* nego, BOOL GatewayBypassLocal)
{
nego->GatewayBypassLocal = GatewayBypassLocal;
}
/**
* Enable RDP security protocol.
* @param nego pointer to the negotiation structure

View File

@ -110,6 +110,8 @@ struct rdp_nego
BOOL NegotiateSecurityLayer;
BYTE enabled_protocols[16];
BOOL RestrictedAdminModeRequired;
BOOL GatewayEnabled;
BOOL GatewayBypassLocal;
rdpTransport* transport;
};
@ -142,6 +144,8 @@ void nego_init(rdpNego* nego);
void nego_set_target(rdpNego* nego, char* hostname, int port);
void nego_set_negotiation_enabled(rdpNego* nego, BOOL NegotiateSecurityLayer_enabled);
void nego_set_restricted_admin_mode_required(rdpNego* nego, BOOL RestrictedAdminModeRequired);
void nego_set_gateway_enabled(rdpNego* nego, BOOL GatewayEnabled);
void nego_set_gateway_bypass_local(rdpNego* nego, BOOL GatewayBypassLocal);
void nego_enable_rdp(rdpNego* nego, BOOL enable_rdp);
void nego_enable_tls(rdpNego* nego, BOOL enable_tls);
void nego_enable_nla(rdpNego* nego, BOOL enable_nla);

View File

@ -651,6 +651,7 @@ rdpSettings* freerdp_settings_clone(rdpSettings* settings)
_settings->PlayRemoteFx = settings->PlayRemoteFx; /* 1857 */
_settings->GatewayUseSameCredentials = settings->GatewayUseSameCredentials; /* 1991 */
_settings->GatewayEnabled = settings->GatewayEnabled; /* 1992 */
_settings->GatewayBypassLocal = settings->GatewayBypassLocal; /* 1993 */
_settings->RemoteApplicationMode = settings->RemoteApplicationMode; /* 2112 */
_settings->DisableRemoteAppCapsCheck = settings->DisableRemoteAppCapsCheck; /* 2121 */
_settings->RemoteAppLanguageBarSupported = settings->RemoteAppLanguageBarSupported; /* 2124 */

View File

@ -394,7 +394,7 @@ BOOL transport_connect(rdpTransport* transport, const char* hostname, UINT16 por
transport->async = settings->AsyncTransport;
if (transport->settings->GatewayEnabled)
if (transport->GatewayEnabled)
{
transport->layer = TRANSPORT_LAYER_TSG;
transport->TcpOut = tcp_new(settings);
@ -1032,6 +1032,11 @@ BOOL transport_set_blocking_mode(rdpTransport* transport, BOOL blocking)
return status;
}
BOOL transport_set_gateway_enabled(rdpTransport* transport, BOOL GatewayEnabled)
{
transport->GatewayEnabled = GatewayEnabled;
}
static void* transport_client_thread(void* arg)
{
DWORD status;
@ -1127,6 +1132,7 @@ rdpTransport* transport_new(rdpSettings* settings)
transport->connectedEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
transport->blocking = TRUE;
transport->GatewayEnabled = FALSE;
InitializeCriticalSectionAndSpinCount(&(transport->ReadLock), 4000);
InitializeCriticalSectionAndSpinCount(&(transport->WriteLock), 4000);

View File

@ -75,6 +75,7 @@ struct rdp_transport
HANDLE stopEvent;
HANDLE thread;
BOOL async;
BOOL GatewayEnabled;
CRITICAL_SECTION ReadLock;
CRITICAL_SECTION WriteLock;
wLog* log;
@ -88,7 +89,6 @@ BOOL transport_disconnect(rdpTransport* transport);
BOOL transport_connect_rdp(rdpTransport* transport);
BOOL transport_connect_tls(rdpTransport* transport);
BOOL transport_connect_nla(rdpTransport* transport);
BOOL transport_connect_tsg(rdpTransport* transport);
BOOL transport_accept_rdp(rdpTransport* transport);
BOOL transport_accept_tls(rdpTransport* transport);
BOOL transport_accept_nla(rdpTransport* transport);
@ -98,6 +98,7 @@ int transport_write(rdpTransport* transport, wStream* s);
void transport_get_fds(rdpTransport* transport, void** rfds, int* rcount);
int transport_check_fds(rdpTransport* transport);
BOOL transport_set_blocking_mode(rdpTransport* transport, BOOL blocking);
BOOL transport_set_gateway_enabled(rdpTransport* transport, BOOL GatewayEnabled);
void transport_get_read_handles(rdpTransport* transport, HANDLE* events, DWORD* count);
wStream* transport_receive_pool_take(rdpTransport* transport);

View File

@ -90,7 +90,7 @@ int freerdp_tcp_connect(const char* hostname, int port)
if (status != 0)
{
fprintf(stderr, "tcp_connect: getaddrinfo (%s)\n", gai_strerror(status));
//fprintf(stderr, "tcp_connect: getaddrinfo (%s)\n", gai_strerror(status));
return -1;
}