From f831ba14e77c7fb78336424a166fdc290b736ef1 Mon Sep 17 00:00:00 2001 From: matt335672 <30179339+matt335672@users.noreply.github.com> Date: Fri, 27 Sep 2024 12:14:21 +0100 Subject: [PATCH] Skip channel join request processing if requested This commit skips channel join request/confirm processing if the client requests it. This only really affects the TLS loop where we need to agree on the exact number of channel requests and confirmations before we ask the TLS library to negotiate a secure connection. --- common/ms-rdpbcgr.h | 1 + libxrdp/xrdp_mcs.c | 66 ++++++++++++++++++++++++++++++--------------- 2 files changed, 45 insertions(+), 22 deletions(-) diff --git a/common/ms-rdpbcgr.h b/common/ms-rdpbcgr.h index eb6ea8691..5e85a5a17 100644 --- a/common/ms-rdpbcgr.h +++ b/common/ms-rdpbcgr.h @@ -80,6 +80,7 @@ #define RNS_UD_CS_WANT_32BPP_SESSION 0x0002 #define RNS_UD_CS_SUPPORT_MONITOR_LAYOUT_PDU 0x0040 #define RNS_UD_CS_SUPPORT_DYNVC_GFX_PROTOCOL 0x0100 +#define RNS_UD_CS_SUPPORT_SKIP_CHANNELJOIN 0x0800 /* Client Core Data: connectionType (2.2.1.3.2) */ #define CONNECTION_TYPE_MODEM 0x01 diff --git a/libxrdp/xrdp_mcs.c b/libxrdp/xrdp_mcs.c index b8fb25c70..ec695341f 100644 --- a/libxrdp/xrdp_mcs.c +++ b/libxrdp/xrdp_mcs.c @@ -1266,31 +1266,46 @@ handle_non_tls_client_channel_join_requests(struct xrdp_mcs *self, static int handle_tls_client_channel_join_requests(struct xrdp_mcs *self) { - int index; int rv = 0; - static const char *tag = "[MCS Connection Sequence (TLS)]"; - /* - * 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, "%s receive channel join request", tag); - if (xrdp_mcs_recv_cjrq(self, &channel_id) != 0) - { - LOG(LOG_LEVEL_ERROR, "%s receive channel join request failed", tag); - rv = 1; - break; - } + int capability_flags = + self->sec_layer->rdp_layer->client_info.mcs_early_capability_flags; - LOG(LOG_LEVEL_DEBUG, "%s send channel join confirm", tag); - if (xrdp_mcs_send_cjcf(self, self->userid, channel_id) != 0) + if ((capability_flags & RNS_UD_CS_SUPPORT_SKIP_CHANNELJOIN) != 0) + { + /* Client has requested to skip channel join request/confirm PDUs. + * Since the server always supports this, there SHOULD be nothing to + * do */ + LOG(LOG_LEVEL_INFO, + "%s : Skipping channel join request/confirm PDUs", tag); + } + else + { + int index; + /* + * 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++) { - LOG(LOG_LEVEL_ERROR, "%s send channel join confirm failed", tag); - rv = 1; - break; + int channel_id; + LOG(LOG_LEVEL_DEBUG, "%s receive channel join request", tag); + if (xrdp_mcs_recv_cjrq(self, &channel_id) != 0) + { + LOG(LOG_LEVEL_ERROR, + "%s receive channel join request failed", tag); + rv = 1; + break; + } + + LOG(LOG_LEVEL_DEBUG, "%s send channel join confirm", tag); + if (xrdp_mcs_send_cjcf(self, self->userid, channel_id) != 0) + { + LOG(LOG_LEVEL_ERROR, + "%s send channel join confirm failed", tag); + rv = 1; + break; + } } } @@ -1370,7 +1385,14 @@ xrdp_mcs_incoming(struct xrdp_mcs *self) else { /* Non-TLS connection - channel joins handled in MCS PDU - * processing loop */ + * processing loop + * + * We set this flag even if we've set + * RNS_UD_SC_SKIP_CHANNELJOIN_SUPPORTED and the client has set + * RNS_UD_CS_SUPPORT_SKIP_CHANNELJOIN. In this instance the client + * shouldn't send channel join requests, but we can ignore them + * anyway. + */ self->expecting_channel_join_requests = 1; }