Merge pull request #2310 from matt335672/physical_desktop_size

Parse more physical monitor size information
This commit is contained in:
matt335672 2022-08-01 08:47:25 +01:00 committed by GitHub
commit d43821f11f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 323 additions and 109 deletions

View File

@ -57,6 +57,7 @@
#define SEC_TAG_CLI_CHANNELS 0xc003 /* CS_CHANNELS? */ #define SEC_TAG_CLI_CHANNELS 0xc003 /* CS_CHANNELS? */
#define SEC_TAG_CLI_4 0xc004 /* CS_CLUSTER? */ #define SEC_TAG_CLI_4 0xc004 /* CS_CLUSTER? */
#define SEC_TAG_CLI_MONITOR 0xc005 /* CS_MONITOR */ #define SEC_TAG_CLI_MONITOR 0xc005 /* CS_MONITOR */
#define SEC_TAG_CLI_MONITOR_EX 0xc008 /* CS_MONITOR_EX */
/* Client Core Data: colorDepth, postBeta2ColorDepth (2.2.1.3.2) */ /* Client Core Data: colorDepth, postBeta2ColorDepth (2.2.1.3.2) */
#define RNS_UD_COLOR_4BPP 0xCA00 #define RNS_UD_COLOR_4BPP 0xCA00

View File

@ -38,7 +38,8 @@ struct monitor_info
int bottom; int bottom;
int flags; int flags;
/* From 2.2.2.2.1 DISPLAYCONTROL_MONITOR_LAYOUT */ /* From [MS-RDPEDISP] 2.2.2.2.1 DISPLAYCONTROL_MONITOR_LAYOUT, or
* [MS-RDPBCGR] 2.2.1.3.9.1 (TS_MONITOR_ATTRIBUTES) */
unsigned int physical_width; unsigned int physical_width;
unsigned int physical_height; unsigned int physical_height;
unsigned int orientation; unsigned int orientation;
@ -205,6 +206,13 @@ struct xrdp_client_info
/* xrdp.override_* values */ /* xrdp.override_* values */
struct xrdp_keyboard_overrides xrdp_keyboard_overrides; struct xrdp_keyboard_overrides xrdp_keyboard_overrides;
/* These values are optionally send over as part of TS_UD_CS_CORE.
* They can be used as a fallback for a single monitor session
* if physical sizes are not available in the monitor-specific
* data */
unsigned int session_physical_width; /* in mm */
unsigned int session_physical_height; /* in mm */
}; };
/* yyyymmdd of last incompatible change to xrdp_client_info */ /* yyyymmdd of last incompatible change to xrdp_client_info */

View File

