diff --git a/xrdp/xrdp.h b/xrdp/xrdp.h index 0bc4a24d..58bedca9 100644 --- a/xrdp/xrdp.h +++ b/xrdp/xrdp.h @@ -417,6 +417,8 @@ server_draw_text(struct xrdp_mod* mod, int font, int x, int y, char* data, int data_len); int DEFAULT_CC server_reset(struct xrdp_mod* mod, int width, int height, int bpp); +int DEFAULT_CC +is_channel_allowed(struct xrdp_wm* wm, int channel_id); int DEFAULT_CC server_query_channel(struct xrdp_mod* mod, int index, char* channel_name, int* channel_flags); diff --git a/xrdp/xrdp.ini b/xrdp/xrdp.ini index af5f2650..2532f670 100644 --- a/xrdp/xrdp.ini +++ b/xrdp/xrdp.ini @@ -19,6 +19,16 @@ fork=yes #autorun=xrdp7 #hidelogwindow=yes +[channels] +# Channel names not listed here will be blocket by XRDP. +# You can block any channel by setting its value to false. +# IMPORTANT! All channels are not supported in all use +# cases even if you set all values to true. +rdpdr=true +rdpsnd=true +drdynvc=true +cliprdr=true + [xrdp1] name=sesman-Xvnc lib=libvnc.so diff --git a/xrdp/xrdp_login_wnd.c b/xrdp/xrdp_login_wnd.c index 2b394837..8379ce66 100644 --- a/xrdp/xrdp_login_wnd.c +++ b/xrdp/xrdp_login_wnd.c @@ -410,7 +410,9 @@ xrdp_wm_login_fill_in_combo(struct xrdp_wm* self, struct xrdp_bitmap* b) { p = (char*)list_get_item(sections, i); file_read_section(fd, p, section_names, section_values); - if (g_strncmp(p, "globals", 255) == 0) + if ((g_strncmp(p, "globals", 255) == 0) + ||(g_strncmp(p, "channels", 255) == 0) + ||(g_strncmp(p, "Logging", 255) == 0)) { } else diff --git a/xrdp/xrdp_mm.c b/xrdp/xrdp_mm.c index 223b128b..10148e60 100644 --- a/xrdp/xrdp_mm.c +++ b/xrdp/xrdp_mm.c @@ -1543,9 +1543,158 @@ server_reset(struct xrdp_mod* mod, int width, int height, int bpp) xrdp_wm_load_static_pointers(wm); return 0; } +/* read the channel section of the ini file into lists + * return 1 on success 0 on failure */ +int read_allowed_channel_names(struct list* names, struct list* values) +{ + int fd; + int ret = 0 ; + char cfg_file[256]; + int pos; + g_snprintf(cfg_file, 255, "%s/xrdp.ini", XRDP_CFG_PATH); + fd = g_file_open(cfg_file); + if (fd > 0) + { + names->auto_free = 1; + values->auto_free = 1; + pos = 0 ; + /* all values in this section can be valid channel names */ + if (file_read_section(fd, "channels", names, values) == 0) + { + ret = 1 ; + } + else + { + g_writeln("Failure reading channel section of configuration") ; + } + g_file_close(fd); + return ret ; + } +} +/* internal function return 1 if name is in list of channels + * and if the value is allowed */ +int DEFAULT_CC is_name_in_lists(char *inName, struct list* names, struct list* values) +{ + int reply = 0 ; /*means not in the list*/ + int index ; + char* val; + char* name ; + for (index = 0; index < names->count; index++) + { + name = (char*)list_get_item(names, index); + if (name != 0) + { + /* ex rdpdr ;rdpsnd ; drdynvc ; cliprdr */ + if(!g_strncmp(name,inName,MAX_CHANNEL_NAME)){ + val = (char*)list_get_item(values, index); + if ((g_strcasecmp(val, "yes") == 0) || + (g_strcasecmp(val, "on") == 0) || + (g_strcasecmp(val, "true") == 0) || + (g_atoi(val) != 0)) + { + reply = 1 ; + } + else + { + g_writeln("This channel is disabled: %s",name); + } + break ; /* stop loop - item found*/ + } + } + } + return reply ; +} +/* internal function only used once per session + * creates the list of allowed channels and store the information + * in wm struct */ +void init_channel_allowed(struct xrdp_wm* wm) +{ + int error ; + int i ; + char channelname[MAX_CHANNEL_NAME]; + int index = 0 ; + int allowindex = 0 ; + struct list* names; + struct list* values; + /* first reset allowedchannels */ + for(i = 0 ; iallowedchannels[i] = -1 ; + } + names = list_create(); + values = list_create(); + if(read_allowed_channel_names(names,values)){ + do{ + /* libxrdp_query_channel return 1 on error*/ + error = libxrdp_query_channel(wm->session, index, channelname,NULL); + if(error==0){ + /* examples of channel names: rdpdr ;rdpsnd ; drdynvc ; cliprdr */ + if(is_name_in_lists(channelname,names,values)){ + g_writeln("The following channel is allowed: %s",channelname) ; + wm->allowedchannels[allowindex] = index ; + allowindex ++ ; + if(allowindex>=MAX_NR_CHANNELS) + { + g_writeln("Programming error in is_channel_allowed"); + error = 1 ; /* end loop */ + } + } + else + { + g_writeln("The following channel is not allowed: %s",channelname) ; + } + index ++ ; + } + }while((error==0) && (indexallowedinitialized==0) + { + init_channel_allowed(wm); + g_writeln("allow channel list initialized"); + wm->allowedinitialized = 1 ; + } + for(i = 0 ; iallowedchannels[i]) + { + /*g_writeln("Channel allowed: %d",channel_id);*/ + reply = 1 ; /*channel allowed*/ + break ; + } + else if(wm->allowedchannels[i]==-1) + { + /* We are in the unused space of the allowedchannels list + * We can end the loop */ + break ; + } + } + /*if(reply==0) + { + g_writeln("This channel is NOT allowed: %d",channel_id) ; + }*/ + return reply ; +} /*****************************************************************************/ -int DEFAULT_CC +/*return 0 if the index is not found*/ +int DEFAULT_CC server_query_channel(struct xrdp_mod* mod, int index, char* channel_name, int* channel_flags) { @@ -1584,12 +1733,19 @@ server_send_to_channel(struct xrdp_mod* mod, int channel_id, struct xrdp_wm* wm; wm = (struct xrdp_wm*)(mod->wm); - if (wm->mm->usechansrv) + if(is_channel_allowed(wm,channel_id)) + { + if (wm->mm->usechansrv) + { + return 1; + } + return libxrdp_send_to_channel(wm->session, channel_id, data, data_len, + total_data_len, flags); + } + else { - return 1; + return 1 ; } - return libxrdp_send_to_channel(wm->session, channel_id, data, data_len, - total_data_len, flags); } /*****************************************************************************/ diff --git a/xrdp/xrdp_types.h b/xrdp/xrdp_types.h index 0366fd83..84f1bd3a 100644 --- a/xrdp/xrdp_types.h +++ b/xrdp/xrdp_types.h @@ -20,6 +20,9 @@ */ + +#define MAX_NR_CHANNELS 16 +#define MAX_CHANNEL_NAME 16 /* lib */ struct xrdp_mod { @@ -286,6 +289,8 @@ struct xrdp_wm struct xrdp_bitmap* target_surface; /* either screen or os surface */ int current_surface_index; int hints; + int allowedchannels[MAX_NR_CHANNELS]; + int allowedinitialized ; }; /* rdp process */ diff --git a/xrdp/xrdp_wm.c b/xrdp/xrdp_wm.c index 3f9d3c6e..4bf9f1b4 100644 --- a/xrdp/xrdp_wm.c +++ b/xrdp/xrdp_wm.c @@ -1391,21 +1391,24 @@ xrdp_wm_process_channel_data(struct xrdp_wm* self, tbus param3, tbus param4) { int rv; - + int chanid ; rv = 1; if (self->mm->mod != 0) - { - if (self->mm->usechansrv) - { - rv = xrdp_mm_process_channel_data(self->mm, param1, param2, + { + chanid = LOWORD(param1); + if(is_channel_allowed(self, chanid)){ + if (self->mm->usechansrv) + { + rv = xrdp_mm_process_channel_data(self->mm, param1, param2, param3, param4); - } - else - { - if (self->mm->mod->mod_event != 0) + } + else { - rv = self->mm->mod->mod_event(self->mm->mod, 0x5555, param1, param2, + if (self->mm->mod->mod_event != 0) + { + rv = self->mm->mod->mod_event(self->mm->mod, 0x5555, param1, param2, param3, param4); + } } } }