From 1070931479a4a4ba8b97bd603d293e69c5e6be7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Mon, 4 Feb 2013 16:39:05 -0500 Subject: [PATCH] libfreerdp-core: fix decryption of encrypted error info PDU in license sequence --- libfreerdp/core/license.c | 39 +++++++++++++++++------- libfreerdp/core/rdp.c | 8 ++--- libfreerdp/core/rdp.h | 64 +++++++++++++++++++-------------------- 3 files changed, 64 insertions(+), 47 deletions(-) diff --git a/libfreerdp/core/license.c b/libfreerdp/core/license.c index 2984e6d77..81b7471b5 100644 --- a/libfreerdp/core/license.c +++ b/libfreerdp/core/license.c @@ -179,12 +179,12 @@ BOOL license_send(rdpLicense* license, STREAM* s, BYTE type) BOOL license_recv(rdpLicense* license, STREAM* s) { - UINT16 length; - UINT16 channelId; - UINT16 sec_flags; BYTE flags; BYTE bMsgType; UINT16 wMsgSize; + UINT16 length; + UINT16 channelId; + UINT16 securityFlags; if (!rdp_read_header(license->rdp, s, &length, &channelId)) { @@ -192,17 +192,29 @@ BOOL license_recv(rdpLicense* license, STREAM* s) return FALSE; } - if (!rdp_read_security_header(s, &sec_flags)) + if (!rdp_read_security_header(s, &securityFlags)) return FALSE; - if (!(sec_flags & SEC_LICENSE_PKT)) + if (securityFlags & SEC_ENCRYPT) { - stream_rewind(s, RDP_SECURITY_HEADER_LENGTH); + if (!rdp_decrypt(license->rdp, s, length - 4, securityFlags)) + { + printf("rdp_decrypt failed\n"); + return FALSE; + } + } + + if (!(securityFlags & SEC_LICENSE_PKT)) + { + if (!(securityFlags & SEC_ENCRYPT)) + stream_rewind(s, RDP_SECURITY_HEADER_LENGTH); + if (rdp_recv_out_of_sequence_pdu(license->rdp, s) != TRUE) { printf("Unexpected license packet.\n"); return FALSE; } + return TRUE; } @@ -686,8 +698,10 @@ BOOL license_read_license_request_packet(rdpLicense* license, STREAM* s) BOOL license_read_platform_challenge_packet(rdpLicense* license, STREAM* s) { DEBUG_LICENSE("Receiving Platform Challenge Packet"); - if(stream_get_left(s) < 4) + + if (stream_get_left(s) < 4) return FALSE; + stream_seek(s, 4); /* ConnectFlags, Reserved (4 bytes) */ /* EncryptedPlatformChallenge */ @@ -696,10 +710,11 @@ BOOL license_read_platform_challenge_packet(rdpLicense* license, STREAM* s) license->encrypted_platform_challenge->type = BB_ENCRYPTED_DATA_BLOB; /* MACData (16 bytes) */ - if(!stream_skip(s, 16)) + if (!stream_skip(s, 16)) return FALSE; license_decrypt_platform_challenge(license); + return TRUE; } @@ -741,11 +756,13 @@ BOOL license_read_error_alert_packet(rdpLicense* license, STREAM* s) UINT32 dwErrorCode; UINT32 dwStateTransition; - if(stream_get_left(s) < 8) + if (stream_get_left(s) < 8) return FALSE; + stream_read_UINT32(s, dwErrorCode); /* dwErrorCode (4 bytes) */ stream_read_UINT32(s, dwStateTransition); /* dwStateTransition (4 bytes) */ - if(!license_read_binary_blob(s, license->error_info)) /* bbErrorInfo */ + + if (!license_read_binary_blob(s, license->error_info)) /* bbErrorInfo */ return FALSE; #ifdef WITH_DEBUG_LICENSE @@ -779,6 +796,7 @@ BOOL license_read_error_alert_packet(rdpLicense* license, STREAM* s) default: break; } + return TRUE; } @@ -956,7 +974,6 @@ rdpLicense* license_new(rdpRdp* rdp) license->rdp = rdp; license->state = LICENSE_STATE_AWAIT; - //license->certificate = certificate_new(rdp); license->certificate = certificate_new(); license->product_info = license_new_product_info(); license->error_info = license_new_binary_blob(BB_ERROR_BLOB); diff --git a/libfreerdp/core/rdp.c b/libfreerdp/core/rdp.c index 54738910b..32518833f 100644 --- a/libfreerdp/core/rdp.c +++ b/libfreerdp/core/rdp.c @@ -103,7 +103,7 @@ void rdp_write_security_header(STREAM* s, UINT16 flags) BOOL rdp_read_share_control_header(STREAM* s, UINT16* length, UINT16* type, UINT16* channel_id) { - if(stream_get_left(s) < 2) + if (stream_get_left(s) < 2) return FALSE; /* Share Control Header */ @@ -117,8 +117,8 @@ BOOL rdp_read_share_control_header(STREAM* s, UINT16* length, UINT16* type, UINT if (*length > 4) stream_read_UINT16(s, *channel_id); /* pduSource */ - else /* Windows XP can send such short DEACTIVATE_ALL PDUs. */ - *channel_id = 0; + else + *channel_id = 0; /* Windows XP can send such short DEACTIVATE_ALL PDUs. */ return TRUE; } @@ -645,7 +645,7 @@ BOOL rdp_recv_out_of_sequence_pdu(rdpRdp* rdp, STREAM* s) UINT16 length; UINT16 channelId; - if(!rdp_read_share_control_header(s, &length, &type, &channelId)) + if (!rdp_read_share_control_header(s, &length, &type, &channelId)) return FALSE; if (type == PDU_TYPE_DATA) diff --git a/libfreerdp/core/rdp.h b/libfreerdp/core/rdp.h index 76789bd97..8a3522c82 100644 --- a/libfreerdp/core/rdp.h +++ b/libfreerdp/core/rdp.h @@ -49,38 +49,38 @@ #include /* Security Header Flags */ -#define SEC_EXCHANGE_PKT 0x0001 -#define SEC_ENCRYPT 0x0008 -#define SEC_RESET_SEQNO 0x0010 -#define SEC_IGNORE_SEQNO 0x0020 -#define SEC_INFO_PKT 0x0040 -#define SEC_LICENSE_PKT 0x0080 -#define SEC_LICENSE_ENCRYPT_CS 0x0200 -#define SEC_LICENSE_ENCRYPT_SC 0x0200 -#define SEC_REDIRECTION_PKT 0x0400 -#define SEC_SECURE_CHECKSUM 0x0800 -#define SEC_FLAGSHI_VALID 0x8000 +#define SEC_EXCHANGE_PKT 0x0001 +#define SEC_ENCRYPT 0x0008 +#define SEC_RESET_SEQNO 0x0010 +#define SEC_IGNORE_SEQNO 0x0020 +#define SEC_INFO_PKT 0x0040 +#define SEC_LICENSE_PKT 0x0080 +#define SEC_LICENSE_ENCRYPT_CS 0x0200 +#define SEC_LICENSE_ENCRYPT_SC 0x0200 +#define SEC_REDIRECTION_PKT 0x0400 +#define SEC_SECURE_CHECKSUM 0x0800 +#define SEC_FLAGSHI_VALID 0x8000 -#define SEC_PKT_CS_MASK (SEC_EXCHANGE_PKT | SEC_INFO_PKT) -#define SEC_PKT_SC_MASK (SEC_LICENSE_PKT | SEC_REDIRECTION_PKT) -#define SEC_PKT_MASK (SEC_PKT_CS_MASK | SEC_PKT_SC_MASK) +#define SEC_PKT_CS_MASK (SEC_EXCHANGE_PKT | SEC_INFO_PKT) +#define SEC_PKT_SC_MASK (SEC_LICENSE_PKT | SEC_REDIRECTION_PKT) +#define SEC_PKT_MASK (SEC_PKT_CS_MASK | SEC_PKT_SC_MASK) -#define RDP_SECURITY_HEADER_LENGTH 4 -#define RDP_SHARE_CONTROL_HEADER_LENGTH 6 -#define RDP_SHARE_DATA_HEADER_LENGTH 12 -#define RDP_PACKET_HEADER_MAX_LENGTH (TPDU_DATA_LENGTH + MCS_SEND_DATA_HEADER_MAX_LENGTH) +#define RDP_SECURITY_HEADER_LENGTH 4 +#define RDP_SHARE_CONTROL_HEADER_LENGTH 6 +#define RDP_SHARE_DATA_HEADER_LENGTH 12 +#define RDP_PACKET_HEADER_MAX_LENGTH (TPDU_DATA_LENGTH + MCS_SEND_DATA_HEADER_MAX_LENGTH) -#define PDU_TYPE_DEMAND_ACTIVE 0x1 -#define PDU_TYPE_CONFIRM_ACTIVE 0x3 -#define PDU_TYPE_DEACTIVATE_ALL 0x6 -#define PDU_TYPE_DATA 0x7 -#define PDU_TYPE_SERVER_REDIRECTION 0xA +#define PDU_TYPE_DEMAND_ACTIVE 0x1 +#define PDU_TYPE_CONFIRM_ACTIVE 0x3 +#define PDU_TYPE_DEACTIVATE_ALL 0x6 +#define PDU_TYPE_DATA 0x7 +#define PDU_TYPE_SERVER_REDIRECTION 0xA -#define FINALIZE_SC_SYNCHRONIZE_PDU 0x01 -#define FINALIZE_SC_CONTROL_COOPERATE_PDU 0x02 -#define FINALIZE_SC_CONTROL_GRANTED_PDU 0x04 -#define FINALIZE_SC_FONT_MAP_PDU 0x08 -#define FINALIZE_SC_COMPLETE 0x0F +#define FINALIZE_SC_SYNCHRONIZE_PDU 0x01 +#define FINALIZE_SC_CONTROL_COOPERATE_PDU 0x02 +#define FINALIZE_SC_CONTROL_GRANTED_PDU 0x04 +#define FINALIZE_SC_FONT_MAP_PDU 0x08 +#define FINALIZE_SC_COMPLETE 0x0F /* Data PDU Types */ #define DATA_PDU_TYPE_UPDATE 0x02 @@ -110,10 +110,10 @@ #define DATA_PDU_TYPE_FRAME_ACKNOWLEDGE 0x38 /* Stream Identifiers */ -#define STREAM_UNDEFINED 0x00 -#define STREAM_LOW 0x01 -#define STREAM_MED 0x02 -#define STREAM_HI 0x04 +#define STREAM_UNDEFINED 0x00 +#define STREAM_LOW 0x01 +#define STREAM_MED 0x02 +#define STREAM_HI 0x04 struct rdp_rdp {