@ -29,6 +29,7 @@
#include "ms-rdpbcgr.h" #include "ms-rdpbcgr.h"
#define MAX_BITMAP_BUF_SIZE (16 * 1024) /* 16K */ #define MAX_BITMAP_BUF_SIZE (16 * 1024) /* 16K */
#define TS_MONITOR_ATTRIBUTES_SIZE 20 /* [MS-RDPBCGR] 2.2.1.3.9 */
/******************************************************************************/ /******************************************************************************/
struct xrdp_session *EXPORT_CC struct xrdp_session *EXPORT_CC
@ -1764,6 +1765,97 @@ libxrdp_send_session_info(struct xrdp_session *session, const char *data,
return xrdp_rdp_send_session_info(rdp, data, data_bytes); return xrdp_rdp_send_session_info(rdp, data, data_bytes);
} }
/*****************************************************************************/
/*
Sanitise extended monitor attributes
The extended attributes are received from either
[MS-RDPEDISP] 2.2.2.2.1 (DISPLAYCONTROL_MONITOR_LAYOUT), or
[MS-RDPBCGR] 2.2.1.3.9.1 (TS_MONITOR_ATTRIBUTES)
@param monitor_layout struct containing extended attributes
*/
static void
sanitise_extended_monitor_attributes(struct monitor_info *monitor_layout)
{
/* if EITHER physical_width or physical_height are
* out of range, BOTH must be ignored.
*/
if (monitor_layout->physical_width > 10000
|| monitor_layout->physical_width < 10)
{
LOG(LOG_LEVEL_WARNING, "sanitise_extended_monitor_attributes:"
" physical_width is not within valid range."
" Setting physical_width to 0mm,"
" Setting physical_height to 0mm,"
" physical_width was: %d",
monitor_layout->physical_width);
monitor_layout->physical_width = 0;
monitor_layout->physical_height = 0;
}
if (monitor_layout->physical_height > 10000
|| monitor_layout->physical_height < 10)
{
LOG(LOG_LEVEL_WARNING, "sanitise_extended_monitor_attributes:"
" physical_height is not within valid range."
" Setting physical_width to 0mm,"
" Setting physical_height to 0mm,"
" physical_height was: %d",
monitor_layout->physical_height);
monitor_layout->physical_width = 0;
monitor_layout->physical_height = 0;
}
switch (monitor_layout->orientation)
{
case ORIENTATION_LANDSCAPE:
case ORIENTATION_PORTRAIT:
case ORIENTATION_LANDSCAPE_FLIPPED:
case ORIENTATION_PORTRAIT_FLIPPED:
break;
default:
LOG(LOG_LEVEL_WARNING, "sanitise_extended_monitor_attributes:"
" Orientation is not one of %d, %d, %d, or %d."
" Value was %d and ignored and set to default value of LANDSCAPE.",
ORIENTATION_LANDSCAPE,
ORIENTATION_PORTRAIT,
ORIENTATION_LANDSCAPE_FLIPPED,
ORIENTATION_PORTRAIT_FLIPPED,
monitor_layout->orientation);
monitor_layout->orientation = ORIENTATION_LANDSCAPE;
}
int check_desktop_scale_factor
= monitor_layout->desktop_scale_factor < 100
|| monitor_layout->desktop_scale_factor > 500;
if (check_desktop_scale_factor)
{
LOG(LOG_LEVEL_WARNING, "sanitise_extended_monitor_attributes:"
" desktop_scale_factor is not within valid range"
" of [100, 500]. Assuming 100. Value was: %d",
monitor_layout->desktop_scale_factor);
}
int check_device_scale_factor
= monitor_layout->device_scale_factor != 100
&& monitor_layout->device_scale_factor != 140
&& monitor_layout->device_scale_factor != 180;
if (check_device_scale_factor)
{
LOG(LOG_LEVEL_WARNING, "sanitise_extended_monitor_attributes:"
" device_scale_factor a valid value (One of 100, 140, 180)."
" Assuming 100. Value was: %d",
monitor_layout->device_scale_factor);
}
if (check_desktop_scale_factor || check_device_scale_factor)
{
monitor_layout->desktop_scale_factor = 100;
monitor_layout->device_scale_factor = 100;
}
}
/*****************************************************************************/ /*****************************************************************************/
/* /*
Process a [MS-RDPBCGR] TS_UD_CS_MONITOR message. Process a [MS-RDPBCGR] TS_UD_CS_MONITOR message.
@ -1907,87 +1999,11 @@ libxrdp_process_monitor_stream(struct stream *s,
in_uint32_le(s, monitor_layout->physical_width); in_uint32_le(s, monitor_layout->physical_width);
in_uint32_le(s, monitor_layout->physical_height); in_uint32_le(s, monitor_layout->physical_height);
/* Per spec (2.2.2.2.1 DISPLAYCONTROL_MONITOR_LAYOUT),
* if EITHER physical_width or physical_height are
* out of range, BOTH must be ignored.
*/
if (monitor_layout->physical_width > 10000
|| monitor_layout->physical_width < 10)
{
LOG(LOG_LEVEL_WARNING, "libxrdp_process_monitor_stream:"
" physical_width is not within valid range."
" Setting physical_width to 0mm,"
" Setting physical_height to 0mm,"
" physical_width was: %d",
monitor_layout->physical_width);
monitor_layout->physical_width = 0;
monitor_layout->physical_height = 0;
}
if (monitor_layout->physical_height > 10000
|| monitor_layout->physical_height < 10)
{
LOG(LOG_LEVEL_WARNING, "libxrdp_process_monitor_stream:"
" physical_height is not within valid range."
" Setting physical_width to 0mm,"
" Setting physical_height to 0mm,"
" physical_height was: %d",
monitor_layout->physical_height);
monitor_layout->physical_width = 0;
monitor_layout->physical_height = 0;
}
in_uint32_le(s, monitor_layout->orientation); in_uint32_le(s, monitor_layout->orientation);
switch (monitor_layout->orientation)
{
case ORIENTATION_LANDSCAPE:
case ORIENTATION_PORTRAIT:
case ORIENTATION_LANDSCAPE_FLIPPED:
case ORIENTATION_PORTRAIT_FLIPPED:
break;
default:
LOG(LOG_LEVEL_WARNING, "libxrdp_process_monitor_stream:"
" Orientation is not one of %d, %d, %d, or %d."
" Value was %d and ignored and set to default value of LANDSCAPE.",
ORIENTATION_LANDSCAPE,
ORIENTATION_PORTRAIT,
ORIENTATION_LANDSCAPE_FLIPPED,
ORIENTATION_PORTRAIT_FLIPPED,
monitor_layout->orientation);
monitor_layout->orientation = ORIENTATION_LANDSCAPE;
}
in_uint32_le(s, monitor_layout->desktop_scale_factor); in_uint32_le(s, monitor_layout->desktop_scale_factor);
int check_desktop_scale_factor
= monitor_layout->desktop_scale_factor < 100
|| monitor_layout->desktop_scale_factor > 500;
if (check_desktop_scale_factor)
{
LOG(LOG_LEVEL_WARNING, "libxrdp_process_monitor_stream:"
" desktop_scale_factor is not within valid range"
" of [100, 500]. Assuming 100. Value was: %d",
monitor_layout->desktop_scale_factor);
}
in_uint32_le(s, monitor_layout->device_scale_factor); in_uint32_le(s, monitor_layout->device_scale_factor);
int check_device_scale_factor
= monitor_layout->device_scale_factor != 100
&& monitor_layout->device_scale_factor != 140
&& monitor_layout->device_scale_factor != 180;
if (check_device_scale_factor)
{
LOG(LOG_LEVEL_WARNING, "libxrdp_process_monitor_stream:"
" device_scale_factor a valid value (One of 100, 140, 180)."
" Assuming 100. Value was: %d",
monitor_layout->device_scale_factor);
}
if (check_desktop_scale_factor || check_device_scale_factor) sanitise_extended_monitor_attributes(monitor_layout);
{
monitor_layout->desktop_scale_factor = 100;
monitor_layout->device_scale_factor = 100;
}
/* /*
* 2.2.2.2.1 DISPLAYCONTROL_MONITOR_LAYOUT * 2.2.2.2.1 DISPLAYCONTROL_MONITOR_LAYOUT
@ -2137,5 +2153,108 @@ libxrdp_process_monitor_stream(struct stream *s,
monitor_layout->bottom = monitor_layout->bottom =
monitor_layout->bottom - all_monitors_encompassing_bounds.top; monitor_layout->bottom - all_monitors_encompassing_bounds.top;
} }
return 0;
}
/*****************************************************************************/
int
libxrdp_process_monitor_ex_stream(struct stream *s,
struct display_size_description *description)
{
uint32_t num_monitor;
uint32_t monitor_index;
uint32_t attribute_size;
struct monitor_info *monitor_layout;
LOG_DEVEL(LOG_LEVEL_TRACE, "libxrdp_process_monitor_ex_stream:");
if (description == NULL)
{
LOG_DEVEL(LOG_LEVEL_ERROR, "libxrdp_process_monitor_ex_stream: "
"description was null. "
" Valid pointer to allocated description expected.");
return SEC_PROCESS_MONITORS_ERR;
}
if (!s_check_rem_and_log(s, 4,
"libxrdp_process_monitor_ex_stream:"
" Parsing [MS-RDPBCGR] TS_UD_CS_MONITOR_EX"))
{
return SEC_PROCESS_MONITORS_ERR;
}
in_uint32_le(s, attribute_size);
if (attribute_size != TS_MONITOR_ATTRIBUTES_SIZE)
{
LOG(LOG_LEVEL_ERROR,
"libxrdp_process_monitor_ex_stream: [MS-RDPBCGR] Protocol"
" error: TS_UD_CS_MONITOR_EX monitorAttributeSize"
" MUST be %d, received: %d",
TS_MONITOR_ATTRIBUTES_SIZE, attribute_size);
return SEC_PROCESS_MONITORS_ERR;
}
in_uint32_le(s, num_monitor);
LOG(LOG_LEVEL_DEBUG, "libxrdp_process_monitor_ex_stream:"
" The number of monitors received is: %d",
num_monitor);
if (num_monitor != description->monitorCount)
{
LOG(LOG_LEVEL_ERROR,
"libxrdp_process_monitor_ex_stream: [MS-RDPBCGR] Protocol"
" error: TS_UD_CS_MONITOR monitorCount"
" MUST be %d, received: %d",
description->monitorCount, num_monitor);
return SEC_PROCESS_MONITORS_ERR;
}
for (monitor_index = 0; monitor_index < num_monitor; ++monitor_index)
{
if (!s_check_rem_and_log(s, attribute_size,
"libxrdp_process_monitor_ex_stream:"
" Parsing TS_UD_CS_MONITOR_EX"))
{
return SEC_PROCESS_MONITORS_ERR;
}
monitor_layout = description->minfo + monitor_index;
in_uint32_le(s, monitor_layout->physical_width);
in_uint32_le(s, monitor_layout->physical_height);
in_uint32_le(s, monitor_layout->orientation);
in_uint32_le(s, monitor_layout->desktop_scale_factor);
in_uint32_le(s, monitor_layout->device_scale_factor);
sanitise_extended_monitor_attributes(monitor_layout);
LOG_DEVEL(LOG_LEVEL_INFO, "libxrdp_process_monitor_ex_stream:"
" Received [MS-RDPBCGR] 2.2.1.3.9.1 "
" TS_MONITOR_ATTRIBUTES"
" Index: %d, PhysicalWidth %d, PhysicalHeight %d,"
" Orientation %d, DesktopScaleFactor %d,"
" DeviceScaleFactor %d",
monitor_index,
monitor_layout->physical_width,
monitor_layout->physical_height,
monitor_layout->orientation,
monitor_layout->desktop_scale_factor,
monitor_layout->device_scale_factor);
}
/* Update non negative monitor info values */
const struct monitor_info *src = description->minfo;
struct monitor_info *dst = description->minfo_wm;
for (monitor_index = 0; monitor_index < num_monitor; ++monitor_index)
{
dst->physical_width = src->physical_width;
dst->physical_height = src->physical_height;
dst->orientation = src->orientation;
dst->desktop_scale_factor = src->desktop_scale_factor;
dst->device_scale_factor = src->device_scale_factor;
++src;
++dst;
}
return 0; return 0;
} }

