From 1d9c773dbfe9ab5ceda85773ed8933d73742a9e6 Mon Sep 17 00:00:00 2001 From: Jay Sorg Date: Sun, 16 Feb 2014 00:34:56 -0800 Subject: [PATCH] libxrdp: improve mcs processing --- libxrdp/xrdp_rdp.c | 232 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 195 insertions(+), 37 deletions(-) diff --git a/libxrdp/xrdp_rdp.c b/libxrdp/xrdp_rdp.c index cdbb46a2..4cc2727f 100644 --- a/libxrdp/xrdp_rdp.c +++ b/libxrdp/xrdp_rdp.c @@ -483,65 +483,223 @@ xrdp_rdp_send_data_update_sync(struct xrdp_rdp *self) } /*****************************************************************************/ +/* http://msdn.microsoft.com/en-us/library/cc240510.aspx + 2.2.1.3.2 Client Core Data (TS_UD_CS_CORE) */ static int APP_CC -xrdp_rdp_parse_client_mcs_data(struct xrdp_rdp *self) +xrdp_rdp_parse_client_mcs_data_CS_CORE(struct xrdp_rdp* self, struct stream* s) { - struct stream *p = (struct stream *)NULL; - int i = 0; - - p = &(self->sec_layer->client_mcs_data); - p->p = p->data; - if (!s_check_rem(p, 31 + 2 + 2 + 120 + 2)) + int colorDepth; + int postBeta2ColorDepth; + int highColorDepth; + int supportedColorDepths; + int earlyCapabilityFlags; + + in_uint8s(s, 4); /* version */ + in_uint16_le(s, self->client_info.width); + in_uint16_le(s, self->client_info.height); + in_uint16_le(s, colorDepth); + g_writeln("colorDepth 0x%4.4x (0xca00 4bpp 0xca01 8bpp)", colorDepth); + switch (colorDepth) { - g_writeln("xrdp_rdp_parse_client_mcs_data: error"); - return 1; + case 0xca00: /* RNS_UD_COLOR_4BPP */ + self->client_info.bpp = 4; + break; + case 0xca01: /* RNS_UD_COLOR_8BPP */ + self->client_info.bpp = 8; + break; } - in_uint8s(p, 31); - in_uint16_le(p, self->client_info.width); - in_uint16_le(p, self->client_info.height); - in_uint8s(p, 120); - self->client_info.bpp = 8; - in_uint16_le(p, i); - - switch (i) + in_uint8s(s, 2); /* SASSequence */ + in_uint8s(s, 4); /* keyboardLayout */ + in_uint8s(s, 4); /* clientBuild */ + in_uint8s(s, 32); /* clientName */ + in_uint8s(s, 4); /* keyboardType */ + in_uint8s(s, 4); /* keyboardSubType */ + in_uint8s(s, 4); /* keyboardFunctionKey */ + in_uint8s(s, 64); /* imeFileName */ + in_uint16_le(s, postBeta2ColorDepth); + g_writeln("postBeta2ColorDepth 0x%4.4x (0xca00 4bpp 0xca01 8bpp " + "0xca02 15bpp 0xca03 16bpp 0xca04 24bpp)", postBeta2ColorDepth); + + switch (postBeta2ColorDepth) { - case 0xca01: - if (!s_check_rem(p, 6 + 1)) - { - return 1; - } - in_uint8s(p, 6); - in_uint8(p, i); - - if (i > 8) - { - self->client_info.bpp = i; - } - + case 0xca00: /* RNS_UD_COLOR_4BPP */ + self->client_info.bpp = 4; break; - case 0xca02: + case 0xca01: /* RNS_UD_COLOR_8BPP */ + self->client_info.bpp = 8; + break; + case 0xca02: /* RNS_UD_COLOR_16BPP_555 */ self->client_info.bpp = 15; break; - case 0xca03: + case 0xca03: /* RNS_UD_COLOR_16BPP_565 */ self->client_info.bpp = 16; break; - case 0xca04: + case 0xca04: /* RNS_UD_COLOR_24BPP */ self->client_info.bpp = 24; break; } + if (!s_check_rem(s, 2)) + { + return 0; + } + in_uint8s(s, 2); /* clientProductId */ + + if (!s_check_rem(s, 4)) + { + return 0; + } + in_uint8s(s, 4); /* serialNumber */ + + if (!s_check_rem(s, 2)) + { + return 0; + } + in_uint16_le(s, highColorDepth); + g_writeln("highColorDepth 0x%4.4x (0x0004 4bpp 0x0008 8bpp 0x000f 15bpp " + "0x0010 16 bpp 0x0018 24bpp)", highColorDepth); + self->client_info.bpp = highColorDepth; + + if (!s_check_rem(s, 2)) + { + return 0; + } + in_uint16_le(s, supportedColorDepths); + g_writeln("supportedColorDepths 0x%4.4x (0x0001 24bpp 0x0002 16bpp " + "0x0004 15bpp 0x0008 32bpp)", supportedColorDepths); + + if (!s_check_rem(s, 2)) + { + return 0; + } + in_uint16_le(s, earlyCapabilityFlags); + self->client_info.mcs_early_capability_flags = earlyCapabilityFlags; + g_writeln("earlyCapabilityFlags 0x%4.4x (0x0002 want32)", + earlyCapabilityFlags); + if ((earlyCapabilityFlags & 0x0002) && (supportedColorDepths & 0x0008)) + { + self->client_info.bpp = 32; + } + + if (!s_check_rem(s, 64)) + { + return 0; + } + in_uint8s(s, 64); /* clientDigProductId */ + + if (!s_check_rem(s, 1)) + { + return 0; + } + in_uint8(s, self->client_info.mcs_connection_type); /* connectionType */ + g_writeln("got client client connection type 0x%8.8x", + self->client_info.mcs_connection_type); + + if (!s_check_rem(s, 1)) + { + return 0; + } + in_uint8s(s, 1); /* pad1octet */ + + if (!s_check_rem(s, 4)) + { + return 0; + } + in_uint8s(s, 4); /* serverSelectedProtocol */ + + if (!s_check_rem(s, 4)) + { + return 0; + } + in_uint8s(s, 4); /* desktopPhysicalWidth */ + + if (!s_check_rem(s, 4)) + { + return 0; + } + in_uint8s(s, 4); /* desktopPhysicalHeight */ + + if (!s_check_rem(s, 2)) + { + return 0; + } + in_uint8s(s, 2); /* reserved */ + + return 0; +} + +/*****************************************************************************/ +static int APP_CC +xrdp_rdp_parse_client_mcs_data(struct xrdp_rdp* self) +{ + struct stream* s; + int i; + int header_type; + int length; + char* hold_p; + char* hold_end; + + s = &(self->sec_layer->client_mcs_data); + s->p = s->data; + in_uint8s(s, 23); + while (s->p < s->end) + { + if (!s_check_rem(s, 4)) + { + g_writeln("xrdp_rdp_parse_client_mcs_data: parse error, bytes " + "left %d", (int)(s->end - s->p)); + return 1; + } + hold_p = s->p; + hold_end = s->end; + in_uint16_le(s, header_type); + in_uint16_le(s, length); + g_writeln("type 0x%2.2x len %d", header_type, length); + if (length < 4) + { + g_writeln("xrdp_rdp_parse_client_mcs_data: parse error"); + return 1; + } + if (!s_check_rem(s, length - 4)) + { + g_writeln("xrdp_rdp_parse_client_mcs_data: parse error"); + return 1; + } + s->end = s->p + length; + switch (header_type) + { + case 0xc001: /* CS_CORE */ + xrdp_rdp_parse_client_mcs_data_CS_CORE(self, s); + break; + case 0xc002: /* CS_SECURITY */ + break; + case 0xc003: /* CS_NET */ + break; + case 0xc004: /* CS_CLUSTER */ + break; + default: + g_writeln("xrdp_rdp_parse_client_mcs_data: error unknown " + "header type 0x%4.4x", header_type); + break; + } + s->p = hold_p + length; + s->end = hold_end; + } if (self->client_info.max_bpp > 0) { if (self->client_info.bpp > self->client_info.max_bpp) { + g_writeln("xrdp_rdp_parse_client_mcs_data: client asked for %dbpp " + "connection but configuration is limited to %dbpp", + self->client_info.bpp, self->client_info.max_bpp); self->client_info.bpp = self->client_info.max_bpp; } } + s->p = s->data; + + g_writeln("xrdp_rdp_parse_client_mcs_data: client bpp %d", + self->client_info.bpp); - p->p = p->data; - DEBUG(("client width %d, client height %d bpp %d", - self->client_info.width, self->client_info.height, - self->client_info.bpp)); return 0; }