diff --git a/libfreerdp/core/capabilities.c b/libfreerdp/core/capabilities.c index 297cfb433..fdbf36186 100644 --- a/libfreerdp/core/capabilities.c +++ b/libfreerdp/core/capabilities.c @@ -3222,19 +3222,12 @@ BOOL rdp_read_capability_sets(wStream* s, rdpSettings* settings, UINT16 numberCa return TRUE; } -BOOL rdp_recv_demand_active(rdpRdp* rdp, wStream* s) +BOOL rdp_recv_get_active_header(rdpRdp* rdp, wStream* s, UINT16* pChannelId) { UINT16 length; - UINT16 channelId; - UINT16 pduType; - UINT16 pduLength; - UINT16 pduSource; - UINT16 numberCapabilities; - UINT16 lengthSourceDescriptor; - UINT16 lengthCombinedCapabilities; UINT16 securityFlags; - if (!rdp_read_header(rdp, s, &length, &channelId)) + if (!rdp_read_header(rdp, s, &length, pChannelId)) return FALSE; if (rdp->disconnect) @@ -3255,12 +3248,31 @@ BOOL rdp_recv_demand_active(rdpRdp* rdp, wStream* s) } } - if (channelId != MCS_GLOBAL_CHANNEL_ID) + if (*pChannelId != MCS_GLOBAL_CHANNEL_ID) { - fprintf(stderr, "expected MCS_GLOBAL_CHANNEL_ID %04x, got %04x\n", MCS_GLOBAL_CHANNEL_ID, channelId); + fprintf(stderr, "expected MCS_GLOBAL_CHANNEL_ID %04x, got %04x\n", MCS_GLOBAL_CHANNEL_ID, *pChannelId); return FALSE; } + return TRUE; +} + +BOOL rdp_recv_demand_active(rdpRdp* rdp, wStream* s) +{ + UINT16 channelId; + UINT16 pduType; + UINT16 pduLength; + UINT16 pduSource; + UINT16 numberCapabilities; + UINT16 lengthSourceDescriptor; + UINT16 lengthCombinedCapabilities; + + if (!rdp_recv_get_active_header(rdp, s, &channelId)) + return FALSE; + + if (rdp->disconnect) + return TRUE; + if (!rdp_read_share_control_header(s, &pduLength, &pduType, &pduSource)) { fprintf(stderr, "rdp_read_share_control_header failed\n"); @@ -3375,7 +3387,6 @@ BOOL rdp_send_demand_active(rdpRdp* rdp) BOOL rdp_recv_confirm_active(rdpRdp* rdp, wStream* s) { - UINT16 length; UINT16 channelId; UINT16 pduType; UINT16 pduLength; @@ -3383,27 +3394,8 @@ BOOL rdp_recv_confirm_active(rdpRdp* rdp, wStream* s) UINT16 lengthSourceDescriptor; UINT16 lengthCombinedCapabilities; UINT16 numberCapabilities; - UINT16 securityFlags; - if (!rdp_read_header(rdp, s, &length, &channelId)) - return FALSE; - - if (rdp->settings->DisableEncryption) - { - if (!rdp_read_security_header(s, &securityFlags)) - return FALSE; - - if (securityFlags & SEC_ENCRYPT) - { - if (!rdp_decrypt(rdp, s, length - 4, securityFlags)) - { - fprintf(stderr, "rdp_decrypt failed\n"); - return FALSE; - } - } - } - - if (channelId != MCS_GLOBAL_CHANNEL_ID) + if (!rdp_recv_get_active_header(rdp, s, &channelId)) return FALSE; if (!rdp_read_share_control_header(s, &pduLength, &pduType, &pduSource)) diff --git a/libfreerdp/core/capabilities.h b/libfreerdp/core/capabilities.h index 1ba4f91f1..4a6191d92 100644 --- a/libfreerdp/core/capabilities.h +++ b/libfreerdp/core/capabilities.h @@ -165,6 +165,7 @@ #define CLW_ENTROPY_RLGR1 0x01 #define CLW_ENTROPY_RLGR3 0x04 +BOOL rdp_recv_get_active_header(rdpRdp* rdp, wStream* s, UINT16* pChannelId); BOOL rdp_recv_demand_active(rdpRdp* rdp, wStream* s); void rdp_write_demand_active(wStream* s, rdpSettings* settings); BOOL rdp_send_demand_active(rdpRdp* rdp); diff --git a/libfreerdp/core/connection.c b/libfreerdp/core/connection.c index d3c84cb6d..dabba597f 100644 --- a/libfreerdp/core/connection.c +++ b/libfreerdp/core/connection.c @@ -529,8 +529,13 @@ BOOL rdp_client_connect_demand_active(rdpRdp* rdp, wStream* s) if (!rdp_recv_demand_active(rdp, s)) { + UINT16 channelId; stream_set_mark(s, mark); - stream_seek(s, RDP_PACKET_HEADER_MAX_LENGTH); + rdp_recv_get_active_header(rdp, s, &channelId); + /* Was stream_seek(s, RDP_PACKET_HEADER_MAX_LENGTH); + * but the headers aren't always that length, + * so that could result in a bad offset. + */ if (rdp_recv_out_of_sequence_pdu(rdp, s) != TRUE) return FALSE;