Merge pull request #2310 from matt335672/physical_desktop_size
Parse more physical monitor size information
This commit is contained in:
commit
d43821f11f
@ -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
|
||||||
|
@ -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 */
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user