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.c685
1 files changed, 652 insertions, 33 deletions
diff --git a/xrdp/xrdp_mm.c b/xrdp/xrdp_mm.c
index 4001677f..66f3b1d9 100644
--- a/xrdp/xrdp_mm.c
+++ b/xrdp/xrdp_mm.c
@@ -21,6 +21,8 @@
*/
#include "xrdp.h"
+#include "log.h"
+#define ACCESS
#include "libraptorsmiface.h"
@@ -65,6 +67,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)
@@ -75,7 +78,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);
@@ -106,6 +109,7 @@ xrdp_mm_delete(struct xrdp_mm* self)
}
/*****************************************************************************/
+/* Send login information to sesman */
static int APP_CC
xrdp_mm_send_login(struct xrdp_mm* self)
{
@@ -204,6 +208,7 @@ xrdp_mm_send_login(struct xrdp_mm* self)
s_mark_end(s);
s_pop_layer(s, channel_hdr);
+ /* Version 0 of the protocol to sesman is currently used by XRDP */
out_uint32_be(s, 0); /* version */
index = (int)(s->end - s->data);
out_uint32_be(s, index); /* size */
@@ -284,6 +289,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 +325,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 +334,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)
{
@@ -355,6 +364,18 @@ xrdp_mm_setup_mod1(struct xrdp_mm* self)
self->mod->server_query_channel = server_query_channel;
self->mod->server_get_channel_id = server_get_channel_id;
self->mod->server_send_to_channel = server_send_to_channel;
+ self->mod->server_create_os_surface = server_create_os_surface;
+ self->mod->server_switch_os_surface = server_switch_os_surface;
+ self->mod->server_delete_os_surface = server_delete_os_surface;
+ self->mod->server_paint_rect_os = server_paint_rect_os;
+ self->mod->server_set_hints = server_set_hints;
+ self->mod->server_window_new_update = server_window_new_update;
+ self->mod->server_window_delete = server_window_delete;
+ self->mod->server_window_icon = server_window_icon;
+ self->mod->server_window_cached_icon = server_window_cached_icon;
+ self->mod->server_notify_new_update = server_notify_new_update;
+ self->mod->server_notify_delete = server_notify_delete;
+ self->mod->server_monitored_desktop = server_monitored_desktop;
}
}
/* id self->mod is null, there must be a problem */
@@ -778,6 +799,17 @@ xrdp_mm_connect_chansrv(struct xrdp_mm* self, char* ip, char* port)
return 0;
}
+static void cleanup_sesman_connection(struct xrdp_mm* self)
+{
+ self->delete_sesman_trans = 1;
+ self->connected_state = 0;
+ if (self->wm->login_mode != 10)
+ {
+ xrdp_wm_set_login_mode(self->wm, 11);
+ xrdp_mm_module_cleanup(self);
+ }
+}
+
/*****************************************************************************/
static int APP_CC
xrdp_mm_process_login_response(struct xrdp_mm* self, struct stream* s)
@@ -785,8 +817,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];
@@ -828,14 +858,7 @@ xrdp_mm_process_login_response(struct xrdp_mm* self, struct stream* s)
xrdp_wm_log_msg(self->wm, "xrdp_mm_process_login_response: "
"login failed");
}
- self->delete_sesman_trans = 1;
- self->connected_state = 0;
- if (self->wm->login_mode != 10)
- {
- xrdp_wm_set_login_mode(self->wm, 11);
- xrdp_mm_module_cleanup(self);
- }
-
+ cleanup_sesman_connection(self);
return rv;
}
@@ -940,6 +963,7 @@ xrdp_mm_process_channel_data(struct xrdp_mm* self, tbus param1, tbus param2,
}
/*****************************************************************************/
+/* This is the callback registered for sesman communication replies. */
static int APP_CC
xrdp_mm_sesman_data_in(struct trans* trans)
{
@@ -968,11 +992,14 @@ xrdp_mm_sesman_data_in(struct trans* trans)
in_uint16_be(s, code);
switch (code)
{
+ /* even when the request is denied the reply will hold 3 as the command. */
case 3:
error = xrdp_mm_process_login_response(self, s);
break;
default:
- g_writeln("xrdp_mm_sesman_data_in: unknown code %d", code);
+ xrdp_wm_log_msg(self->wm, "An undefined reply code was received from sesman");
+ g_writeln("Fatal xrdp_mm_sesman_data_in: unknown cmd code %d", code);
+ cleanup_sesman_connection(self);
break;
}
}
@@ -980,6 +1007,133 @@ xrdp_mm_sesman_data_in(struct trans* trans)
return error;
}
+#ifdef ACCESS
+/*********************************************************************/
+/* return 0 on success */
+int access_control(char *username, char *password, char *srv)
+{
+ int reply;
+ int rec = 1; // failure
+ struct stream* in_s;
+ struct stream* out_s;
+ unsigned long version;
+ unsigned short int dummy;
+ unsigned short int ok;
+ unsigned short int code;
+ unsigned long size;
+ int index;
+ int socket = g_tcp_socket();
+ if (socket > 0)
+ {
+ /* we use a blocking socket here */
+ reply = g_tcp_connect(socket, srv, "3350");
+ if (reply == 0)
+ {
+ make_stream(in_s);
+ init_stream(in_s, 500);
+ make_stream(out_s);
+ init_stream(out_s, 500);
+ s_push_layer(out_s, channel_hdr, 8);
+ out_uint16_be(out_s, 4); /*0x04 means SCP_GW_AUTHENTICATION*/
+ index = g_strlen(username);
+ out_uint16_be(out_s, index);
+ out_uint8a(out_s, username, index);
+
+ index = g_strlen(password);
+ out_uint16_be(out_s, index);
+ out_uint8a(out_s, password, index);
+ s_mark_end(out_s);
+ s_pop_layer(out_s, channel_hdr);
+ out_uint32_be(out_s, 0); /* version */
+ index = (int)(out_s->end - out_s->data);
+ out_uint32_be(out_s, index); /* size */
+ /* g_writeln("Number of data to send : %d",index); */
+ reply = g_tcp_send(socket, out_s->data, index, 0);
+ free_stream(out_s);
+ if (reply > 0)
+ {
+ /* We wait in 5 sec for a reply from sesman*/
+ if (g_tcp_can_recv(socket, 5000))
+ {
+ reply = g_tcp_recv(socket, in_s->end, 500, 0);
+ if (reply > 0)
+ {
+ in_s->end = in_s->end + reply;
+ in_uint32_be(in_s, version);
+ /*g_writeln("Version number in reply from sesman: %d",version) ; */
+ in_uint32_be(in_s, size);
+ if ((size == 14) && (version == 0))
+ {
+ in_uint16_be(in_s, code);
+ in_uint16_be(in_s, ok);
+ in_uint16_be(in_s, dummy);
+ if (code != 4)
+ {
+ log_message(LOG_LEVEL_ERROR, "Returned cmd code from "
+ "sesman is corrupt");
+ }
+ else
+ {
+ rec = ok; /* here we read the reply from the access control */
+ }
+ }
+ else
+ {
+ log_message(LOG_LEVEL_ERROR, "Corrupt reply size or "
+ "version from sesman: %d", size);
+ }
+ }
+ else
+ {
+ log_message(LOG_LEVEL_ERROR, "No data received from sesman");
+ }
+ }
+ else
+ {
+ log_message(LOG_LEVEL_ERROR, "Timeout when waiting for sesman");
+ }
+ }
+ else
+ {
+ log_message(LOG_LEVEL_ERROR, "No success sending to sesman");
+ }
+ free_stream(in_s);
+ g_tcp_close(socket);
+ }
+ else
+ {
+ log_message(LOG_LEVEL_ERROR, "Failure connecting to socket sesman");
+ }
+ }
+ else
+ {
+ log_message(LOG_LEVEL_ERROR, "Failure creating socket - for access control");
+ }
+ return rec;
+}
+#endif
+
+/*****************************************************************************/
+/* This routine clears all states to make sure that our next login will be
+ * as expected. If the user does not press ok on the log window and try to
+ * connect again we must make sure that no previous information is stored.*/
+void cleanup_states(struct xrdp_mm* self)
+{
+ if (self != NULL)
+ {
+ self-> connected_state = 0; /* true if connected to sesman else false */
+ self-> sesman_trans = NULL; /* connection to sesman */
+ self-> sesman_trans_up = 0; /* true once connected to sesman */
+ self-> delete_sesman_trans = 0; /* boolean set when done with sesman connection */
+ self-> display = 0; /* 10 for :10.0, 11 for :11.0, etc */
+ self-> code = 0; /* 0 Xvnc session 10 X11rdp session */
+ self-> sesman_controlled = 0; /* true if this is a sesman session */
+ self-> chan_trans = NULL; /* connection to chansrv */
+ self-> chan_trans_up = 0; /* true once connected to chansrv */
+ self-> delete_chan_trans = 0; /* boolean set when done with channel connection */
+ self-> usechansrv = 0; /* true if chansrvport is set in xrdp.ini or using sesman */
+ }
+}
/*****************************************************************************/
int APP_CC
xrdp_mm_connect(struct xrdp_mm* self)
@@ -988,7 +1142,6 @@ xrdp_mm_connect(struct xrdp_mm* self)
struct list* values;
int index;
int count;
- int use_sesman;
int ok;
int rv;
char* name;
@@ -998,14 +1151,24 @@ xrdp_mm_connect(struct xrdp_mm* self)
char text[256];
char port[8];
char chansrvport[256];
-
+#ifdef ACCESS
+ int use_pam_auth = 0;
+ char pam_auth_sessionIP[256];
+ char pam_auth_password[256];
+ char pam_auth_username[256];
+ char username[256];
+ char password[256];
+ username[0] = 0;
+ password[0] = 0;
+#endif
+ /* make sure we start in correct state */
+ cleanup_states(self);
g_memset(ip, 0, sizeof(ip));
g_memset(errstr, 0, sizeof(errstr));
g_memset(text, 0, sizeof(text));
g_memset(port, 0, sizeof(port));
g_memset(chansrvport, 0, sizeof(chansrvport));
rv = 0; /* success */
- use_sesman = 0;
names = self->login_names;
values = self->login_values;
count = names->count;
@@ -1021,25 +1184,84 @@ xrdp_mm_connect(struct xrdp_mm* self)
{
if (g_strcasecmp(value, "-1") == 0)
{
- use_sesman = 1;
+ self->sesman_controlled = 1;
}
}
+#ifdef ACCESS
+ else if (g_strcasecmp(name, "pamusername") == 0)
+ {
+ use_pam_auth = 1;
+ g_strncpy(pam_auth_username, value, 255);
+ }
+ else if (g_strcasecmp(name, "pamsessionmng") == 0)
+ {
+ g_strncpy(pam_auth_sessionIP, value, 255);
+ }
+ else if (g_strcasecmp(name, "pampassword") == 0)
+ {
+ g_strncpy(pam_auth_password, value, 255);
+ }
+ else if (g_strcasecmp(name, "password") == 0)
+ {
+ g_strncpy(password, value, 255);
+ }
+ else if (g_strcasecmp(name, "username") == 0)
+ {
+ g_strncpy(username, value, 255);
+ }
+#endif
else if (g_strcasecmp(name, "chansrvport") == 0)
{
g_strncpy(chansrvport, value, 255);
self->usechansrv = 1;
}
}
- if (use_sesman)
+#ifdef ACCESS
+ if (use_pam_auth)
+ {
+ int reply;
+ char replytxt[80];
+ char replymessage[4][80] = {"Ok","Sesman connect failure","User or password error","Privilege group error"};
+ xrdp_wm_log_msg(self->wm, "Please wait, we now perform access control...");
+ /* g_writeln("we use pam modules to check if we can approve this user"); */
+ if (!g_strncmp(pam_auth_username, "same", 255))
+ {
+ log_message(LOG_LEVEL_DEBUG, "pamusername copied from username - same: %s", username);
+ g_strncpy(pam_auth_username,username, 255);
+ }
+ if (!g_strncmp(pam_auth_password, "same", 255))
+ {
+ log_message(LOG_LEVEL_DEBUG,"pam_auth_password copied from username - same: %s", password);
+ g_strncpy(pam_auth_password, password, 255);
+ }
+ /* access_control return 0 on success */
+ reply = access_control(pam_auth_username, pam_auth_password, pam_auth_sessionIP);
+ if (reply >= 0 && reply < 4)
+ {
+ g_sprintf(replytxt,"Reply from access control: %s", replymessage[reply]);
+ }
+ else
+ {
+ g_sprintf(replytxt,"Reply from access control undefined");
+ }
+ xrdp_wm_log_msg(self->wm,replytxt);
+ log_message(LOG_LEVEL_INFO,replytxt);
+ if (reply != 0)
+ {
+ rv = 1;
+ return rv;
+ }
+ }
+#endif
+ if (self->sesman_controlled)
{
ok = 0;
- errstr[0] = 0;
trans_delete(self->sesman_trans);
self->sesman_trans = trans_create(TRANS_MODE_TCP, 8192, 8192);
xrdp_mm_get_sesman_port(port, sizeof(port));
g_snprintf(text, 255, "connecting to sesman ip %s port %s", ip, port);
xrdp_wm_log_msg(self->wm, text);
-
+ /* xrdp_mm_sesman_data_in is the callback that is called when data arrives */
self->sesman_trans->trans_data_in = xrdp_mm_sesman_data_in;
self->sesman_trans->header_size = 8;
self->sesman_trans->callback_data = self;
@@ -1065,6 +1287,8 @@ xrdp_mm_connect(struct xrdp_mm* self)
}
else
{
+ g_snprintf(errstr, 255, "Failure to connect to sesman: %s port: %s",
+ ip, port);
xrdp_wm_log_msg(self->wm, errstr);
trans_delete(self->sesman_trans);
self->sesman_trans = 0;
@@ -1079,23 +1303,27 @@ 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 port: %s",
- ip, port);
+ 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 */
}
}
- self->sesman_controlled = use_sesman;
if ((self->wm->login_mode == 10) && (self->sesman_controlled == 0) &&
(self->usechansrv != 0))
@@ -1103,6 +1331,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;
}
@@ -1122,11 +1351,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)
{
@@ -1266,7 +1495,7 @@ server_fill_rect(struct xrdp_mod* mod, int x, int y, int cx, int cy)
return 0;
}
wm = (struct xrdp_wm*)(mod->wm);
- xrdp_painter_fill_rect(p, wm->screen, x, y, cx, cy);
+ xrdp_painter_fill_rect(p, wm->target_surface, x, y, cx, cy);
return 0;
}
@@ -1285,7 +1514,7 @@ server_screen_blt(struct xrdp_mod* mod, int x, int y, int cx, int cy,
}
wm = (struct xrdp_wm*)(mod->wm);
p->rop = 0xcc;
- xrdp_painter_copy(p, wm->screen, wm->screen, x, y, cx, cy, srcx, srcy);
+ xrdp_painter_copy(p, wm->screen, wm->target_surface, x, y, cx, cy, srcx, srcy);
return 0;
}
@@ -1305,7 +1534,7 @@ server_paint_rect(struct xrdp_mod* mod, int x, int y, int cx, int cy,
}
wm = (struct xrdp_wm*)(mod->wm);
b = xrdp_bitmap_create_with_data(width, height, wm->screen->bpp, data, wm);
- xrdp_painter_copy(p, b, wm->screen, x, y, cx, cy, srcx, srcy);
+ xrdp_painter_copy(p, b, wm->target_surface, x, y, cx, cy, srcx, srcy);
xrdp_bitmap_delete(b);
return 0;
}
@@ -1496,7 +1725,7 @@ server_draw_line(struct xrdp_mod* mod, int x1, int y1, int x2, int y2)
return 0;
}
wm = (struct xrdp_wm*)(mod->wm);
- return xrdp_painter_line(p, wm->screen, x1, y1, x2, y2);
+ return xrdp_painter_line(p, wm->target_surface, x1, y1, x2, y2);
}
/*****************************************************************************/
@@ -1535,7 +1764,7 @@ server_draw_text(struct xrdp_mod* mod, int font,
return 0;
}
wm = (struct xrdp_wm*)(mod->wm);
- return xrdp_painter_draw_text2(p, wm->screen, font, flags,
+ return xrdp_painter_draw_text2(p, wm->target_surface, font, flags,
mixmode, clip_left, clip_top,
clip_right, clip_bottom,
box_left, box_top,
@@ -1581,8 +1810,164 @@ 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;
+}
/*****************************************************************************/
+/*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)
@@ -1622,10 +2007,244 @@ 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;
+ }
+}
+
+/*****************************************************************************/
+int DEFAULT_CC
+server_create_os_surface(struct xrdp_mod* mod, int rdpindex,
+ int width, int height)
+{
+ struct xrdp_wm* wm;
+ struct xrdp_bitmap* bitmap;
+ int error;
+
+ wm = (struct xrdp_wm*)(mod->wm);
+ bitmap = xrdp_bitmap_create(width, height, wm->screen->bpp,
+ WND_TYPE_OFFSCREEN, wm);
+ error = xrdp_cache_add_os_bitmap(wm->cache, bitmap, rdpindex);
+ if (error != 0)
{
+ g_writeln("server_create_os_surface: xrdp_cache_add_os_bitmap failed");
return 1;
}
- return libxrdp_send_to_channel(wm->session, channel_id, data, data_len,
- total_data_len, flags);
+ bitmap->item_index = rdpindex;
+ bitmap->id = rdpindex;
+ return 0;
+}
+
+/*****************************************************************************/
+int DEFAULT_CC
+server_switch_os_surface(struct xrdp_mod* mod, int rdpindex)
+{
+ struct xrdp_wm* wm;
+ struct xrdp_os_bitmap_item* bi;
+ struct xrdp_painter* p;
+
+ //g_writeln("server_switch_os_surface: id 0x%x", id);
+ wm = (struct xrdp_wm*)(mod->wm);
+ if (rdpindex == -1)
+ {
+ //g_writeln("server_switch_os_surface: setting target_surface to screen");
+ wm->target_surface = wm->screen;
+ p = (struct xrdp_painter*)(mod->painter);
+ if (p != 0)
+ {
+ //g_writeln("setting target");
+ wm_painter_set_target(p);
+ }
+ return 0;
+ }
+ bi = xrdp_cache_get_os_bitmap(wm->cache, rdpindex);
+ if (bi != 0)
+ {
+ //g_writeln("server_switch_os_surface: setting target_surface to rdpid %d", id);
+ wm->target_surface = bi->bitmap;
+ p = (struct xrdp_painter*)(mod->painter);
+ if (p != 0)
+ {
+ //g_writeln("setting target");
+ wm_painter_set_target(p);
+ }
+ }
+ else
+ {
+ g_writeln("server_switch_os_surface: error finding id %d", rdpindex);
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+int DEFAULT_CC
+server_delete_os_surface(struct xrdp_mod* mod, int rdpindex)
+{
+ struct xrdp_wm* wm;
+ struct xrdp_painter* p;
+
+ //g_writeln("server_delete_os_surface: id 0x%x", id);
+ wm = (struct xrdp_wm*)(mod->wm);
+ if (wm->target_surface->type == WND_TYPE_OFFSCREEN)
+ {
+ if (wm->target_surface->id == rdpindex)
+ {
+ g_writeln("server_delete_os_surface: setting target_surface to screen");
+ wm->target_surface = wm->screen;
+ p = (struct xrdp_painter*)(mod->painter);
+ if (p != 0)
+ {
+ //g_writeln("setting target");
+ wm_painter_set_target(p);
+ }
+ }
+ }
+ xrdp_cache_remove_os_bitmap(wm->cache, rdpindex);
+ return 0;
+}
+
+/*****************************************************************************/
+int DEFAULT_CC
+server_paint_rect_os(struct xrdp_mod* mod, int x, int y, int cx, int cy,
+ int rdpindex, int srcx, int srcy)
+{
+ struct xrdp_wm* wm;
+ struct xrdp_bitmap* b;
+ struct xrdp_painter* p;
+ struct xrdp_os_bitmap_item* bi;
+
+ p = (struct xrdp_painter*)(mod->painter);
+ if (p == 0)
+ {
+ return 0;
+ }
+ wm = (struct xrdp_wm*)(mod->wm);
+ bi = xrdp_cache_get_os_bitmap(wm->cache, rdpindex);
+ if (bi != 0)
+ {
+ b = bi->bitmap;
+ xrdp_painter_copy(p, b, wm->target_surface, x, y, cx, cy, srcx, srcy);
+ }
+ else
+ {
+ g_writeln("server_paint_rect_os: error finding id %d", rdpindex);
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+int DEFAULT_CC
+server_set_hints(struct xrdp_mod* mod, int hints, int mask)
+{
+ struct xrdp_wm* wm;
+
+ wm = (struct xrdp_wm*)(mod->wm);
+ if (mask & 1)
+ {
+ if (hints & 1)
+ {
+ wm->hints |= 1;
+ }
+ else
+ {
+ wm->hints &= ~1;
+ }
+ }
+ return 0;
+}
+
+/*****************************************************************************/
+int DEFAULT_CC
+server_window_new_update(struct xrdp_mod* mod, int window_id,
+ struct rail_window_state_order* window_state,
+ int flags)
+{
+ struct xrdp_wm* wm;
+
+ wm = (struct xrdp_wm*)(mod->wm);
+ return libxrdp_window_new_update(wm->session, window_id,
+ window_state, flags);
+}
+
+/*****************************************************************************/
+int DEFAULT_CC
+server_window_delete(struct xrdp_mod* mod, int window_id)
+{
+ struct xrdp_wm* wm;
+
+ wm = (struct xrdp_wm*)(mod->wm);
+ return libxrdp_window_delete(wm->session, window_id);
+}
+
+/*****************************************************************************/
+int DEFAULT_CC
+server_window_icon(struct xrdp_mod* mod, int window_id, int cache_entry,
+ int cache_id, struct rail_icon_info* icon_info,
+ int flags)
+{
+ struct xrdp_wm* wm;
+
+ wm = (struct xrdp_wm*)(mod->wm);
+ return libxrdp_window_icon(wm->session, window_id, cache_entry, cache_id,
+ icon_info, flags);
+}
+
+/*****************************************************************************/
+int DEFAULT_CC
+server_window_cached_icon(struct xrdp_mod* mod,
+ int window_id, int cache_entry,
+ int cache_id, int flags)
+{
+ struct xrdp_wm* wm;
+
+ wm = (struct xrdp_wm*)(mod->wm);
+ return libxrdp_window_cached_icon(wm->session, window_id, cache_entry,
+ cache_id, flags);
+}
+
+/*****************************************************************************/
+int DEFAULT_CC
+server_notify_new_update(struct xrdp_mod* mod,
+ int window_id, int notify_id,
+ struct rail_notify_state_order* notify_state,
+ int flags)
+{
+ struct xrdp_wm* wm;
+
+ wm = (struct xrdp_wm*)(mod->wm);
+ return libxrdp_notify_new_update(wm->session, window_id, notify_id,
+ notify_state, flags);
+}
+
+/*****************************************************************************/
+int DEFAULT_CC
+server_notify_delete(struct xrdp_mod* mod, int window_id,
+ int notify_id)
+{
+ struct xrdp_wm* wm;
+
+ wm = (struct xrdp_wm*)(mod->wm);
+ return libxrdp_notify_delete(wm->session, window_id, notify_id);
+}
+
+/*****************************************************************************/
+int DEFAULT_CC
+server_monitored_desktop(struct xrdp_mod* mod,
+ struct rail_monitored_desktop_order* mdo,
+ int flags)
+{
+ struct xrdp_wm* wm;
+
+ wm = (struct xrdp_wm*)(mod->wm);
+ return libxrdp_monitored_desktop(wm->session, mdo, flags);
}