summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJay Sorg <jay.sorg@gmail.com>2014-02-16 00:34:56 -0800
committerJay Sorg <jay.sorg@gmail.com>2014-02-16 00:34:56 -0800
commit1d9c773dbfe9ab5ceda85773ed8933d73742a9e6 (patch)
tree5fd7fab93d10f5e5387ce6dc1218b207b4557824
parentc8579c340319d39778ee0a5ce328879ba274862a (diff)
downloadxrdp-proprietary-1d9c773dbfe9ab5ceda85773ed8933d73742a9e6.tar.gz
xrdp-proprietary-1d9c773dbfe9ab5ceda85773ed8933d73742a9e6.zip
libxrdp: improve mcs processing
-rw-r--r--libxrdp/xrdp_rdp.c232
1 files 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;
}