Fix sending of monitor layout PDU
From [MS-RCPBCGR] 3.3.5.12.1:- > ...The contents of this PDU SHOULD NOT be compressed. > > This PDU MUST NOT be sent to a client that has not indicated support for > it by setting the RNS_UD_CS_SUPPORT_MONITOR_LAYOUT_PDU flag (0x0040) > in the earlyCapabilityFlags field of the Client Core Data (section > 2.2.1.3.2). Also, 2.2.12.1 specifies the source channel must be zero. In testing, a compressed monitor layout PDU causes mstsc.exe to exit with a protocol error.
This commit is contained in:
parent
689269dcde
commit
74598d1cc3
@ -74,6 +74,7 @@
|
|||||||
|
|
||||||
/* Client Core Data: earlyCapabilityFlags (2.2.1.3.2) */
|
/* Client Core Data: earlyCapabilityFlags (2.2.1.3.2) */
|
||||||
#define RNS_UD_CS_WANT_32BPP_SESSION 0x0002
|
#define RNS_UD_CS_WANT_32BPP_SESSION 0x0002
|
||||||
|
#define RNS_UD_CS_SUPPORT_MONITOR_LAYOUT_PDU 0x0040
|
||||||
#define RNS_UD_CS_SUPPORT_DYNVC_GFX_PROTOCOL 0x0100
|
#define RNS_UD_CS_SUPPORT_DYNVC_GFX_PROTOCOL 0x0100
|
||||||
|
|
||||||
/* Client Core Data: connectionType (2.2.1.3.2) */
|
/* Client Core Data: connectionType (2.2.1.3.2) */
|
||||||
@ -448,6 +449,7 @@
|
|||||||
#define RDP_DATA_PDU_LOGON 38
|
#define RDP_DATA_PDU_LOGON 38
|
||||||
#define RDP_DATA_PDU_FONT2 39
|
#define RDP_DATA_PDU_FONT2 39
|
||||||
#define RDP_DATA_PDU_DISCONNECT 47
|
#define RDP_DATA_PDU_DISCONNECT 47
|
||||||
|
#define PDUTYPE2_MONITOR_LAYOUT_PDU 55
|
||||||
|
|
||||||
/* TS_SECURITY_HEADER: flags (2.2.8.1.1.2.1) */
|
/* TS_SECURITY_HEADER: flags (2.2.8.1.1.2.1) */
|
||||||
/* TODO: to be renamed */
|
/* TODO: to be renamed */
|
||||||
|
@ -437,6 +437,10 @@ int
|
|||||||
xrdp_rdp_send_data(struct xrdp_rdp *self, struct stream *s,
|
xrdp_rdp_send_data(struct xrdp_rdp *self, struct stream *s,
|
||||||
int data_pdu_type);
|
int data_pdu_type);
|
||||||
int
|
int
|
||||||
|
xrdp_rdp_send_data_from_channel(struct xrdp_rdp *self, struct stream *s,
|
||||||
|
int data_pdu_type, int channel_id,
|
||||||
|
int compress);
|
||||||
|
int
|
||||||
xrdp_rdp_send_fastpath(struct xrdp_rdp *self, struct stream *s,
|
xrdp_rdp_send_fastpath(struct xrdp_rdp *self, struct stream *s,
|
||||||
int data_pdu_type);
|
int data_pdu_type);
|
||||||
int
|
int
|
||||||
|
@ -48,6 +48,7 @@ xrdp_caps_send_monitorlayout(struct xrdp_rdp *self)
|
|||||||
struct stream *s;
|
struct stream *s;
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
struct display_size_description *description;
|
struct display_size_description *description;
|
||||||
|
int rv = 0;
|
||||||
|
|
||||||
make_stream(s);
|
make_stream(s);
|
||||||
init_stream(s, 8192);
|
init_stream(s, 8192);
|
||||||
@ -74,14 +75,13 @@ xrdp_caps_send_monitorlayout(struct xrdp_rdp *self)
|
|||||||
|
|
||||||
s_mark_end(s);
|
s_mark_end(s);
|
||||||
|
|
||||||
if (xrdp_rdp_send_data(self, s, 0x37) != 0)
|
// [MS-RDPBCGR]
|
||||||
{
|
// - 2.2.12.1 - ...the pduSource field MUST be set to zero.
|
||||||
free_stream(s);
|
// - 3.3.5.12.1 - The contents of this PDU SHOULD NOT be compressed
|
||||||
return 1;
|
rv = xrdp_rdp_send_data_from_channel(self, s,
|
||||||
}
|
PDUTYPE2_MONITOR_LAYOUT_PDU, 0, 0);
|
||||||
|
|
||||||
free_stream(s);
|
free_stream(s);
|
||||||
return 0;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
@ -1337,8 +1337,11 @@ xrdp_caps_send_demand_active(struct xrdp_rdp *self)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* send Monitor Layout PDU for dual monitor */
|
/* send Monitor Layout PDU for multi-monitor */
|
||||||
if (self->client_info.display_sizes.monitorCount > 0 &&
|
int early_cap_flags = self->client_info.mcs_early_capability_flags;
|
||||||
|
|
||||||
|
if ((early_cap_flags & RNS_UD_CS_SUPPORT_MONITOR_LAYOUT_PDU) != 0 &&
|
||||||
|
self->client_info.display_sizes.monitorCount > 0 &&
|
||||||
self->client_info.multimon == 1)
|
self->client_info.multimon == 1)
|
||||||
{
|
{
|
||||||
LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_caps_send_demand_active: sending monitor layout pdu");
|
LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_caps_send_demand_active: sending monitor layout pdu");
|
||||||
|
@ -585,11 +585,13 @@ xrdp_rdp_send(struct xrdp_rdp *self, struct stream *s, int pdu_type)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Send a [MS-RDPBCGR] Data PDU with for the given pduType2 with the headers
|
/* Send a [MS-RDPBCGR] Data PDU for the given pduType2 from
|
||||||
|
* the specified source with the headers
|
||||||
added and data compressed */
|
added and data compressed */
|
||||||
int
|
int
|
||||||
xrdp_rdp_send_data(struct xrdp_rdp *self, struct stream *s,
|
xrdp_rdp_send_data_from_channel(struct xrdp_rdp *self, struct stream *s,
|
||||||
int data_pdu_type)
|
int data_pdu_type, int channel_id,
|
||||||
|
int compress)
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
int ctype;
|
int ctype;
|
||||||
@ -614,7 +616,8 @@ xrdp_rdp_send_data(struct xrdp_rdp *self, struct stream *s,
|
|||||||
clen = len;
|
clen = len;
|
||||||
tocomplen = pdulen - 18;
|
tocomplen = pdulen - 18;
|
||||||
|
|
||||||
if (self->client_info.rdp_compression && self->session->up_and_running)
|
if (compress && self->client_info.rdp_compression &&
|
||||||
|
self->session->up_and_running)
|
||||||
{
|
{
|
||||||
mppc_enc = self->mppc_enc;
|
mppc_enc = self->mppc_enc;
|
||||||
if (compress_rdp(mppc_enc, (tui8 *)(s->p + 18), tocomplen))
|
if (compress_rdp(mppc_enc, (tui8 *)(s->p + 18), tocomplen))
|
||||||
@ -643,7 +646,8 @@ xrdp_rdp_send_data(struct xrdp_rdp *self, struct stream *s,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
LOG_DEVEL(LOG_LEVEL_TRACE,
|
LOG_DEVEL(LOG_LEVEL_TRACE,
|
||||||
"xrdp_rdp_send_data: compress_rdp failed, sending "
|
"xrdp_rdp_send_data_from_channel: "
|
||||||
|
"compress_rdp failed, sending "
|
||||||
"uncompressed data. type %d, flags %d",
|
"uncompressed data. type %d, flags %d",
|
||||||
mppc_enc->protocol_type, mppc_enc->flags);
|
mppc_enc->protocol_type, mppc_enc->flags);
|
||||||
}
|
}
|
||||||
@ -652,11 +656,11 @@ xrdp_rdp_send_data(struct xrdp_rdp *self, struct stream *s,
|
|||||||
/* TS_SHARECONTROLHEADER */
|
/* TS_SHARECONTROLHEADER */
|
||||||
out_uint16_le(s, pdulen); /* totalLength */
|
out_uint16_le(s, pdulen); /* totalLength */
|
||||||
out_uint16_le(s, pdutype); /* pduType */
|
out_uint16_le(s, pdutype); /* pduType */
|
||||||
out_uint16_le(s, self->mcs_channel); /* pduSource */
|
out_uint16_le(s, channel_id); /* pduSource */
|
||||||
LOG_DEVEL(LOG_LEVEL_TRACE, "Adding header [MS-RDPBCGR] TS_SHARECONTROLHEADER "
|
LOG_DEVEL(LOG_LEVEL_TRACE, "Adding header [MS-RDPBCGR] TS_SHARECONTROLHEADER "
|
||||||
"totalLength %d, pduType.type %s (%d), pduType.PDUVersion %d, "
|
"totalLength %d, pduType.type %s (%d), pduType.PDUVersion %d, "
|
||||||
"pduSource %d", pdulen, PDUTYPE_TO_STR(pdutype & 0xf),
|
"pduSource %d", pdulen, PDUTYPE_TO_STR(pdutype & 0xf),
|
||||||
pdutype & 0xf, ((pdutype & 0xfff0) >> 4), self->mcs_channel);
|
pdutype & 0xf, ((pdutype & 0xfff0) >> 4), channel_id);
|
||||||
|
|
||||||
/* TS_SHAREDATAHEADER */
|
/* TS_SHAREDATAHEADER */
|
||||||
out_uint32_le(s, self->share_id);
|
out_uint32_le(s, self->share_id);
|
||||||
@ -673,13 +677,26 @@ xrdp_rdp_send_data(struct xrdp_rdp *self, struct stream *s,
|
|||||||
|
|
||||||
if (xrdp_sec_send(self->sec_layer, s, MCS_GLOBAL_CHANNEL) != 0)
|
if (xrdp_sec_send(self->sec_layer, s, MCS_GLOBAL_CHANNEL) != 0)
|
||||||
{
|
{
|
||||||
LOG(LOG_LEVEL_ERROR, "xrdp_rdp_send_data: xrdp_sec_send failed");
|
LOG(LOG_LEVEL_ERROR, "xrdp_rdp_send_data_from_channel: "
|
||||||
|
"xrdp_sec_send failed");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* Send a [MS-RDPBCGR] Data PDU on the MCS channel for the given pduType2
|
||||||
|
* with the headers added and data compressed */
|
||||||
|
int
|
||||||
|
xrdp_rdp_send_data(struct xrdp_rdp *self, struct stream *s,
|
||||||
|
int data_pdu_type)
|
||||||
|
{
|
||||||
|
return xrdp_rdp_send_data_from_channel(self, s, data_pdu_type,
|
||||||
|
self->mcs_channel, 1);
|
||||||
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* returns the fastpath rdp byte count */
|
/* returns the fastpath rdp byte count */
|
||||||
int
|
int
|
||||||
|
Loading…
Reference in New Issue
Block a user