diff --git a/libxrdp/libxrdp.c b/libxrdp/libxrdp.c index ec4aebed..3367306d 100644 --- a/libxrdp/libxrdp.c +++ b/libxrdp/libxrdp.c @@ -1234,13 +1234,34 @@ libxrdp_orders_send_bitmap3(struct xrdp_session *session, cache_id, cache_idx, hints); } +/*****************************************************************************/ +int EXPORT_CC +libxrdp_get_channel_count(const struct xrdp_session *session) +{ + int count = 0; + const struct xrdp_rdp *rdp = (const struct xrdp_rdp *)session->rdp; + const struct xrdp_mcs *mcs = rdp->sec_layer->mcs_layer; + + if (mcs->channel_list == NULL) + { + LOG(LOG_LEVEL_WARNING, + "libxrdp_get_channel_count - No channel initialized"); + } + else + { + count = mcs->channel_list->count; + } + + return count; +} + /*****************************************************************************/ /* returns error */ /* this function gets the channel name and its flags, index is zero based. either channel_name or channel_flags can be passed in nil if they are not needed */ int EXPORT_CC -libxrdp_query_channel(struct xrdp_session *session, int index, +libxrdp_query_channel(struct xrdp_session *session, int channel_id, char *channel_name, int *channel_flags) { int count = 0; @@ -1259,16 +1280,16 @@ libxrdp_query_channel(struct xrdp_session *session, int index, count = mcs->channel_list->count; - if (index < 0 || index >= count) + if (channel_id < 0 || channel_id >= count) { LOG(LOG_LEVEL_ERROR, "libxrdp_query_channel: Channel index out of range. " "max channel index %d, received channel index %d", - count, index); + count, channel_id); return 1; } channel_item = (struct mcs_channel_item *) - list_get_item(mcs->channel_list, index); + list_get_item(mcs->channel_list, channel_id); if (channel_item == NULL) { @@ -1280,7 +1301,8 @@ libxrdp_query_channel(struct xrdp_session *session, int index, if (channel_name != 0) { g_strncpy(channel_name, channel_item->name, 8); - LOG(LOG_LEVEL_DEBUG, "libxrdp_query_channel - Channel %d name %s", index, channel_name); + LOG(LOG_LEVEL_DEBUG, "libxrdp_query_channel - Channel %d name %s", + channel_id, channel_name); } if (channel_flags != 0) diff --git a/libxrdp/libxrdpinc.h b/libxrdp/libxrdpinc.h index fc79ea22..7ec669c4 100644 --- a/libxrdp/libxrdpinc.h +++ b/libxrdp/libxrdpinc.h @@ -203,9 +203,28 @@ int libxrdp_orders_send_bitmap3(struct xrdp_session *session, int width, int height, int bpp, char *data, int cache_id, int cache_idx, int hints); +/** + * Returns the number of channels in the session + * + * This value is one more than the last valid channel ID + * + * @param session RDP session + * @return Number of available channels + */ int -libxrdp_query_channel(struct xrdp_session *session, int index, +libxrdp_get_channel_count(const struct xrdp_session *session); +int +libxrdp_query_channel(struct xrdp_session *session, int channel_id, char *channel_name, int *channel_flags); +/** + * Gets the channel ID for the named channel + * + * Channel IDs are in the range 0..(channel_count-1) + * + * @param session RDP session + * @param name name of channel + * @return channel ID, or -1 if the channel cannot be found + */ int libxrdp_get_channel_id(struct xrdp_session *session, const char *name); int diff --git a/xrdp/xrdp_mm.c b/xrdp/xrdp_mm.c index 7d4bb86d..e8e2bf8a 100644 --- a/xrdp/xrdp_mm.c +++ b/xrdp/xrdp_mm.c @@ -638,7 +638,10 @@ xrdp_mm_setup_mod2(struct xrdp_mm *self, tui8 *guid) static int xrdp_mm_trans_send_channel_setup(struct xrdp_mm *self, struct trans *trans) { - int index; + int chan_count; + /* This value should be the same as chan_count, but we need to + * cater for a possible failure of libxrdp_query_channel() */ + int output_chan_count; int chan_id; int chan_flags; int size; @@ -657,21 +660,24 @@ xrdp_mm_trans_send_channel_setup(struct xrdp_mm *self, struct trans *trans) s_push_layer(s, iso_hdr, 8); s_push_layer(s, mcs_hdr, 8); s_push_layer(s, sec_hdr, 2); - index = 0; - while (libxrdp_query_channel(self->wm->session, index, chan_name, - &chan_flags) == 0) + chan_count = libxrdp_get_channel_count(self->wm->session); + output_chan_count = 0; + for (chan_id = 0 ; chan_id < chan_count; ++chan_id) { - chan_id = libxrdp_get_channel_id(self->wm->session, chan_name); - out_uint8a(s, chan_name, 8); - out_uint16_le(s, chan_id); - out_uint16_le(s, chan_flags); - index++; + if (libxrdp_query_channel(self->wm->session, chan_id, chan_name, + &chan_flags) == 0) + { + out_uint8a(s, chan_name, 8); + out_uint16_le(s, chan_id); + out_uint16_le(s, chan_flags); + ++output_chan_count; + } } s_mark_end(s); s_pop_layer(s, sec_hdr); - out_uint16_le(s, index); + out_uint16_le(s, output_chan_count); s_pop_layer(s, mcs_hdr); size = (int)(s->end - s->p); out_uint32_le(s, 3); /* msg id */ diff --git a/xrdp/xrdp_wm.c b/xrdp/xrdp_wm.c index 558be618..0ef7a348 100644 --- a/xrdp/xrdp_wm.c +++ b/xrdp/xrdp_wm.c @@ -583,56 +583,35 @@ xrdp_wm_init(struct xrdp_wm *self) if (file_by_name_read_section(self->session->xrdp_ini, "Channels", names, values) == 0) { - int error; - int ii; int chan_id; - int chan_flags; - int disabled; - char chan_name[16]; + int chan_count = libxrdp_get_channel_count(self->session); + const char *disabled_str = NULL; - ii = 0; - error = libxrdp_query_channel(self->session, ii, chan_name, - &chan_flags); - while (error == 0) + for (chan_id = 0 ; chan_id < chan_count ; ++chan_id) { - r = NULL; - for (index = 0; index < names->count; index++) + char chan_name[16]; + if (libxrdp_query_channel(self->session, chan_id, chan_name, + NULL) == 0) { - q = (char *) list_get_item(names, index); - if (g_strcasecmp(q, chan_name) == 0) + int disabled = 1; /* Channels disabled if not found */ + + for (index = 0; index < names->count; index++) { - r = (char *) list_get_item(values, index); - break; + q = (char *) list_get_item(names, index); + if (g_strcasecmp(q, chan_name) == 0) + { + r = (const char *) list_get_item(values, index); + disabled = !g_text2bool(r); + break; + } } - } - if (r == NULL) - { - /* not found, disable the channel */ - chan_id = libxrdp_get_channel_id(self->session, chan_name); - libxrdp_disable_channel(self->session, chan_id, 1); - g_writeln("xrdp_wm_init: channel %s channel id %d is " - "disabled", chan_name, chan_id); - } - else - { - /* found */ - chan_id = libxrdp_get_channel_id(self->session, q); - disabled = !g_text2bool(r); + disabled_str = (disabled) ? "disabled" : "enabled"; + LOG(LOG_LEVEL_DEBUG, "xrdp_wm_init: " + "channel %s channel id %d is %s", + chan_name, chan_id, disabled_str); + libxrdp_disable_channel(self->session, chan_id, disabled); - if (disabled) - { - g_writeln("xrdp_wm_init: channel %s channel id %d is " - "disabled", chan_name, chan_id); - } - else - { - g_writeln("xrdp_wm_init: channel %s channel id %d is " - "allowed", chan_name, chan_id); - } } - ii++; - error = libxrdp_query_channel(self->session, ii, chan_name, - &chan_flags); } } list_delete(names);