Skip to content

Commit

Permalink
Don't pass drdynvc to neutrinoRDP
Browse files Browse the repository at this point in the history
Since v0.9.9, xrdp has assumed that the "drdynvc" static virtual
channel is available for its exclusive use. With GFX support, it
is necessary to codify this to prevent this sequence of operations:-

- NeutrinoRDP target sends DVC Capabilities Request PDU
- target responds wih DVC Capabilities Response PDU
- xrdp processes this, starting the GFX virtual channel again

In the future, if NeutrinoRDP requires access to virtual channels,
data may somehow need to be passed through to the target while being
parsed and handled appropriately within xrdp.
  • Loading branch information
matt335672 authored and Nexarian committed Jan 29, 2024
1 parent 8cdec40 commit 7277860
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 15 deletions.
6 changes: 5 additions & 1 deletion common/ms-rdpbcgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,15 @@
#define CONNECTION_TYPE_LAN 0x06
#define CONNECTION_TYPE_AUTODETECT 0x07

/* Channel definition structure CHANNEL_DEF (2.2.1.3.4.1) */
/* TS_UD_CS_NET (2.2.1.3.4) */
/* This isn't explicitly named in MS-RDPBCGR */
#define MAX_STATIC_CHANNELS 31

/* Channel definition structure CHANNEL_DEF (2.2.1.3.4.1) */
#define CHANNEL_NAME_LEN 7
/* These names are also not explicitly defined in MS-RDPBCGR */
#define CLIPRDR_SVC_CHANNEL_NAME "cliprdr"
#define DRDYNVC_SVC_CHANNEL_NAME "drdynvc"
#define RAIL_SVC_CHANNEL_NAME "rail"
#define RDPSND_SVC_CHANNEL_NAME "rdpsnd"
#define RDPDR_SVC_CHANNEL_NAME "rdpdr"
Expand Down
4 changes: 2 additions & 2 deletions libxrdp/xrdp_sec.c
Original file line number Diff line number Diff line change
Expand Up @@ -2388,10 +2388,10 @@ xrdp_sec_process_mcs_data_channels(struct xrdp_sec *self, struct stream *s)
in_uint32_le(s, num_channels);
LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] TS_UD_CS_NET "
"channelCount %d", num_channels);
if (num_channels > 31)
if (num_channels > MAX_STATIC_CHANNELS)
{
LOG(LOG_LEVEL_ERROR, "[MS-RDPBCGR] Protocol error: too many channels requested. "
"max 31, received %d", num_channels);
"max %d, received %d", MAX_STATIC_CHANNELS, num_channels);
return 1;
}

Expand Down
37 changes: 25 additions & 12 deletions neutrinordp/xrdp-neutrinordp.c
Original file line number Diff line number Diff line change
Expand Up @@ -1779,8 +1779,10 @@ lfreerdp_pre_connect(freerdp *instance)
int index;
int error;
int num_chans;
int target_chan;
int ch_flags;
char ch_name[256];
const char *ch_names[MAX_STATIC_CHANNELS];
char *dst_ch_name;

LOG_DEVEL(LOG_LEVEL_INFO, "lfreerdp_pre_connect:");
Expand All @@ -1794,6 +1796,7 @@ lfreerdp_pre_connect(freerdp *instance)
num_chans = 0;
}

target_chan = 0;
for (index = 0 ; index < num_chans; ++index)
{
error = mod->server_query_channel(mod, index, ch_name, &ch_flags);
Expand All @@ -1802,21 +1805,31 @@ lfreerdp_pre_connect(freerdp *instance)
LOG_DEVEL(LOG_LEVEL_DEBUG, "lfreerdp_pre_connect: "
"got channel [%s], id [%d], flags [0x%8.8x]",
ch_name, index, ch_flags);
dst_ch_name = instance->settings->channels[index].name;
g_memset(dst_ch_name, 0, 8);
g_snprintf(dst_ch_name, 8, "%s", ch_name);
instance->settings->channels[index].options = ch_flags;
}
else
{
LOG(LOG_LEVEL_ERROR, "lfreerdp_pre_connect: "
"Expected %d channels, got %d",
num_chans, index);
num_chans = index;

if (g_strcmp(ch_name, DRDYNVC_SVC_CHANNEL_NAME) == 0)
{
/* xrdp currently reserves dynamic channels for its
* exclusive use (e.g. for GFX support) */
LOG(LOG_LEVEL_INFO, "Channel '%s' not passed to module",
ch_name);
}
else if (target_chan < MAX_STATIC_CHANNELS)
{
dst_ch_name = instance->settings->channels[target_chan].name;
ch_names[target_chan] = dst_ch_name;
g_memset(dst_ch_name, 0, CHANNEL_NAME_LEN + 1);
g_snprintf(dst_ch_name, CHANNEL_NAME_LEN + 1, "%s", ch_name);
instance->settings->channels[target_chan].options = ch_flags;
++target_chan;
}
}
}

instance->settings->num_channels = num_chans;
g_strnjoin(ch_name, sizeof(ch_name), ",", ch_names, target_chan);
LOG(LOG_LEVEL_INFO, "Static channels (from %d) passed to module : %s",
num_chans, ch_name);

instance->settings->num_channels = target_chan;

instance->settings->offscreen_bitmap_cache = 0;
instance->settings->draw_nine_grid = 0;
Expand Down

0 comments on commit 7277860

Please sign in to comment.