[core,gateway] implement RDG and TSG policy
* use dynamic logger in RDG * honor [MS-TSGU] 2.2.9.2.1.5.2 TSG_REDIRECTION_FLAGS * honor [MS-TSGU] 2.2.10.16 HTTP_TUNNEL_AUTH_RESPONSE HTTP_TUNNEL_AUTH_RESPONSE_FIELD_REDIR_FLAGS flag * add setting GatewayIgnoreRedirectionPolicy to ignore the gateway policy if desired
This commit is contained in:
parent
6a7c375831
commit
93eb4df524
@ -164,6 +164,17 @@ typedef struct rdp_settings rdpSettings;
|
||||
const char* option, const char* value);
|
||||
|
||||
FREERDP_API BOOL freerdp_device_collection_add(rdpSettings* settings, RDPDR_DEVICE* device);
|
||||
|
||||
/** \brief Removed a device from the settings, returns ownership of the allocated device to
|
||||
* caller.
|
||||
*
|
||||
* \param settings the settings to remove the device from
|
||||
* \param device the device to remove
|
||||
*
|
||||
* \return \b TRUE if the device was removed, \b FALSE if device was not found or is NULL
|
||||
*/
|
||||
FREERDP_API BOOL freerdp_device_collection_del(rdpSettings* settings,
|
||||
const RDPDR_DEVICE* device);
|
||||
FREERDP_API RDPDR_DEVICE* freerdp_device_collection_find(rdpSettings* settings,
|
||||
const char* name);
|
||||
FREERDP_API RDPDR_DEVICE* freerdp_device_collection_find_type(rdpSettings* settings,
|
||||
|
@ -467,7 +467,8 @@ struct rdp_settings
|
||||
SETTINGS_DEPRECATED(ALIGN64 char* GatewayAvdDiagnosticserviceurl); /* 2009 */
|
||||
SETTINGS_DEPRECATED(ALIGN64 char* GatewayAvdHubdiscoverygeourl); /* 2010 */
|
||||
SETTINGS_DEPRECATED(ALIGN64 char* GatewayAvdActivityhint); /* 2011 */
|
||||
UINT64 padding2015[2015 - 2012]; /* 2012 */
|
||||
SETTINGS_DEPRECATED(ALIGN64 BOOL GatewayIgnoreRedirectionPolicy); /* 2012 */
|
||||
UINT64 padding2015[2015 - 2013]; /* 2013 */
|
||||
|
||||
/* Proxy */
|
||||
SETTINGS_DEPRECATED(ALIGN64 UINT32 ProxyType); /* 2015 */
|
||||
|
@ -237,6 +237,33 @@ BOOL freerdp_device_collection_add(rdpSettings* settings, RDPDR_DEVICE* device)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL freerdp_device_collection_del(rdpSettings* settings, const RDPDR_DEVICE* device)
|
||||
{
|
||||
WINPR_ASSERT(settings);
|
||||
|
||||
if (!device)
|
||||
return FALSE;
|
||||
|
||||
const UINT32 count = settings->DeviceCount;
|
||||
for (size_t x = 0; x < count; x++)
|
||||
{
|
||||
const RDPDR_DEVICE* cur = settings->DeviceArray[x];
|
||||
if (cur == device)
|
||||
{
|
||||
for (size_t y = x + 1; y < count; y++)
|
||||
{
|
||||
RDPDR_DEVICE* next = settings->DeviceArray[y];
|
||||
settings->DeviceArray[y - 1] = next;
|
||||
}
|
||||
settings->DeviceArray[count - 1] = NULL;
|
||||
settings->DeviceCount--;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
RDPDR_DEVICE* freerdp_device_collection_find(rdpSettings* settings, const char* name)
|
||||
{
|
||||
RDPDR_DEVICE* device = NULL;
|
||||
|
@ -252,6 +252,9 @@ BOOL freerdp_settings_get_bool(const rdpSettings* settings, FreeRDP_Settings_Key
|
||||
case FreeRDP_GatewayHttpUseWebsockets:
|
||||
return settings->GatewayHttpUseWebsockets;
|
||||
|
||||
case FreeRDP_GatewayIgnoreRedirectionPolicy:
|
||||
return settings->GatewayIgnoreRedirectionPolicy;
|
||||
|
||||
case FreeRDP_GatewayRpcTransport:
|
||||
return settings->GatewayRpcTransport;
|
||||
|
||||
@ -908,6 +911,10 @@ BOOL freerdp_settings_set_bool(rdpSettings* settings, FreeRDP_Settings_Keys_Bool
|
||||
settings->GatewayHttpUseWebsockets = cnv.c;
|
||||
break;
|
||||
|
||||
case FreeRDP_GatewayIgnoreRedirectionPolicy:
|
||||
settings->GatewayIgnoreRedirectionPolicy = cnv.c;
|
||||
break;
|
||||
|
||||
case FreeRDP_GatewayRpcTransport:
|
||||
settings->GatewayRpcTransport = cnv.c;
|
||||
break;
|
||||
|
@ -114,6 +114,8 @@ static const struct settings_str_entry settings_map[] = {
|
||||
{ FreeRDP_GatewayHttpTransport, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_GatewayHttpTransport" },
|
||||
{ FreeRDP_GatewayHttpUseWebsockets, FREERDP_SETTINGS_TYPE_BOOL,
|
||||
"FreeRDP_GatewayHttpUseWebsockets" },
|
||||
{ FreeRDP_GatewayIgnoreRedirectionPolicy, FREERDP_SETTINGS_TYPE_BOOL,
|
||||
"FreeRDP_GatewayIgnoreRedirectionPolicy" },
|
||||
{ FreeRDP_GatewayRpcTransport, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_GatewayRpcTransport" },
|
||||
{ FreeRDP_GatewayUdpTransport, FREERDP_SETTINGS_TYPE_BOOL, "FreeRDP_GatewayUdpTransport" },
|
||||
{ FreeRDP_GatewayUseSameCredentials, FREERDP_SETTINGS_TYPE_BOOL,
|
||||
|
@ -661,6 +661,8 @@ static int freerdp_channels_process_sync(rdpChannels* channels, freerdp* instanc
|
||||
int status = TRUE;
|
||||
wMessage message = { 0 };
|
||||
|
||||
WINPR_ASSERT(channels);
|
||||
|
||||
while (MessageQueue_Peek(channels->queue, &message, TRUE))
|
||||
{
|
||||
freerdp_channels_process_message(instance, &message);
|
||||
@ -728,6 +730,8 @@ int freerdp_channels_process_pending_messages(freerdp* instance)
|
||||
*/
|
||||
BOOL freerdp_channels_check_fds(rdpChannels* channels, freerdp* instance)
|
||||
{
|
||||
WINPR_ASSERT(channels);
|
||||
|
||||
if (WaitForSingleObject(MessageQueue_Event(channels->queue), 0) == WAIT_OBJECT_0)
|
||||
{
|
||||
freerdp_channels_process_sync(channels, instance);
|
||||
@ -742,6 +746,8 @@ UINT freerdp_channels_disconnect(rdpChannels* channels, freerdp* instance)
|
||||
CHANNEL_OPEN_DATA* pChannelOpenData = NULL;
|
||||
CHANNEL_CLIENT_DATA* pChannelClientData = NULL;
|
||||
|
||||
WINPR_ASSERT(channels);
|
||||
|
||||
if (!channels->connected)
|
||||
return 0;
|
||||
|
||||
@ -808,8 +814,6 @@ void freerdp_channels_close(rdpChannels* channels, freerdp* instance)
|
||||
}
|
||||
}
|
||||
|
||||
channels->clientDataCount = 0;
|
||||
|
||||
for (int index = 0; index < channels->openDataCount; index++)
|
||||
{
|
||||
pChannelOpenData = &channels->openDataList[index];
|
||||
|
@ -89,15 +89,6 @@
|
||||
#define HTTP_TUNNEL_PACKET_FIELD_PAA_COOKIE 0x1
|
||||
#define HTTP_TUNNEL_PACKET_FIELD_REAUTH 0x2
|
||||
|
||||
/* HTTP tunnel redir flags. */
|
||||
#define HTTP_TUNNEL_REDIR_ENABLE_ALL 0x80000000
|
||||
#define HTTP_TUNNEL_REDIR_DISABLE_ALL 0x40000000
|
||||
#define HTTP_TUNNEL_REDIR_DISABLE_DRIVE 0x1
|
||||
#define HTTP_TUNNEL_REDIR_DISABLE_PRINTER 0x2
|
||||
#define HTTP_TUNNEL_REDIR_DISABLE_PORT 0x4
|
||||
#define HTTP_TUNNEL_REDIR_DISABLE_CLIPBOARD 0x8
|
||||
#define HTTP_TUNNEL_REDIR_DISABLE_PNP 0x10
|
||||
|
||||
/* HTTP tunnel response fields present flags. */
|
||||
#define HTTP_TUNNEL_RESPONSE_FIELD_TUNNEL_ID 0x1
|
||||
#define HTTP_TUNNEL_RESPONSE_FIELD_CAPS 0x2
|
||||
@ -146,6 +137,7 @@ struct rdp_rdg
|
||||
rdg_http_encoding_context transferEncoding;
|
||||
|
||||
SmartcardCertInfo* smartcard;
|
||||
wLog* log;
|
||||
};
|
||||
|
||||
enum
|
||||
@ -261,15 +253,17 @@ static const char* capabilities_enum_to_string(UINT32 capabilities)
|
||||
return flags_to_string(capabilities, capabilities_enum, ARRAYSIZE(capabilities_enum));
|
||||
}
|
||||
|
||||
static BOOL rdg_read_http_unicode_string(wStream* s, const WCHAR** string, UINT16* lengthInBytes)
|
||||
static BOOL rdg_read_http_unicode_string(wLog* log, wStream* s, const WCHAR** string,
|
||||
UINT16* lengthInBytes)
|
||||
{
|
||||
UINT16 strLenBytes = 0;
|
||||
size_t rem = Stream_GetRemainingLength(s);
|
||||
|
||||
/* Read length of the string */
|
||||
if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
|
||||
if (!Stream_CheckAndLogRequiredLengthWLog(log, s, 4))
|
||||
{
|
||||
WLog_ERR(TAG, "Could not read stream length, only have %" PRIuz " bytes", rem);
|
||||
WLog_Print(log, WLOG_ERROR, "Could not read stream length, only have %" PRIuz " bytes",
|
||||
rem);
|
||||
return FALSE;
|
||||
}
|
||||
Stream_Read_UINT16(s, strLenBytes);
|
||||
@ -280,8 +274,9 @@ static BOOL rdg_read_http_unicode_string(wStream* s, const WCHAR** string, UINT1
|
||||
/* seek past the string - if this fails something is wrong */
|
||||
if (!Stream_SafeSeek(s, strLenBytes))
|
||||
{
|
||||
WLog_ERR(TAG, "Could not read stream data, only have %" PRIuz " bytes, expected %" PRIu16,
|
||||
rem - 4, strLenBytes);
|
||||
WLog_Print(log, WLOG_ERROR,
|
||||
"Could not read stream data, only have %" PRIuz " bytes, expected %" PRIu16,
|
||||
rem - 4, strLenBytes);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -699,7 +694,7 @@ out:
|
||||
return s;
|
||||
}
|
||||
|
||||
static BOOL rdg_recv_auth_token(rdpCredsspAuth* auth, HttpResponse* response)
|
||||
static BOOL rdg_recv_auth_token(wLog* log, rdpCredsspAuth* auth, HttpResponse* response)
|
||||
{
|
||||
size_t len = 0;
|
||||
const char* token64 = NULL;
|
||||
@ -719,7 +714,7 @@ static BOOL rdg_recv_auth_token(rdpCredsspAuth* auth, HttpResponse* response)
|
||||
case HTTP_STATUS_OK:
|
||||
break;
|
||||
default:
|
||||
http_response_log_error_status(WLog_Get(TAG), WLOG_WARN, response);
|
||||
http_response_log_error_status(log, WLOG_WARN, response);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -774,14 +769,14 @@ static BOOL rdg_process_handshake_response(rdpRdg* rdg, wStream* s)
|
||||
BYTE verMajor = 0;
|
||||
BYTE verMinor = 0;
|
||||
const char* error = NULL;
|
||||
WLog_DBG(TAG, "Handshake response received");
|
||||
WLog_Print(rdg->log, WLOG_DEBUG, "Handshake response received");
|
||||
|
||||
if (rdg->state != RDG_CLIENT_STATE_HANDSHAKE)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!Stream_CheckAndLogRequiredLength(TAG, s, 10))
|
||||
if (!Stream_CheckAndLogRequiredLengthWLog(rdg->log, s, 10))
|
||||
return FALSE;
|
||||
|
||||
Stream_Read_UINT32(s, errorCode);
|
||||
@ -790,14 +785,14 @@ static BOOL rdg_process_handshake_response(rdpRdg* rdg, wStream* s)
|
||||
Stream_Read_UINT16(s, serverVersion);
|
||||
Stream_Read_UINT16(s, extendedAuth);
|
||||
error = rpc_error_to_string(errorCode);
|
||||
WLog_DBG(TAG,
|
||||
"errorCode=%s, verMajor=%" PRId8 ", verMinor=%" PRId8 ", serverVersion=%" PRId16
|
||||
", extendedAuth=%s",
|
||||
error, verMajor, verMinor, serverVersion, extended_auth_to_string(extendedAuth));
|
||||
WLog_Print(rdg->log, WLOG_DEBUG,
|
||||
"errorCode=%s, verMajor=%" PRId8 ", verMinor=%" PRId8 ", serverVersion=%" PRId16
|
||||
", extendedAuth=%s",
|
||||
error, verMajor, verMinor, serverVersion, extended_auth_to_string(extendedAuth));
|
||||
|
||||
if (FAILED((HRESULT)errorCode))
|
||||
{
|
||||
WLog_ERR(TAG, "Handshake error %s", error);
|
||||
WLog_Print(rdg->log, WLOG_ERROR, "Handshake error %s", error);
|
||||
freerdp_set_last_error_log(rdg->context, errorCode);
|
||||
return FALSE;
|
||||
}
|
||||
@ -815,8 +810,8 @@ static BOOL rdg_process_tunnel_response_optional(rdpRdg* rdg, wStream* s, UINT16
|
||||
/* Seek over tunnelId (4 bytes) */
|
||||
if (!Stream_SafeSeek(s, 4))
|
||||
{
|
||||
WLog_ERR(TAG, "Short tunnelId, got %" PRIuz ", expected 4",
|
||||
Stream_GetRemainingLength(s));
|
||||
WLog_Print(rdg->log, WLOG_ERROR, "Short tunnelId, got %" PRIuz ", expected 4",
|
||||
Stream_GetRemainingLength(s));
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
@ -824,11 +819,11 @@ static BOOL rdg_process_tunnel_response_optional(rdpRdg* rdg, wStream* s, UINT16
|
||||
if (fieldsPresent & HTTP_TUNNEL_RESPONSE_FIELD_CAPS)
|
||||
{
|
||||
UINT32 caps = 0;
|
||||
if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
|
||||
if (!Stream_CheckAndLogRequiredLengthWLog(rdg->log, s, 4))
|
||||
return FALSE;
|
||||
|
||||
Stream_Read_UINT32(s, caps);
|
||||
WLog_DBG(TAG, "capabilities=%s", capabilities_enum_to_string(caps));
|
||||
WLog_Print(rdg->log, WLOG_DEBUG, "capabilities=%s", capabilities_enum_to_string(caps));
|
||||
}
|
||||
|
||||
if (fieldsPresent & HTTP_TUNNEL_RESPONSE_FIELD_SOH_REQ)
|
||||
@ -836,14 +831,15 @@ static BOOL rdg_process_tunnel_response_optional(rdpRdg* rdg, wStream* s, UINT16
|
||||
/* Seek over nonce (20 bytes) */
|
||||
if (!Stream_SafeSeek(s, 20))
|
||||
{
|
||||
WLog_ERR(TAG, "Short nonce, got %" PRIuz ", expected 20", Stream_GetRemainingLength(s));
|
||||
WLog_Print(rdg->log, WLOG_ERROR, "Short nonce, got %" PRIuz ", expected 20",
|
||||
Stream_GetRemainingLength(s));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Read serverCert */
|
||||
if (!rdg_read_http_unicode_string(s, NULL, NULL))
|
||||
if (!rdg_read_http_unicode_string(rdg->log, s, NULL, NULL))
|
||||
{
|
||||
WLog_ERR(TAG, "Failed to read server certificate");
|
||||
WLog_Print(rdg->log, WLOG_ERROR, "Failed to read server certificate");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
@ -858,9 +854,9 @@ static BOOL rdg_process_tunnel_response_optional(rdpRdg* rdg, wStream* s, UINT16
|
||||
WINPR_ASSERT(context->instance);
|
||||
|
||||
/* Read message string and invoke callback */
|
||||
if (!rdg_read_http_unicode_string(s, &msg, &msgLenBytes))
|
||||
if (!rdg_read_http_unicode_string(rdg->log, s, &msg, &msgLenBytes))
|
||||
{
|
||||
WLog_ERR(TAG, "Failed to read consent message");
|
||||
WLog_Print(rdg->log, WLOG_ERROR, "Failed to read consent message");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -877,14 +873,14 @@ static BOOL rdg_process_tunnel_response(rdpRdg* rdg, wStream* s)
|
||||
UINT16 fieldsPresent = 0;
|
||||
UINT32 errorCode = 0;
|
||||
const char* error = NULL;
|
||||
WLog_DBG(TAG, "Tunnel response received");
|
||||
WLog_Print(rdg->log, WLOG_DEBUG, "Tunnel response received");
|
||||
|
||||
if (rdg->state != RDG_CLIENT_STATE_TUNNEL_CREATE)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!Stream_CheckAndLogRequiredLength(TAG, s, 10))
|
||||
if (!Stream_CheckAndLogRequiredLengthWLog(rdg->log, s, 10))
|
||||
return FALSE;
|
||||
|
||||
Stream_Read_UINT16(s, serverVersion);
|
||||
@ -892,12 +888,12 @@ static BOOL rdg_process_tunnel_response(rdpRdg* rdg, wStream* s)
|
||||
Stream_Read_UINT16(s, fieldsPresent);
|
||||
Stream_Seek_UINT16(s); /* reserved */
|
||||
error = rpc_error_to_string(errorCode);
|
||||
WLog_DBG(TAG, "serverVersion=%" PRId16 ", errorCode=%s, fieldsPresent=%s", serverVersion, error,
|
||||
tunnel_response_fields_present_to_string(fieldsPresent));
|
||||
WLog_Print(rdg->log, WLOG_DEBUG, "serverVersion=%" PRId16 ", errorCode=%s, fieldsPresent=%s",
|
||||
serverVersion, error, tunnel_response_fields_present_to_string(fieldsPresent));
|
||||
|
||||
if (FAILED((HRESULT)errorCode))
|
||||
{
|
||||
WLog_ERR(TAG, "Tunnel creation error %s", error);
|
||||
WLog_Print(rdg->log, WLOG_ERROR, "Tunnel creation error %s", error);
|
||||
freerdp_set_last_error_log(rdg->context, errorCode);
|
||||
return FALSE;
|
||||
}
|
||||
@ -913,31 +909,66 @@ static BOOL rdg_process_tunnel_authorization_response(rdpRdg* rdg, wStream* s)
|
||||
UINT32 errorCode = 0;
|
||||
UINT16 fieldsPresent = 0;
|
||||
const char* error = NULL;
|
||||
WLog_DBG(TAG, "Tunnel authorization received");
|
||||
WLog_Print(rdg->log, WLOG_DEBUG, "Tunnel authorization received");
|
||||
|
||||
if (rdg->state != RDG_CLIENT_STATE_TUNNEL_AUTHORIZE)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
|
||||
if (!Stream_CheckAndLogRequiredLengthWLog(rdg->log, s, 8))
|
||||
return FALSE;
|
||||
|
||||
Stream_Read_UINT32(s, errorCode);
|
||||
Stream_Read_UINT16(s, fieldsPresent);
|
||||
Stream_Seek_UINT16(s); /* reserved */
|
||||
error = rpc_error_to_string(errorCode);
|
||||
WLog_DBG(TAG, "errorCode=%s, fieldsPresent=%s", error,
|
||||
tunnel_authorization_response_fields_present_to_string(fieldsPresent));
|
||||
WLog_Print(rdg->log, WLOG_DEBUG, "errorCode=%s, fieldsPresent=%s", error,
|
||||
tunnel_authorization_response_fields_present_to_string(fieldsPresent));
|
||||
|
||||
/* [MS-TSGU] 3.7.5.2.7 */
|
||||
if (errorCode != S_OK && errorCode != E_PROXY_QUARANTINE_ACCESSDENIED)
|
||||
{
|
||||
WLog_ERR(TAG, "Tunnel authorization error %s", error);
|
||||
WLog_Print(rdg->log, WLOG_ERROR, "Tunnel authorization error %s", error);
|
||||
freerdp_set_last_error_log(rdg->context, errorCode);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (fieldsPresent & HTTP_TUNNEL_AUTH_RESPONSE_FIELD_REDIR_FLAGS)
|
||||
{
|
||||
UINT32 redirFlags = 0;
|
||||
if (!Stream_CheckAndLogRequiredCapacityWLog(rdg->log, s, 4))
|
||||
return FALSE;
|
||||
Stream_Read_UINT32(s, redirFlags);
|
||||
|
||||
rdpContext* context = rdg->context;
|
||||
if (!utils_apply_gateway_policy(rdg->log, context, redirFlags, "RDG"))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (fieldsPresent & HTTP_TUNNEL_AUTH_RESPONSE_FIELD_IDLE_TIMEOUT)
|
||||
{
|
||||
UINT32 idleTimeout = 0;
|
||||
if (!Stream_CheckAndLogRequiredCapacityWLog(rdg->log, s, 4))
|
||||
return FALSE;
|
||||
Stream_Read_UINT32(s, idleTimeout);
|
||||
WLog_Print(rdg->log, WLOG_DEBUG, "[IDLE_TIMEOUT] idleTimeout=%" PRIu32 ": TODO: unused",
|
||||
idleTimeout);
|
||||
}
|
||||
|
||||
if (fieldsPresent & HTTP_TUNNEL_AUTH_RESPONSE_FIELD_SOH_RESPONSE)
|
||||
{
|
||||
UINT16 cbLen = 0;
|
||||
if (!Stream_CheckAndLogRequiredCapacityWLog(rdg->log, s, 2))
|
||||
return FALSE;
|
||||
Stream_Read_UINT16(s, cbLen);
|
||||
|
||||
WLog_Print(rdg->log, WLOG_DEBUG, "[SOH_RESPONSE] cbLen=%" PRIu16 ": TODO: unused", cbLen);
|
||||
if (!Stream_CheckAndLogRequiredLengthWLog(rdg->log, s, cbLen))
|
||||
return FALSE;
|
||||
Stream_Seek(s, cbLen);
|
||||
}
|
||||
|
||||
return rdg_send_channel_create(rdg);
|
||||
}
|
||||
|
||||
@ -955,8 +986,8 @@ static BOOL rdg_process_extauth_sspi(rdpRdg* rdg, wStream* s)
|
||||
|
||||
if (errorCode != ERROR_SUCCESS)
|
||||
{
|
||||
WLog_ERR(TAG, "EXTAUTH_SSPI_NTLM failed with error %s [0x%08X]",
|
||||
GetSecurityStatusString(errorCode), errorCode);
|
||||
WLog_Print(rdg->log, WLOG_ERROR, "EXTAUTH_SSPI_NTLM failed with error %s [0x%08X]",
|
||||
GetSecurityStatusString(errorCode), errorCode);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -993,27 +1024,27 @@ static BOOL rdg_process_channel_response(rdpRdg* rdg, wStream* s)
|
||||
UINT16 fieldsPresent = 0;
|
||||
UINT32 errorCode = 0;
|
||||
const char* error = NULL;
|
||||
WLog_DBG(TAG, "Channel response received");
|
||||
WLog_Print(rdg->log, WLOG_DEBUG, "Channel response received");
|
||||
|
||||
if (rdg->state != RDG_CLIENT_STATE_CHANNEL_CREATE)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
|
||||
if (!Stream_CheckAndLogRequiredLengthWLog(rdg->log, s, 8))
|
||||
return FALSE;
|
||||
|
||||
Stream_Read_UINT32(s, errorCode);
|
||||
Stream_Read_UINT16(s, fieldsPresent);
|
||||
Stream_Seek_UINT16(s); /* reserved */
|
||||
error = rpc_error_to_string(errorCode);
|
||||
WLog_DBG(TAG, "channel response errorCode=%s, fieldsPresent=%s", error,
|
||||
channel_response_fields_present_to_string(fieldsPresent));
|
||||
WLog_Print(rdg->log, WLOG_DEBUG, "channel response errorCode=%s, fieldsPresent=%s", error,
|
||||
channel_response_fields_present_to_string(fieldsPresent));
|
||||
|
||||
if (FAILED((HRESULT)errorCode))
|
||||
{
|
||||
WLog_ERR(TAG, "channel response errorCode=%s, fieldsPresent=%s", error,
|
||||
channel_response_fields_present_to_string(fieldsPresent));
|
||||
WLog_Print(rdg->log, WLOG_ERROR, "channel response errorCode=%s, fieldsPresent=%s", error,
|
||||
channel_response_fields_present_to_string(fieldsPresent));
|
||||
freerdp_set_last_error_log(rdg->context, errorCode);
|
||||
return FALSE;
|
||||
}
|
||||
@ -1029,7 +1060,7 @@ static BOOL rdg_process_packet(rdpRdg* rdg, wStream* s)
|
||||
UINT32 packetLength = 0;
|
||||
Stream_SetPosition(s, 0);
|
||||
|
||||
if (!Stream_CheckAndLogRequiredLength(TAG, s, 8))
|
||||
if (!Stream_CheckAndLogRequiredLengthWLog(rdg->log, s, 8))
|
||||
return FALSE;
|
||||
|
||||
Stream_Read_UINT16(s, type);
|
||||
@ -1038,7 +1069,8 @@ static BOOL rdg_process_packet(rdpRdg* rdg, wStream* s)
|
||||
|
||||
if (Stream_Length(s) < packetLength)
|
||||
{
|
||||
WLog_ERR(TAG, "Short packet %" PRIuz ", expected %" PRIuz, Stream_Length(s), packetLength);
|
||||
WLog_Print(rdg->log, WLOG_ERROR, "Short packet %" PRIuz ", expected %" PRIuz,
|
||||
Stream_Length(s), packetLength);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -1061,7 +1093,7 @@ static BOOL rdg_process_packet(rdpRdg* rdg, wStream* s)
|
||||
break;
|
||||
|
||||
case PKT_TYPE_DATA:
|
||||
WLog_ERR(TAG, "Unexpected packet type DATA");
|
||||
WLog_Print(rdg->log, WLOG_ERROR, "Unexpected packet type DATA");
|
||||
return FALSE;
|
||||
|
||||
case PKT_TYPE_EXTENDED_AUTH_MSG:
|
||||
@ -1069,7 +1101,7 @@ static BOOL rdg_process_packet(rdpRdg* rdg, wStream* s)
|
||||
break;
|
||||
|
||||
default:
|
||||
WLog_ERR(TAG, "PKG TYPE 0x%x not implemented", type);
|
||||
WLog_Print(rdg->log, WLOG_ERROR, "PKG TYPE 0x%x not implemented", type);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -1325,7 +1357,7 @@ static BOOL rdg_establish_data_connection(rdpRdg* rdg, rdpTls* tls, const char*
|
||||
* sending an answer if it is not happy with the http request */
|
||||
if (!response)
|
||||
{
|
||||
WLog_INFO(TAG, "RD Gateway HTTP transport broken.");
|
||||
WLog_Print(rdg->log, WLOG_INFO, "RD Gateway HTTP transport broken.");
|
||||
*rpcFallback = TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
@ -1336,7 +1368,7 @@ static BOOL rdg_establish_data_connection(rdpRdg* rdg, rdpTls* tls, const char*
|
||||
{
|
||||
case HTTP_STATUS_NOT_FOUND:
|
||||
{
|
||||
WLog_INFO(TAG, "RD Gateway does not support HTTP transport.");
|
||||
WLog_Print(rdg->log, WLOG_INFO, "RD Gateway does not support HTTP transport.");
|
||||
*rpcFallback = TRUE;
|
||||
|
||||
http_response_free(response);
|
||||
@ -1345,13 +1377,13 @@ static BOOL rdg_establish_data_connection(rdpRdg* rdg, rdpTls* tls, const char*
|
||||
case HTTP_STATUS_OK:
|
||||
break;
|
||||
default:
|
||||
http_response_log_error_status(WLog_Get(TAG), WLOG_WARN, response);
|
||||
http_response_log_error_status(rdg->log, WLOG_WARN, response);
|
||||
break;
|
||||
}
|
||||
|
||||
while (!credssp_auth_is_complete(rdg->auth))
|
||||
{
|
||||
if (!rdg_recv_auth_token(rdg->auth, response))
|
||||
if (!rdg_recv_auth_token(rdg->log, rdg->auth, response))
|
||||
{
|
||||
http_response_free(response);
|
||||
return FALSE;
|
||||
@ -1367,7 +1399,7 @@ static BOOL rdg_establish_data_connection(rdpRdg* rdg, rdpTls* tls, const char*
|
||||
response = http_response_recv(tls, TRUE);
|
||||
if (!response)
|
||||
{
|
||||
WLog_INFO(TAG, "RD Gateway HTTP transport broken.");
|
||||
WLog_Print(rdg->log, WLOG_INFO, "RD Gateway HTTP transport broken.");
|
||||
*rpcFallback = TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
@ -1388,7 +1420,7 @@ static BOOL rdg_establish_data_connection(rdpRdg* rdg, rdpTls* tls, const char*
|
||||
|
||||
if (!response)
|
||||
{
|
||||
WLog_INFO(TAG, "RD Gateway HTTP transport broken.");
|
||||
WLog_Print(rdg->log, WLOG_INFO, "RD Gateway HTTP transport broken.");
|
||||
*rpcFallback = TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
@ -1399,8 +1431,8 @@ static BOOL rdg_establish_data_connection(rdpRdg* rdg, rdpTls* tls, const char*
|
||||
const TRANSFER_ENCODING encoding = http_response_get_transfer_encoding(response);
|
||||
const BOOL isWebsocket = http_response_is_websocket(rdg->http, response);
|
||||
http_response_free(response);
|
||||
WLog_DBG(TAG, "%s authorization result: %s", method,
|
||||
freerdp_http_status_string_format(statusCode, buffer, ARRAYSIZE(buffer)));
|
||||
WLog_Print(rdg->log, WLOG_DEBUG, "%s authorization result: %s", method,
|
||||
freerdp_http_status_string_format(statusCode, buffer, ARRAYSIZE(buffer)));
|
||||
|
||||
switch (statusCode)
|
||||
{
|
||||
@ -1442,7 +1474,7 @@ static BOOL rdg_establish_data_connection(rdpRdg* rdg, rdpTls* tls, const char*
|
||||
}
|
||||
return TRUE;
|
||||
default:
|
||||
http_response_log_error_status(WLog_Get(TAG), WLOG_WARN, response);
|
||||
http_response_log_error_status(rdg->log, WLOG_WARN, response);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -1522,7 +1554,7 @@ BOOL rdg_connect(rdpRdg* rdg, DWORD timeout, BOOL* rpcFallback)
|
||||
{
|
||||
if (rdg->transferEncoding.isWebsocketTransport)
|
||||
{
|
||||
WLog_DBG(TAG, "Upgraded to websocket. RDG_IN_DATA not required");
|
||||
WLog_Print(rdg->log, WLOG_DEBUG, "Upgraded to websocket. RDG_IN_DATA not required");
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1717,7 +1749,7 @@ static BOOL rdg_process_close_packet(rdpRdg* rdg, wStream* s)
|
||||
UINT32 packetSize = 12;
|
||||
|
||||
/* Read error code */
|
||||
if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
|
||||
if (!Stream_CheckAndLogRequiredLengthWLog(rdg->log, s, 4))
|
||||
return FALSE;
|
||||
Stream_Read_UINT32(s, errorCode);
|
||||
|
||||
@ -1769,9 +1801,9 @@ static BOOL rdg_process_service_message(rdpRdg* rdg, wStream* s)
|
||||
WINPR_ASSERT(context->instance);
|
||||
|
||||
/* Read message string */
|
||||
if (!rdg_read_http_unicode_string(s, &msg, &msgLenBytes))
|
||||
if (!rdg_read_http_unicode_string(rdg->log, s, &msg, &msgLenBytes))
|
||||
{
|
||||
WLog_ERR(TAG, "Failed to read string");
|
||||
WLog_Print(rdg->log, WLOG_ERROR, "Failed to read string");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -1783,7 +1815,7 @@ static BOOL rdg_process_unknown_packet(rdpRdg* rdg, int type)
|
||||
{
|
||||
WINPR_UNUSED(rdg);
|
||||
WINPR_UNUSED(type);
|
||||
WLog_WARN(TAG, "Unknown Control Packet received: %X", type);
|
||||
WLog_Print(rdg->log, WLOG_WARN, "Unknown Control Packet received: %X", type);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -1852,7 +1884,8 @@ static BOOL rdg_process_control_packet(rdpRdg* rdg, int type, size_t packetLengt
|
||||
case PKT_TYPE_SERVICE_MESSAGE:
|
||||
if (!s)
|
||||
{
|
||||
WLog_ERR(TAG, "PKT_TYPE_SERVICE_MESSAGE requires payload but none was sent");
|
||||
WLog_Print(rdg->log, WLOG_ERROR,
|
||||
"PKT_TYPE_SERVICE_MESSAGE requires payload but none was sent");
|
||||
return FALSE;
|
||||
}
|
||||
status = rdg_process_service_message(rdg, s);
|
||||
@ -2153,6 +2186,7 @@ rdpRdg* rdg_new(rdpContext* context)
|
||||
|
||||
if (rdg)
|
||||
{
|
||||
rdg->log = WLog_Get(TAG);
|
||||
rdg->state = RDG_CLIENT_STATE_INITIAL;
|
||||
rdg->context = context;
|
||||
rdg->settings = rdg->context->settings;
|
||||
@ -2212,8 +2246,8 @@ rdpRdg* rdg_new(rdpContext* context)
|
||||
break;
|
||||
|
||||
default:
|
||||
WLog_DBG(TAG, "RDG extended authentication method %d not supported",
|
||||
rdg->extAuth);
|
||||
WLog_Print(rdg->log, WLOG_DEBUG,
|
||||
"RDG extended authentication method %d not supported", rdg->extAuth);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include "rpc_bind.h"
|
||||
#include "rpc_client.h"
|
||||
#include "tsg.h"
|
||||
#include "../utils.h"
|
||||
#include "../../crypto/opensslcompat.h"
|
||||
|
||||
#define TAG FREERDP_TAG("core.gateway.tsg")
|
||||
@ -1590,7 +1591,7 @@ fail:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static BOOL TsProxyCreateTunnelReadResponse(rdpTsg* tsg, RPC_PDU* pdu,
|
||||
static BOOL TsProxyCreateTunnelReadResponse(rdpTsg* tsg, const RPC_PDU* pdu,
|
||||
CONTEXT_HANDLE* tunnelContext, UINT32* tunnelId)
|
||||
{
|
||||
BOOL rc = FALSE;
|
||||
@ -1728,7 +1729,41 @@ fail:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static BOOL TsProxyAuthorizeTunnelReadResponse(wLog* log, RPC_PDU* pdu)
|
||||
static UINT32 tsg_redir_to_flags(const TSG_REDIRECTION_FLAGS* redirect)
|
||||
{
|
||||
UINT32 flags = 0;
|
||||
if (redirect->enableAllRedirections)
|
||||
flags |= HTTP_TUNNEL_REDIR_ENABLE_ALL;
|
||||
if (redirect->disableAllRedirections)
|
||||
flags |= HTTP_TUNNEL_REDIR_DISABLE_ALL;
|
||||
|
||||
if (redirect->driveRedirectionDisabled)
|
||||
flags |= HTTP_TUNNEL_REDIR_DISABLE_DRIVE;
|
||||
if (redirect->printerRedirectionDisabled)
|
||||
flags |= HTTP_TUNNEL_REDIR_DISABLE_PRINTER;
|
||||
if (redirect->portRedirectionDisabled)
|
||||
flags |= HTTP_TUNNEL_REDIR_DISABLE_PORT;
|
||||
if (redirect->clipboardRedirectionDisabled)
|
||||
flags |= HTTP_TUNNEL_REDIR_DISABLE_CLIPBOARD;
|
||||
if (redirect->pnpRedirectionDisabled)
|
||||
flags |= HTTP_TUNNEL_REDIR_DISABLE_PNP;
|
||||
return flags;
|
||||
}
|
||||
|
||||
static BOOL tsg_redirect_apply(rdpTsg* tsg, const TSG_REDIRECTION_FLAGS* redirect)
|
||||
{
|
||||
WINPR_ASSERT(tsg);
|
||||
WINPR_ASSERT(redirect);
|
||||
|
||||
rdpTransport* transport = tsg->transport;
|
||||
WINPR_ASSERT(transport);
|
||||
|
||||
rdpContext* context = transport_get_context(transport);
|
||||
UINT32 redirFlags = tsg_redir_to_flags(redirect);
|
||||
return utils_apply_gateway_policy(tsg->log, context, redirFlags, "TSG");
|
||||
}
|
||||
|
||||
static BOOL TsProxyAuthorizeTunnelReadResponse(rdpTsg* tsg, const RPC_PDU* pdu)
|
||||
{
|
||||
BOOL rc = FALSE;
|
||||
UINT32 SwitchValue = 0;
|
||||
@ -1736,8 +1771,12 @@ static BOOL TsProxyAuthorizeTunnelReadResponse(wLog* log, RPC_PDU* pdu)
|
||||
TSG_PACKET packet = { 0 };
|
||||
UINT32 PacketPtr = 0;
|
||||
UINT32 PacketResponsePtr = 0;
|
||||
if (!pdu)
|
||||
return FALSE;
|
||||
|
||||
WINPR_ASSERT(tsg);
|
||||
WINPR_ASSERT(pdu);
|
||||
|
||||
wLog* log = tsg->log;
|
||||
WINPR_ASSERT(log);
|
||||
|
||||
if (!tsg_ndr_pointer_read(log, pdu->s, &index, &PacketPtr, TRUE))
|
||||
goto fail;
|
||||
@ -1773,6 +1812,9 @@ static BOOL TsProxyAuthorizeTunnelReadResponse(wLog* log, RPC_PDU* pdu)
|
||||
goto fail;
|
||||
|
||||
rc = TRUE;
|
||||
|
||||
if (packet.tsgPacket.packetResponse.flags & TSG_PACKET_TYPE_QUARREQUEST)
|
||||
rc = tsg_redirect_apply(tsg, &packet.tsgPacket.packetResponse.redirectionFlags);
|
||||
fail:
|
||||
return rc;
|
||||
}
|
||||
@ -1846,7 +1888,7 @@ static BOOL TsProxyReadPacketSTringMessage(rdpTsg* tsg, wStream* s, TSG_PACKET_S
|
||||
return tsg_ndr_read_string(tsg->log, s, &msg->msgBuffer, msg->msgBytes);
|
||||
}
|
||||
|
||||
static BOOL TsProxyMakeTunnelCallReadResponse(rdpTsg* tsg, RPC_PDU* pdu)
|
||||
static BOOL TsProxyMakeTunnelCallReadResponse(rdpTsg* tsg, const RPC_PDU* pdu)
|
||||
{
|
||||
BOOL rc = FALSE;
|
||||
UINT32 index = 0;
|
||||
@ -2036,7 +2078,7 @@ fail:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static BOOL TsProxyCreateChannelReadResponse(wLog* log, RPC_PDU* pdu,
|
||||
static BOOL TsProxyCreateChannelReadResponse(wLog* log, const RPC_PDU* pdu,
|
||||
CONTEXT_HANDLE* channelContext, UINT32* channelId)
|
||||
{
|
||||
BOOL rc = FALSE;
|
||||
@ -2090,7 +2132,7 @@ fail:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static BOOL TsProxyCloseChannelReadResponse(wLog* log, RPC_PDU* pdu, CONTEXT_HANDLE* context)
|
||||
static BOOL TsProxyCloseChannelReadResponse(wLog* log, const RPC_PDU* pdu, CONTEXT_HANDLE* context)
|
||||
{
|
||||
BOOL rc = FALSE;
|
||||
WLog_Print(log, WLOG_DEBUG, "TsProxyCloseChannelReadResponse");
|
||||
@ -2146,7 +2188,7 @@ fail:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static BOOL TsProxyCloseTunnelReadResponse(wLog* log, RPC_PDU* pdu, CONTEXT_HANDLE* context)
|
||||
static BOOL TsProxyCloseTunnelReadResponse(wLog* log, const RPC_PDU* pdu, CONTEXT_HANDLE* context)
|
||||
{
|
||||
BOOL rc = FALSE;
|
||||
WLog_Print(log, WLOG_DEBUG, "TsProxyCloseTunnelReadResponse");
|
||||
@ -2294,7 +2336,7 @@ static BOOL tsg_proxy_reauth(rdpTsg* tsg)
|
||||
return tsg_transition_to_state(tsg, TSG_STATE_INITIAL);
|
||||
}
|
||||
|
||||
BOOL tsg_recv_pdu(rdpTsg* tsg, RPC_PDU* pdu)
|
||||
BOOL tsg_recv_pdu(rdpTsg* tsg, const RPC_PDU* pdu)
|
||||
{
|
||||
BOOL rc = FALSE;
|
||||
RpcClientCall* call = NULL;
|
||||
@ -2345,7 +2387,7 @@ BOOL tsg_recv_pdu(rdpTsg* tsg, RPC_PDU* pdu)
|
||||
CONTEXT_HANDLE* TunnelContext = NULL;
|
||||
TunnelContext = (tsg->reauthSequence) ? &tsg->NewTunnelContext : &tsg->TunnelContext;
|
||||
|
||||
if (!TsProxyAuthorizeTunnelReadResponse(tsg->log, pdu))
|
||||
if (!TsProxyAuthorizeTunnelReadResponse(tsg, pdu))
|
||||
{
|
||||
WLog_Print(tsg->log, WLOG_ERROR, "TsProxyAuthorizeTunnelReadResponse failure");
|
||||
return FALSE;
|
||||
|
@ -109,7 +109,7 @@ FREERDP_LOCAL BOOL tsg_proxy_begin(rdpTsg* tsg);
|
||||
FREERDP_LOCAL BOOL tsg_connect(rdpTsg* tsg, const char* hostname, UINT16 port, DWORD timeout);
|
||||
FREERDP_LOCAL BOOL tsg_disconnect(rdpTsg* tsg);
|
||||
|
||||
FREERDP_LOCAL BOOL tsg_recv_pdu(rdpTsg* tsg, RPC_PDU* pdu);
|
||||
FREERDP_LOCAL BOOL tsg_recv_pdu(rdpTsg* tsg, const RPC_PDU* pdu);
|
||||
|
||||
FREERDP_LOCAL BOOL tsg_check_event_handles(rdpTsg* tsg);
|
||||
FREERDP_LOCAL DWORD tsg_get_event_handles(rdpTsg* tsg, HANDLE* events, DWORD count);
|
||||
|
@ -68,6 +68,7 @@ static const size_t bool_list_indices[] = {
|
||||
FreeRDP_GatewayHttpExtAuthSspiNtlm,
|
||||
FreeRDP_GatewayHttpTransport,
|
||||
FreeRDP_GatewayHttpUseWebsockets,
|
||||
FreeRDP_GatewayIgnoreRedirectionPolicy,
|
||||
FreeRDP_GatewayRpcTransport,
|
||||
FreeRDP_GatewayUdpTransport,
|
||||
FreeRDP_GatewayUseSameCredentials,
|
||||
|
@ -25,6 +25,8 @@
|
||||
#include <winpr/assert.h>
|
||||
|
||||
#include <freerdp/freerdp.h>
|
||||
#include <freerdp/channels/cliprdr.h>
|
||||
#include <freerdp/channels/rdpdr.h>
|
||||
|
||||
#include <freerdp/log.h>
|
||||
#define TAG FREERDP_TAG("core.gateway.utils")
|
||||
@ -299,3 +301,176 @@ const char* utils_is_vsock(const char* hostname)
|
||||
return &hostname[sizeof(vsock)];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static BOOL remove_rdpdr_type(rdpSettings* settings, UINT32 type)
|
||||
{
|
||||
RDPDR_DEVICE* printer = NULL;
|
||||
do
|
||||
{
|
||||
printer = freerdp_device_collection_find_type(settings, type);
|
||||
freerdp_device_collection_del(settings, printer);
|
||||
freerdp_device_free(printer);
|
||||
} while (printer);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL disable_clipboard(rdpSettings* settings)
|
||||
{
|
||||
if (!freerdp_settings_set_bool(settings, FreeRDP_RedirectClipboard, FALSE))
|
||||
return FALSE;
|
||||
freerdp_static_channel_collection_del(settings, CLIPRDR_SVC_CHANNEL_NAME);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL disable_drive(rdpSettings* settings)
|
||||
{
|
||||
if (!freerdp_settings_set_bool(settings, FreeRDP_RedirectDrives, FALSE))
|
||||
return FALSE;
|
||||
if (!freerdp_settings_set_bool(settings, FreeRDP_RedirectHomeDrive, FALSE))
|
||||
return FALSE;
|
||||
|
||||
return remove_rdpdr_type(settings, RDPDR_DTYP_FILESYSTEM);
|
||||
}
|
||||
|
||||
static BOOL disable_printers(rdpSettings* settings)
|
||||
{
|
||||
if (!freerdp_settings_set_bool(settings, FreeRDP_RedirectPrinters, FALSE))
|
||||
return FALSE;
|
||||
|
||||
return remove_rdpdr_type(settings, RDPDR_DTYP_PRINT);
|
||||
}
|
||||
|
||||
static BOOL disable_port(rdpSettings* settings)
|
||||
{
|
||||
if (!freerdp_settings_set_bool(settings, FreeRDP_RedirectParallelPorts, FALSE))
|
||||
return FALSE;
|
||||
if (!freerdp_settings_set_bool(settings, FreeRDP_RedirectSerialPorts, FALSE))
|
||||
return FALSE;
|
||||
if (!remove_rdpdr_type(settings, RDPDR_DTYP_SERIAL))
|
||||
return FALSE;
|
||||
return remove_rdpdr_type(settings, RDPDR_DTYP_PARALLEL);
|
||||
}
|
||||
|
||||
static BOOL disable_pnp(rdpSettings* settings)
|
||||
{
|
||||
// TODO(akallabeth): [MS-RDPEPNP] related stuff is disabled.
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL apply_gw_policy(rdpContext* context)
|
||||
{
|
||||
WINPR_ASSERT(context);
|
||||
|
||||
freerdp_channels_disconnect(context->channels, context->instance);
|
||||
freerdp_channels_close(context->channels, context->instance);
|
||||
freerdp_channels_free(context->channels);
|
||||
context->channels = freerdp_channels_new(context->instance);
|
||||
WINPR_ASSERT(context->channels);
|
||||
|
||||
BOOL rc = TRUE;
|
||||
IFCALLRET(context->instance->LoadChannels, rc, context->instance);
|
||||
if (rc)
|
||||
return freerdp_channels_pre_connect(context->channels, context->instance) == CHANNEL_RC_OK;
|
||||
return rc;
|
||||
}
|
||||
|
||||
BOOL utils_apply_gateway_policy(wLog* log, rdpContext* context, UINT32 flags, const char* module)
|
||||
{
|
||||
WINPR_ASSERT(log);
|
||||
WINPR_ASSERT(context);
|
||||
|
||||
rdpSettings* settings = context->settings;
|
||||
WINPR_ASSERT(settings);
|
||||
|
||||
if (flags & HTTP_TUNNEL_REDIR_ENABLE_ALL)
|
||||
{
|
||||
WLog_Print(log, WLOG_DEBUG, "[%s] policy allows all redirections", module);
|
||||
}
|
||||
else if (freerdp_settings_get_bool(settings, FreeRDP_GatewayIgnoreRedirectionPolicy))
|
||||
{
|
||||
char buffer[128] = { 0 };
|
||||
WLog_Print(log, WLOG_INFO, "[%s] policy ignored on user request %s", module,
|
||||
utils_redir_flags_to_string(flags, buffer, sizeof(buffer)));
|
||||
}
|
||||
else if (flags & HTTP_TUNNEL_REDIR_DISABLE_ALL)
|
||||
{
|
||||
WLog_Print(log, WLOG_INFO, "[%s] policy denies all redirections", module);
|
||||
if (!disable_drive(settings))
|
||||
return FALSE;
|
||||
if (!disable_printers(settings))
|
||||
return FALSE;
|
||||
if (!disable_clipboard(settings))
|
||||
return FALSE;
|
||||
if (!disable_port(settings))
|
||||
return FALSE;
|
||||
if (!disable_pnp(settings))
|
||||
return FALSE;
|
||||
if (!apply_gw_policy(context))
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (flags & HTTP_TUNNEL_REDIR_DISABLE_DRIVE)
|
||||
{
|
||||
WLog_Print(log, WLOG_INFO, "[%s] policy denies drive redirections", module);
|
||||
if (!disable_drive(settings))
|
||||
return FALSE;
|
||||
}
|
||||
if (flags & HTTP_TUNNEL_REDIR_DISABLE_PRINTER)
|
||||
{
|
||||
WLog_Print(log, WLOG_INFO, "[%s] policy denies printer redirections", module);
|
||||
if (!disable_printers(settings))
|
||||
return FALSE;
|
||||
}
|
||||
if (flags & HTTP_TUNNEL_REDIR_DISABLE_PORT)
|
||||
{
|
||||
WLog_Print(log, WLOG_INFO, "[%s] policy denies port redirections", module);
|
||||
if (!disable_port(settings))
|
||||
return FALSE;
|
||||
}
|
||||
if (flags & HTTP_TUNNEL_REDIR_DISABLE_CLIPBOARD)
|
||||
{
|
||||
WLog_Print(log, WLOG_INFO, "[%s] policy denies clipboard redirections", module);
|
||||
if (!disable_clipboard(settings))
|
||||
return FALSE;
|
||||
}
|
||||
if (flags & HTTP_TUNNEL_REDIR_DISABLE_PNP)
|
||||
{
|
||||
WLog_Print(log, WLOG_INFO, "[%s] policy denies PNP redirections", module);
|
||||
if (!disable_pnp(settings))
|
||||
return FALSE;
|
||||
}
|
||||
if (flags != 0)
|
||||
{
|
||||
if (!apply_gw_policy(context))
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
char* utils_redir_flags_to_string(UINT32 flags, char* buffer, size_t size)
|
||||
{
|
||||
winpr_str_append("{", buffer, size, "");
|
||||
if (flags & HTTP_TUNNEL_REDIR_ENABLE_ALL)
|
||||
winpr_str_append("ENABLE_ALL", buffer, size, "|");
|
||||
if (flags & HTTP_TUNNEL_REDIR_DISABLE_ALL)
|
||||
winpr_str_append("DISABLE_ALL", buffer, size, "|");
|
||||
if (flags & HTTP_TUNNEL_REDIR_DISABLE_DRIVE)
|
||||
winpr_str_append("DISABLE_DRIVE", buffer, size, "|");
|
||||
if (flags & HTTP_TUNNEL_REDIR_DISABLE_PRINTER)
|
||||
winpr_str_append("DISABLE_PRINTER", buffer, size, "|");
|
||||
if (flags & HTTP_TUNNEL_REDIR_DISABLE_PORT)
|
||||
winpr_str_append("DISABLE_PORT", buffer, size, "|");
|
||||
if (flags & HTTP_TUNNEL_REDIR_DISABLE_CLIPBOARD)
|
||||
winpr_str_append("DISABLE_CLIPBOARD", buffer, size, "|");
|
||||
if (flags & HTTP_TUNNEL_REDIR_DISABLE_PNP)
|
||||
winpr_str_append("DISABLE_PNP", buffer, size, "|");
|
||||
|
||||
char fbuffer[16] = { 0 };
|
||||
_snprintf(fbuffer, sizeof(fbuffer), "[0x%08" PRIx32 "]", flags);
|
||||
|
||||
winpr_str_append(fbuffer, buffer, size, " ");
|
||||
winpr_str_append("{", buffer, size, "}");
|
||||
return buffer;
|
||||
}
|
||||
|
@ -24,6 +24,15 @@
|
||||
#include <winpr/winpr.h>
|
||||
#include <freerdp/freerdp.h>
|
||||
|
||||
/* HTTP tunnel redir flags. */
|
||||
#define HTTP_TUNNEL_REDIR_ENABLE_ALL 0x80000000
|
||||
#define HTTP_TUNNEL_REDIR_DISABLE_ALL 0x40000000
|
||||
#define HTTP_TUNNEL_REDIR_DISABLE_DRIVE 0x1
|
||||
#define HTTP_TUNNEL_REDIR_DISABLE_PRINTER 0x2
|
||||
#define HTTP_TUNNEL_REDIR_DISABLE_PORT 0x4
|
||||
#define HTTP_TUNNEL_REDIR_DISABLE_CLIPBOARD 0x8
|
||||
#define HTTP_TUNNEL_REDIR_DISABLE_PNP 0x10
|
||||
|
||||
typedef enum
|
||||
{
|
||||
AUTH_SUCCESS,
|
||||
@ -47,4 +56,7 @@ BOOL utils_str_copy(const char* value, char** dst);
|
||||
|
||||
const char* utils_is_vsock(const char* hostname);
|
||||
|
||||
BOOL utils_apply_gateway_policy(wLog* log, rdpContext* context, UINT32 flags, const char* module);
|
||||
char* utils_redir_flags_to_string(UINT32 flags, char* buffer, size_t size);
|
||||
|
||||
#endif /* FREERDP_LIB_CORE_UTILS_H */
|
||||
|
Loading…
Reference in New Issue
Block a user