View File

@ -364,9 +364,10 @@ xrdp_mcs_disconnect(struct xrdp_mcs *self);
/* xrdp_sec.c */ /* xrdp_sec.c */
/* /*
These are error return codes for both: These are error return codes for:-
1. xrdp_sec_process_mcs_data_monitors 1. xrdp_sec_process_mcs_data_monitors
2. libxrdp_process_monitor_stream 2. libxrdp_process_monitor_stream
3. libxrdp_process_monitor_ex_stream
To clarify any reason for a non-zero response code. To clarify any reason for a non-zero response code.
*/ */
#define SEC_PROCESS_MONITORS_ERR 1 #define SEC_PROCESS_MONITORS_ERR 1

View File

@ -324,4 +324,19 @@ int EXPORT_CC
libxrdp_process_monitor_stream(struct stream *s, struct display_size_description *description, libxrdp_process_monitor_stream(struct stream *s, struct display_size_description *description,
int full_parameters); int full_parameters);
/**
* Processes a stream that is based on [MS-RDPBCGR] 2.2.1.3.9 Client
* Monitor Extended Data (TS_UD_CS_MONITOR_EX)
*
* Data is stored in a struct which has already been read by
* libxrdp_process_monitor_stream() withj full_parameters set to 0.
*
* @param s Stream to read data from. Stream is read up to monitorAttributeSize
* @param description Result of reading TS_UD_CS_MONITOR PDU
* @return 0 if the data is processed, non-zero if there is an error.
*/
int EXPORT_CC
libxrdp_process_monitor_ex_stream(struct stream *s,
struct display_size_description *description);
#endif #endif

