summaryrefslogtreecommitdiffstats
path: root/xrdp/xrdp_mm.c
diff options
context:
space:
mode:
Diffstat (limited to 'xrdp/xrdp_mm.c')
-rw-r--r--xrdp/xrdp_mm.c190
1 files changed, 178 insertions, 12 deletions
diff --git a/xrdp/xrdp_mm.c b/xrdp/xrdp_mm.c
index 9cfb30a4..8dfac0b9 100644
--- a/xrdp/xrdp_mm.c
+++ b/xrdp/xrdp_mm.c
@@ -64,6 +64,7 @@ xrdp_mm_sync_load(long param1, long param2)
static void APP_CC
xrdp_mm_module_cleanup(struct xrdp_mm* self)
{
+ g_writeln("xrdp_mm_module_cleanup");
if (self->mod != 0)
{
if (self->mod_exit != 0)
@@ -74,7 +75,7 @@ xrdp_mm_module_cleanup(struct xrdp_mm* self)
}
if (self->mod_handle != 0)
{
- /* main thread unload */
+ /* Let the main thread unload the module.*/
g_xrdp_sync(xrdp_mm_sync_unload, self->mod_handle, 0);
}
trans_delete(self->chan_trans);
@@ -284,6 +285,7 @@ xrdp_mm_setup_mod1(struct xrdp_mm* self)
}
if (self->mod_handle == 0)
{
+ /* Let the main thread load the lib,*/
self->mod_handle = g_xrdp_sync(xrdp_mm_sync_load, (long)lib, 0);
if (self->mod_handle != 0)
{
@@ -319,6 +321,8 @@ xrdp_mm_setup_mod1(struct xrdp_mm* self)
g_writeln("loaded module '%s' ok, interface size %d, version %d", lib,
self->mod->size, self->mod->version);
}
+ }else{
+ g_writeln("no mod_init or mod_exit address found");
}
}
else
@@ -326,6 +330,7 @@ xrdp_mm_setup_mod1(struct xrdp_mm* self)
g_snprintf(text, 255, "error loading %s specified in xrdp.ini, please "
"add a valid entry like lib=libxrdp-vnc.so or similar", lib);
xrdp_wm_log_msg(self->wm, text);
+ return 1 ;
}
if (self->mod != 0)
{
@@ -702,7 +707,7 @@ xrdp_mm_connect_chansrv(struct xrdp_mm* self, char* ip, char* port)
self->usechansrv = 1;
/* connect channel redir */
- if ((ip == 0) || (strcmp(ip, "127.0.0.1") == 0) || (ip[0] == 0))
+ if ((ip == 0) || (g_strcmp(ip, "127.0.0.1") == 0) || (ip[0] == 0))
{
/* unix socket */
self->chan_trans = trans_create(TRANS_MODE_UNIX, 8192, 8192);
@@ -765,8 +770,6 @@ xrdp_mm_process_login_response(struct xrdp_mm* self, struct stream* s)
int ok;
int display;
int rv;
- int uid;
- int gid;
char text[256];
char ip[256];
char port[256];
@@ -788,7 +791,7 @@ xrdp_mm_process_login_response(struct xrdp_mm* self, struct stream* s)
xrdp_wm_set_login_mode(self->wm, 10);
self->wm->dragging = 0;
/* connect channel redir */
- if ((ip == 0) || (strcmp(ip, "127.0.0.1") == 0) || (ip[0] == 0))
+ if ((ip == 0) || (g_strcmp(ip, "127.0.0.1") == 0) || (ip[0] == 0))
{
g_snprintf(port, 255, "/tmp/.xrdp/xrdp_chansrv_socket_%d", 7200 + display);
}
@@ -1246,19 +1249,25 @@ xrdp_mm_connect(struct xrdp_mm* self)
if (xrdp_mm_setup_mod2(self) == 0)
{
xrdp_wm_set_login_mode(self->wm, 10);
+ rv = 0 ; /*sucess*/
}
else
{
/* connect error */
g_snprintf(errstr, 255, "Failure to connect to: %s",ip);
xrdp_wm_log_msg(self->wm, errstr);
- rv = 1 ; /* failure */
+ rv = 1; /* failure */
}
}
+ else
+ {
+ g_writeln("Failure setting up module");
+ }
if (self->wm->login_mode != 10)
{
xrdp_wm_set_login_mode(self->wm, 11);
xrdp_mm_module_cleanup(self);
+ rv = 1 ; /* failure */
}
}
@@ -1268,6 +1277,7 @@ xrdp_mm_connect(struct xrdp_mm* self)
/* if sesman controlled, this will connect later */
xrdp_mm_connect_chansrv(self, "", chansrvport);
}
+ g_writeln("returnvalue from xrdp_mm_connect %d",rv);
return rv;
}
@@ -1287,11 +1297,11 @@ xrdp_mm_get_wait_objs(struct xrdp_mm* self,
rv = 0;
if ((self->sesman_trans != 0) && self->sesman_trans_up)
{
- trans_get_wait_objs(self->sesman_trans, read_objs, rcount, timeout);
+ trans_get_wait_objs(self->sesman_trans, read_objs, rcount);
}
if ((self->chan_trans != 0) && self->chan_trans_up)
{
- trans_get_wait_objs(self->chan_trans, read_objs, rcount, timeout);
+ trans_get_wait_objs(self->chan_trans, read_objs, rcount);
}
if (self->mod != 0)
{
@@ -1746,9 +1756,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 ; i<MAX_NR_CHANNELS;i++)
+ {
+ /* 0 is a valid channel so we use -1 to mark the index as unused */
+ wm->allowedchannels[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) && (index<MAX_NR_CHANNELS)) ;
+ }
+ else
+ {
+ g_writeln("Error reading channel section in inifile") ;
+ }
+ list_delete(names);
+ list_delete(values);
+}
+/*****************************************************************************/
+/* This function returns 1 if the channelID is allowed by rule set
+ * returns 0 if not allowed */
+int DEFAULT_CC is_channel_allowed(struct xrdp_wm* wm, int channel_id)
+{
+ int i ;
+ int reply = 0 ; /* not allowed */
+ /* The first time each client is using this function we have to
+ * define the list of allowed channels */
+ if(wm->allowedinitialized==0)
+ {
+ init_channel_allowed(wm);
+ g_writeln("allow channel list initialized");
+ wm->allowedinitialized = 1 ;
+ }
+ for(i = 0 ; i<MAX_NR_CHANNELS;i++)
+ {
+ if(channel_id == wm->allowedchannels[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)
{
@@ -1787,12 +1946,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 libxrdp_send_to_channel(wm->session, channel_id, data, data_len,
- total_data_len, flags);
}
/*****************************************************************************/