From 28da2045d9d7dca741fb0a5cfad12fe244f370d4 Mon Sep 17 00:00:00 2001 From: matt335672 <30179339+matt335672@users.noreply.github.com> Date: Thu, 12 May 2022 16:10:53 +0100 Subject: [PATCH] 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. --- libxrdp/xrdp_mcs.c | 19 +++++++++++-------- libxrdp/xrdp_sec.c | 17 ++++++++++++++++- 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/libxrdp/xrdp_mcs.c b/libxrdp/xrdp_mcs.c index c5d7b33e..f90a7f30 100644 --- a/libxrdp/xrdp_mcs.c +++ b/libxrdp/xrdp_mcs.c @@ -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; diff --git a/libxrdp/xrdp_sec.c b/libxrdp/xrdp_sec.c index 885b5a3d..1795dcff 100644 --- a/libxrdp/xrdp_sec.c +++ b/libxrdp/xrdp_sec.c @@ -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; }