Fix tpkt header length checks for encrypted packets
authorArmin Novak <armin.novak@gmail.com>
Mon, 9 Mar 2020 20:54:34 +0000 (21:54 +0100)
committerakallabeth <akallabeth@users.noreply.github.com>
Tue, 10 Mar 2020 11:20:50 +0000 (12:20 +0100)
If securityFlag SEC_ENCRYPT is set, remove the encryption headers from
the TPKT header length on comparison.

libfreerdp/core/capabilities.c
libfreerdp/core/connection.c
libfreerdp/core/info.c
libfreerdp/core/license.c
libfreerdp/core/peer.c
libfreerdp/core/rdp.c
libfreerdp/core/rdp.h

index d672737..be0c2d5 100644 (file)
@@ -3862,7 +3862,7 @@ BOOL rdp_recv_get_active_header(rdpRdp* rdp, wStream* s, UINT16* pChannelId, UIN
 
                if (securityFlags & SEC_ENCRYPT)
                {
-                       if (!rdp_decrypt(rdp, s, *length, securityFlags))
+                       if (!rdp_decrypt(rdp, s, length, securityFlags))
                        {
                                WLog_ERR(TAG, "rdp_decrypt failed");
                                return FALSE;
index 6c6ae26..7a66e8e 100644 (file)
@@ -991,7 +991,7 @@ BOOL rdp_client_connect_auto_detect(rdpRdp* rdp, wStream* s)
 
                                if (securityFlags & SEC_ENCRYPT)
                                {
-                                       if (!rdp_decrypt(rdp, s, length, securityFlags))
+                                       if (!rdp_decrypt(rdp, s, &length, securityFlags))
                                        {
                                                WLog_ERR(TAG, "rdp_decrypt failed");
                                                return FALSE;
index fbe5071..843693e 100644 (file)
@@ -991,7 +991,7 @@ BOOL rdp_recv_client_info(rdpRdp* rdp, wStream* s)
 
                if (securityFlags & SEC_ENCRYPT)
                {
-                       if (!rdp_decrypt(rdp, s, length, securityFlags))
+                       if (!rdp_decrypt(rdp, s, &length, securityFlags))
                        {
                                WLog_ERR(TAG, "rdp_decrypt failed");
                                return FALSE;
index 08081c0..18bcb9f 100644 (file)
@@ -467,7 +467,7 @@ int license_recv(rdpLicense* license, wStream* s)
 
        if (securityFlags & SEC_ENCRYPT)
        {
-               if (!rdp_decrypt(license->rdp, s, length, securityFlags))
+               if (!rdp_decrypt(license->rdp, s, &length, securityFlags))
                {
                        WLog_ERR(TAG, "rdp_decrypt failed");
                        return -1;
index 63bb52f..f160c3c 100644 (file)
@@ -371,7 +371,7 @@ static int peer_recv_tpkt_pdu(freerdp_peer* client, wStream* s)
 
                if (securityFlags & SEC_ENCRYPT)
                {
-                       if (!rdp_decrypt(rdp, s, length, securityFlags))
+                       if (!rdp_decrypt(rdp, s, &length, securityFlags))
                        {
                                WLog_ERR(TAG, "rdp_decrypt failed");
                                return -1;
@@ -446,7 +446,7 @@ static int peer_recv_fastpath_pdu(freerdp_peer* client, wStream* s)
 
        if (fastpath->encryptionFlags & FASTPATH_OUTPUT_ENCRYPTED)
        {
-               if (!rdp_decrypt(rdp, s, length,
+               if (!rdp_decrypt(rdp, s, &length,
                                 (fastpath->encryptionFlags & FASTPATH_OUTPUT_SECURE_CHECKSUM)
                                     ? SEC_SECURE_CHECKSUM
                                     : 0))
index 2830e1e..144a344 100644 (file)
@@ -1141,15 +1141,17 @@ void rdp_read_flow_control_pdu(wStream* s, UINT16* type)
  * @param length int
  */
 
-BOOL rdp_decrypt(rdpRdp* rdp, wStream* s, INT32 length, UINT16 securityFlags)
+BOOL rdp_decrypt(rdpRdp* rdp, wStream* s, UINT16* pLength, UINT16 securityFlags)
 {
        BYTE cmac[8];
        BYTE wmac[8];
        BOOL status;
+       INT32 length;
 
-       if (!rdp || !s || (length < 0))
+       if (!rdp || !s || !pLength)
                return FALSE;
 
+       length = *pLength;
        if (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS)
        {
                UINT16 len;
@@ -1184,6 +1186,7 @@ BOOL rdp_decrypt(rdpRdp* rdp, wStream* s, INT32 length, UINT16 securityFlags)
                }
 
                Stream_SetLength(s, Stream_Length(s) - pad);
+               *pLength = padLength;
                return TRUE;
        }
 
@@ -1220,6 +1223,7 @@ BOOL rdp_decrypt(rdpRdp* rdp, wStream* s, INT32 length, UINT16 securityFlags)
                // return FALSE;
        }
 
+       *pLength = length;
        return TRUE;
 }
 
@@ -1290,7 +1294,7 @@ static int rdp_recv_tpkt_pdu(rdpRdp* rdp, wStream* s)
 
                if (securityFlags & (SEC_ENCRYPT | SEC_REDIRECTION_PKT))
                {
-                       if (!rdp_decrypt(rdp, s, length, securityFlags))
+                       if (!rdp_decrypt(rdp, s, &length, securityFlags))
                        {
                                WLog_ERR(TAG, "rdp_decrypt failed");
                                return -1;
@@ -1435,7 +1439,7 @@ static int rdp_recv_fastpath_pdu(rdpRdp* rdp, wStream* s)
                UINT16 flags =
                    (fastpath->encryptionFlags & FASTPATH_OUTPUT_SECURE_CHECKSUM) ? SEC_SECURE_CHECKSUM : 0;
 
-               if (!rdp_decrypt(rdp, s, length, flags))
+               if (!rdp_decrypt(rdp, s, &length, flags))
                {
                        WLog_ERR(TAG, "rdp_recv_fastpath_pdu: rdp_decrypt() fail");
                        return -1;
index f28d45e..8e12a44 100644 (file)
@@ -233,7 +233,7 @@ extern const char* DATA_PDU_TYPE_STRINGS[80];
        } while (0)
 #endif
 
-BOOL rdp_decrypt(rdpRdp* rdp, wStream* s, INT32 length, UINT16 securityFlags);
+BOOL rdp_decrypt(rdpRdp* rdp, wStream* s, UINT16* pLength, UINT16 securityFlags);
 
 BOOL rdp_set_error_info(rdpRdp* rdp, UINT32 errorInfo);
 BOOL rdp_send_error_info(rdpRdp* rdp);