Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/FreeRDP/FreeRDP.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'libfreerdp/core/gateway/tsg.c')
-rw-r--r--libfreerdp/core/gateway/tsg.c543
1 files changed, 442 insertions, 101 deletions
diff --git a/libfreerdp/core/gateway/tsg.c b/libfreerdp/core/gateway/tsg.c
index 9d01c9fdd..c03f266f2 100644
--- a/libfreerdp/core/gateway/tsg.c
+++ b/libfreerdp/core/gateway/tsg.c
@@ -24,6 +24,7 @@
#include "config.h"
#endif
+#include <assert.h>
#include <winpr/crt.h>
#include <winpr/ndr.h>
#include <winpr/error.h>
@@ -39,13 +40,14 @@
#define TAG FREERDP_TAG("core.gateway.tsg")
+#define TSG_CAPABILITY_TYPE_NAP 0x00000001
+
#define TSG_PACKET_TYPE_HEADER 0x00004844
#define TSG_PACKET_TYPE_VERSIONCAPS 0x00005643
#define TSG_PACKET_TYPE_QUARCONFIGREQUEST 0x00005143
#define TSG_PACKET_TYPE_QUARREQUEST 0x00005152
#define TSG_PACKET_TYPE_RESPONSE 0x00005052
#define TSG_PACKET_TYPE_QUARENC_RESPONSE 0x00004552
-#define TSG_CAPABILITY_TYPE_NAP 0x00000001
#define TSG_PACKET_TYPE_CAPS_RESPONSE 0x00004350
#define TSG_PACKET_TYPE_MSGREQUEST_PACKET 0x00004752
#define TSG_PACKET_TYPE_MESSAGE_PACKET 0x00004750
@@ -222,7 +224,6 @@ struct rdp_tsg
UINT32 TunnelId;
UINT32 ChannelId;
BOOL reauthSequence;
- rdpSettings* settings;
rdpTransport* transport;
UINT64 ReauthTunnelContext;
CONTEXT_HANDLE TunnelContext;
@@ -311,16 +312,35 @@ static BOOL tsg_print(char** buffer, size_t* len, const char* fmt, ...)
static BOOL tsg_packet_header_to_string(char** buffer, size_t* length,
const TSG_PACKET_HEADER* header)
{
+ assert(buffer);
+ assert(length);
+ assert(header);
+
return tsg_print(buffer, length,
"header { ComponentId=0x%04" PRIx16 ", PacketId=0x%04" PRIx16 " }",
header->ComponentId, header->PacketId);
}
+static BOOL tsg_type_capability_nap_to_string(char** buffer, size_t* length,
+ const TSG_CAPABILITY_NAP* cur)
+{
+ assert(buffer);
+ assert(length);
+ assert(cur);
+
+ return tsg_print(buffer, length, "%s { capabilities=0x%08" PRIx32 " }",
+ tsg_packet_id_to_string(TSG_CAPABILITY_TYPE_NAP), cur->capabilities);
+}
+
static BOOL tsg_packet_capabilities_to_string(char** buffer, size_t* length,
const TSG_PACKET_CAPABILITIES* caps, UINT32 numCaps)
{
UINT32 x;
+ assert(buffer);
+ assert(length);
+ assert(caps);
+
if (!tsg_print(buffer, length, "capabilities { "))
return FALSE;
@@ -330,9 +350,7 @@ static BOOL tsg_packet_capabilities_to_string(char** buffer, size_t* length,
switch (cur->capabilityType)
{
case TSG_CAPABILITY_TYPE_NAP:
- if (!tsg_print(buffer, length, "%s { capabilities=0x%08" PRIx32 " }",
- tsg_packet_id_to_string(cur->capabilityType),
- cur->tsgPacket.tsgCapNap.capabilities))
+ if (!tsg_type_capability_nap_to_string(buffer, length, &cur->tsgPacket.tsgCapNap))
return FALSE;
break;
default:
@@ -347,6 +365,10 @@ static BOOL tsg_packet_capabilities_to_string(char** buffer, size_t* length,
static BOOL tsg_packet_versioncaps_to_string(char** buffer, size_t* length,
const TSG_PACKET_VERSIONCAPS* caps)
{
+ assert(buffer);
+ assert(length);
+ assert(caps);
+
if (!tsg_print(buffer, length, "versioncaps { "))
return FALSE;
if (!tsg_packet_header_to_string(buffer, length, &caps->tsgHeader))
@@ -368,6 +390,281 @@ static BOOL tsg_packet_versioncaps_to_string(char** buffer, size_t* length,
return tsg_print(buffer, length, " }");
}
+static BOOL tsg_packet_quarconfigrequest_to_string(char** buffer, size_t* length,
+ const TSG_PACKET_QUARCONFIGREQUEST* caps)
+{
+ assert(buffer);
+ assert(length);
+ assert(caps);
+
+ if (!tsg_print(buffer, length, "quarconfigrequest { "))
+ return FALSE;
+
+ if (!tsg_print(buffer, length, " "))
+ return FALSE;
+
+ if (!tsg_print(buffer, length, " flags=0x%08" PRIx32, caps->flags))
+ return FALSE;
+
+ return tsg_print(buffer, length, " }");
+}
+
+static BOOL tsg_packet_quarrequest_to_string(char** buffer, size_t* length,
+ const TSG_PACKET_QUARREQUEST* caps)
+{
+ BOOL rc = FALSE;
+ char* name = NULL;
+ char* strdata = NULL;
+
+ assert(buffer);
+ assert(length);
+ assert(caps);
+
+ if (!tsg_print(buffer, length, "quarrequest { "))
+ return FALSE;
+
+ if (!tsg_print(buffer, length, " "))
+ return FALSE;
+
+ if (caps->nameLength > 0)
+ {
+ if (caps->nameLength > INT_MAX)
+ return FALSE;
+ if (ConvertFromUnicode(CP_UTF8, 0, caps->machineName, (int)caps->nameLength, &name, 0, NULL,
+ NULL) < 0)
+ return FALSE;
+ }
+
+ strdata = winpr_BinToHexString(caps->data, caps->dataLen, TRUE);
+ if (strdata || (caps->dataLen == 0))
+ rc = tsg_print(buffer, length,
+ " flags=0x%08" PRIx32 ", machineName=%s [%" PRIu32 "], data[%" PRIu32 "]=%s",
+ caps->flags, name, caps->nameLength, caps->dataLen, strdata);
+ free(name);
+ free(strdata);
+ if (!rc)
+ return FALSE;
+
+ return tsg_print(buffer, length, " }");
+}
+
+static const char* tsg_bool_to_string(BOOL val)
+{
+ if (val)
+ return "true";
+ return "false";
+}
+
+static const char* tsg_redirection_flags_to_string(char* buffer, size_t size,
+ const TSG_REDIRECTION_FLAGS* flags)
+{
+ assert(buffer || (size == 0));
+ assert(flags);
+
+ _snprintf(buffer, size,
+ "enableAllRedirections=%s, disableAllRedirections=%s, driveRedirectionDisabled=%s, "
+ "printerRedirectionDisabled=%s, portRedirectionDisabled=%s, reserved=%s, "
+ "clipboardRedirectionDisabled=%s, pnpRedirectionDisabled=%s",
+ tsg_bool_to_string(flags->enableAllRedirections),
+ tsg_bool_to_string(flags->disableAllRedirections),
+ tsg_bool_to_string(flags->driveRedirectionDisabled),
+ tsg_bool_to_string(flags->printerRedirectionDisabled),
+ tsg_bool_to_string(flags->portRedirectionDisabled),
+ tsg_bool_to_string(flags->reserved),
+ tsg_bool_to_string(flags->clipboardRedirectionDisabled),
+ tsg_bool_to_string(flags->pnpRedirectionDisabled));
+ return buffer;
+}
+
+static BOOL tsg_packet_response_to_string(char** buffer, size_t* length,
+ const TSG_PACKET_RESPONSE* caps)
+{
+ BOOL rc = FALSE;
+ char* strdata = NULL;
+ char tbuffer[8192] = { 0 };
+
+ assert(buffer);
+ assert(length);
+ assert(caps);
+
+ if (!tsg_print(buffer, length, "response { "))
+ return FALSE;
+
+ if (!tsg_print(buffer, length, " "))
+ return FALSE;
+
+ strdata = winpr_BinToHexString(caps->responseData, caps->responseDataLen, TRUE);
+ if (strdata || (caps->responseDataLen == 0))
+ rc = tsg_print(
+ buffer, length,
+ " flags=0x%08" PRIx32 ", reserved=0x%08" PRIx32 ", responseData[%" PRIu32
+ "]=%s, redirectionFlags={ %s }",
+ caps->flags, caps->reserved, caps->responseDataLen, strdata,
+ tsg_redirection_flags_to_string(tbuffer, ARRAYSIZE(tbuffer), &caps->redirectionFlags));
+ free(strdata);
+ if (!rc)
+ return FALSE;
+
+ return tsg_print(buffer, length, " }");
+}
+
+static BOOL tsg_packet_quarenc_response_to_string(char** buffer, size_t* length,
+ const TSG_PACKET_QUARENC_RESPONSE* caps)
+{
+ BOOL rc = FALSE;
+ char* strdata = NULL;
+ RPC_CSTR uuid;
+ char tbuffer[8192] = { 0 };
+ size_t size = ARRAYSIZE(tbuffer);
+ char* ptbuffer = tbuffer;
+
+ assert(buffer);
+ assert(length);
+ assert(caps);
+
+ if (!tsg_print(buffer, length, "quarenc_response { "))
+ return FALSE;
+
+ if (!tsg_print(buffer, length, " "))
+ return FALSE;
+
+ if (caps->certChainLen > 0)
+ {
+ if (caps->certChainLen > INT_MAX)
+ return FALSE;
+ if (ConvertFromUnicode(CP_UTF8, 0, caps->certChainData, (int)caps->certChainLen, &strdata,
+ 0, NULL, NULL) <= 0)
+ return FALSE;
+ }
+
+ tsg_packet_versioncaps_to_string(&ptbuffer, &size, caps->versionCaps);
+ UuidToStringA(&caps->nonce, &uuid);
+ if (strdata || (caps->certChainLen == 0))
+ rc =
+ tsg_print(buffer, length,
+ " flags=0x%08" PRIx32 ", certChain[%" PRIu32 "]=%s, nonce=%s, versionCaps=%s",
+ caps->flags, caps->certChainLen, strdata, uuid, tbuffer);
+ free(strdata);
+ free(uuid);
+ if (!rc)
+ return FALSE;
+
+ return tsg_print(buffer, length, " }");
+}
+
+static BOOL tsg_packet_message_response_to_string(char** buffer, size_t* length,
+ const TSG_PACKET_MSG_RESPONSE* caps)
+{
+ assert(buffer);
+ assert(length);
+ assert(caps);
+
+ if (!tsg_print(buffer, length, "msg_response { "))
+ return FALSE;
+
+ if (!tsg_print(buffer, length,
+ " msgID=0x%08" PRIx32 ", msgType=0x%08" PRIx32 ", isMsgPresent=%" PRId32,
+ caps->msgID, caps->msgType, caps->isMsgPresent))
+ return FALSE;
+
+ return tsg_print(buffer, length, " }");
+}
+
+static BOOL tsg_packet_caps_response_to_string(char** buffer, size_t* length,
+ const TSG_PACKET_CAPS_RESPONSE* caps)
+{
+ assert(buffer);
+ assert(length);
+ assert(caps);
+
+ if (!tsg_print(buffer, length, "caps_response { "))
+ return FALSE;
+
+ if (!tsg_packet_quarenc_response_to_string(buffer, length, &caps->pktQuarEncResponse))
+ return FALSE;
+
+ if (!tsg_packet_message_response_to_string(buffer, length, &caps->pktConsentMessage))
+ return FALSE;
+
+ return tsg_print(buffer, length, " }");
+}
+
+static BOOL tsg_packet_message_request_to_string(char** buffer, size_t* length,
+ const TSG_PACKET_MSG_REQUEST* caps)
+{
+ assert(buffer);
+ assert(length);
+ assert(caps);
+
+ if (!tsg_print(buffer, length, "caps_message_request { "))
+ return FALSE;
+
+ if (!tsg_print(buffer, length, " maxMessagesPerBatch=%" PRIu32, caps->maxMessagesPerBatch))
+ return FALSE;
+
+ return tsg_print(buffer, length, " }");
+}
+
+static BOOL tsg_packet_auth_to_string(char** buffer, size_t* length, const TSG_PACKET_AUTH* caps)
+{
+ BOOL rc = FALSE;
+ char* strdata = NULL;
+ assert(buffer);
+ assert(length);
+ assert(caps);
+
+ if (!tsg_print(buffer, length, "caps_message_request { "))
+ return FALSE;
+
+ if (!tsg_packet_versioncaps_to_string(buffer, length, &caps->tsgVersionCaps))
+ return FALSE;
+
+ strdata = winpr_BinToHexString(caps->cookie, caps->cookieLen, TRUE);
+ if (strdata || (caps->cookieLen == 0))
+ rc = tsg_print(buffer, length, " cookie[%" PRIu32 "]=%s", caps->cookieLen, strdata);
+ free(strdata);
+ if (!rc)
+ return FALSE;
+
+ return tsg_print(buffer, length, " }");
+}
+
+static BOOL tsg_packet_reauth_to_string(char** buffer, size_t* length,
+ const TSG_PACKET_REAUTH* caps)
+{
+ BOOL rc = FALSE;
+ assert(buffer);
+ assert(length);
+ assert(caps);
+
+ if (!tsg_print(buffer, length, "caps_message_request { "))
+ return FALSE;
+
+ if (!tsg_print(buffer, length, " tunnelContext=0x%016" PRIx64 ", packetId=%s [0x%08" PRIx32 "]",
+ caps->tunnelContext, tsg_packet_id_to_string(caps->packetId), caps->packetId))
+ return FALSE;
+
+ switch (caps->packetId)
+ {
+ case TSG_PACKET_TYPE_VERSIONCAPS:
+ rc = tsg_packet_versioncaps_to_string(buffer, length,
+ caps->tsgInitialPacket.packetVersionCaps);
+ break;
+ case TSG_PACKET_TYPE_AUTH:
+ rc = tsg_packet_auth_to_string(buffer, length, caps->tsgInitialPacket.packetAuth);
+ break;
+ default:
+ rc = tsg_print(buffer, length, "TODO: Unhandled packet type %s [0x%08" PRIx32 "]",
+ tsg_packet_id_to_string(caps->packetId), caps->packetId);
+ break;
+ }
+
+ if (!rc)
+ return FALSE;
+
+ return tsg_print(buffer, length, " }");
+}
+
static const char* tsg_packet_to_string(const TSG_PACKET* packet)
{
size_t len = 8192;
@@ -390,43 +687,45 @@ static const char* tsg_packet_to_string(const TSG_PACKET* packet)
goto fail;
break;
case TSG_PACKET_TYPE_QUARCONFIGREQUEST:
- if (!tsg_print(&buffer, &len, "TODO"))
+ if (!tsg_packet_quarconfigrequest_to_string(&buffer, &len,
+ packet->tsgPacket.packetQuarConfigRequest))
goto fail;
break;
case TSG_PACKET_TYPE_QUARREQUEST:
- if (!tsg_print(&buffer, &len, "TODO"))
+ if (!tsg_packet_quarrequest_to_string(&buffer, &len,
+ packet->tsgPacket.packetQuarRequest))
goto fail;
break;
case TSG_PACKET_TYPE_RESPONSE:
- if (!tsg_print(&buffer, &len, "TODO"))
+ if (!tsg_packet_response_to_string(&buffer, &len, packet->tsgPacket.packetResponse))
goto fail;
break;
case TSG_PACKET_TYPE_QUARENC_RESPONSE:
- if (!tsg_print(&buffer, &len, "TODO"))
- goto fail;
- break;
- case TSG_CAPABILITY_TYPE_NAP:
- if (!tsg_print(&buffer, &len, "TODO"))
+ if (!tsg_packet_quarenc_response_to_string(&buffer, &len,
+ packet->tsgPacket.packetQuarEncResponse))
goto fail;
break;
case TSG_PACKET_TYPE_CAPS_RESPONSE:
- if (!tsg_print(&buffer, &len, "TODO"))
+ if (!tsg_packet_caps_response_to_string(&buffer, &len,
+ packet->tsgPacket.packetCapsResponse))
goto fail;
break;
case TSG_PACKET_TYPE_MSGREQUEST_PACKET:
- if (!tsg_print(&buffer, &len, "TODO"))
+ if (!tsg_packet_message_request_to_string(&buffer, &len,
+ packet->tsgPacket.packetMsgRequest))
goto fail;
break;
case TSG_PACKET_TYPE_MESSAGE_PACKET:
- if (!tsg_print(&buffer, &len, "TODO"))
+ if (!tsg_packet_message_response_to_string(&buffer, &len,
+ packet->tsgPacket.packetMsgResponse))
goto fail;
break;
case TSG_PACKET_TYPE_AUTH:
- if (!tsg_print(&buffer, &len, "TODO"))
+ if (!tsg_packet_auth_to_string(&buffer, &len, packet->tsgPacket.packetAuth))
goto fail;
break;
case TSG_PACKET_TYPE_REAUTH:
- if (!tsg_print(&buffer, &len, "TODO"))
+ if (!tsg_packet_reauth_to_string(&buffer, &len, packet->tsgPacket.packetReauth))
goto fail;
break;
default:
@@ -500,7 +799,7 @@ static int TsProxySendToServer(handle_t IDL_handle, const byte pRpcMessage[], UI
{
wStream* s;
rdpTsg* tsg;
- int length;
+ size_t length;
const byte* buffer1 = NULL;
const byte* buffer2 = NULL;
const byte* buffer3 = NULL;
@@ -536,7 +835,9 @@ static int TsProxySendToServer(handle_t IDL_handle, const byte pRpcMessage[], UI
totalDataBytes += lengths[2] + 4;
}
- length = 28 + totalDataBytes;
+ length = 28ull + totalDataBytes;
+ if (length > INT_MAX)
+ return -1;
s = Stream_New(NULL, length);
if (!s)
@@ -572,7 +873,7 @@ static int TsProxySendToServer(handle_t IDL_handle, const byte pRpcMessage[], UI
if (!rpc_client_write_call(tsg->rpc, s, TsProxySendToServerOpnum))
return -1;
- return length;
+ return (int)length;
}
/**
@@ -725,12 +1026,19 @@ static BOOL TsProxyCreateTunnelReadResponse(rdpTsg* tsg, RPC_PDU* pdu,
UINT32 SwitchValue;
UINT32 MessageSwitchValue = 0;
UINT32 IsMessagePresent;
+ rdpContext* context;
PTSG_PACKET_CAPABILITIES tsgCaps = NULL;
PTSG_PACKET_VERSIONCAPS versionCaps = NULL;
TSG_PACKET_STRING_MESSAGE packetStringMessage;
PTSG_PACKET_CAPS_RESPONSE packetCapsResponse = NULL;
PTSG_PACKET_QUARENC_RESPONSE packetQuarEncResponse = NULL;
+ assert(tsg);
+ assert(tsg->rpc);
+
+ context = tsg->rpc->context;
+ assert(context);
+
if (!pdu)
return FALSE;
@@ -877,8 +1185,8 @@ static BOOL TsProxyCreateTunnelReadResponse(rdpTsg* tsg, RPC_PDU* pdu,
if (Stream_GetRemainingLength(pdu->s) < 16)
goto fail;
- Stream_Read_UINT32(pdu->s, packetStringMessage.isDisplayMandatory);
- Stream_Read_UINT32(pdu->s, packetStringMessage.isConsentMandatory);
+ Stream_Read_INT32(pdu->s, packetStringMessage.isDisplayMandatory);
+ Stream_Read_INT32(pdu->s, packetStringMessage.isConsentMandatory);
Stream_Read_UINT32(pdu->s, packetStringMessage.msgBytes);
Stream_Read_UINT32(pdu->s, Pointer);
@@ -907,16 +1215,15 @@ static BOOL TsProxyCreateTunnelReadResponse(rdpTsg* tsg, RPC_PDU* pdu,
goto fail;
}
- if (tsg->rpc && tsg->rpc->context && tsg->rpc->context->instance)
+ if (context->instance)
{
- rc = IFCALLRESULT(TRUE, tsg->rpc->context->instance->PresentGatewayMessage,
- tsg->rpc->context->instance,
- TSG_ASYNC_MESSAGE_CONSENT_MESSAGE
- ? GATEWAY_MESSAGE_CONSENT
- : TSG_ASYNC_MESSAGE_SERVICE_MESSAGE,
- packetStringMessage.isDisplayMandatory != 0,
- packetStringMessage.isConsentMandatory != 0,
- packetStringMessage.msgBytes, packetStringMessage.msgBuffer);
+ rc = IFCALLRESULT(
+ TRUE, context->instance->PresentGatewayMessage, context->instance,
+ TSG_ASYNC_MESSAGE_CONSENT_MESSAGE ? GATEWAY_MESSAGE_CONSENT
+ : TSG_ASYNC_MESSAGE_SERVICE_MESSAGE,
+ packetStringMessage.isDisplayMandatory != 0,
+ packetStringMessage.isConsentMandatory != 0, packetStringMessage.msgBytes,
+ packetStringMessage.msgBuffer);
if (!rc)
goto fail;
}
@@ -1079,16 +1386,19 @@ fail:
static BOOL TsProxyAuthorizeTunnelWriteRequest(rdpTsg* tsg, CONTEXT_HANDLE* tunnelContext)
{
- UINT32 pad;
+ size_t pad;
wStream* s;
size_t count;
- UINT32 offset;
+ size_t offset;
rdpRpc* rpc;
if (!tsg || !tsg->rpc || !tunnelContext || !tsg->MachineName)
return FALSE;
count = _wcslen(tsg->MachineName) + 1;
+ if (count > UINT32_MAX)
+ return FALSE;
+
rpc = tsg->rpc;
WLog_DBG(TAG, "TsProxyAuthorizeTunnelWriteRequest");
s = Stream_New(NULL, 1024 + count * 2);
@@ -1105,13 +1415,13 @@ static BOOL TsProxyAuthorizeTunnelWriteRequest(rdpTsg* tsg, CONTEXT_HANDLE* tunn
Stream_Write_UINT32(s, 0x00020000); /* PacketQuarRequestPtr (4 bytes) */
Stream_Write_UINT32(s, 0x00000000); /* Flags (4 bytes) */
Stream_Write_UINT32(s, 0x00020004); /* MachineNamePtr (4 bytes) */
- Stream_Write_UINT32(s, count); /* NameLength (4 bytes) */
+ Stream_Write_UINT32(s, (UINT32)count); /* NameLength (4 bytes) */
Stream_Write_UINT32(s, 0x00020008); /* DataPtr (4 bytes) */
Stream_Write_UINT32(s, 0); /* DataLength (4 bytes) */
/* MachineName */
- Stream_Write_UINT32(s, count); /* MaxCount (4 bytes) */
+ Stream_Write_UINT32(s, (UINT32)count); /* MaxCount (4 bytes) */
Stream_Write_UINT32(s, 0); /* Offset (4 bytes) */
- Stream_Write_UINT32(s, count); /* ActualCount (4 bytes) */
+ Stream_Write_UINT32(s, (UINT32)count); /* ActualCount (4 bytes) */
Stream_Write_UTF16_String(s, tsg->MachineName, count); /* Array */
/* 4-byte alignment */
offset = Stream_GetPosition(s);
@@ -1122,7 +1432,7 @@ static BOOL TsProxyAuthorizeTunnelWriteRequest(rdpTsg* tsg, CONTEXT_HANDLE* tunn
return rpc_client_write_call(rpc, s, TsProxyAuthorizeTunnelOpnum);
}
-static BOOL TsProxyAuthorizeTunnelReadResponse(rdpTsg* tsg, RPC_PDU* pdu)
+static BOOL TsProxyAuthorizeTunnelReadResponse(RPC_PDU* pdu)
{
BOOL rc = FALSE;
UINT32 Pointer;
@@ -1184,25 +1494,24 @@ static BOOL TsProxyAuthorizeTunnelReadResponse(rdpTsg* tsg, RPC_PDU* pdu)
Stream_Seek_UINT32(pdu->s); /* Reserved (4 bytes) */
Stream_Read_UINT32(pdu->s, Pointer); /* ResponseDataPtr (4 bytes) */
Stream_Read_UINT32(pdu->s, packetResponse->responseDataLen); /* ResponseDataLength (4 bytes) */
- Stream_Read_UINT32(pdu->s, packetResponse->redirectionFlags
- .enableAllRedirections); /* EnableAllRedirections (4 bytes) */
- Stream_Read_UINT32(pdu->s, packetResponse->redirectionFlags
- .disableAllRedirections); /* DisableAllRedirections (4 bytes) */
- Stream_Read_UINT32(pdu->s,
- packetResponse->redirectionFlags
- .driveRedirectionDisabled); /* DriveRedirectionDisabled (4 bytes) */
- Stream_Read_UINT32(pdu->s,
- packetResponse->redirectionFlags
- .printerRedirectionDisabled); /* PrinterRedirectionDisabled (4 bytes) */
- Stream_Read_UINT32(pdu->s,
- packetResponse->redirectionFlags
- .portRedirectionDisabled); /* PortRedirectionDisabled (4 bytes) */
- Stream_Read_UINT32(pdu->s, packetResponse->redirectionFlags.reserved); /* Reserved (4 bytes) */
- Stream_Read_UINT32(
+ Stream_Read_INT32(pdu->s, packetResponse->redirectionFlags
+ .enableAllRedirections); /* EnableAllRedirections (4 bytes) */
+ Stream_Read_INT32(pdu->s, packetResponse->redirectionFlags
+ .disableAllRedirections); /* DisableAllRedirections (4 bytes) */
+ Stream_Read_INT32(pdu->s,
+ packetResponse->redirectionFlags
+ .driveRedirectionDisabled); /* DriveRedirectionDisabled (4 bytes) */
+ Stream_Read_INT32(pdu->s,
+ packetResponse->redirectionFlags
+ .printerRedirectionDisabled); /* PrinterRedirectionDisabled (4 bytes) */
+ Stream_Read_INT32(pdu->s, packetResponse->redirectionFlags
+ .portRedirectionDisabled); /* PortRedirectionDisabled (4 bytes) */
+ Stream_Read_INT32(pdu->s, packetResponse->redirectionFlags.reserved); /* Reserved (4 bytes) */
+ Stream_Read_INT32(
pdu->s, packetResponse->redirectionFlags
.clipboardRedirectionDisabled); /* ClipboardRedirectionDisabled (4 bytes) */
- Stream_Read_UINT32(pdu->s, packetResponse->redirectionFlags
- .pnpRedirectionDisabled); /* PnpRedirectionDisabled (4 bytes) */
+ Stream_Read_INT32(pdu->s, packetResponse->redirectionFlags
+ .pnpRedirectionDisabled); /* PnpRedirectionDisabled (4 bytes) */
Stream_Read_UINT32(pdu->s, SizeValue); /* (4 bytes) */
if (SizeValue != packetResponse->responseDataLen)
@@ -1302,11 +1611,18 @@ static BOOL TsProxyMakeTunnelCallReadResponse(rdpTsg* tsg, RPC_PDU* pdu)
UINT32 Pointer;
UINT32 SwitchValue;
TSG_PACKET packet;
+ rdpContext* context;
char* messageText = NULL;
TSG_PACKET_MSG_RESPONSE packetMsgResponse = { 0 };
TSG_PACKET_STRING_MESSAGE packetStringMessage = { 0 };
TSG_PACKET_REAUTH_MESSAGE packetReauthMessage = { 0 };
+ assert(tsg);
+ assert(tsg->rpc);
+
+ context = tsg->rpc->context;
+ assert(context);
+
/* This is an asynchronous response */
if (!pdu)
@@ -1356,10 +1672,10 @@ static BOOL TsProxyMakeTunnelCallReadResponse(rdpTsg* tsg, RPC_PDU* pdu)
WLog_INFO(TAG, "Consent Message: %s", messageText);
free(messageText);
- if (tsg->rpc && tsg->rpc->context && tsg->rpc->context->instance)
+ if (context->instance)
{
- rc = IFCALLRESULT(TRUE, tsg->rpc->context->instance->PresentGatewayMessage,
- tsg->rpc->context->instance, GATEWAY_MESSAGE_CONSENT,
+ rc = IFCALLRESULT(TRUE, context->instance->PresentGatewayMessage, context->instance,
+ GATEWAY_MESSAGE_CONSENT,
packetStringMessage.isDisplayMandatory != 0,
packetStringMessage.isConsentMandatory != 0,
packetStringMessage.msgBytes, packetStringMessage.msgBuffer);
@@ -1377,10 +1693,10 @@ static BOOL TsProxyMakeTunnelCallReadResponse(rdpTsg* tsg, RPC_PDU* pdu)
WLog_INFO(TAG, "Service Message: %s", messageText);
free(messageText);
- if (tsg->rpc && tsg->rpc->context && tsg->rpc->context->instance)
+ if (context->instance)
{
- rc = IFCALLRESULT(TRUE, tsg->rpc->context->instance->PresentGatewayMessage,
- tsg->rpc->context->instance, GATEWAY_MESSAGE_SERVICE,
+ rc = IFCALLRESULT(TRUE, context->instance->PresentGatewayMessage, context->instance,
+ GATEWAY_MESSAGE_SERVICE,
packetStringMessage.isDisplayMandatory != 0,
packetStringMessage.isConsentMandatory != 0,
packetStringMessage.msgBytes, packetStringMessage.msgBuffer);
@@ -1432,6 +1748,8 @@ static BOOL TsProxyCreateChannelWriteRequest(rdpTsg* tsg, CONTEXT_HANDLE* tunnel
rpc = tsg->rpc;
count = _wcslen(tsg->Hostname) + 1;
+ if (count > UINT32_MAX)
+ return FALSE;
s = Stream_New(NULL, 60 + count * 2);
if (!s)
@@ -1451,15 +1769,15 @@ static BOOL TsProxyCreateChannelWriteRequest(rdpTsg* tsg, CONTEXT_HANDLE* tunnel
Stream_Write_UINT16(s, tsg->Port); /* PortNumber (0xD3D = 3389) (2 bytes) */
Stream_Write_UINT32(s, 0x00000001); /* NumResourceNames (4 bytes) */
Stream_Write_UINT32(s, 0x00020004); /* ResourceNamePtr (4 bytes) */
- Stream_Write_UINT32(s, count); /* MaxCount (4 bytes) */
+ Stream_Write_UINT32(s, (UINT32)count); /* MaxCount (4 bytes) */
Stream_Write_UINT32(s, 0); /* Offset (4 bytes) */
- Stream_Write_UINT32(s, count); /* ActualCount (4 bytes) */
+ Stream_Write_UINT32(s, (UINT32)count); /* ActualCount (4 bytes) */
Stream_Write_UTF16_String(s, tsg->Hostname, count); /* Array */
return rpc_client_write_call(rpc, s, TsProxyCreateChannelOpnum);
}
-static BOOL TsProxyCreateChannelReadResponse(rdpTsg* tsg, RPC_PDU* pdu,
- CONTEXT_HANDLE* channelContext, UINT32* channelId)
+static BOOL TsProxyCreateChannelReadResponse(RPC_PDU* pdu, CONTEXT_HANDLE* channelContext,
+ UINT32* channelId)
{
BOOL rc = FALSE;
WLog_DBG(TAG, "TsProxyCreateChannelReadResponse");
@@ -1507,7 +1825,7 @@ static BOOL TsProxyCloseChannelWriteRequest(rdpTsg* tsg, CONTEXT_HANDLE* context
return rpc_client_write_call(rpc, s, TsProxyCloseChannelOpnum);
}
-static BOOL TsProxyCloseChannelReadResponse(rdpTsg* tsg, RPC_PDU* pdu, CONTEXT_HANDLE* context)
+static BOOL TsProxyCloseChannelReadResponse(RPC_PDU* pdu, CONTEXT_HANDLE* context)
{
BOOL rc = FALSE;
WLog_DBG(TAG, "TsProxyCloseChannelReadResponse");
@@ -1554,7 +1872,7 @@ static BOOL TsProxyCloseTunnelWriteRequest(rdpTsg* tsg, CONTEXT_HANDLE* context)
return rpc_client_write_call(rpc, s, TsProxyCloseTunnelOpnum);
}
-static BOOL TsProxyCloseTunnelReadResponse(rdpTsg* tsg, RPC_PDU* pdu, CONTEXT_HANDLE* context)
+static BOOL TsProxyCloseTunnelReadResponse(RPC_PDU* pdu, CONTEXT_HANDLE* context)
{
BOOL rc = FALSE;
WLog_DBG(TAG, "TsProxyCloseTunnelReadResponse");
@@ -1705,8 +2023,6 @@ BOOL tsg_recv_pdu(rdpTsg* tsg, RPC_PDU* pdu)
return FALSE;
rpc = tsg->rpc;
- Stream_SealLength(pdu->s);
- Stream_SetPosition(pdu->s, 0);
if (!(pdu->Flags & RPC_PDU_FLAG_STUB))
{
@@ -1745,7 +2061,7 @@ BOOL tsg_recv_pdu(rdpTsg* tsg, RPC_PDU* pdu)
CONTEXT_HANDLE* TunnelContext;
TunnelContext = (tsg->reauthSequence) ? &tsg->NewTunnelContext : &tsg->TunnelContext;
- if (!TsProxyAuthorizeTunnelReadResponse(tsg, pdu))
+ if (!TsProxyAuthorizeTunnelReadResponse(pdu))
{
WLog_ERR(TAG, "TsProxyAuthorizeTunnelReadResponse failure");
return FALSE;
@@ -1794,7 +2110,7 @@ BOOL tsg_recv_pdu(rdpTsg* tsg, RPC_PDU* pdu)
{
CONTEXT_HANDLE ChannelContext;
- if (!TsProxyCreateChannelReadResponse(tsg, pdu, &ChannelContext, &tsg->ChannelId))
+ if (!TsProxyCreateChannelReadResponse(pdu, &ChannelContext, &tsg->ChannelId))
{
WLog_ERR(TAG, "TsProxyCreateChannelReadResponse failure");
return FALSE;
@@ -1867,7 +2183,7 @@ BOOL tsg_recv_pdu(rdpTsg* tsg, RPC_PDU* pdu)
{
CONTEXT_HANDLE ChannelContext;
- if (!TsProxyCloseChannelReadResponse(tsg, pdu, &ChannelContext))
+ if (!TsProxyCloseChannelReadResponse(pdu, &ChannelContext))
{
WLog_ERR(TAG, "TsProxyCloseChannelReadResponse failure");
return FALSE;
@@ -1879,7 +2195,7 @@ BOOL tsg_recv_pdu(rdpTsg* tsg, RPC_PDU* pdu)
{
CONTEXT_HANDLE TunnelContext;
- if (!TsProxyCloseTunnelReadResponse(tsg, pdu, &TunnelContext))
+ if (!TsProxyCloseTunnelReadResponse(pdu, &TunnelContext))
{
WLog_ERR(TAG, "TsProxyCloseTunnelReadResponse failure");
return FALSE;
@@ -1894,7 +2210,7 @@ BOOL tsg_recv_pdu(rdpTsg* tsg, RPC_PDU* pdu)
{
CONTEXT_HANDLE ChannelContext;
- if (!TsProxyCloseChannelReadResponse(tsg, pdu, &ChannelContext))
+ if (!TsProxyCloseChannelReadResponse(pdu, &ChannelContext))
{
WLog_ERR(TAG, "TsProxyCloseChannelReadResponse failure");
return FALSE;
@@ -1924,7 +2240,7 @@ BOOL tsg_recv_pdu(rdpTsg* tsg, RPC_PDU* pdu)
{
CONTEXT_HANDLE TunnelContext;
- if (!TsProxyCloseTunnelReadResponse(tsg, pdu, &TunnelContext))
+ if (!TsProxyCloseTunnelReadResponse(pdu, &TunnelContext))
{
WLog_ERR(TAG, "TsProxyCloseTunnelReadResponse failure");
return FALSE;
@@ -2033,10 +2349,25 @@ BOOL tsg_connect(rdpTsg* tsg, const char* hostname, UINT16 port, DWORD timeout)
{
UINT64 looptimeout = timeout * 1000ULL;
DWORD nCount;
- HANDLE events[64];
- rdpRpc* rpc = tsg->rpc;
- rdpSettings* settings = rpc->settings;
- rdpTransport* transport = rpc->transport;
+ HANDLE events[MAXIMUM_WAIT_OBJECTS] = { 0 };
+ rdpRpc* rpc;
+ rdpContext* context;
+ rdpSettings* settings;
+ rdpTransport* transport;
+
+ assert(tsg);
+
+ rpc = tsg->rpc;
+ assert(rpc);
+
+ transport = rpc->transport;
+ assert(transport);
+
+ context = tsg->rpc->context;
+ assert(context);
+
+ settings = context->settings;
+
tsg->Port = port;
tsg->transport = transport;
@@ -2055,7 +2386,7 @@ BOOL tsg_connect(rdpTsg* tsg, const char* hostname, UINT16 port, DWORD timeout)
return FALSE;
}
- nCount = tsg_get_event_handles(tsg, events, 64);
+ nCount = tsg_get_event_handles(tsg, events, ARRAYSIZE(events));
if (nCount == 0)
return FALSE;
@@ -2138,7 +2469,7 @@ BOOL tsg_disconnect(rdpTsg* tsg)
* @return < 0 on error; 0 if not enough data is available (non blocking mode); > 0 bytes to read
*/
-static int tsg_read(rdpTsg* tsg, BYTE* data, UINT32 length)
+static int tsg_read(rdpTsg* tsg, BYTE* data, size_t length)
{
rdpRpc* rpc;
int status = 0;
@@ -2156,7 +2487,7 @@ static int tsg_read(rdpTsg* tsg, BYTE* data, UINT32 length)
do
{
- status = rpc_client_receive_pipe_read(rpc->client, data, (size_t)length);
+ status = rpc_client_receive_pipe_read(rpc->client, data, length);
if (status < 0)
return -1;
@@ -2206,7 +2537,7 @@ static int tsg_write(rdpTsg* tsg, const BYTE* data, UINT32 length)
if (status < 0)
return -1;
- return length;
+ return (int)length;
}
rdpTsg* tsg_new(rdpTransport* transport)
@@ -2218,7 +2549,6 @@ rdpTsg* tsg_new(rdpTransport* transport)
return NULL;
tsg->transport = transport;
- tsg->settings = transport->settings;
tsg->rpc = rpc_new(tsg->transport);
if (!tsg->rpc)
@@ -2246,7 +2576,10 @@ static int transport_bio_tsg_write(BIO* bio, const char* buf, int num)
int status;
rdpTsg* tsg = (rdpTsg*)BIO_get_data(bio);
BIO_clear_flags(bio, BIO_FLAGS_WRITE);
- status = tsg_write(tsg, (BYTE*)buf, num);
+
+ if (num < 0)
+ return -1;
+ status = tsg_write(tsg, (const BYTE*)buf, (UINT32)num);
if (status < 0)
{
@@ -2278,7 +2611,7 @@ static int transport_bio_tsg_read(BIO* bio, char* buf, int size)
}
BIO_clear_flags(bio, BIO_FLAGS_READ);
- status = tsg_read(tsg, (BYTE*)buf, size);
+ status = tsg_read(tsg, (BYTE*)buf, (size_t)size);
if (status < 0)
{
@@ -2300,17 +2633,22 @@ static int transport_bio_tsg_read(BIO* bio, char* buf, int size)
static int transport_bio_tsg_puts(BIO* bio, const char* str)
{
+ WINPR_UNUSED(bio);
+ WINPR_UNUSED(str);
return 1;
}
static int transport_bio_tsg_gets(BIO* bio, char* str, int size)
{
+ WINPR_UNUSED(bio);
+ WINPR_UNUSED(str);
+ WINPR_UNUSED(size);
return 1;
}
static long transport_bio_tsg_ctrl(BIO* bio, int cmd, long arg1, void* arg2)
{
- int status = -1;
+ long status = -1;
rdpTsg* tsg = (rdpTsg*)BIO_get_data(bio);
RpcVirtualConnection* connection = tsg->rpc->VirtualConnection;
RpcInChannel* inChannel = connection->DefaultInChannel;
@@ -2339,27 +2677,27 @@ static long transport_bio_tsg_ctrl(BIO* bio, int cmd, long arg1, void* arg2)
case BIO_C_READ_BLOCKED:
{
- BIO* bio = outChannel->common.bio;
- status = BIO_read_blocked(bio);
+ BIO* cbio = outChannel->common.bio;
+ status = BIO_read_blocked(cbio);
}
break;
case BIO_C_WRITE_BLOCKED:
{
- BIO* bio = inChannel->common.bio;
- status = BIO_write_blocked(bio);
+ BIO* cbio = inChannel->common.bio;
+ status = BIO_write_blocked(cbio);
}
break;
case BIO_C_WAIT_READ:
{
int timeout = (int)arg1;
- BIO* bio = outChannel->common.bio;
+ BIO* cbio = outChannel->common.bio;
- if (BIO_read_blocked(bio))
- return BIO_wait_read(bio, timeout);
- else if (BIO_write_blocked(bio))
- return BIO_wait_write(bio, timeout);
+ if (BIO_read_blocked(cbio))
+ return BIO_wait_read(cbio, timeout);
+ else if (BIO_write_blocked(cbio))
+ return BIO_wait_write(cbio, timeout);
else
status = 1;
}
@@ -2368,12 +2706,12 @@ static long transport_bio_tsg_ctrl(BIO* bio, int cmd, long arg1, void* arg2)
case BIO_C_WAIT_WRITE:
{
int timeout = (int)arg1;
- BIO* bio = inChannel->common.bio;
+ BIO* cbio = inChannel->common.bio;
- if (BIO_write_blocked(bio))
- status = BIO_wait_write(bio, timeout);
- else if (BIO_read_blocked(bio))
- status = BIO_wait_read(bio, timeout);
+ if (BIO_write_blocked(cbio))
+ status = BIO_wait_write(cbio, timeout);
+ else if (BIO_read_blocked(cbio))
+ status = BIO_wait_read(cbio, timeout);
else
status = 1;
}
@@ -2388,6 +2726,7 @@ static long transport_bio_tsg_ctrl(BIO* bio, int cmd, long arg1, void* arg2)
static int transport_bio_tsg_new(BIO* bio)
{
+ assert(bio);
BIO_set_init(bio, 1);
BIO_set_flags(bio, BIO_FLAGS_SHOULD_RETRY);
return 1;
@@ -2395,6 +2734,8 @@ static int transport_bio_tsg_new(BIO* bio)
static int transport_bio_tsg_free(BIO* bio)
{
+ assert(bio);
+ WINPR_UNUSED(bio);
return 1;
}