libfreerdp-core: fix tsg_read to strip TSG layers for transport_read

This commit is contained in:
Marc-André Moreau
2012-11-14 19:51:45 -05:00
parent 3aa043584d
commit ac319e72ae
4 changed files with 88 additions and 66 deletions

View File

@@ -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))
{

View File

@@ -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);

View File

@@ -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;

View File

@@ -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;