mirror of
https://github.com/morgan9e/FreeRDP
synced 2026-04-15 00:44:19 +09:00
libfreerdp-core: fix tsg_read to strip TSG layers for transport_read
This commit is contained in:
@@ -960,16 +960,45 @@ int rpc_recv_fault_pdu(RPC_PDU_HEADER* header)
|
||||
return 0;
|
||||
}
|
||||
|
||||
BOOL rpc_get_stub_data_info(rdpRpc* rpc, BYTE* header, UINT32* offset, UINT32* length)
|
||||
{
|
||||
RPC_PDU_HEADER* pCommonFields;
|
||||
|
||||
*offset = RPC_COMMON_FIELDS_LENGTH;
|
||||
pCommonFields = ((RPC_PDU_HEADER*) header);
|
||||
|
||||
if (pCommonFields->ptype == PTYPE_RESPONSE)
|
||||
{
|
||||
*offset += 4;
|
||||
rpc_offset_align(offset, 8);
|
||||
}
|
||||
else if (pCommonFields->ptype == PTYPE_REQUEST)
|
||||
{
|
||||
*offset += 4;
|
||||
rpc_offset_align(offset, 8);
|
||||
}
|
||||
else
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (length)
|
||||
{
|
||||
*length = pCommonFields->frag_length - (pCommonFields->auth_length + *offset);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int rpc_recv_pdu_header(rdpRpc* rpc, BYTE* header)
|
||||
{
|
||||
int status;
|
||||
int bytesRead;
|
||||
UINT32 offset;
|
||||
RPC_PDU_HEADER* pCommonFields;
|
||||
UINT32 offset;
|
||||
|
||||
/* read first 20 bytes to get RPC common fields */
|
||||
|
||||
bytesRead = 0;
|
||||
bytesRead = 0;
|
||||
|
||||
while (bytesRead < RPC_COMMON_FIELDS_LENGTH)
|
||||
{
|
||||
@@ -985,52 +1014,40 @@ int rpc_recv_pdu_header(rdpRpc* rpc, BYTE* header)
|
||||
}
|
||||
|
||||
rpc_pdu_header_print((RPC_PDU_HEADER*) header);
|
||||
pCommonFields = ((RPC_PDU_HEADER*) header);
|
||||
|
||||
offset = RPC_COMMON_FIELDS_LENGTH;
|
||||
|
||||
if (pCommonFields->ptype == PTYPE_RESPONSE)
|
||||
{
|
||||
offset += 4;
|
||||
rpc_offset_align(&offset, 8);
|
||||
}
|
||||
else if (pCommonFields->ptype == PTYPE_REQUEST)
|
||||
{
|
||||
offset += 4;
|
||||
rpc_offset_align(&offset, 8);
|
||||
}
|
||||
|
||||
while (bytesRead < offset)
|
||||
{
|
||||
status = tls_read(rpc->tls_out, &header[bytesRead], offset - bytesRead);
|
||||
rpc_get_stub_data_info(rpc, header, &offset, NULL);
|
||||
|
||||
while (bytesRead < offset)
|
||||
{
|
||||
status = tls_read(rpc->tls_out, &header[bytesRead], offset - bytesRead);
|
||||
|
||||
if (status < 0)
|
||||
return status;
|
||||
if (status < 0)
|
||||
return status;
|
||||
|
||||
bytesRead += status;
|
||||
}
|
||||
bytesRead += status;
|
||||
}
|
||||
|
||||
return bytesRead;
|
||||
return bytesRead;
|
||||
}
|
||||
|
||||
int rpc_recv_pdu(rdpRpc* rpc)
|
||||
{
|
||||
int status;
|
||||
int headerLength;
|
||||
int headerLength;
|
||||
int bytesRead = 0;
|
||||
RPC_PDU_HEADER* header;
|
||||
|
||||
status = rpc_recv_pdu_header(rpc, rpc->buffer);
|
||||
status = rpc_recv_pdu_header(rpc, rpc->buffer);
|
||||
|
||||
if (status < 1)
|
||||
{
|
||||
printf("rpc_recv_pdu_header: error reading header\n");
|
||||
return status;
|
||||
}
|
||||
if (status < 1)
|
||||
{
|
||||
printf("rpc_recv_pdu_header: error reading header\n");
|
||||
return status;
|
||||
}
|
||||
|
||||
headerLength = status;
|
||||
header = (RPC_PDU_HEADER*) rpc->buffer;
|
||||
bytesRead += status;
|
||||
headerLength = status;
|
||||
header = (RPC_PDU_HEADER*) rpc->buffer;
|
||||
bytesRead += status;
|
||||
|
||||
if (header->frag_length > rpc->length)
|
||||
{
|
||||
@@ -1051,12 +1068,6 @@ int rpc_recv_pdu(rdpRpc* rpc)
|
||||
|
||||
bytesRead += status;
|
||||
}
|
||||
|
||||
if (headerLength > RPC_COMMON_FIELDS_LENGTH)
|
||||
{
|
||||
printf("RPC Stub Data:\n");
|
||||
freerdp_hexdump(&rpc->buffer[headerLength], header->frag_length - headerLength);
|
||||
}
|
||||
|
||||
if (!(header->pfc_flags & PFC_LAST_FRAG))
|
||||
{
|
||||
|
||||
@@ -622,6 +622,7 @@ UINT32 rpc_offset_pad(UINT32* offset, UINT32 pad);
|
||||
int rpc_out_write(rdpRpc* rpc, BYTE* data, int length);
|
||||
int rpc_in_write(rdpRpc* rpc, BYTE* data, int length);
|
||||
|
||||
BOOL rpc_get_stub_data_info(rdpRpc* rpc, BYTE* header, UINT32* offset, UINT32* length);
|
||||
int rpc_recv_pdu_header(rdpRpc* rpc, BYTE* header);
|
||||
|
||||
int rpc_recv_pdu(rdpRpc* rpc);
|
||||
|
||||
@@ -1098,32 +1098,31 @@ BOOL tsg_connect(rdpTsg* tsg, const char* hostname, UINT16 port)
|
||||
int tsg_read(rdpTsg* tsg, BYTE* data, UINT32 length)
|
||||
{
|
||||
int status;
|
||||
int copyLength;
|
||||
int CopyLength;
|
||||
RPC_PDU_HEADER* header;
|
||||
rdpRpc* rpc = tsg->rpc;
|
||||
BYTE buffer[RPC_PDU_HEADER_MAX_LENGTH];
|
||||
|
||||
printf("tsg_read: %d, pending: %d\n", length, tsg->pendingPdu);
|
||||
printf("tsg_read: %d, pending: %d\n", length, tsg->PendingPdu);
|
||||
|
||||
if (tsg->pendingPdu)
|
||||
if (tsg->PendingPdu)
|
||||
{
|
||||
header = (RPC_PDU_HEADER*) rpc->buffer;
|
||||
|
||||
copyLength = (tsg->bytesAvailable > length) ? length : tsg->bytesAvailable;
|
||||
CopyLength = (tsg->BytesAvailable > length) ? length : tsg->BytesAvailable;
|
||||
|
||||
CopyMemory(data, &rpc->buffer[tsg->bytesRead], copyLength);
|
||||
tsg->bytesAvailable -= copyLength;
|
||||
tsg->bytesRead += copyLength;
|
||||
CopyMemory(data, &rpc->buffer[tsg->StubOffset + tsg->BytesRead], CopyLength);
|
||||
tsg->BytesAvailable -= CopyLength;
|
||||
tsg->BytesRead += CopyLength;
|
||||
|
||||
if (tsg->bytesAvailable < 1)
|
||||
tsg->pendingPdu = FALSE;
|
||||
if (tsg->BytesAvailable < 1)
|
||||
tsg->PendingPdu = FALSE;
|
||||
|
||||
return copyLength;
|
||||
return CopyLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
status = rpc_recv_pdu_header(rpc, buffer);
|
||||
header = (RPC_PDU_HEADER*) buffer;
|
||||
status = rpc_recv_pdu(rpc);
|
||||
header = (RPC_PDU_HEADER*) rpc->buffer;
|
||||
|
||||
if (header->frag_length == 64)
|
||||
{
|
||||
@@ -1131,17 +1130,26 @@ int tsg_read(rdpTsg* tsg, BYTE* data, UINT32 length)
|
||||
return tsg_read(tsg, data, length);
|
||||
}
|
||||
|
||||
tsg->pendingPdu = TRUE;
|
||||
tsg->bytesAvailable = header->frag_length;
|
||||
tsg->bytesRead = 0;
|
||||
if (!rpc_get_stub_data_info(rpc, rpc->buffer, &tsg->StubOffset, &tsg->StubLength))
|
||||
{
|
||||
printf("tsg_read error: expected stub\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
copyLength = (tsg->bytesAvailable > length) ? length : tsg->bytesAvailable;
|
||||
tsg->PendingPdu = TRUE;
|
||||
tsg->BytesAvailable = tsg->StubLength;
|
||||
tsg->BytesRead = 0;
|
||||
|
||||
CopyMemory(data, &rpc->buffer[tsg->bytesRead], copyLength);
|
||||
tsg->bytesAvailable -= copyLength;
|
||||
tsg->bytesRead += copyLength;
|
||||
printf("RPC Stub (offset: %d length: %d):\n", tsg->StubOffset, tsg->StubLength);
|
||||
freerdp_hexdump(&rpc->buffer[tsg->StubOffset], tsg->StubLength);
|
||||
|
||||
return copyLength;
|
||||
CopyLength = (tsg->BytesAvailable > length) ? length : tsg->BytesAvailable;
|
||||
|
||||
CopyMemory(data, &rpc->buffer[tsg->StubOffset + tsg->BytesRead], CopyLength);
|
||||
tsg->BytesAvailable -= CopyLength;
|
||||
tsg->BytesRead += CopyLength;
|
||||
|
||||
return CopyLength;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1161,7 +1169,7 @@ rdpTsg* tsg_new(rdpTransport* transport)
|
||||
tsg->transport = transport;
|
||||
tsg->settings = transport->settings;
|
||||
tsg->rpc = rpc_new(tsg->transport);
|
||||
tsg->pendingPdu = FALSE;
|
||||
tsg->PendingPdu = FALSE;
|
||||
}
|
||||
|
||||
return tsg;
|
||||
|
||||
@@ -45,9 +45,11 @@ struct rdp_tsg
|
||||
UINT16 Port;
|
||||
LPWSTR Hostname;
|
||||
LPWSTR MachineName;
|
||||
BOOL pendingPdu;
|
||||
BOOL bytesRead;
|
||||
BOOL bytesAvailable;
|
||||
BOOL PendingPdu;
|
||||
BOOL BytesRead;
|
||||
BOOL BytesAvailable;
|
||||
UINT32 StubOffset;
|
||||
UINT32 StubLength;
|
||||
rdpSettings* settings;
|
||||
rdpTransport* transport;
|
||||
CONTEXT_HANDLE TunnelContext;
|
||||
|
||||
Reference in New Issue
Block a user