mirror of https://github.com/neutrinolabs/xrdp
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) */
|
||||
#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
|
||||
|
||||
/* Client Core Data: connectionType (2.2.1.3.2) */
|
||||
|
@ -448,6 +449,7 @@
|
|||
#define RDP_DATA_PDU_LOGON 38
|
||||
#define RDP_DATA_PDU_FONT2 39
|
||||
#define RDP_DATA_PDU_DISCONNECT 47
|
||||
#define PDUTYPE2_MONITOR_LAYOUT_PDU 55
|
||||
|
||||
/* TS_SECURITY_HEADER: flags (2.2.8.1.1.2.1) */
|
||||
/* TODO: to be renamed */
|
||||
|
|
|
@ -437,6 +437,10 @@ int
|
|||
xrdp_rdp_send_data(struct xrdp_rdp *self, struct stream *s,
|
||||
int data_pdu_type);
|
||||
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,
|
||||
int data_pdu_type);
|
||||
int
|
||||
|
|
|
@ -48,6 +48,7 @@ xrdp_caps_send_monitorlayout(struct xrdp_rdp *self)
|
|||
struct stream *s;
|
||||
uint32_t i;
|
||||
struct display_size_description *description;
|
||||
int rv = 0;
|
||||
|
||||
make_stream(s);
|
||||
init_stream(s, 8192);
|
||||
|
@ -74,14 +75,13 @@ xrdp_caps_send_monitorlayout(struct xrdp_rdp *self)
|
|||
|
||||
s_mark_end(s);
|
||||
|
||||
if (xrdp_rdp_send_data(self, s, 0x37) != 0)
|
||||
{
|
||||
free_stream(s);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// [MS-RDPBCGR]
|
||||
// - 2.2.12.1 - ...the pduSource field MUST be set to zero.
|
||||
// - 3.3.5.12.1 - The contents of this PDU SHOULD NOT be compressed
|
||||
rv = xrdp_rdp_send_data_from_channel(self, s,
|
||||
PDUTYPE2_MONITOR_LAYOUT_PDU, 0, 0);
|
||||
free_stream(s);
|
||||
return 0;
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
@ -1337,8 +1337,11 @@ xrdp_caps_send_demand_active(struct xrdp_rdp *self)
|
|||
return 1;
|
||||
}
|
||||
|
||||
/* send Monitor Layout PDU for dual monitor */
|
||||
if (self->client_info.display_sizes.monitorCount > 0 &&
|
||||
/* send Monitor Layout PDU for multi-monitor */
|
||||
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)
|
||||
{
|
||||
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 */
|
||||
int
|
||||
xrdp_rdp_send_data(struct xrdp_rdp *self, struct stream *s,
|
||||
int data_pdu_type)
|
||||
xrdp_rdp_send_data_from_channel(struct xrdp_rdp *self, struct stream *s,
|
||||
int data_pdu_type, int channel_id,
|
||||
int compress)
|
||||
{
|
||||
int len;
|
||||
int ctype;
|
||||
|
@ -614,7 +616,8 @@ xrdp_rdp_send_data(struct xrdp_rdp *self, struct stream *s,
|
|||
clen = len;
|
||||
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;
|
||||
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
|
||||
{
|
||||
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",
|
||||
mppc_enc->protocol_type, mppc_enc->flags);
|
||||
}
|
||||
|
@ -652,11 +656,11 @@ xrdp_rdp_send_data(struct xrdp_rdp *self, struct stream *s,
|
|||
/* TS_SHARECONTROLHEADER */
|
||||
out_uint16_le(s, pdulen); /* totalLength */
|
||||
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 "
|
||||
"totalLength %d, pduType.type %s (%d), pduType.PDUVersion %d, "
|
||||
"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 */
|
||||
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)
|
||||
{
|
||||
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 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 */
|
||||
int
|
||||
|
|
Loading…
Reference in New Issue