View File

@ -1953,19 +1953,23 @@ xrdp_sec_process_mcs_data_CS_CORE(struct xrdp_sec *self, struct stream *s)
char clientName[INFO_CLIENT_NAME_BYTES / 2] = { '\0' }; char clientName[INFO_CLIENT_NAME_BYTES / 2] = { '\0' };
UNUSED_VAR(version); UNUSED_VAR(version);
struct xrdp_client_info *client_info = &self->rdp_layer->client_info;
/* Clear physical sizes. These are optional and may not be read later */
client_info->session_physical_width = 0;
client_info->session_physical_height = 0;
/* TS_UD_CS_CORE requiered fields */ /* TS_UD_CS_CORE required fields */
in_uint32_le(s, version); in_uint32_le(s, version);
in_uint16_le(s, self->rdp_layer->client_info.display_sizes.session_width); in_uint16_le(s, client_info->display_sizes.session_width);
in_uint16_le(s, self->rdp_layer->client_info.display_sizes.session_height); in_uint16_le(s, client_info->display_sizes.session_height);
in_uint16_le(s, colorDepth); in_uint16_le(s, colorDepth);
switch (colorDepth) switch (colorDepth)
{ {
case RNS_UD_COLOR_4BPP: case RNS_UD_COLOR_4BPP:
self->rdp_layer->client_info.bpp = 4; client_info->bpp = 4;
break; break;
case RNS_UD_COLOR_8BPP: case RNS_UD_COLOR_8BPP:
self->rdp_layer->client_info.bpp = 8; client_info->bpp = 8;
break; break;
} }
in_uint8s(s, 2); /* SASSequence */ in_uint8s(s, 2); /* SASSequence */
@ -1985,8 +1989,8 @@ xrdp_sec_process_mcs_data_CS_CORE(struct xrdp_sec *self, struct stream *s)
"keyboardSubType (ignored), keyboardFunctionKey (ignored), " "keyboardSubType (ignored), keyboardFunctionKey (ignored), "
"imeFileName (ignored)", "imeFileName (ignored)",
version, version,
self->rdp_layer->client_info.display_sizes.session_width, client_info->display_sizes.session_width,
self->rdp_layer->client_info.display_sizes.session_height, client_info->display_sizes.session_height,
(colorDepth == 0xca00 ? "RNS_UD_COLOR_4BPP" : (colorDepth == 0xca00 ? "RNS_UD_COLOR_4BPP" :
colorDepth == 0xca01 ? "RNS_UD_COLOR_8BPP" : "unknown"), colorDepth == 0xca01 ? "RNS_UD_COLOR_8BPP" : "unknown"),
clientName); clientName);
@ -2005,19 +2009,19 @@ xrdp_sec_process_mcs_data_CS_CORE(struct xrdp_sec *self, struct stream *s)
switch (postBeta2ColorDepth) switch (postBeta2ColorDepth)
{ {
case RNS_UD_COLOR_4BPP: case RNS_UD_COLOR_4BPP:
self->rdp_layer->client_info.bpp = 4; client_info->bpp = 4;
break; break;
case RNS_UD_COLOR_8BPP : case RNS_UD_COLOR_8BPP :
self->rdp_layer->client_info.bpp = 8; client_info->bpp = 8;
break; break;
case RNS_UD_COLOR_16BPP_555: case RNS_UD_COLOR_16BPP_555:
self->rdp_layer->client_info.bpp = 15; client_info->bpp = 15;
break; break;
case RNS_UD_COLOR_16BPP_565: case RNS_UD_COLOR_16BPP_565:
self->rdp_layer->client_info.bpp = 16; client_info->bpp = 16;
break; break;
case RNS_UD_COLOR_24BPP: case RNS_UD_COLOR_24BPP:
self->rdp_layer->client_info.bpp = 24; client_info->bpp = 24;
break; break;
} }
if (!s_check_rem(s, 2)) if (!s_check_rem(s, 2))
@ -2049,7 +2053,7 @@ xrdp_sec_process_mcs_data_CS_CORE(struct xrdp_sec *self, struct stream *s)
highColorDepth == 0x0010 ? "HIGH_COLOR_16BPP" : highColorDepth == 0x0010 ? "HIGH_COLOR_16BPP" :
highColorDepth == 0x0018 ? "HIGH_COLOR_24BPP" : highColorDepth == 0x0018 ? "HIGH_COLOR_24BPP" :
"unknown"); "unknown");
self->rdp_layer->client_info.bpp = highColorDepth; client_info->bpp = highColorDepth;
if (!s_check_rem(s, 2)) if (!s_check_rem(s, 2))
{ {
@ -2069,13 +2073,13 @@ xrdp_sec_process_mcs_data_CS_CORE(struct xrdp_sec *self, struct stream *s)
return 0; return 0;
} }
in_uint16_le(s, earlyCapabilityFlags); in_uint16_le(s, earlyCapabilityFlags);
self->rdp_layer->client_info.mcs_early_capability_flags = earlyCapabilityFlags; client_info->mcs_early_capability_flags = earlyCapabilityFlags;
LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] TS_UD_CS_CORE " LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] TS_UD_CS_CORE "
"<Optional Field> earlyCapabilityFlags 0x%4.4x", "<Optional Field> earlyCapabilityFlags 0x%4.4x",
earlyCapabilityFlags); earlyCapabilityFlags);
if ((earlyCapabilityFlags & 0x0002) && (supportedColorDepths & 0x0008)) if ((earlyCapabilityFlags & 0x0002) && (supportedColorDepths & 0x0008))
{ {
self->rdp_layer->client_info.bpp = 32; client_info->bpp = 32;
} }
if (!s_check_rem(s, 64)) if (!s_check_rem(s, 64))
@ -2090,10 +2094,10 @@ xrdp_sec_process_mcs_data_CS_CORE(struct xrdp_sec *self, struct stream *s)
{ {
return 0; return 0;
} }
in_uint8(s, self->rdp_layer->client_info.mcs_connection_type); /* connectionType */ in_uint8(s, client_info->mcs_connection_type); /* connectionType */
LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] TS_UD_CS_CORE " LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] TS_UD_CS_CORE "
"<Optional Field> connectionType 0x%2.2x", "<Optional Field> connectionType 0x%2.2x",
self->rdp_layer->client_info.mcs_connection_type); client_info->mcs_connection_type);
if (!s_check_rem(s, 1)) if (!s_check_rem(s, 1))
{ {
@ -2111,22 +2115,43 @@ xrdp_sec_process_mcs_data_CS_CORE(struct xrdp_sec *self, struct stream *s)
LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] TS_UD_CS_CORE " LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] TS_UD_CS_CORE "
"<Optional Field> serverSelectedProtocol (ignored)"); "<Optional Field> serverSelectedProtocol (ignored)");
/*
* Non-zero values for the desktop physical width and height values
* are only sent if the client has a single monitor. For multiple
* monitors, the physical size of each monitor is sent in the
* TS_UD_CS_MONITOR_EX PDU */
if (!s_check_rem(s, 4)) if (!s_check_rem(s, 4))
{ {
return 0; return 0;
} }
in_uint8s(s, 4); /* desktopPhysicalWidth */ in_uint32_le(s, client_info->session_physical_width);
LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] TS_UD_CS_CORE " LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] TS_UD_CS_CORE "
"<Optional Field> desktopPhysicalWidth (ignored)"); "<Optional Field> desktopPhysicalWidth %u",
client_info->session_physical_width);
if (!s_check_rem(s, 4)) if (!s_check_rem(s, 4))
{ {
client_info->session_physical_width = 0;
return 0; return 0;
} }
in_uint8s(s, 4); /* desktopPhysicalHeight */ in_uint32_le(s, client_info->session_physical_height);
LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] TS_UD_CS_CORE " LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] TS_UD_CS_CORE "
"<Optional Field> desktopPhysicalHeight (ignored)"); "<Optional Field> desktopPhysicalHeight %u",
client_info->session_physical_height);
/* MS-RDPBCGR 2.2.1.3.2 */
if (client_info->session_physical_width < 10 ||
client_info->session_physical_width > 10000 ||
client_info->session_physical_height < 10 ||
client_info->session_physical_height > 10000)
{
LOG(LOG_LEVEL_WARNING,
"Physical desktop dimensions (%ux%u) are invalid",
client_info->session_physical_width,
client_info->session_physical_height);
client_info->session_physical_width = 0;
client_info->session_physical_height = 0;
}
if (!s_check_rem(s, 2)) if (!s_check_rem(s, 2))
{ {
return 0; return 0;
@ -2407,6 +2432,45 @@ xrdp_sec_process_mcs_data_monitors(struct xrdp_sec *self, struct stream *s)
return error; return error;
} }
/*****************************************************************************/
/* Process a [MS-RDPBCGR] TS_UD_CS_MONITOR_EX message.
reads the client monitor's extended data */
int
xrdp_sec_process_mcs_data_monitors_ex(struct xrdp_sec *self, struct stream *s)
{
int flags;
struct xrdp_client_info *client_info = &(self->rdp_layer->client_info);
LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_sec_process_mcs_data_monitors_ex:");
/* this is an option set in xrdp.ini */
if (client_info->multimon != 1) /* are multi-monitors allowed ? */
{
/* This should already be logged in
xrdp_sec_process_mcs_data_monitors() */
return 0;
}
if (!s_check_rem_and_log(s, 4,
"xrdp_sec_process_mcs_data_monitors_ex:"
" Parsing [MS-RDPBCGR] TS_UD_CS_MONITOR_EX"))
{
return SEC_PROCESS_MONITORS_ERR;
}
in_uint32_le(s, flags); /* flags */
//verify flags - must be 0x0
if (flags != 0)
{
LOG(LOG_LEVEL_ERROR,
"xrdp_sec_process_mcs_data_monitors_ex: [MS-RDPBCGR]"
" Protocol error: TS_UD_CS_MONITOR_EX flags MUST be zero,"
" received: 0x%8.8x", flags);
return SEC_PROCESS_MONITORS_ERR;
}
return libxrdp_process_monitor_ex_stream(s, &client_info->display_sizes);
}
/*****************************************************************************/ /*****************************************************************************/
/* Process a Client MCS Connect Initial PDU with GCC Conference Create Request. /* Process a Client MCS Connect Initial PDU with GCC Conference Create Request.
process client mcs data, we need some things in here to create the server process client mcs data, we need some things in here to create the server
@ -2418,6 +2482,7 @@ xrdp_sec_process_mcs_data(struct xrdp_sec *self)
char *hold_p = (char *)NULL; char *hold_p = (char *)NULL;
int tag = 0; int tag = 0;
int size = 0; int size = 0;
struct xrdp_client_info *client_info = &self->rdp_layer->client_info;
s = &(self->client_mcs_data); s = &(self->client_mcs_data);
/* set p to beginning */ /* set p to beginning */
@ -2486,8 +2551,15 @@ xrdp_sec_process_mcs_data(struct xrdp_sec *self)
return 1; return 1;
} }
break; break;
case SEC_TAG_CLI_MONITOR_EX: /* CS_MONITOR_EX 0xC008 */
if (xrdp_sec_process_mcs_data_monitors_ex(self, s) != 0)
{
LOG(LOG_LEVEL_ERROR,
"Processing [MS-RDPBCGR] TS_UD_CS_MONITOR_EX failed");
return 1;
}
break;
/* CS_MCS_MSGCHANNEL 0xC006 /* CS_MCS_MSGCHANNEL 0xC006
CS_MONITOR_EX 0xC008
CS_MULTITRANSPORT 0xC00A CS_MULTITRANSPORT 0xC00A
SC_CORE 0x0C01 SC_CORE 0x0C01
SC_SECURITY 0x0C02 SC_SECURITY 0x0C02
@ -2504,19 +2576,17 @@ xrdp_sec_process_mcs_data(struct xrdp_sec *self)
s->p = hold_p + size; s->p = hold_p + size;
} }
if (self->rdp_layer->client_info.max_bpp > 0) if (client_info->max_bpp > 0)
{ {
if (self->rdp_layer->client_info.bpp > if (client_info->bpp > client_info->max_bpp)
self->rdp_layer->client_info.max_bpp)
{ {
LOG(LOG_LEVEL_WARNING, "Client requested %d bpp color depth, " LOG(LOG_LEVEL_WARNING, "Client requested %d bpp color depth, "
"but the server configuration is limited to %d bpp. " "but the server configuration is limited to %d bpp. "
"Downgrading the color depth to %d bits-per-pixel.", "Downgrading the color depth to %d bits-per-pixel.",
self->rdp_layer->client_info.bpp, client_info->bpp,
self->rdp_layer->client_info.max_bpp, client_info->max_bpp,
self->rdp_layer->client_info.max_bpp); client_info->max_bpp);
self->rdp_layer->client_info.bpp = client_info->bpp = client_info->max_bpp;
self->rdp_layer->client_info.max_bpp;
} }
} }