Ignore T.128 FlowPDU in Share Control header

According to the Microsoft RDP specification, T.128 flow control PDUs
should be ignored when reading Share Control headers.
(http://msdn.microsoft.com/en-us/library/cc240576.aspx). This patch
checks if we got a flow control PDU (length = 0x8000) and advances the
stream to ignore the PDU.
This commit is contained in:
Mehul Dhorda 2014-11-05 11:32:46 -08:00
parent 2cb47d119b
commit f64d620a3b
3 changed files with 44 additions and 0 deletions

View File

@ -379,6 +379,11 @@ static int peer_recv_tpkt_pdu(freerdp_peer* client, wStream* s)
return -1;
break;
case PDU_TYPE_FLOW_RESPONSE:
case PDU_TYPE_FLOW_STOP:
case PDU_TYPE_FLOW_TEST:
break;
default:
WLog_ERR(TAG, "Client sent pduType %d", pduType);
return -1;

View File

@ -112,6 +112,15 @@ BOOL rdp_read_share_control_header(wStream* s, UINT16* length, UINT16* type, UIN
/* Share Control Header */
Stream_Read_UINT16(s, *length); /* totalLength */
/* If length is 0x8000 then we actually got a flow control PDU that we should ignore
http://msdn.microsoft.com/en-us/library/cc240576.aspx */
if (*length == 0x8000)
{
rdp_read_flow_control_pdu(s, type);
*length = 8; /* Flow control PDU is 8 bytes */
return TRUE;
}
if (((size_t) *length - 2) > Stream_GetRemainingLength(s))
return FALSE;
@ -894,12 +903,31 @@ int rdp_recv_out_of_sequence_pdu(rdpRdp* rdp, wStream* s)
{
return rdp_recv_enhanced_security_redirection_packet(rdp, s);
}
else if (type == PDU_TYPE_FLOW_RESPONSE ||
type == PDU_TYPE_FLOW_STOP ||
type == PDU_TYPE_FLOW_TEST)
{
return 0;
}
else
{
return -1;
}
}
void rdp_read_flow_control_pdu(wStream* s, UINT16* type)
{
/* Read flow control PDU - documented in FlowPDU section in T.128
http://www.itu.int/rec/T-REC-T.128-199802-S/en */
UINT8 pduType;
Stream_Read_UINT8(s, pduType); /* pduTypeFlow */
*type = pduType;
Stream_Seek_UINT8(s); /* pad8bits */
Stream_Seek_UINT8(s); /* flowIdentifier */
Stream_Seek_UINT8(s); /* flowNumber */
Stream_Seek_UINT16(s); /* pduSource */
}
/**
* Decrypt an RDP packet.\n
* @param rdp RDP module
@ -1058,6 +1086,11 @@ static int rdp_recv_tpkt_pdu(rdpRdp* rdp, wStream* s)
case PDU_TYPE_SERVER_REDIRECTION:
return rdp_recv_enhanced_security_redirection_packet(rdp, s);
break;
case PDU_TYPE_FLOW_RESPONSE:
case PDU_TYPE_FLOW_STOP:
case PDU_TYPE_FLOW_TEST:
break;
default:
WLog_ERR(TAG, "incorrect PDU type: 0x%04X", pduType);

View File

@ -83,6 +83,10 @@
#define PDU_TYPE_DATA 0x7
#define PDU_TYPE_SERVER_REDIRECTION 0xA
#define PDU_TYPE_FLOW_TEST 0x41
#define PDU_TYPE_FLOW_STOP 0x42
#define PDU_TYPE_FLOW_RESPONSE 0x43
#define FINALIZE_SC_SYNCHRONIZE_PDU 0x01
#define FINALIZE_SC_CONTROL_COOPERATE_PDU 0x02
#define FINALIZE_SC_CONTROL_GRANTED_PDU 0x04
@ -206,6 +210,8 @@ int rdp_recv_message_channel_pdu(rdpRdp* rdp, wStream* s);
int rdp_recv_out_of_sequence_pdu(rdpRdp* rdp, wStream* s);
void rdp_read_flow_control_pdu(wStream* s, UINT16* type);
void rdp_set_blocking_mode(rdpRdp* rdp, BOOL blocking);
int rdp_check_fds(rdpRdp* rdp);