Send MS-compatible user channel

The Windows 10 RDS sets the user channel ID to be one more than the
ID of the last allocated static virtual channel. Currently we set it to
1002 (0x03ea) which is allocated to the server channel. This change
makes xrdp emulate RDS more closely.
This commit is contained in:
matt335672 2022-05-12 16:10:53 +01:00
parent 7eb44bd54c
commit 28da2045d9
2 changed files with 27 additions and 9 deletions

View File

@ -109,7 +109,7 @@ xrdp_mcs_send_cjcf(struct xrdp_mcs *self, int userid, int chanid)
out_uint16_be(s, chanid); /* channelId (OPTIONAL) */
s_mark_end(s);
LOG_DEVEL(LOG_LEVEL_TRACE, "Sening [ITU-T T.125] ChannelJoinConfirm "
LOG_DEVEL(LOG_LEVEL_TRACE, "Sending [ITU-T T.125] ChannelJoinConfirm "
"result SUCCESS, initiator %d, requested %d, "
"channelId %d", userid, chanid, chanid);
if (xrdp_iso_send(self->iso_layer, s) != 0)
@ -714,12 +714,11 @@ xrdp_mcs_send_aucf(struct xrdp_mcs *self)
*
* returns error */
static int
xrdp_mcs_recv_cjrq(struct xrdp_mcs *self)
xrdp_mcs_recv_cjrq(struct xrdp_mcs *self, int *channel_id)
{
int opcode;
struct stream *s;
int initiator;
int channel_id;
s = libxrdp_force_read(self->iso_layer->trans);
if (s == 0)
@ -756,7 +755,7 @@ xrdp_mcs_recv_cjrq(struct xrdp_mcs *self)
}
in_uint16_be(s, initiator);
in_uint16_be(s, channel_id);
in_uint16_be(s, *channel_id);
/*
* [MS-RDPBCGR] 2.2.1.8 says that the mcsAUrq field is 5 bytes (which have
@ -776,7 +775,7 @@ xrdp_mcs_recv_cjrq(struct xrdp_mcs *self)
LOG_DEVEL(LOG_LEVEL_TRACE, "Received [ITU-T T.125] ChannelJoinRequest "
"initiator %d, channelId %d, "
"nonStandard (%s)",
initiator, channel_id,
initiator, *channel_id,
(opcode & 2) ? "present" : "not present");
if (!s_check_end_and_log(s, "MCS protocol error [ITU-T T.125] ChannelJoinRequest"))
@ -1237,18 +1236,22 @@ xrdp_mcs_incoming(struct xrdp_mcs *self)
return 1;
}
/*
* Expect a channel join request PDU for each of the static virtual channels, plus
* the user channel (self->chanid) and the I/O channel (MCS_GLOBAL_CHANNEL)
*/
for (index = 0; index < self->channel_list->count + 2; index++)
{
int channel_id;
LOG(LOG_LEVEL_DEBUG, "[MCS Connection Sequence] receive channel join request");
if (xrdp_mcs_recv_cjrq(self) != 0)
if (xrdp_mcs_recv_cjrq(self, &channel_id) != 0)
{
LOG(LOG_LEVEL_ERROR, "[MCS Connection Sequence] receive channel join request failed");
return 1;
}
LOG(LOG_LEVEL_DEBUG, "[MCS Connection Sequence] send channel join confirm");
if (xrdp_mcs_send_cjcf(self, self->userid,
self->userid + MCS_USERCHANNEL_BASE + index) != 0)
if (xrdp_mcs_send_cjcf(self, self->userid, channel_id) != 0)
{
LOG(LOG_LEVEL_ERROR, "[MCS Connection Sequence] send channel join confirm failed");
return 1;

View File

@ -2267,6 +2267,7 @@ xrdp_sec_process_mcs_data_channels(struct xrdp_sec *self, struct stream *s)
int index;
struct xrdp_client_info *client_info;
struct mcs_channel_item *channel_item;
int next_mcs_channel_id;
client_info = &(self->rdp_layer->client_info);
/* this is an option set in xrdp.ini */
@ -2288,6 +2289,13 @@ xrdp_sec_process_mcs_data_channels(struct xrdp_sec *self, struct stream *s)
"max 31, received %d", num_channels);
return 1;
}
/* GOTCHA: When adding a channel the MCS channel ID is set to
* MCS_GLOBAL_CHANNEL + (index + 1). This is assumed by
* xrdp_channel_process(), when mapping an incoming PDU into an
* entry in this array */
next_mcs_channel_id = MCS_GLOBAL_CHANNEL + 1;
for (index = 0; index < num_channels; index++)
{
channel_item = g_new0(struct mcs_channel_item, 1);
@ -2304,7 +2312,7 @@ xrdp_sec_process_mcs_data_channels(struct xrdp_sec *self, struct stream *s)
LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] "
"TS_UD_CS_NET.CHANNEL_DEF %d, name %s, options 0x%8.8x",
index, channel_item->name, channel_item->flags);
channel_item->chanid = MCS_GLOBAL_CHANNEL + (index + 1);
channel_item->chanid = next_mcs_channel_id++;
list_add_item(self->mcs_layer->channel_list,
(intptr_t) channel_item);
LOG(LOG_LEVEL_DEBUG,
@ -2322,6 +2330,13 @@ xrdp_sec_process_mcs_data_channels(struct xrdp_sec *self, struct stream *s)
g_free(channel_item);
}
}
/* Set the user channel as well */
self->mcs_layer->chanid = next_mcs_channel_id++;
self->mcs_layer->userid = self->mcs_layer->chanid - MCS_USERCHANNEL_BASE;
LOG_DEVEL(LOG_LEVEL_DEBUG, "MCS user is %d, channel id is %d",
self->mcs_layer->userid, self->mcs_layer->chanid);
return 0;
}