diff --git a/common/ms-rdpbcgr.h b/common/ms-rdpbcgr.h index 6e39053543..11d50bdde6 100644 --- a/common/ms-rdpbcgr.h +++ b/common/ms-rdpbcgr.h @@ -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" diff --git a/libxrdp/xrdp_sec.c b/libxrdp/xrdp_sec.c index bc3551fd5d..f2d1a4d4ee 100644 --- a/libxrdp/xrdp_sec.c +++ b/libxrdp/xrdp_sec.c @@ -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; } diff --git a/neutrinordp/xrdp-neutrinordp.c b/neutrinordp/xrdp-neutrinordp.c index 859b29b586..1d8ad8bbd0 100644 --- a/neutrinordp/xrdp-neutrinordp.c +++ b/neutrinordp/xrdp-neutrinordp.c @@ -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:"); @@ -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); @@ -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;