Export remaining packet length from rdp_read_share_control_header
authorakallabeth <akallabeth@posteo.net>
Mon, 6 Apr 2020 11:01:20 +0000 (13:01 +0200)
committerakallabeth <akallabeth@posteo.net>
Mon, 6 Apr 2020 11:18:35 +0000 (13:18 +0200)
libfreerdp/core/capabilities.c
libfreerdp/core/peer.c
libfreerdp/core/rdp.c
libfreerdp/core/rdp.h

index 49e1706..391a2a7 100644 (file)
@@ -3888,7 +3888,6 @@ BOOL rdp_recv_demand_active(rdpRdp* rdp, wStream* s)
 {
        UINT16 channelId;
        UINT16 pduType;
-       UINT16 pduLength;
        UINT16 pduSource;
        UINT16 length;
        UINT16 numberCapabilities;
@@ -3901,7 +3900,7 @@ BOOL rdp_recv_demand_active(rdpRdp* rdp, wStream* s)
        if (freerdp_shall_disconnect(rdp->instance))
                return TRUE;
 
-       if (!rdp_read_share_control_header(s, &pduLength, &pduType, &pduSource))
+       if (!rdp_read_share_control_header(s, NULL, NULL, &pduType, &pduSource))
        {
                WLog_ERR(TAG, "rdp_read_share_control_header failed");
                return FALSE;
index 73fa418..9a69900 100644 (file)
@@ -348,7 +348,6 @@ static int peer_recv_tpkt_pdu(freerdp_peer* client, wStream* s)
        rdpRdp* rdp;
        UINT16 length;
        UINT16 pduType;
-       UINT16 pduLength;
        UINT16 pduSource;
        UINT16 channelId;
        UINT16 securityFlags = 0;
@@ -381,7 +380,8 @@ static int peer_recv_tpkt_pdu(freerdp_peer* client, wStream* s)
 
        if (channelId == MCS_GLOBAL_CHANNEL_ID)
        {
-               if (!rdp_read_share_control_header(s, &pduLength, &pduType, &pduSource))
+               UINT16 pduLength, remain;
+               if (!rdp_read_share_control_header(s, &pduLength, &remain, &pduType, &pduSource))
                        return -1;
 
                client->settings->PduSource = pduSource;
@@ -403,6 +403,8 @@ static int peer_recv_tpkt_pdu(freerdp_peer* client, wStream* s)
                        case PDU_TYPE_FLOW_RESPONSE:
                        case PDU_TYPE_FLOW_STOP:
                        case PDU_TYPE_FLOW_TEST:
+                               if (!Stream_SafeSeek(s, remain))
+                                       return -1;
                                break;
 
                        default:
index ce51f10..341d15d 100644 (file)
@@ -143,7 +143,8 @@ void rdp_write_security_header(wStream* s, UINT16 flags)
        Stream_Write_UINT16(s, 0);     /* flagsHi (unused) */
 }
 
-BOOL rdp_read_share_control_header(wStream* s, UINT16* length, UINT16* type, UINT16* channel_id)
+BOOL rdp_read_share_control_header(wStream* s, UINT16* tpktLength, UINT16* remainingLength,
+                                   UINT16* type, UINT16* channel_id)
 {
        UINT16 len;
        if (Stream_GetRemainingLength(s) < 2)
@@ -152,8 +153,6 @@ BOOL rdp_read_share_control_header(wStream* s, UINT16* length, UINT16* type, UIN
        /* Share Control Header */
        Stream_Read_UINT16(s, len); /* totalLength */
 
-       *length = len;
-
        /* 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 (len == 0x8000)
@@ -161,20 +160,34 @@ BOOL rdp_read_share_control_header(wStream* s, UINT16* length, UINT16* type, UIN
                if (!rdp_read_flow_control_pdu(s, type, channel_id))
                        return FALSE;
                *channel_id = 0;
-               *length = 8; /* Flow control PDU is 8 bytes */
+               if (tpktLength)
+                       *tpktLength = 8; /* Flow control PDU is 8 bytes */
+               if (remainingLength)
+                       *remainingLength = 0;
                return TRUE;
        }
 
        if ((len < 4) || ((len - 2) > Stream_GetRemainingLength(s)))
                return FALSE;
 
+       if (tpktLength)
+               *tpktLength = len;
+
        Stream_Read_UINT16(s, *type); /* pduType */
        *type &= 0x0F;                /* type is in the 4 least significant bits */
 
-       if (len > 4)
+       if (len > 5)
+       {
                Stream_Read_UINT16(s, *channel_id); /* pduSource */
+               if (remainingLength)
+                       *remainingLength = len - 6;
+       }
        else
+       {
                *channel_id = 0; /* Windows XP can send such short DEACTIVATE_ALL PDUs. */
+               if (remainingLength)
+                       *remainingLength = len - 4;
+       }
 
        return TRUE;
 }
@@ -1098,7 +1111,7 @@ int rdp_recv_out_of_sequence_pdu(rdpRdp* rdp, wStream* s)
        UINT16 length;
        UINT16 channelId;
 
-       if (!rdp_read_share_control_header(s, &length, &type, &channelId))
+       if (!rdp_read_share_control_header(s, &length, NULL, &type, &channelId))
                return -1;
 
        if (type == PDU_TYPE_DATA)
@@ -1274,7 +1287,6 @@ static int rdp_recv_tpkt_pdu(rdpRdp* rdp, wStream* s)
        int rc = 0;
        UINT16 length;
        UINT16 pduType;
-       UINT16 pduLength;
        UINT16 pduSource;
        UINT16 channelId = 0;
        UINT16 securityFlags = 0;
@@ -1330,20 +1342,16 @@ static int rdp_recv_tpkt_pdu(rdpRdp* rdp, wStream* s)
                {
                        wStream sub;
                        size_t diff;
+                       UINT16 remain;
 
-                       if (!rdp_read_share_control_header(s, &pduLength, &pduType, &pduSource))
+                       if (!rdp_read_share_control_header(s, NULL, &remain, &pduType, &pduSource))
                        {
                                WLog_ERR(TAG, "rdp_recv_tpkt_pdu: rdp_read_share_control_header() fail");
                                return -1;
                        }
 
-                       /* Remove header data. */
-                       if (pduLength > 5)
-                               pduLength -= 6;
-                       else
-                               pduLength -= 4;
-                       Stream_StaticInit(&sub, Stream_Pointer(s), pduLength);
-                       if (!Stream_SafeSeek(s, pduLength))
+                       Stream_StaticInit(&sub, Stream_Pointer(s), remain);
+                       if (!Stream_SafeSeek(s, remain))
                                return -1;
 
                        rdp->settings->PduSource = pduSource;
@@ -1374,7 +1382,7 @@ static int rdp_recv_tpkt_pdu(rdpRdp* rdp, wStream* s)
                                case PDU_TYPE_FLOW_TEST:
                                        WLog_DBG(TAG, "flow message 0x%04" PRIX16 "", pduType);
                                        /* http://msdn.microsoft.com/en-us/library/cc240576.aspx */
-                                       if (!Stream_SafeSeek(&sub, pduLength))
+                                       if (!Stream_SafeSeek(&sub, remain))
                                                return -1;
                                        break;
 
index 8e12a44..e728ea3 100644 (file)
@@ -184,7 +184,8 @@ struct rdp_rdp
 FREERDP_LOCAL BOOL rdp_read_security_header(wStream* s, UINT16* flags, UINT16* length);
 FREERDP_LOCAL void rdp_write_security_header(wStream* s, UINT16 flags);
 
-FREERDP_LOCAL BOOL rdp_read_share_control_header(wStream* s, UINT16* length, UINT16* type,
+FREERDP_LOCAL BOOL rdp_read_share_control_header(wStream* s, UINT16* tpktLength,
+                                                 UINT16* remainingLength, UINT16* type,
                                                  UINT16* channel_id);
 
 FREERDP_LOCAL BOOL rdp_read_share_data_header(wStream* s, UINT16* length, BYTE* type,