From a45f993bfe74aed27245454f1ae32302b0528d9f Mon Sep 17 00:00:00 2001 From: norrarvid Date: Tue, 29 May 2012 12:46:56 +0200 Subject: [PATCH 01/17] added comments, added define, removed unused inparameter --- common/os_calls.c | 47 +++++++++++++++++++++++++--------------- common/trans.c | 2 +- common/trans.h | 2 +- sesman/chansrv/chansrv.c | 6 ++--- xrdp/xrdp.c | 41 ++++++++++++++++++++++++++++------- xrdp/xrdp.h | 2 +- xrdp/xrdp_listen.c | 31 ++++++++++++++++---------- xrdp/xrdp_mm.c | 8 ++++--- xrdp/xrdp_process.c | 2 +- xrdp/xrdpwin.c | 2 +- 10 files changed, 94 insertions(+), 49 deletions(-) diff --git a/common/os_calls.c b/common/os_calls.c index 692dc015..eb5bdea5 100644 --- a/common/os_calls.c +++ b/common/os_calls.c @@ -1055,28 +1055,39 @@ g_obj_wait(tbus* read_objs, int rcount, tbus* write_objs, int wcount, ptime = &time; } FD_ZERO(&rfds); - FD_ZERO(&wfds); - for (i = 0; i < rcount; i++) - { - sck = (int)(read_objs[i]); - if (sck > 0) { - FD_SET(sck, &rfds); - if (sck > max) - { - max = sck; + FD_ZERO(&wfds); + /*Find the highest descriptor number in read_obj */ + if(read_objs!=NULL){ + for (i = 0; i < rcount; i++) + { + sck = (int)(read_objs[i]); + if (sck > 0) { + FD_SET(sck, &rfds); + if (sck > max) + { + max = sck; /*max holds the highest socket/descriptor number */ + } } } + }else if(rcount>0){ + g_writeln("Programming error read_objs is null"); + return 1; /*error*/ } - for (i = 0; i < wcount; i++) - { - sck = (int)(write_objs[i]); - if (sck > 0) { - FD_SET(sck, &wfds); - if (sck > max) - { - max = sck; + if(write_objs!=NULL){ + for (i = 0; i < wcount; i++) + { + sck = (int)(write_objs[i]); + if (sck > 0) { + FD_SET(sck, &wfds); + if (sck > max) + { + max = sck; /*max holds the highest socket/descriptor number */ + } } } + }else if(wcount>0){ + g_writeln("Programming error write_objs is null"); + return 1; /*error*/ } res = select(max + 1, &rfds, &wfds, 0, ptime); if (res < 0) @@ -1089,7 +1100,7 @@ g_obj_wait(tbus* read_objs, int rcount, tbus* write_objs, int wcount, { return 0; } - return 1; + return 1; /*error*/ } return 0; #endif diff --git a/common/trans.c b/common/trans.c index 377b90ba..6b762d00 100644 --- a/common/trans.c +++ b/common/trans.c @@ -69,7 +69,7 @@ trans_delete(struct trans* self) /*****************************************************************************/ int APP_CC -trans_get_wait_objs(struct trans* self, tbus* objs, int* count, int* timeout) +trans_get_wait_objs(struct trans* self, tbus* objs, int* count) { if (self == 0) { diff --git a/common/trans.h b/common/trans.h index bb0f42c0..8e8d942a 100644 --- a/common/trans.h +++ b/common/trans.h @@ -64,7 +64,7 @@ trans_create(int mode, int in_size, int out_size); void APP_CC trans_delete(struct trans* self); int APP_CC -trans_get_wait_objs(struct trans* self, tbus* objs, int* count, int* timeout); +trans_get_wait_objs(struct trans* self, tbus* objs, int* count); int APP_CC trans_check_wait_objs(struct trans* self); int APP_CC diff --git a/sesman/chansrv/chansrv.c b/sesman/chansrv/chansrv.c index f2ca961d..e9d596cf 100644 --- a/sesman/chansrv/chansrv.c +++ b/sesman/chansrv/chansrv.c @@ -447,7 +447,7 @@ channel_thread_loop(void* in_val) num_objs = 0; objs[num_objs] = g_term_event; num_objs++; - trans_get_wait_objs(g_lis_trans, objs, &num_objs, &timeout); + trans_get_wait_objs(g_lis_trans, objs, &num_objs); while (g_obj_wait(objs, num_objs, 0, 0, timeout) == 0) { if (g_is_wait_obj_set(g_term_event)) @@ -492,8 +492,8 @@ channel_thread_loop(void* in_val) num_objs = 0; objs[num_objs] = g_term_event; num_objs++; - trans_get_wait_objs(g_lis_trans, objs, &num_objs, &timeout); - trans_get_wait_objs(g_con_trans, objs, &num_objs, &timeout); + trans_get_wait_objs(g_lis_trans, objs, &num_objs); + trans_get_wait_objs(g_con_trans, objs, &num_objs); clipboard_get_wait_objs(objs, &num_objs, &timeout); sound_get_wait_objs(objs, &num_objs, &timeout); dev_redir_get_wait_objs(objs, &num_objs, &timeout); diff --git a/xrdp/xrdp.c b/xrdp/xrdp.c index fb8dfbc0..9fc10df6 100644 --- a/xrdp/xrdp.c +++ b/xrdp/xrdp.c @@ -22,6 +22,8 @@ #include "xrdp.h" +#define THREAD_WAITING 100 + static struct xrdp_listen* g_listen = 0; static long g_threadid = 0; /* main threadid */ @@ -37,6 +39,9 @@ static long g_sync_param2 = 0; static long (*g_sync_func)(long param1, long param2); /*****************************************************************************/ +/* This function is used to run a function from the main thread. + Sync_func is the function pointer that will run from main thread + The function can have two long in parameters and must return long */ long APP_CC g_xrdp_sync(long (*sync_func)(long param1, long param2), long sync_param1, long sync_param2) @@ -44,31 +49,45 @@ g_xrdp_sync(long (*sync_func)(long param1, long param2), long sync_param1, long sync_result; int sync_command; + /* If the function is called from the main thread, the function can + * be called directly. g_threadid= main thread ID*/ if (tc_threadid_equal(tc_get_threadid(), g_threadid)) { /* this is the main thread, call the function directly */ sync_result = sync_func(sync_param1, sync_param2); + /*g_writeln("g_xrdp_sync processed IN main thread -> continue");*/ } else { + /* All threads have to wait here until the main thread + * process the function. g_process_waiting_function() is called + * from the listening thread. g_process_waiting_function() process the function*/ tc_mutex_lock(g_sync1_mutex); tc_mutex_lock(g_sync_mutex); g_sync_param1 = sync_param1; g_sync_param2 = sync_param2; g_sync_func = sync_func; - g_sync_command = 100; + /* set a value THREAD_WAITING so the g_process_waiting_function function + * know if any function must be processed */ + g_sync_command = THREAD_WAITING; tc_mutex_unlock(g_sync_mutex); - g_set_wait_obj(g_sync_event); + /* set this event so that the main thread know if + * g_process_waiting_function() must be called */ + g_set_wait_obj(g_sync_event); do { g_sleep(100); tc_mutex_lock(g_sync_mutex); - sync_command = g_sync_command; + /* load new value from global to see if the g_process_waiting_function() + * function has processed the function */ + sync_command = g_sync_command; sync_result = g_sync_result; tc_mutex_unlock(g_sync_mutex); } - while (sync_command != 0); + while (sync_command != 0); /* loop until g_process_waiting_function() + * has processed the request*/ tc_mutex_unlock(g_sync1_mutex); + /*g_writeln("g_xrdp_sync processed BY main thread -> continue");*/ } return sync_result; } @@ -132,15 +151,17 @@ pipe_sig(int sig_num) } /*****************************************************************************/ +/*Some function must be called from the main thread. + if g_sync_command==THREAD_WAITING a function is waiting to be processed*/ void APP_CC -g_loop(void) +g_process_waiting_function(void) { tc_mutex_lock(g_sync_mutex); if (g_sync_command != 0) { if (g_sync_func != 0) { - if (g_sync_command == 100) + if (g_sync_command == THREAD_WAITING) { g_sync_result = g_sync_func(g_sync_param1, g_sync_param2); } @@ -426,12 +447,16 @@ main(int argc, char** argv) pid = g_getpid(); g_snprintf(text, 255, "xrdp_%8.8x_main_term", pid); g_term_event = g_create_wait_obj(text); - g_snprintf(text, 255, "xrdp_%8.8x_main_sync", pid); - g_sync_event = g_create_wait_obj(text); if (g_term_event == 0) { g_writeln("error creating g_term_event"); } + g_snprintf(text, 255, "xrdp_%8.8x_main_sync", pid); + g_sync_event = g_create_wait_obj(text); + if (g_sync_event == 0) + { + g_writeln("error creating g_sync_event"); + } xrdp_listen_main_loop(g_listen, startup_params); xrdp_listen_delete(g_listen); tc_mutex_delete(g_sync_mutex); diff --git a/xrdp/xrdp.h b/xrdp/xrdp.h index 9b280bfc..6c15ed8d 100644 --- a/xrdp/xrdp.h +++ b/xrdp/xrdp.h @@ -52,7 +52,7 @@ g_get_term_event(void); tbus APP_CC g_get_sync_event(void); void APP_CC -g_loop(void); +g_process_waiting_function(void); /* xrdp_cache.c */ struct xrdp_cache* APP_CC diff --git a/xrdp/xrdp_listen.c b/xrdp/xrdp_listen.c index 23f532a8..18aed34f 100644 --- a/xrdp/xrdp_listen.c +++ b/xrdp/xrdp_listen.c @@ -39,6 +39,10 @@ xrdp_listen_create(void) self = (struct xrdp_listen*)g_malloc(sizeof(struct xrdp_listen), 1); g_snprintf(text, 255, "xrdp_%8.8x_listen_pro_done_event", pid); self->pro_done_event = g_create_wait_obj(text); + if(self->pro_done_event == 0) + { + g_writeln("Failure creating pro_done_event"); + } self->process_list = list_create(); if (g_process_sem == 0) { @@ -237,7 +241,7 @@ xrdp_listen_main_loop(struct xrdp_listen* self, { self->listen_trans->trans_conn_in = xrdp_listen_conn_in; self->listen_trans->callback_data = self; - term_obj = g_get_term_event(); + term_obj = g_get_term_event(); /*Global termination event */ sync_obj = g_get_sync_event(); done_obj = self->pro_done_event; cont = 1; @@ -249,31 +253,33 @@ xrdp_listen_main_loop(struct xrdp_listen* self, robjs[robjs_count++] = sync_obj; robjs[robjs_count++] = done_obj; timeout = -1; - if (trans_get_wait_objs(self->listen_trans, robjs, &robjs_count, - &timeout) != 0) + if (trans_get_wait_objs(self->listen_trans, robjs, &robjs_count) != 0) { + g_writeln("Listening socket is in wrong state we terminate listener") ; break; } - /* wait */ + /* wait - timeout -1 means wait indefinitely*/ if (g_obj_wait(robjs, robjs_count, 0, 0, timeout) != 0) { /* error, should not get here */ g_sleep(100); } - if (g_is_wait_obj_set(term_obj)) /* term */ + if (g_is_wait_obj_set(term_obj)) /* termination called */ { break; } - if (g_is_wait_obj_set(sync_obj)) /* sync */ + if (g_is_wait_obj_set(sync_obj)) /* some function must be processed by this thread */ { g_reset_wait_obj(sync_obj); - g_loop(); + g_process_waiting_function(); /* run the function */ } if (g_is_wait_obj_set(done_obj)) /* pro_done_event */ { - g_reset_wait_obj(done_obj); + g_reset_wait_obj(done_obj); + /* a process has died remove it from lists*/ xrdp_listen_delete_done_pro(self); } + /* Run the callback when accept() returns a new socket*/ if (trans_check_wait_objs(self->listen_trans) != 0) { break; @@ -290,20 +296,21 @@ xrdp_listen_main_loop(struct xrdp_listen* self, { break; } + timeout = -1; /* build the wait obj list */ robjs_count = 0; robjs[robjs_count++] = sync_obj; robjs[robjs_count++] = done_obj; - /* wait */ - if (g_obj_wait(robjs, robjs_count, 0, 0, -1) != 0) + /* wait - timeout -1 means wait indefinitely*/ + if (g_obj_wait(robjs, robjs_count, 0, 0, timeout) != 0) { /* error, should not get here */ g_sleep(100); } - if (g_is_wait_obj_set(sync_obj)) /* sync */ + if (g_is_wait_obj_set(sync_obj)) /* some function must be processed by this thread */ { g_reset_wait_obj(sync_obj); - g_loop(); + g_process_waiting_function(); /* run the function that is waiting*/ } if (g_is_wait_obj_set(done_obj)) /* pro_done_event */ { diff --git a/xrdp/xrdp_mm.c b/xrdp/xrdp_mm.c index 223b128b..2d14351f 100644 --- a/xrdp/xrdp_mm.c +++ b/xrdp/xrdp_mm.c @@ -62,6 +62,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) @@ -72,7 +73,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); @@ -280,6 +281,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) { @@ -1084,11 +1086,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) { diff --git a/xrdp/xrdp_process.c b/xrdp/xrdp_process.c index 905db928..869cfd34 100644 --- a/xrdp/xrdp_process.c +++ b/xrdp/xrdp_process.c @@ -161,7 +161,7 @@ xrdp_process_main_loop(struct xrdp_process* self) robjs[robjs_count++] = self->self_term_event; xrdp_wm_get_wait_objs(self->wm, robjs, &robjs_count, wobjs, &wobjs_count, &timeout); - trans_get_wait_objs(self->server_trans, robjs, &robjs_count, &timeout); + trans_get_wait_objs(self->server_trans, robjs, &robjs_count); /* wait */ if (g_obj_wait(robjs, robjs_count, wobjs, wobjs_count, timeout) != 0) { diff --git a/xrdp/xrdpwin.c b/xrdp/xrdpwin.c index d2c2d0f3..849f7112 100644 --- a/xrdp/xrdpwin.c +++ b/xrdp/xrdpwin.c @@ -140,7 +140,7 @@ pipe_sig(int sig_num) /*****************************************************************************/ void APP_CC -g_loop(void) +g_process_waiting_function(void) { tc_mutex_lock(g_sync_mutex); if (g_sync_command != 0) From 02f3fe1e2a2f971246d7775468425636a05e6246 Mon Sep 17 00:00:00 2001 From: norrarvid Date: Wed, 30 May 2012 07:40:06 +0200 Subject: [PATCH 02/17] Improved error handling for module load and init, fixed bug in logwindow --- common/os_calls.c | 25 +++++++++++++++++++++++++ common/os_calls.h | 2 ++ xrdp/xrdp_mm.c | 11 ++++++++++- xrdp/xrdp_types.h | 2 ++ xrdp/xrdp_wm.c | 17 ++++++++++++++++- 5 files changed, 55 insertions(+), 2 deletions(-) diff --git a/common/os_calls.c b/common/os_calls.c index 80e5bad3..ae48fc94 100644 --- a/common/os_calls.c +++ b/common/os_calls.c @@ -1579,7 +1579,32 @@ g_strdup(const char* in) } return p; } +/*****************************************************************************/ +/* if in = 0, return 0 else return newly alloced copy of input string + * if the input string is larger than maxlen the returned string will be + * truncated. All strings returned will include null termination*/ +char* APP_CC +g_strndup(const char* in, const unsigned int maxlen) +{ + int len; + char* p; + if (in == 0) + { + return 0; + } + len = g_strlen(in); + if(len>maxlen) + { + len = maxlen-1 ; + } + p = (char*)g_malloc(len + 2, 0); + if (p != NULL) + { + g_strncpy(p, in,len+1); + } + return p; +} /*****************************************************************************/ int APP_CC g_strcmp(const char* c1, const char* c2) diff --git a/common/os_calls.h b/common/os_calls.h index ddcb59d8..7be659d6 100644 --- a/common/os_calls.h +++ b/common/os_calls.h @@ -178,6 +178,8 @@ char* APP_CC g_strcat(char* dest, const char* src); char* APP_CC g_strdup(const char* in); +char* APP_CC +g_strndup(const char* in, const unsigned int maxlen); int APP_CC g_strcmp(const char* c1, const char* c2); int APP_CC diff --git a/xrdp/xrdp_mm.c b/xrdp/xrdp_mm.c index 2d14351f..5c8d325f 100644 --- a/xrdp/xrdp_mm.c +++ b/xrdp/xrdp_mm.c @@ -305,7 +305,7 @@ xrdp_mm_setup_mod1(struct xrdp_mm* self) if (func == 0) { g_snprintf(text, 255, "error finding proc mod_exit in %s, not a valid " - "xrdp backend", lib); + "xrdp backend", lib); xrdp_wm_log_msg(self->wm, text); } self->mod_exit = (int (*)(struct xrdp_mod*))func; @@ -317,6 +317,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 @@ -324,6 +326,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) { @@ -1043,20 +1046,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 port: %s", ip, port); + g_writeln(errstr); xrdp_wm_log_msg(self->wm, errstr); 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; @@ -1067,6 +1075,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; } diff --git a/xrdp/xrdp_types.h b/xrdp/xrdp_types.h index 0366fd83..1e833d16 100644 --- a/xrdp/xrdp_types.h +++ b/xrdp/xrdp_types.h @@ -19,6 +19,8 @@ types */ +#define DEFAULT_STRING_LEN 255 +#define LOG_WINDOW_CHAR_PER_LINE 60 /* lib */ struct xrdp_mod diff --git a/xrdp/xrdp_wm.c b/xrdp/xrdp_wm.c index 3f9d3c6e..14af31ed 100644 --- a/xrdp/xrdp_wm.c +++ b/xrdp/xrdp_wm.c @@ -1556,6 +1556,21 @@ xrdp_wm_log_wnd_notify(struct xrdp_bitmap* wnd, return 0; } + void add_string_to_logwindow(char *msg,struct list* log) + { + + char *new_part_message; + char *current_pointer = msg ; + int processedlen ; + do{ + new_part_message = g_strndup(current_pointer,LOG_WINDOW_CHAR_PER_LINE) ; + g_writeln(new_part_message); + list_add_item(log, (long)new_part_message); + processedlen = processedlen + g_strlen(new_part_message); + current_pointer = current_pointer + g_strlen(new_part_message) ; + }while((processedlenlog, (long)g_strdup(msg)); + add_string_to_logwindow(msg,self->log); if (self->log_wnd == 0) { w = DEFAULT_WND_LOG_W; From 7c512ba042ebb88460612f87c9a99a522db0ea24 Mon Sep 17 00:00:00 2001 From: norrarvid Date: Wed, 30 May 2012 08:42:05 +0200 Subject: [PATCH 03/17] freerdp disconnect added in exit --- freerdp1/xrdp-freerdp.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/freerdp1/xrdp-freerdp.c b/freerdp1/xrdp-freerdp.c index bad9d4ad..2b23194e 100644 --- a/freerdp1/xrdp-freerdp.c +++ b/freerdp1/xrdp-freerdp.c @@ -1334,13 +1334,18 @@ mod_exit(struct mod* mod) { return 0; } - + if(mod->inst == NULL) + { + LLOGLN(0, ("mod_exit - null pointer for inst:")); + return 0 ; + } + freerdp_disconnect(mod->inst); if ((mod->vmaj == 1) && (mod->vmin == 0) && (mod->vrev == 1)) { /* this version has a bug with double free in freerdp_free */ } else - { + { freerdp_context_free(mod->inst); } freerdp_free(mod->inst); From f4ffaafc20f454481b87e500ef5ca8d651083a1d Mon Sep 17 00:00:00 2001 From: norrarvid Date: Wed, 30 May 2012 17:11:53 +0200 Subject: [PATCH 04/17] channels can be disabled by XRDP --- xrdp/xrdp.h | 2 + xrdp/xrdp.ini | 10 +++ xrdp/xrdp_login_wnd.c | 4 +- xrdp/xrdp_mm.c | 168 ++++++++++++++++++++++++++++++++++++++++-- xrdp/xrdp_types.h | 5 ++ xrdp/xrdp_wm.c | 25 ++++--- 6 files changed, 196 insertions(+), 18 deletions(-) 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) - { - return 1; - } - return libxrdp_send_to_channel(wm->session, channel_id, data, data_len, + 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 ; + } } /*****************************************************************************/ 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, - param3, param4); - } - else - { - if (self->mm->mod->mod_event != 0) + { + chanid = LOWORD(param1); + if(is_channel_allowed(self, chanid)){ + if (self->mm->usechansrv) { - rv = self->mm->mod->mod_event(self->mm->mod, 0x5555, param1, param2, + rv = xrdp_mm_process_channel_data(self->mm, param1, param2, + param3, param4); + } + else + { + if (self->mm->mod->mod_event != 0) + { + rv = self->mm->mod->mod_event(self->mm->mod, 0x5555, param1, param2, param3, param4); + } } } } From 10fdc5c17f7aec2df8885d2cf7354f6681af76f6 Mon Sep 17 00:00:00 2001 From: norrarvid Date: Thu, 31 May 2012 16:57:17 +0200 Subject: [PATCH 05/17] separate pam authentication for gateways --- sesman/libscp/libscp_session.c | 3 + sesman/libscp/libscp_types.h | 4 + sesman/libscp/libscp_v0.c | 63 +++++++++- sesman/libscp/libscp_v0.h | 9 ++ sesman/scp_v0.c | 23 +++- xrdp/xrdp.ini | 5 +- xrdp/xrdp_login_wnd.c | 6 +- xrdp/xrdp_mm.c | 210 ++++++++++++++++++++++++++++++--- 8 files changed, 298 insertions(+), 25 deletions(-) diff --git a/sesman/libscp/libscp_session.c b/sesman/libscp/libscp_session.c index 8ac94d25..5c2a12a3 100644 --- a/sesman/libscp/libscp_session.c +++ b/sesman/libscp/libscp_session.c @@ -60,6 +60,9 @@ scp_session_set_type(struct SCP_SESSION* s, tui8 type) case SCP_SESSION_TYPE_XRDP: s->type = SCP_SESSION_TYPE_XRDP; break; + case SCP_GW_AUTHENTICATION: + s->type = SCP_GW_AUTHENTICATION; + break; case SCP_SESSION_TYPE_MANAGE: s->type = SCP_SESSION_TYPE_MANAGE; s->mng = (struct SCP_MNG_DATA*)g_malloc(sizeof(struct SCP_MNG_DATA), 1); diff --git a/sesman/libscp/libscp_types.h b/sesman/libscp/libscp_types.h index 7a54545a..e6521741 100644 --- a/sesman/libscp/libscp_types.h +++ b/sesman/libscp/libscp_types.h @@ -42,6 +42,10 @@ #define SCP_SESSION_TYPE_XVNC 0x00 #define SCP_SESSION_TYPE_XRDP 0x01 #define SCP_SESSION_TYPE_MANAGE 0x02 +/* SCP_GW_AUTHENTICATION can be used when XRDP + sesman act as a gateway + * XRDP sends this command to let sesman verify if the user is allowed + * to use the gateway */ +#define SCP_GW_AUTHENTICATION 0x04 #define SCP_ADDRESS_TYPE_IPV4 0x00 #define SCP_ADDRESS_TYPE_IPV6 0x01 diff --git a/sesman/libscp/libscp_v0.c b/sesman/libscp/libscp_v0.c index d46d6afa..e581691f 100644 --- a/sesman/libscp/libscp_v0.c +++ b/sesman/libscp/libscp_v0.c @@ -277,6 +277,42 @@ scp_v0s_accept(struct SCP_CONNECTION* c, struct SCP_SESSION** s, int skipVchk) } } } + if (code == SCP_GW_AUTHENTICATION) + { + /* g_writeln("Command is SCP_GW_AUTHENTICATION"); */ + session = scp_session_create(); + if (0 == session) + { + /* until syslog merge log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__);*/ + return SCP_SERVER_STATE_INTERNAL_ERR; + } + + scp_session_set_version(session, version); + scp_session_set_type(session, SCP_GW_AUTHENTICATION); + /* reading username */ + in_uint16_be(c->in_s, sz); + buf[sz]='\0'; + in_uint8a(c->in_s, buf, sz); + /* g_writeln("Received user name: %s",buf); */ + if (0 != scp_session_set_username(session, buf)) + { + scp_session_destroy(session); + /* until syslog merge log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: error setting username", __LINE__);*/ + return SCP_SERVER_STATE_INTERNAL_ERR; + } + + /* reading password */ + in_uint16_be(c->in_s, sz); + buf[sz]='\0'; + in_uint8a(c->in_s, buf, sz); + /* g_writeln("Received password: %s",buf); */ + if (0 != scp_session_set_password(session, buf)) + { + scp_session_destroy(session); + /* until syslog merge log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: error setting password", __LINE__); */ + return SCP_SERVER_STATE_INTERNAL_ERR; + } + } else { log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: sequence error", __LINE__); @@ -315,8 +351,8 @@ scp_v0s_deny_connection(struct SCP_CONNECTION* c) out_uint32_be(c->out_s, 0); /* version */ out_uint32_be(c->out_s, 14); /* size */ out_uint16_be(c->out_s, 3); /* cmd */ - out_uint16_be(c->out_s, 0); /* data */ - out_uint16_be(c->out_s, 0); /* data */ + out_uint16_be(c->out_s, 0); /* data = 0 - means NOT ok*/ + out_uint16_be(c->out_s, 0); /* reserved for display number*/ s_mark_end(c->out_s); if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, c->out_s->end - c->out_s->data)) @@ -328,3 +364,26 @@ scp_v0s_deny_connection(struct SCP_CONNECTION* c) LOG_DBG(s_log, "[v0:%d] connection terminated (denied)", __LINE__); return SCP_SERVER_STATE_OK; } + +/******************************************************************************/ +enum SCP_SERVER_STATES_E +scp_v0s_replyauthentication(struct SCP_CONNECTION* c, unsigned short int value) +{ + out_uint32_be(c->out_s, 0); /* version */ + out_uint32_be(c->out_s, 14); /* size */ + /* cmd SCP_GW_AUTHENTICATION means authentication reply */ + out_uint16_be(c->out_s, SCP_GW_AUTHENTICATION); + out_uint16_be(c->out_s, value); /* reply code */ + out_uint16_be(c->out_s, 0); /* dummy data */ + s_mark_end(c->out_s); + + /* g_writeln("Total number of bytes that will be sent %d",c->out_s->end - c->out_s->data);*/ + if (0 != scp_tcp_force_send(c->in_sck, c->out_s->data, c->out_s->end - c->out_s->data)) + { + /* until syslog merge log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__); */ + return SCP_SERVER_STATE_NETWORK_ERR; + } + + /* until syslog merge LOG_DBG(s_log, "[v0:%d] connection terminated (scp_v0s_deny_authentication)", __LINE__);*/ + return SCP_SERVER_STATE_OK; +} diff --git a/sesman/libscp/libscp_v0.h b/sesman/libscp/libscp_v0.h index 7c6fd4b2..92b835f0 100644 --- a/sesman/libscp/libscp_v0.h +++ b/sesman/libscp/libscp_v0.h @@ -73,5 +73,14 @@ scp_v0s_allow_connection(struct SCP_CONNECTION* c, SCP_DISPLAY d); enum SCP_SERVER_STATES_E scp_v0s_deny_connection(struct SCP_CONNECTION* c); +/** + * @brief send reply to an authentication request + * @param c connection descriptor + * @param value the reply code 0 means ok + * @return + */ +enum SCP_SERVER_STATES_E +scp_v0s_replyauthentication(struct SCP_CONNECTION* c, unsigned short int value); + #endif diff --git a/sesman/scp_v0.c b/sesman/scp_v0.c index 0b4dc791..71b1ffad 100644 --- a/sesman/scp_v0.c +++ b/sesman/scp_v0.c @@ -38,9 +38,28 @@ scp_v0_process(struct SCP_CONNECTION* c, struct SCP_SESSION* s) struct session_item* s_item; data = auth_userpass(s->username, s->password); - - if (data) + if(s->type==SCP_GW_AUTHENTICATION) { + /* this is just authentication in a gateway situation */ + /* g_writeln("SCP_GW_AUTHENTICATION message received"); */ + if(data){ + if (1 == access_login_allowed(s->username)) + { + /* the user is member of the correct groups. */ + scp_v0s_replyauthentication(c,0); + /* g_writeln("Connection allowed"); */ + }else{ + scp_v0s_replyauthentication(c,3); + /* g_writeln("user password ok, but group problem"); */ + } + }else{ + /* g_writeln("username or password error"); */ + scp_v0s_replyauthentication(c,2); + } + auth_end(data); + } + else if (data) + { s_item = session_get_bydata(s->username, s->width, s->height, s->bpp, s->type); if (s_item != 0) { diff --git a/xrdp/xrdp.ini b/xrdp/xrdp.ini index af5f2650..a1da4f04 100644 --- a/xrdp/xrdp.ini +++ b/xrdp/xrdp.ini @@ -6,7 +6,7 @@ port=3389 crypt_level=low channel_code=1 max_bpp=24 -fork=yes +fork=no #black=000000 #grey=d6d3ce #dark_grey=808080 @@ -42,6 +42,9 @@ ip=ask port=ask5900 username=na password=ask +pamusername=asksame +pampassword=asksame +pamsessionmng=127.0.0.1 [xrdp4] name=sesman-any diff --git a/xrdp/xrdp_login_wnd.c b/xrdp/xrdp_login_wnd.c index 2b394837..7065c2ce 100644 --- a/xrdp/xrdp_login_wnd.c +++ b/xrdp/xrdp_login_wnd.c @@ -21,7 +21,7 @@ */ #include "xrdp.h" - +#define ACCESS /*****************************************************************************/ /* all login help screen events go here */ static int DEFAULT_CC @@ -302,7 +302,11 @@ xrdp_wm_show_edits(struct xrdp_wm* self, struct xrdp_bitmap* combo) username_set = 1; } } +#ifdef ACCESS + if ((g_strncmp(name, "password", 255) == 0) || (g_strncmp(name, "pampassword", 255) == 0)) +#else if (g_strncmp(name, "password", 255) == 0) +#endif { b->password_char = '*'; if (username_set) diff --git a/xrdp/xrdp_mm.c b/xrdp/xrdp_mm.c index 223b128b..e7919e9b 100644 --- a/xrdp/xrdp_mm.c +++ b/xrdp/xrdp_mm.c @@ -21,6 +21,7 @@ */ #include "xrdp.h" +#define ACCESS /*****************************************************************************/ struct xrdp_mm* APP_CC @@ -103,6 +104,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) { @@ -200,6 +202,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 */ @@ -743,6 +746,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) @@ -790,14 +804,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; } @@ -902,6 +909,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) { @@ -930,11 +938,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; } } @@ -942,6 +953,103 @@ 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) + { + g_writeln("Connected to sesman user %s: password %s :srv %s",username, password, srv); + 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) + { + 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) + { + g_writeln("Return cmd code is corrupt"); + } + else + { + rec = ok; /* here we read the reply from the access control */ + /* g_writeln("Valid reply received"); */ + } + } + else + { + g_writeln("corrupt reply size or version from sesman: %d",size); + } + } + else + { + g_writeln("no data received from sesman"); + } + } + else + { + g_writeln("no success sending to sesman"); + } + free_stream(in_s); + g_tcp_close(socket); + } + else + { + g_writeln("failure connecting to socket sesman"); + } + } + else + { + g_writeln("failure creating socket"); + } + //g_free(port); + return rec; +} +#endif + /*****************************************************************************/ int APP_CC xrdp_mm_connect(struct xrdp_mm* self) @@ -950,7 +1058,6 @@ xrdp_mm_connect(struct xrdp_mm* self) struct list* values; int index; int count; - int use_sesman; int ok; int rv; char* name; @@ -960,14 +1067,22 @@ 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 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; @@ -983,25 +1098,82 @@ 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)) + { + g_writeln("pamusername copied from username - same: %s",username); + g_strncpy(pam_auth_username,username,255); + } + if(!g_strncmp(pam_auth_password,"same",255)) + { + g_writeln("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); + 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; @@ -1027,6 +1199,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; @@ -1045,8 +1219,7 @@ xrdp_mm_connect(struct xrdp_mm* self) 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 */ } @@ -1057,7 +1230,6 @@ xrdp_mm_connect(struct xrdp_mm* self) xrdp_mm_module_cleanup(self); } } - self->sesman_controlled = use_sesman; if ((self->wm->login_mode == 10) && (self->sesman_controlled == 0) && (self->usechansrv != 0)) From a555dc5a4282514b9d4eae2a26a5d57665176f1a Mon Sep 17 00:00:00 2001 From: norrarvid Date: Thu, 31 May 2012 19:57:16 +0200 Subject: [PATCH 06/17] pamusername and pampassword are now readable on login screen --- xrdp/xrdp.ini | 2 +- xrdp/xrdp_login_wnd.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/xrdp/xrdp.ini b/xrdp/xrdp.ini index a1da4f04..d173edd2 100644 --- a/xrdp/xrdp.ini +++ b/xrdp/xrdp.ini @@ -6,7 +6,7 @@ port=3389 crypt_level=low channel_code=1 max_bpp=24 -fork=no +fork=yes #black=000000 #grey=d6d3ce #dark_grey=808080 diff --git a/xrdp/xrdp_login_wnd.c b/xrdp/xrdp_login_wnd.c index 7065c2ce..b498697b 100644 --- a/xrdp/xrdp_login_wnd.c +++ b/xrdp/xrdp_login_wnd.c @@ -261,7 +261,7 @@ xrdp_wm_show_edits(struct xrdp_wm* self, struct xrdp_bitmap* combo) if (g_strncmp("ask", value, 3) == 0) { /* label */ - b = xrdp_bitmap_create(70, DEFAULT_EDIT_H, self->screen->bpp, + b = xrdp_bitmap_create(95, DEFAULT_EDIT_H, self->screen->bpp, WND_TYPE_LABEL, self); list_insert_item(self->login_window->child_list, insert_index, (long)b); From 42bda50fe0a9f030ae0ea62a236ed6ae741db3a3 Mon Sep 17 00:00:00 2001 From: norrarvid Date: Fri, 1 Jun 2012 16:20:29 +0200 Subject: [PATCH 07/17] Deadlock situation bug fix and improved debug information --- freerdp1/xrdp-freerdp.c | 2 +- libxrdp/libxrdp.c | 29 ++++++++++++++++++++++++++- libxrdp/xrdp_channel.c | 14 ++++++++++--- libxrdp/xrdp_mcs.c | 25 ++++++++++++++++++----- libxrdp/xrdp_rdp.c | 44 ++++++++++++++++++++++++++++++----------- libxrdp/xrdp_sec.c | 19 ++++++++++++++++-- rdp/rdp_sec.c | 8 ++++++++ 7 files changed, 117 insertions(+), 24 deletions(-) diff --git a/freerdp1/xrdp-freerdp.c b/freerdp1/xrdp-freerdp.c index bad9d4ad..4dfa9648 100644 --- a/freerdp1/xrdp-freerdp.c +++ b/freerdp1/xrdp-freerdp.c @@ -917,7 +917,7 @@ static void DEFAULT_CC lfreerdp_pointer_system(rdpContext* context, POINTER_SYSTEM_UPDATE* pointer_system) { - LLOGLN(0, ("lfreerdp_pointer_system:")); + LLOGLN(0, ("lfreerdp_pointer_system: - no code here")); } /******************************************************************************/ diff --git a/libxrdp/libxrdp.c b/libxrdp/libxrdp.c index 5c228305..cafd63fb 100644 --- a/libxrdp/libxrdp.c +++ b/libxrdp/libxrdp.c @@ -75,10 +75,12 @@ libxrdp_process_data(struct xrdp_session* session) int rv; int code; int term; + int dead_lock_counter; term = 0; cont = 1; rv = 0; + dead_lock_counter = 0 ; while ((cont || !session->up_and_running) && !term) { if (session->is_term != 0) @@ -102,6 +104,7 @@ libxrdp_process_data(struct xrdp_session* session) session->up_and_running = 0; break; case 0: + dead_lock_counter ++ ; break; case RDP_PDU_CONFIRM_ACTIVE: /* 3 */ xrdp_rdp_process_confirm_active((struct xrdp_rdp*)session->rdp, @@ -118,7 +121,16 @@ libxrdp_process_data(struct xrdp_session* session) break; default: g_writeln("unknown in libxrdp_process_data"); + dead_lock_counter ++ ; break; + } + if(dead_lock_counter>100000) + { + /*This situation can happen and this is a workaround*/ + cont = 0 ; + g_writeln("Serious programming error we were locked in a deadly loop") ; + g_writeln("remaining :%d",session->s->end-session->s->next_packet); + session->s->next_packet = 0; } if (cont) { @@ -616,7 +628,10 @@ libxrdp_reset(struct xrdp_session* session, } /* process till up and running */ session->up_and_running = 0; - libxrdp_process_data(session); + if(libxrdp_process_data(session)!=0) + { + g_writeln("non handled error from libxrdp_process_data"); + } return 0; } @@ -658,6 +673,11 @@ libxrdp_query_channel(struct xrdp_session* session, int index, rdp = (struct xrdp_rdp*)session->rdp; mcs = rdp->sec_layer->mcs_layer; + if(mcs->channel_list==NULL) + { + g_writeln("libxrdp_query_channel - No channel initialized"); + return 1 ; + } count = mcs->channel_list->count; if (index < 0 || index >= count) { @@ -668,6 +688,7 @@ libxrdp_query_channel(struct xrdp_session* session, int index, if (channel_item == 0) { /* this should not happen */ + g_writeln("libxrdp_query_channel - channel item is 0"); return 1; } if (channel_name != 0) @@ -695,6 +716,11 @@ libxrdp_get_channel_id(struct xrdp_session* session, char* name) rdp = (struct xrdp_rdp*)session->rdp; mcs = rdp->sec_layer->mcs_layer; + if(mcs->channel_list==NULL) + { + g_writeln("libxrdp_get_channel_id No channel initialized"); + return -1 ; + } count = mcs->channel_list->count; for (index = 0; index < count; index++) { @@ -737,6 +763,7 @@ libxrdp_send_to_channel(struct xrdp_session* session, int channel_id, s_mark_end(s); if (xrdp_channel_send(chan, s, channel_id, total_data_len, flags) != 0) { + g_writeln("Debug - data NOT sent to channel"); free_stream(s); return 1; } diff --git a/libxrdp/xrdp_channel.c b/libxrdp/xrdp_channel.c index 00497c35..4085f650 100644 --- a/libxrdp/xrdp_channel.c +++ b/libxrdp/xrdp_channel.c @@ -35,7 +35,11 @@ static struct mcs_channel_item* APP_CC xrdp_channel_get_item(struct xrdp_channel* self, int channel_id) { struct mcs_channel_item* channel; - + if(self->mcs_layer->channel_list==NULL) + { + g_writeln("xrdp_channel_get_item - No channel initialized"); + return NULL ; + } channel = (struct mcs_channel_item*) list_get_item(self->mcs_layer->channel_list, channel_id); return channel; @@ -62,6 +66,7 @@ xrdp_channel_delete(struct xrdp_channel* self) { return; } + memset(self,0,sizeof(struct xrdp_channel)); g_free(self); } @@ -88,8 +93,9 @@ xrdp_channel_send(struct xrdp_channel* self, struct stream* s, int channel_id, struct mcs_channel_item* channel; channel = xrdp_channel_get_item(self, channel_id); - if (channel == 0) + if (channel == NULL) { + g_writeln("xrdp_channel_send - no such channel"); return 1; } s_pop_layer(s, channel_hdr); @@ -101,6 +107,7 @@ xrdp_channel_send(struct xrdp_channel* self, struct stream* s, int channel_id, out_uint32_le(s, flags); if (xrdp_sec_send(self->sec_layer, s, channel->chanid) != 0) { + g_writeln("xrdp_channel_send - failure sending data"); return 1; } return 0; @@ -159,13 +166,14 @@ xrdp_channel_process(struct xrdp_channel* self, struct stream* s, int channel_id; struct mcs_channel_item* channel; + /* this assumes that the channels are in order of chanid(mcs channel id) but they should be, see xrdp_sec_process_mcs_data_channels the first channel should be MCS_GLOBAL_CHANNEL + 1, second one should be MCS_GLOBAL_CHANNEL + 2, and so on */ channel_id = (chanid - MCS_GLOBAL_CHANNEL) - 1; channel = xrdp_channel_get_item(self, channel_id); - if (channel == 0) + if (channel == NULL) { g_writeln("xrdp_channel_process, channel not found"); return 1; diff --git a/libxrdp/xrdp_mcs.c b/libxrdp/xrdp_mcs.c index af65faf2..57494191 100644 --- a/libxrdp/xrdp_mcs.c +++ b/libxrdp/xrdp_mcs.c @@ -65,11 +65,15 @@ xrdp_mcs_delete(struct xrdp_mcs* self) } list_delete(self->channel_list); xrdp_iso_delete(self->iso_layer); + /* make sure we get null pointer exception if struct is used again. */ + DEBUG(("xrdp_mcs_delete processed")) + g_memset(self,0,sizeof(struct xrdp_mcs)) ; g_free(self); } /*****************************************************************************/ -/* returns error */ +/* This function sends channel join confirm*/ +/* returns error = 1 ok = 0*/ static int APP_CC xrdp_mcs_send_cjcf(struct xrdp_mcs* self, int userid, int chanid) { @@ -87,7 +91,7 @@ xrdp_mcs_send_cjcf(struct xrdp_mcs* self, int userid, int chanid) out_uint8(s, (MCS_CJCF << 2) | 2); out_uint8(s, 0); out_uint16_be(s, userid); - out_uint16_be(s, chanid); + out_uint16_be(s, chanid); /* TODO Explain why we send this two times */ out_uint16_be(s, chanid); s_mark_end(s); if (xrdp_iso_send(self->iso_layer, s) != 0) @@ -122,20 +126,31 @@ xrdp_mcs_recv(struct xrdp_mcs* self, struct stream* s, int* chan) } in_uint8(s, opcode); appid = opcode >> 2; - if (appid == MCS_DPUM) + if (appid == MCS_DPUM) /* Disconnect Provider Ultimatum */ { + g_writeln("received Disconnect Provider Ultimatum"); DEBUG((" out xrdp_mcs_recv appid != MCS_DPUM")); return 1; } /* this is channels getting added from the client */ if (appid == MCS_CJRQ) { + g_writeln("channel join request received"); in_uint16_be(s, userid); in_uint16_be(s, chanid); - DEBUG((" adding channel %4.4x", chanid)); - xrdp_mcs_send_cjcf(self, userid, chanid); + DEBUG(("xrdp_mcs_recv adding channel %4.4x", chanid)); + if(xrdp_mcs_send_cjcf(self, userid, chanid)!=0) + { + g_writeln("Non handled error from xrdp_mcs_send_cjcf") ; + } continue; } + if(appid==MCS_SDRQ || appid==MCS_SDIN) + { + break ; + }else{ + g_writeln("Recieved an unhandled appid:%d",appid); + } break; } if (appid != MCS_SDRQ) diff --git a/libxrdp/xrdp_rdp.c b/libxrdp/xrdp_rdp.c index f25ec274..54f8a24f 100644 --- a/libxrdp/xrdp_rdp.c +++ b/libxrdp/xrdp_rdp.c @@ -113,13 +113,25 @@ xrdp_rdp_read_config(struct xrdp_client_info* client_info) { client_info->crypt_level = 3; } + else + { + g_writeln("Warning: Your configured crypt level is" + "undefined 'high' will be used"); + client_info->crypt_level = 3; + } } else if (g_strcasecmp(item, "channel_code") == 0) { - if (g_strcasecmp(value, "1") == 0) + if ((g_strcasecmp(value, "yes") == 0) || + (g_strcasecmp(value, "1") == 0) || + (g_strcasecmp(value, "true") == 0)) { client_info->channel_code = 1; } + else + { + g_writeln("Info: All channels are disabled"); + } } else if (g_strcasecmp(item, "max_bpp") == 0) { @@ -223,7 +235,7 @@ xrdp_rdp_recv(struct xrdp_rdp* self, struct stream* s, int* code) { s->next_packet = 0; *code = -1; - DEBUG(("out xrdp_rdp_recv")); + DEBUG(("out (1) xrdp_rdp_recv")); return 0; } if (error != 0) @@ -235,35 +247,43 @@ xrdp_rdp_recv(struct xrdp_rdp* self, struct stream* s, int* code) { if (chan > MCS_GLOBAL_CHANNEL) { - xrdp_channel_process(self->sec_layer->chan_layer, s, chan); + if(xrdp_channel_process(self->sec_layer->chan_layer, s, chan)!=0) + { + g_writeln("xrdp_channel_process returned unhandled error") ; + } + }else{ + g_writeln("Wrong channel Id to be handled by xrdp_channel_process %d",chan); } s->next_packet = 0; *code = 0; - DEBUG(("out xrdp_rdp_recv")); + DEBUG(("out (2) xrdp_rdp_recv")); return 0; } s->next_packet = s->p; } else { + DEBUG(("xrdp_rdp_recv stream not touched")) s->p = s->next_packet; } if (!s_check_rem(s, 6)) { s->next_packet = 0; *code = 0; - DEBUG(("out xrdp_rdp_recv")); + DEBUG(("out (3) xrdp_rdp_recv")); len = (int)(s->end - s->p); g_writeln("xrdp_rdp_recv: bad RDP packet, length [%d]", len); return 0; + }else{ + in_uint16_le(s, len); + /*g_writeln("New len received : %d next packet: %d s_end: %d",len,s->next_packet,s->end); */ + in_uint16_le(s, pdu_code); + *code = pdu_code & 0xf; + in_uint8s(s, 2); /* mcs user id */ + s->next_packet += len; + DEBUG(("out (4) xrdp_rdp_recv")); + return 0; } - in_uint16_le(s, len); - in_uint16_le(s, pdu_code); - *code = pdu_code & 0xf; - in_uint8s(s, 2); /* mcs user id */ - s->next_packet += len; - DEBUG(("out xrdp_rdp_recv")); - return 0; } /*****************************************************************************/ diff --git a/libxrdp/xrdp_sec.c b/libxrdp/xrdp_sec.c index 952ff12f..381e8435 100644 --- a/libxrdp/xrdp_sec.c +++ b/libxrdp/xrdp_sec.c @@ -148,9 +148,20 @@ xrdp_sec_create(struct xrdp_rdp* owner, struct trans* trans, int crypt_level, self->rc4_key_size = 2; self->crypt_level = 3; break; + default: + g_writeln("Fatal : Illegal crypt_level"); + break ; } self->channel_code = channel_code; + if(self->decrypt_rc4_info!=NULL) + { + g_writeln("xrdp_sec_create - decrypt_rc4_info already created !!!"); + } self->decrypt_rc4_info = ssl_rc4_info_create(); + if(self->encrypt_rc4_info!=NULL) + { + g_writeln("xrdp_sec_create - encrypt_rc4_info already created !!!"); + } self->encrypt_rc4_info = ssl_rc4_info_create(); self->mcs_layer = xrdp_mcs_create(self, trans, &self->client_mcs_data, &self->server_mcs_data); @@ -165,14 +176,17 @@ xrdp_sec_delete(struct xrdp_sec* self) { if (self == 0) { + g_writeln("xrdp_sec_delete: indata is null"); return; } xrdp_channel_delete(self->chan_layer); xrdp_mcs_delete(self->mcs_layer); - ssl_rc4_info_delete(self->decrypt_rc4_info); - ssl_rc4_info_delete(self->encrypt_rc4_info); + ssl_rc4_info_delete(self->decrypt_rc4_info); /* TODO clear all data */ + ssl_rc4_info_delete(self->encrypt_rc4_info); /* TODO clear all data */ g_free(self->client_mcs_data.data); g_free(self->server_mcs_data.data); + /* Crypto information must always be cleared */ + g_memset(self,0,sizeof(struct xrdp_sec)); g_free(self); } @@ -722,6 +736,7 @@ xrdp_sec_process_mcs_data_channels(struct xrdp_sec* self, struct stream* s) /* this is an option set in xrdp.ini */ if (self->channel_code != 1) /* are channels on? */ { + g_writeln("Processing channel data from client - The channel is off"); return 0; } in_uint32_le(s, num_channels); diff --git a/rdp/rdp_sec.c b/rdp/rdp_sec.c index e57c188d..5efab76e 100644 --- a/rdp/rdp_sec.c +++ b/rdp/rdp_sec.c @@ -46,7 +46,15 @@ rdp_sec_create(struct rdp_rdp* owner) init_stream(self->server_mcs_data, 8192); self->mcs_layer = rdp_mcs_create(self, self->client_mcs_data, self->server_mcs_data); + if(self->decrypt_rc4_info!=NULL) + { + g_writeln("rdp_sec_create - decrypt_rc4_info already created !!!"); + } self->decrypt_rc4_info = ssl_rc4_info_create(); + if(self->encrypt_rc4_info!=NULL) + { + g_writeln("rdp_sec_create - encrypt_rc4_info already created !!!"); + } self->encrypt_rc4_info = ssl_rc4_info_create(); self->lic_layer = rdp_lic_create(self); return self; From e5fb05e9cba476ec67f71fee1d79ddd5cdd12f2c Mon Sep 17 00:00:00 2001 From: norrarvid Date: Mon, 4 Jun 2012 10:11:11 +0200 Subject: [PATCH 08/17] Support for TCP keepalive and TCP no_delay added --- common/os_calls.c | 52 +++++++++++++++++++++++++++++++++++++++++++--- common/os_calls.h | 2 ++ xrdp/xrdp.ini | 6 ++++++ xrdp/xrdp_listen.c | 43 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 100 insertions(+), 3 deletions(-) diff --git a/common/os_calls.c b/common/os_calls.c index 211adc82..a0a8304c 100644 --- a/common/os_calls.c +++ b/common/os_calls.c @@ -321,9 +321,11 @@ g_getchar(void) } /*****************************************************************************/ +/*Returns 0 on success*/ int APP_CC g_tcp_set_no_delay(int sck) { + int ret = 1 ; /*error*/ #if defined(_WIN32) int option_value; int option_len; @@ -341,11 +343,55 @@ g_tcp_set_no_delay(int sck) { option_value = 1; option_len = sizeof(option_value); - setsockopt(sck, IPPROTO_TCP, TCP_NODELAY, (char*)&option_value, - option_len); + if(setsockopt(sck, IPPROTO_TCP, TCP_NODELAY, (char*)&option_value, + option_len)==0) + { + ret = 0 ; /* success */ + } } } - return 0; + else + { + g_writeln("Error getting tcp_nodelay"); + } + return ret; +} + +/*****************************************************************************/ +/*Returns 0 on success*/ +int APP_CC +g_tcp_set_keepalive(int sck) +{ + int ret = 1 ; /*error*/ +#if defined(_WIN32) + int option_value; + int option_len; +#else + int option_value; + unsigned int option_len; +#endif + + option_len = sizeof(option_value); + /* SOL_TCP IPPROTO_TCP */ + if (getsockopt(sck, SOL_SOCKET, SO_KEEPALIVE, (char*)&option_value, + &option_len) == 0) + { + if (option_value == 0) + { + option_value = 1; + option_len = sizeof(option_value); + if(setsockopt(sck, SOL_SOCKET, SO_KEEPALIVE, (char*)&option_value, + option_len)==0) + { + ret = 0 ; /* success */ + } + } + } + else + { + g_writeln("Error getting tcp_keepalive"); + } + return ret; } /*****************************************************************************/ diff --git a/common/os_calls.h b/common/os_calls.h index ddcb59d8..e23550fc 100644 --- a/common/os_calls.h +++ b/common/os_calls.h @@ -64,6 +64,8 @@ g_getchar(void); int APP_CC g_tcp_set_no_delay(int sck); int APP_CC +g_tcp_set_keepalive(int sck); +int APP_CC g_tcp_socket(void); int APP_CC g_tcp_local_socket(void); diff --git a/xrdp/xrdp.ini b/xrdp/xrdp.ini index af5f2650..be59be45 100644 --- a/xrdp/xrdp.ini +++ b/xrdp/xrdp.ini @@ -7,6 +7,12 @@ crypt_level=low channel_code=1 max_bpp=24 fork=yes +# regulate if the listening socket use socket option tcp_nodelay +# no buffering will be performed in the TCP stack +tcp_nodelay=yes +# regulate if the listening socket use socket option keepalive +# if the network connection disappear without close messages the connection will be closed +tcp_keepalive=yes #black=000000 #grey=d6d3ce #dark_grey=808080 diff --git a/xrdp/xrdp_listen.c b/xrdp/xrdp_listen.c index bbdd729a..d3529ce5 100644 --- a/xrdp/xrdp_listen.c +++ b/xrdp/xrdp_listen.c @@ -130,6 +130,7 @@ xrdp_process_run(void* in_val) static int xrdp_listen_get_port_address(char* port, int port_bytes, char* address, int address_bytes, + int *tcp_nodelay, int *tcp_keepalive, struct xrdp_startup_params* startup_param) { int fd; @@ -147,6 +148,8 @@ xrdp_listen_get_port_address(char* port, int port_bytes, /* see if port or address is in xrdp.ini file */ g_snprintf(cfg_file, 255, "%s/xrdp.ini", XRDP_CFG_PATH); fd = g_file_open(cfg_file); + *tcp_nodelay = 0 ; + *tcp_keepalive = 0 ; if (fd > 0) { names = list_create(); @@ -185,6 +188,28 @@ xrdp_listen_get_port_address(char* port, int port_bytes, startup_param->fork = 1; } } + if (g_strcasecmp(val, "tcp_nodelay") == 0) + { + 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)) + { + *tcp_nodelay = 1 ; + } + } + if (g_strcasecmp(val, "tcp_keepalive") == 0) + { + 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)) + { + *tcp_keepalive = 1 ; + } + } } } } @@ -280,19 +305,37 @@ xrdp_listen_main_loop(struct xrdp_listen* self) tbus sync_obj; tbus sck_obj; tbus done_obj; + int tcp_nodelay; + int tcp_keepalive; self->status = 1; if (xrdp_listen_get_port_address(port, sizeof(port), address, sizeof(address), + &tcp_nodelay, &tcp_keepalive, self->startup_params) != 0) { g_writeln("xrdp_listen_main_loop: xrdp_listen_get_port failed"); self->status = -1; return 1; } + /*Create socket*/ error = trans_listen_address(self->listen_trans, port, address); if (error == 0) { + if(tcp_nodelay) + { + if(g_tcp_set_no_delay(self->listen_trans->sck)) + { + g_writeln("Error setting tcp_nodelay"); + } + } + if(tcp_keepalive) + { + if(g_tcp_set_keepalive(self->listen_trans->sck)) + { + g_writeln("Error setting tcp_keepalive"); + } + } self->listen_trans->trans_conn_in = xrdp_listen_conn_in; self->listen_trans->callback_data = self; term_obj = g_get_term_event(); From 048154ccefa549e94292473b4b7e8ea0a29fcefa Mon Sep 17 00:00:00 2001 From: norrarvid Date: Mon, 4 Jun 2012 14:06:09 +0200 Subject: [PATCH 09/17] missing init of variable added --- xrdp/xrdp_wm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xrdp/xrdp_wm.c b/xrdp/xrdp_wm.c index 14af31ed..c486f67b 100644 --- a/xrdp/xrdp_wm.c +++ b/xrdp/xrdp_wm.c @@ -1561,7 +1561,7 @@ xrdp_wm_log_wnd_notify(struct xrdp_bitmap* wnd, char *new_part_message; char *current_pointer = msg ; - int processedlen ; + int processedlen = 0; do{ new_part_message = g_strndup(current_pointer,LOG_WINDOW_CHAR_PER_LINE) ; g_writeln(new_part_message); From a1274b0320f8ec61934192e2711a464572c8548b Mon Sep 17 00:00:00 2001 From: norrarvid Date: Tue, 5 Jun 2012 09:59:04 +0200 Subject: [PATCH 10/17] Clear state required when relogin is performed --- xrdp/xrdp_login_wnd.c | 4 ++++ xrdp/xrdp_mm.c | 23 +++++++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/xrdp/xrdp_login_wnd.c b/xrdp/xrdp_login_wnd.c index 1ab90f95..996af0f9 100644 --- a/xrdp/xrdp_login_wnd.c +++ b/xrdp/xrdp_login_wnd.c @@ -224,6 +224,10 @@ xrdp_wm_ok_clicked(struct xrdp_bitmap* wnd) xrdp_wm_set_login_mode(wm, 2); } } + else + { + log_message(LOG_LEVEL_ERROR,"Combo is 0 - potential programming error"); + } return 0; } diff --git a/xrdp/xrdp_mm.c b/xrdp/xrdp_mm.c index 2eb538c2..8ca71505 100644 --- a/xrdp/xrdp_mm.c +++ b/xrdp/xrdp_mm.c @@ -1056,6 +1056,27 @@ int access_control(char *username, char *password, char *srv){ } #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) @@ -1083,6 +1104,8 @@ xrdp_mm_connect(struct xrdp_mm* self) 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)); From 42edcbb6c193e5e825e7600a6784bd48fa9bf503 Mon Sep 17 00:00:00 2001 From: norrarvid Date: Thu, 7 Jun 2012 13:46:44 +0200 Subject: [PATCH 11/17] Improved logging --- sesman/libscp/libscp_v0.c | 4 ++-- sesman/scp_v0.c | 45 ++++++++++++++++++++++++++------------- xrdp/xrdp_mm.c | 1 + 3 files changed, 33 insertions(+), 17 deletions(-) diff --git a/sesman/libscp/libscp_v0.c b/sesman/libscp/libscp_v0.c index 32ef586f..f92383d4 100644 --- a/sesman/libscp/libscp_v0.c +++ b/sesman/libscp/libscp_v0.c @@ -283,7 +283,7 @@ scp_v0s_accept(struct SCP_CONNECTION* c, struct SCP_SESSION** s, int skipVchk) session = scp_session_create(); if (0 == session) { - /* until syslog merge log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__);*/ + /* until syslog merge log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: network error", __LINE__);*/ return SCP_SERVER_STATE_INTERNAL_ERR; } @@ -297,7 +297,7 @@ scp_v0s_accept(struct SCP_CONNECTION* c, struct SCP_SESSION** s, int skipVchk) if (0 != scp_session_set_username(session, buf)) { scp_session_destroy(session); - /* until syslog merge log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: error setting username", __LINE__);*/ + /* until syslog merge log_message(s_log, LOG_LEVEL_WARNING, "[v0:%d] connection aborted: error setting username", __LINE__);*/ return SCP_SERVER_STATE_INTERNAL_ERR; } diff --git a/sesman/scp_v0.c b/sesman/scp_v0.c index 75abb14a..b4e1a845 100644 --- a/sesman/scp_v0.c +++ b/sesman/scp_v0.c @@ -42,21 +42,32 @@ scp_v0_process(struct SCP_CONNECTION* c, struct SCP_SESSION* s) { /* this is just authentication in a gateway situation */ /* g_writeln("SCP_GW_AUTHENTICATION message received"); */ - if(data){ - if (1 == access_login_allowed(s->username)) - { + if(data) + { + if (1 == access_login_allowed(s->username)) + { /* the user is member of the correct groups. */ scp_v0s_replyauthentication(c,0); + log_message( LOG_LEVEL_INFO,"Access permitted for user: %s", + s->username); /* g_writeln("Connection allowed"); */ - }else{ - scp_v0s_replyauthentication(c,3); + } + else + { + scp_v0s_replyauthentication(c,3); + log_message( LOG_LEVEL_INFO,"Username okey but group problem for user: %s", + s->username); /* g_writeln("user password ok, but group problem"); */ - } - }else{ - /* g_writeln("username or password error"); */ - scp_v0s_replyauthentication(c,2); - } - auth_end(data); + } + } + else + { + /* g_writeln("username or password error"); */ + log_message( LOG_LEVEL_INFO,"Username or password error for user: %s", + s->username); + scp_v0s_replyauthentication(c,2); + } + auth_end(data); } else if (data) { @@ -66,11 +77,13 @@ scp_v0_process(struct SCP_CONNECTION* c, struct SCP_SESSION* s) display = s_item->display; if (0 != s->client_ip) { - log_message( LOG_LEVEL_INFO, "++ reconnected session: username %s, display :%d.0, session_pid %d, ip %s", s->username, display, s_item->pid, s->client_ip); + log_message( LOG_LEVEL_INFO, "++ reconnected session: username %s, display :%d.0, " + "session_pid %d, ip %s", s->username, display, s_item->pid, s->client_ip); } else { - log_message(LOG_LEVEL_INFO, "++ reconnected session: username %s, display :%d.0, session_pid %d", s->username, display, s_item->pid); + log_message(LOG_LEVEL_INFO, "++ reconnected session: username %s, display :%d.0, " + "session_pid %d", s->username, display, s_item->pid); } auth_end(data); /* don't set data to null here */ @@ -82,11 +95,13 @@ scp_v0_process(struct SCP_CONNECTION* c, struct SCP_SESSION* s) { if (0 != s->client_ip) { - log_message(LOG_LEVEL_INFO, "++ created session (access granted): username %s, ip %s", s->username, s->client_ip); + log_message(LOG_LEVEL_INFO, "++ created session (access granted): " + "username %s, ip %s", s->username, s->client_ip); } else { - log_message(LOG_LEVEL_INFO, "++ created session (access granted): username %s", s->username); + log_message(LOG_LEVEL_INFO, "++ created session (access granted): " + "username %s", s->username); } if (SCP_SESSION_TYPE_XVNC == s->type) diff --git a/xrdp/xrdp_mm.c b/xrdp/xrdp_mm.c index 8ca71505..9cfb30a4 100644 --- a/xrdp/xrdp_mm.c +++ b/xrdp/xrdp_mm.c @@ -21,6 +21,7 @@ */ #include "xrdp.h" +#include "log.h" #define ACCESS /*****************************************************************************/ From b52bf1b838c35c61479ff4d8ba139c29daaeb6cd Mon Sep 17 00:00:00 2001 From: Jay Sorg Date: Thu, 14 Jun 2012 14:37:02 -0700 Subject: [PATCH 12/17] libxrdp: started adding RAIL support --- common/rail.h | 147 +++++++++ libxrdp/Makefile.am | 3 +- libxrdp/libxrdp.h | 2 + libxrdp/xrdp_orders.c | 2 +- libxrdp/xrdp_orders_rail.c | 625 +++++++++++++++++++++++++++++++++++++ libxrdp/xrdp_orders_rail.h | 50 +++ 6 files changed, 827 insertions(+), 2 deletions(-) create mode 100644 common/rail.h create mode 100644 libxrdp/xrdp_orders_rail.c create mode 100644 libxrdp/xrdp_orders_rail.h diff --git a/common/rail.h b/common/rail.h new file mode 100644 index 00000000..deed3a9e --- /dev/null +++ b/common/rail.h @@ -0,0 +1,147 @@ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if !defined(_RAIL_H) +#define _RAIL_H + +/* + ORDER_TYPE_WINDOW + WINDOW_ORDER_TYPE_WINDOW + WINDOW_ORDER_ICON + WINDOW_ORDER_CACHED_ICON + WINDOW_ORDER_STATE_DELETED + WINDOW_ORDER_STATE_NEW on + WINDOW_ORDER_STATE_NEW off + WINDOW_ORDER_TYPE_NOTIFY + WINDOW_ORDER_STATE_DELETED + WINDOW_ORDER_STATE_NEW on + WINDOW_ORDER_STATE_NEW off + WINDOW_ORDER_TYPE_DESKTOP + WINDOW_ORDER_FIELD_DESKTOP_NONE on + WINDOW_ORDER_FIELD_DESKTOP_NONE off +*/ + +/* Window Order Header Flags */ +#define WINDOW_ORDER_TYPE_WINDOW 0x01000000 +#define WINDOW_ORDER_TYPE_NOTIFY 0x02000000 +#define WINDOW_ORDER_TYPE_DESKTOP 0x04000000 +#define WINDOW_ORDER_STATE_NEW 0x10000000 +#define WINDOW_ORDER_STATE_DELETED 0x20000000 +#define WINDOW_ORDER_FIELD_OWNER 0x00000002 +#define WINDOW_ORDER_FIELD_STYLE 0x00000008 +#define WINDOW_ORDER_FIELD_SHOW 0x00000010 +#define WINDOW_ORDER_FIELD_TITLE 0x00000004 +#define WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET 0x00004000 +#define WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE 0x00010000 +#define WINDOW_ORDER_FIELD_RP_CONTENT 0x00020000 +#define WINDOW_ORDER_FIELD_ROOT_PARENT 0x00040000 +#define WINDOW_ORDER_FIELD_WND_OFFSET 0x00000800 +#define WINDOW_ORDER_FIELD_WND_CLIENT_DELTA 0x00008000 +#define WINDOW_ORDER_FIELD_WND_SIZE 0x00000400 +#define WINDOW_ORDER_FIELD_WND_RECTS 0x00000100 +#define WINDOW_ORDER_FIELD_VIS_OFFSET 0x00001000 +#define WINDOW_ORDER_FIELD_VISIBILITY 0x00000200 +#define WINDOW_ORDER_FIELD_ICON_BIG 0x00002000 +#define WINDOW_ORDER_ICON 0x40000000 +#define WINDOW_ORDER_CACHED_ICON 0x80000000 +#define WINDOW_ORDER_FIELD_NOTIFY_VERSION 0x00000008 +#define WINDOW_ORDER_FIELD_NOTIFY_TIP 0x00000001 +#define WINDOW_ORDER_FIELD_NOTIFY_INFO_TIP 0x00000002 +#define WINDOW_ORDER_FIELD_NOTIFY_STATE 0x00000004 +#define WINDOW_ORDER_FIELD_DESKTOP_NONE 0x00000001 +#define WINDOW_ORDER_FIELD_DESKTOP_HOOKED 0x00000002 +#define WINDOW_ORDER_FIELD_DESKTOP_ARC_COMPLETED 0x00000004 +#define WINDOW_ORDER_FIELD_DESKTOP_ARC_BEGAN 0x00000008 +#define WINDOW_ORDER_FIELD_DESKTOP_ZORDER 0x00000010 +#define WINDOW_ORDER_FIELD_DESKTOP_ACTIVE_WND 0x00000020 + +struct rail_icon_info +{ + int bpp; + int width; + int height; + int cmap_bytes; + int mask_bytes; + int data_bytes; + char* mask; + char* cmap; + char* data; +}; + +struct rail_window_rect +{ + short left; + short top; + short right; + short bottom; +}; + +struct rail_notify_icon_infotip +{ + int timeout; + int flags; + char* text; + char* title; +}; + +struct rail_window_state_order +{ + int owner_window_id; + int style; + int extended_style; + int show_state; + char* title_info; + int client_offset_x; + int client_offset_y; + int client_area_width; + int client_area_height; + int rp_content; + int root_parent_handle; + int window_offset_x; + int window_offset_y; + int window_client_delta_x; + int window_client_delta_y; + int window_width; + int window_height; + int num_window_rects; + struct rail_window_rect* window_rects; + int visible_offset_x; + int visible_offset_y; + int num_visibility_rects; + struct rail_window_rect* visibility_rects; +}; + +struct rail_notify_state_order +{ + int version; + char* tool_tip; + struct rail_notify_icon_infotip infotip; + int state; + int icon_cache_entry; + int icon_cache_id; + struct rail_icon_info icon_info; +}; + +struct rail_monitored_desktop_order +{ + int active_window_id; + int num_window_ids; + int* window_ids; +}; + +#endif diff --git a/libxrdp/Makefile.am b/libxrdp/Makefile.am index 08fb7130..ad891bd8 100644 --- a/libxrdp/Makefile.am +++ b/libxrdp/Makefile.am @@ -50,7 +50,8 @@ libxrdp_la_SOURCES = \ xrdp_sec.c \ xrdp_tcp.c \ xrdp_bitmap_compress.c \ - xrdp_jpeg_compress.c + xrdp_jpeg_compress.c \ + xrdp_orders_rail.c libxrdp_la_LDFLAGS = \ $(EXTRA_FLAGS) diff --git a/libxrdp/libxrdp.h b/libxrdp/libxrdp.h index 7aae38b5..7792d157 100644 --- a/libxrdp/libxrdp.h +++ b/libxrdp/libxrdp.h @@ -325,6 +325,8 @@ xrdp_orders_send(struct xrdp_orders* self); int APP_CC xrdp_orders_force_send(struct xrdp_orders* self); int APP_CC +xrdp_orders_check(struct xrdp_orders* self, int max_size); +int APP_CC xrdp_orders_rect(struct xrdp_orders* self, int x, int y, int cx, int cy, int color, struct xrdp_rect* rect); int APP_CC diff --git a/libxrdp/xrdp_orders.c b/libxrdp/xrdp_orders.c index cff1324a..d068c39a 100644 --- a/libxrdp/xrdp_orders.c +++ b/libxrdp/xrdp_orders.c @@ -152,7 +152,7 @@ xrdp_orders_force_send(struct xrdp_orders* self) /* check if the current order will fit in packet size of 16384, if not */ /* send what we got and init a new one */ /* returns error */ -static int APP_CC +int APP_CC xrdp_orders_check(struct xrdp_orders* self, int max_size) { int size; diff --git a/libxrdp/xrdp_orders_rail.c b/libxrdp/xrdp_orders_rail.c new file mode 100644 index 00000000..087cf42e --- /dev/null +++ b/libxrdp/xrdp_orders_rail.c @@ -0,0 +1,625 @@ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "libxrdp.h" +#include "rail.h" + +/* [MS-RDPERP]: Remote Desktop Protocol: + Remote Programs Virtual Channel Extension + http://msdn.microsoft.com/en-us/library/cc242568(v=prot.10) */ + +/*****************************************************************************/ +/* RAIL */ +/* returns error */ +int APP_CC +xrdp_orders_send_window_delete(struct xrdp_orders* self, int window_id) +{ + int order_size; + int order_flags; + int field_present_flags; + + order_size = 11; + xrdp_orders_check(self, order_size); + self->order_count++; + order_flags = RDP_ORDER_SECONDARY; + order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */ + out_uint8(self->out_s, order_flags); + /* orderSize (2 bytes) */ + out_uint16_le(self->out_s, order_size); + /* FieldsPresentFlags (4 bytes) */ + field_present_flags = WINDOW_ORDER_TYPE_WINDOW | WINDOW_ORDER_STATE_DELETED; + out_uint32_le(self->out_s, field_present_flags); + /* windowId (4 bytes) */ + out_uint32_le(self->out_s, window_id); + return 0; +} + +/*****************************************************************************/ +/* RAIL */ +/* returns error */ +/* flags can contain WINDOW_ORDER_STATE_NEW and/or + WINDOW_ORDER_FIELD_ICON_BIG */ +int APP_CC +xrdp_orders_send_window_cached_icon(struct xrdp_orders* self, + int window_id, int cache_entry, + int cache_id, int flags) +{ + int order_size; + int order_flags; + int field_present_flags; + + order_size = 14; + xrdp_orders_check(self, order_size); + self->order_count++; + order_flags = RDP_ORDER_SECONDARY; + order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */ + out_uint8(self->out_s, order_flags); + /* orderSize (2 bytes) */ + out_uint16_le(self->out_s, order_size); + /* FieldsPresentFlags (4 bytes) */ + field_present_flags = flags | WINDOW_ORDER_TYPE_WINDOW | + WINDOW_ORDER_CACHED_ICON; + out_uint32_le(self->out_s, field_present_flags); + /* windowId (4 bytes) */ + out_uint32_le(self->out_s, window_id); + /* CacheEntry (2 bytes) */ + out_uint16_le(self->out_s, cache_entry); + /* CacheId (1 byte) */ + out_uint8(self->out_s, cache_id); + return 0; +} + +/*****************************************************************************/ +/* RAIL */ +/* returns error */ +static int APP_CC +xrdp_orders_send_ts_icon(struct stream* s, int cache_entry, int cache_id, + struct rail_icon_info* icon_info) +{ + int use_cmap; + + use_cmap = 0; + if ((icon_info->bpp == 1) || (icon_info->bpp == 2) || (icon_info->bpp == 4)) + { + use_cmap = 1; + } + + /* TS_ICON_INFO */ + out_uint16_le(s, cache_entry); + out_uint8(s, cache_id); + out_uint8(s, icon_info->bpp); + out_uint16_le(s, icon_info->width); + out_uint16_le(s, icon_info->height); + if (use_cmap) + { + out_uint16_le(s, icon_info->cmap_bytes); + } + out_uint16_le(s, icon_info->mask_bytes); + out_uint16_le(s, icon_info->data_bytes); + out_uint8p(s, icon_info->mask, icon_info->mask_bytes); + if (use_cmap) + { + out_uint8p(s, icon_info->cmap, icon_info->cmap_bytes); + } + out_uint8p(s, icon_info->data, icon_info->data_bytes); + return 0; +} + +/*****************************************************************************/ +/* RAIL */ +/* returns error */ +/* flags can contain WINDOW_ORDER_STATE_NEW and/or + WINDOW_ORDER_FIELD_ICON_BIG */ +int APP_CC +xrdp_orders_send_window_icon(struct xrdp_orders* self, + int window_id, int cache_entry, int cache_id, + struct rail_icon_info* icon_info, + int flags) +{ + int order_size; + int order_flags; + int field_present_flags; + int use_cmap; + + use_cmap = 0; + if ((icon_info->bpp == 1) || (icon_info->bpp == 2) || (icon_info->bpp == 4)) + { + use_cmap = 1; + } + order_size = 23 + icon_info->mask_bytes + icon_info->data_bytes; + if (use_cmap) + { + order_size += icon_info->cmap_bytes + 2; + } + xrdp_orders_check(self, order_size); + self->order_count++; + order_flags = RDP_ORDER_SECONDARY; + order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */ + out_uint8(self->out_s, order_flags); + /* orderSize (2 bytes) */ + out_uint16_le(self->out_s, order_size); + /* FieldsPresentFlags (4 bytes) */ + field_present_flags = flags | WINDOW_ORDER_TYPE_WINDOW | + WINDOW_ORDER_ICON; + out_uint32_le(self->out_s, field_present_flags); + /* windowId (4 bytes) */ + out_uint32_le(self->out_s, window_id); + + xrdp_orders_send_ts_icon(self->out_s, cache_entry, cache_id, icon_info); + + return 0; +} + +/*****************************************************************************/ +/* returns error */ +static int APP_CC +xrdp_orders_send_as_unicode(struct stream* s, const char* text) +{ + int str_chars; + int index; + int i32; + twchar wdst[256]; + + str_chars = g_mbstowcs(wdst, text, 255); + if (str_chars > 0) + { + i32 = str_chars * 2; + out_uint16_le(s, i32); + for (index = 0; index < str_chars; index++) + { + i32 = wdst[index]; + out_uint16_le(s, i32); + } + } + else + { + out_uint16_le(s, 0); + } + return 0; +} + +/*****************************************************************************/ +/* RAIL */ +/* returns error */ +/* flags can contain WINDOW_ORDER_STATE_NEW */ +int APP_CC +xrdp_orders_send_window_new_update(struct xrdp_orders* self, int window_id, + struct rail_window_state_order* window_state, + int flags) +{ + int order_size; + int order_flags; + int field_present_flags; + int num_chars; + int index; + + order_size = 11; + field_present_flags = flags | WINDOW_ORDER_TYPE_WINDOW; + if (field_present_flags & WINDOW_ORDER_FIELD_OWNER) + { + /* ownerWindowId (4 bytes) */ + order_size += 4; + } + if (field_present_flags & WINDOW_ORDER_FIELD_STYLE) + { + /* style (4 bytes) */ + order_size += 4; + /* extendedStyle (4 bytes) */ + order_size += 4; + } + if (field_present_flags & WINDOW_ORDER_FIELD_SHOW) + { + /* showState (1 byte) */ + order_size += 1; + } + if (field_present_flags & WINDOW_ORDER_FIELD_TITLE) + { + /* titleInfo */ + num_chars = g_mbstowcs(0, window_state->title_info, 0); + order_size += 2 * num_chars + 2; + } + if (field_present_flags & WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET) + { + /* clientOffsetX (4 bytes) */ + order_size += 4; + /* clientOffsetY (4 bytes) */ + order_size += 4; + } + if (field_present_flags & WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE) + { + /* clientAreaWidth (4 bytes) */ + order_size += 4; + /* clientAreaHeight (4 bytes) */ + order_size += 4; + } + if (field_present_flags & WINDOW_ORDER_FIELD_RP_CONTENT) + { + /* RPContent (1 byte) */ + order_size += 1; + } + if (field_present_flags & WINDOW_ORDER_FIELD_ROOT_PARENT) + { + /* rootParentHandle (4 bytes) */ + order_size += 4; + } + if (field_present_flags & WINDOW_ORDER_FIELD_WND_OFFSET) + { + /* windowOffsetX (4 bytes) */ + order_size += 4; + /* windowOffsetY (4 bytes) */ + order_size += 4; + } + if (field_present_flags & WINDOW_ORDER_FIELD_WND_CLIENT_DELTA) + { + /* windowClientDeltaX (4 bytes) */ + order_size += 4; + /* windowClientDeltaY (4 bytes) */ + order_size += 4; + } + if (field_present_flags & WINDOW_ORDER_FIELD_WND_SIZE) + { + /* windowWidth (4 bytes) */ + order_size += 4; + /* windowHeight (4 bytes) */ + order_size += 4; + } + if (field_present_flags & WINDOW_ORDER_FIELD_WND_RECTS) + { + /* numWindowRects (2 bytes) */ + order_size += 2; + order_size += 8 * window_state->num_window_rects; + } + if (field_present_flags & WINDOW_ORDER_FIELD_VIS_OFFSET) + { + /* visibleOffsetX (4 bytes) */ + order_size += 4; + /* visibleOffsetY (4 bytes) */ + order_size += 4; + } + if (field_present_flags & WINDOW_ORDER_FIELD_VISIBILITY) + { + /* numVisibilityRects (2 bytes) */ + order_size += 2; + order_size += 8 * window_state->num_visibility_rects; + } + + xrdp_orders_check(self, order_size); + self->order_count++; + order_flags = RDP_ORDER_SECONDARY; + order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */ + out_uint8(self->out_s, order_flags); + /* orderSize (2 bytes) */ + out_uint16_le(self->out_s, order_size); + /* FieldsPresentFlags (4 bytes) */ + out_uint32_le(self->out_s, field_present_flags); + /* windowId (4 bytes) */ + out_uint32_le(self->out_s, window_id); + + if (field_present_flags & WINDOW_ORDER_FIELD_OWNER) + { + /* ownerWindowId (4 bytes) */ + out_uint32_le(self->out_s, window_state->owner_window_id); + } + if (field_present_flags & WINDOW_ORDER_FIELD_STYLE) + { + /* style (4 bytes) */ + out_uint32_le(self->out_s, window_state->style); + /* extendedStyle (4 bytes) */ + out_uint32_le(self->out_s, window_state->extended_style); + } + if (field_present_flags & WINDOW_ORDER_FIELD_SHOW) + { + /* showState (1 byte) */ + out_uint8(self->out_s, window_state->show_state); + } + if (field_present_flags & WINDOW_ORDER_FIELD_TITLE) + { + /* titleInfo */ + xrdp_orders_send_as_unicode(self->out_s, window_state->title_info); + } + if (field_present_flags & WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET) + { + /* clientOffsetX (4 bytes) */ + out_uint32_le(self->out_s, window_state->client_offset_x); + /* clientOffsetY (4 bytes) */ + out_uint32_le(self->out_s, window_state->client_offset_y); + } + if (field_present_flags & WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE) + { + /* clientAreaWidth (4 bytes) */ + out_uint32_le(self->out_s, window_state->client_area_width); + /* clientAreaHeight (4 bytes) */ + out_uint32_le(self->out_s, window_state->client_area_height); + } + if (field_present_flags & WINDOW_ORDER_FIELD_RP_CONTENT) + { + /* RPContent (1 byte) */ + out_uint8(self->out_s, window_state->rp_content); + } + if (field_present_flags & WINDOW_ORDER_FIELD_ROOT_PARENT) + { + /* rootParentHandle (4 bytes) */ + out_uint32_le(self->out_s, window_state->root_parent_handle); + } + if (field_present_flags & WINDOW_ORDER_FIELD_WND_OFFSET) + { + /* windowOffsetX (4 bytes) */ + out_uint32_le(self->out_s, window_state->window_offset_x); + /* windowOffsetY (4 bytes) */ + out_uint32_le(self->out_s, window_state->window_offset_y); + } + if (field_present_flags & WINDOW_ORDER_FIELD_WND_CLIENT_DELTA) + { + /* windowClientDeltaX (4 bytes) */ + out_uint32_le(self->out_s, window_state->window_client_delta_x); + /* windowClientDeltaY (4 bytes) */ + out_uint32_le(self->out_s, window_state->window_client_delta_y); + } + if (field_present_flags & WINDOW_ORDER_FIELD_WND_SIZE) + { + /* windowWidth (4 bytes) */ + out_uint32_le(self->out_s, window_state->window_width); + /* windowHeight (4 bytes) */ + out_uint32_le(self->out_s, window_state->window_height); + } + if (field_present_flags & WINDOW_ORDER_FIELD_WND_RECTS) + { + /* numWindowRects (2 bytes) */ + out_uint16_le(self->out_s, window_state->num_window_rects); + for (index = 0; index < window_state->num_window_rects; index++) + { + out_uint16_le(self->out_s, window_state->window_rects[index].left); + out_uint16_le(self->out_s, window_state->window_rects[index].top); + out_uint16_le(self->out_s, window_state->window_rects[index].right); + out_uint16_le(self->out_s, window_state->window_rects[index].bottom); + } + } + if (field_present_flags & WINDOW_ORDER_FIELD_VIS_OFFSET) + { + /* visibleOffsetX (4 bytes) */ + out_uint32_le(self->out_s, window_state->visible_offset_x); + /* visibleOffsetY (4 bytes) */ + out_uint32_le(self->out_s, window_state->visible_offset_y); + } + if (field_present_flags & WINDOW_ORDER_FIELD_VISIBILITY) + { + /* numVisibilityRects (2 bytes) */ + out_uint16_le(self->out_s, window_state->num_visibility_rects); + for (index = 0; index < window_state->num_visibility_rects; index++) + { + out_uint16_le(self->out_s, window_state->visibility_rects[index].left); + out_uint16_le(self->out_s, window_state->visibility_rects[index].top); + out_uint16_le(self->out_s, window_state->visibility_rects[index].right); + out_uint16_le(self->out_s, window_state->visibility_rects[index].bottom); + } + } + + return 0; +} + +/*****************************************************************************/ +/* RAIL */ +/* returns error */ +int APP_CC +xrdp_orders_send_notify_delete(struct xrdp_orders* self, int window_id, + int notify_id) +{ + int order_size; + int order_flags; + int field_present_flags; + + order_size = 15; + xrdp_orders_check(self, order_size); + self->order_count++; + order_flags = RDP_ORDER_SECONDARY; + order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */ + out_uint8(self->out_s, order_flags); + /* orderSize (2 bytes) */ + out_uint16_le(self->out_s, order_size); + /* FieldsPresentFlags (4 bytes) */ + field_present_flags = WINDOW_ORDER_TYPE_NOTIFY | WINDOW_ORDER_STATE_DELETED; + out_uint32_le(self->out_s, field_present_flags); + /* windowId (4 bytes) */ + out_uint32_le(self->out_s, window_id); + /* notifyIconId (4 bytes) */ + out_uint32_le(self->out_s, notify_id); + return 0; +} + +/*****************************************************************************/ +/* RAIL */ +/* returns error */ +/* flags can contain WINDOW_ORDER_STATE_NEW */ +int APP_CC +xrdp_orders_send_notify_new_update(struct xrdp_orders* self, + int window_id, int notify_id, + struct rail_notify_state_order* notify_state, + int flags) +{ + int order_size; + int order_flags; + int field_present_flags; + int num_chars; + int use_cmap; + + order_size = 15; + field_present_flags = flags | WINDOW_ORDER_TYPE_NOTIFY; + if (field_present_flags & WINDOW_ORDER_FIELD_NOTIFY_VERSION) + { + /* Version (4 bytes) */ + order_size += 4; + } + if (field_present_flags & WINDOW_ORDER_FIELD_NOTIFY_TIP) + { + /* ToolTip (variable) UNICODE_STRING */ + num_chars = g_mbstowcs(0, notify_state->tool_tip, 0); + order_size += 2 * num_chars + 2; + } + if (field_present_flags & WINDOW_ORDER_FIELD_NOTIFY_INFO_TIP) + { + /* InfoTip (variable) TS_NOTIFY_ICON_INFOTIP */ + /* UNICODE_STRING */ + num_chars = g_mbstowcs(0, notify_state->infotip.title, 0); + order_size += 2 * num_chars + 2; + /* UNICODE_STRING */ + num_chars = g_mbstowcs(0, notify_state->infotip.text, 0); + order_size += 2 * num_chars + 2; + /* Timeout (4 bytes) */ + /* InfoFlags (4 bytes) */ + order_size += 8; + } + if (field_present_flags & WINDOW_ORDER_FIELD_NOTIFY_STATE) + { + /* State (4 bytes) */ + order_size += 4; + } + if (field_present_flags & WINDOW_ORDER_ICON) + { + /* Icon (variable) */ + use_cmap = 0; + if ((notify_state->icon_info.bpp == 1) || (notify_state->icon_info.bpp == 2) || + (notify_state->icon_info.bpp == 4)) + { + use_cmap = 1; + } + order_size += 12 + notify_state->icon_info.mask_bytes + + notify_state->icon_info.data_bytes; + if (use_cmap) + { + order_size += notify_state->icon_info.cmap_bytes + 2; + } + } + if (field_present_flags & WINDOW_ORDER_CACHED_ICON) + { + /* CachedIcon (3 bytes) */ + order_size += 3; + } + + xrdp_orders_check(self, order_size); + self->order_count++; + order_flags = RDP_ORDER_SECONDARY; + order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */ + out_uint8(self->out_s, order_flags); + /* orderSize (2 bytes) */ + out_uint16_le(self->out_s, order_size); + /* FieldsPresentFlags (4 bytes) */ + out_uint32_le(self->out_s, field_present_flags); + /* windowId (4 bytes) */ + out_uint32_le(self->out_s, window_id); + /* notifyIconId (4 bytes) */ + out_uint32_le(self->out_s, notify_id); + + if (field_present_flags & WINDOW_ORDER_FIELD_NOTIFY_VERSION) + { + /* Version (4 bytes) */ + out_uint32_le(self->out_s, notify_state->version); + } + if (field_present_flags & WINDOW_ORDER_FIELD_NOTIFY_TIP) + { + /* ToolTip (variable) UNICODE_STRING */ + xrdp_orders_send_as_unicode(self->out_s, notify_state->tool_tip); + } + if (field_present_flags & WINDOW_ORDER_FIELD_NOTIFY_INFO_TIP) + { + /* InfoTip (variable) TS_NOTIFY_ICON_INFOTIP */ + out_uint32_le(self->out_s, notify_state->infotip.timeout); + out_uint32_le(self->out_s, notify_state->infotip.flags); + xrdp_orders_send_as_unicode(self->out_s, notify_state->infotip.text); + xrdp_orders_send_as_unicode(self->out_s, notify_state->infotip.title); + } + if (field_present_flags & WINDOW_ORDER_FIELD_NOTIFY_STATE) + { + /* State (4 bytes) */ + out_uint32_le(self->out_s, notify_state->state); + } + if (field_present_flags & WINDOW_ORDER_ICON) + { + /* Icon (variable) */ + xrdp_orders_send_ts_icon(self->out_s, notify_state->icon_cache_entry, + notify_state->icon_cache_id, + ¬ify_state->icon_info); + } + if (field_present_flags & WINDOW_ORDER_CACHED_ICON) + { + /* CacheEntry (2 bytes) */ + out_uint16_le(self->out_s, notify_state->icon_cache_entry); + /* CacheId (1 byte) */ + out_uint8(self->out_s, notify_state->icon_cache_id); + } + + return 0; +} + +/*****************************************************************************/ +/* RAIL */ +/* returns error */ +/* used for both Non-Monitored Desktop and Actively Monitored Desktop */ +int APP_CC +xrdp_orders_send_monitored_desktop(struct xrdp_orders* self, + struct rail_monitored_desktop_order* mdo, + int flags) +{ + int order_size; + int order_flags; + int field_present_flags; + int index; + + order_size = 7; + field_present_flags = flags | WINDOW_ORDER_TYPE_DESKTOP; + + if (field_present_flags & WINDOW_ORDER_FIELD_DESKTOP_ACTIVE_WND) + { + /* ActiveWindowId (4 bytes) */ + order_size += 4; + } + if (field_present_flags & WINDOW_ORDER_FIELD_DESKTOP_ZORDER) + { + /* NumWindowIds (1 byte) */ + order_size += 1; + /* WindowIds (variable) */ + order_size += mdo->num_window_ids * 4; + } + + xrdp_orders_check(self, order_size); + self->order_count++; + order_flags = RDP_ORDER_SECONDARY; + order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */ + out_uint8(self->out_s, order_flags); + /* orderSize (2 bytes) */ + out_uint16_le(self->out_s, order_size); + /* FieldsPresentFlags (4 bytes) */ + out_uint32_le(self->out_s, field_present_flags); + + if (field_present_flags & WINDOW_ORDER_FIELD_DESKTOP_ACTIVE_WND) + { + /* ActiveWindowId (4 bytes) */ + out_uint32_le(self->out_s, mdo->active_window_id); + } + if (field_present_flags & WINDOW_ORDER_FIELD_DESKTOP_ZORDER) + { + /* NumWindowIds (1 byte) */ + out_uint8(self->out_s, mdo->num_window_ids); + /* WindowIds (variable) */ + for (index = 0; index < mdo->num_window_ids; index++) + { + out_uint32_le(self->out_s, mdo->window_ids[index]); + } + } + + return 0; +} diff --git a/libxrdp/xrdp_orders_rail.h b/libxrdp/xrdp_orders_rail.h new file mode 100644 index 00000000..8f5b402f --- /dev/null +++ b/libxrdp/xrdp_orders_rail.h @@ -0,0 +1,50 @@ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if !defined(_XRDP_ORDERS_RAIL_H) +#define _XRDP_ORDERS_RAIL_H + +int APP_CC +xrdp_orders_send_window_delete(struct xrdp_orders* self, int window_id); +int APP_CC +xrdp_orders_send_window_cached_icon(struct xrdp_orders* self, + int window_id, int cache_entry, + int cache_id, int flags); +int APP_CC +xrdp_orders_send_window_icon(struct xrdp_orders* self, + int window_id, int cache_entry, int cache_id, + struct rail_icon_info* icon_info, + int flags); +int APP_CC +xrdp_orders_send_window_new_update(struct xrdp_orders* self, int window_id, + struct rail_window_state_order* window_state, + int flags); +int APP_CC +xrdp_orders_send_notify_delete(struct xrdp_orders* self, int window_id, + int notify_id); +int APP_CC +xrdp_orders_send_notify_new_update(struct xrdp_orders* self, + int window_id, int notify_id, + struct rail_notify_state_order* notify_state, + int flags); +int APP_CC +xrdp_orders_send_monitored_desktop(struct xrdp_orders* self, + struct rail_monitored_desktop_order* mdo, + int flags); + +#endif From 4ba8cdc343d96cd449c18c107f623e8e73d2d470 Mon Sep 17 00:00:00 2001 From: Jay Sorg Date: Thu, 14 Jun 2012 15:15:00 -0700 Subject: [PATCH 13/17] libxrdp: added RAIL caps --- common/xrdp_client_info.h | 6 ++++ libxrdp/xrdp_rdp.c | 64 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/common/xrdp_client_info.h b/common/xrdp_client_info.h index 7fe93c26..cdd77921 100644 --- a/common/xrdp_client_info.h +++ b/common/xrdp_client_info.h @@ -74,6 +74,12 @@ struct xrdp_client_info int offscreen_cache_size; int offscreen_cache_entries; int rfx; + /* CAPSETTYPE_RAIL */ + int rail_support_level; + /* CAPSETTYPE_WINDOW */ + int wnd_support_level; + int wnd_num_icon_caches; + int wnd_num_icon_cache_entries; }; #endif diff --git a/libxrdp/xrdp_rdp.c b/libxrdp/xrdp_rdp.c index fd163308..c9f5dedf 100644 --- a/libxrdp/xrdp_rdp.c +++ b/libxrdp/xrdp_rdp.c @@ -620,6 +620,21 @@ xrdp_rdp_send_demand_active(struct xrdp_rdp* self) out_uint8(s, 1); out_uint8s(s, 83); + /* Remote Programs Capability Set */ + caps_count++; + out_uint16_le(s, 0x0017); /* CAPSETTYPE_RAIL */ + out_uint16_le(s, 8); + out_uint32_le(s, 3); /* TS_RAIL_LEVEL_SUPPORTED + TS_RAIL_LEVEL_DOCKED_LANGBAR_SUPPORTED */ + + /* Window List Capability Set */ + caps_count++; + out_uint16_le(s, 0x0018); /* CAPSETTYPE_WINDOW */ + out_uint16_le(s, 11); + out_uint32_le(s, 2); /* TS_WINDOW_LEVEL_SUPPORTED_EX */ + out_uint8(s, 3); /* NumIconCaches */ + out_uint16_le(s, 12); /* NumIconCacheEntries */ + out_uint8s(s, 4); /* pad */ s_mark_end(s); @@ -825,6 +840,49 @@ xrdp_process_offscreen_bmpcache(struct xrdp_rdp* self, struct stream* s, return 0; } +/*****************************************************************************/ +static int APP_CC +xrdp_process_capset_rail(struct xrdp_rdp* self, struct stream* s, int len) +{ + int i32; + + if (len - 4 < 4) + { + g_writeln("xrdp_process_capset_rail: bad len"); + return 1; + } + in_uint32_le(s, i32); + self->client_info.rail_support_level = i32; + g_writeln("xrdp_process_capset_rail: rail_support_level %d", + self->client_info.rail_support_level); + return 0; +} + +/*****************************************************************************/ +static int APP_CC +xrdp_process_capset_window(struct xrdp_rdp* self, struct stream* s, int len) +{ + int i32; + + if (len - 4 < 7) + { + g_writeln("xrdp_process_capset_window: bad len"); + return 1; + } + in_uint32_le(s, i32); + self->client_info.wnd_support_level = i32; + in_uint8(s, i32); + self->client_info.wnd_num_icon_caches = i32; + in_uint16_le(s, i32); + self->client_info.wnd_num_icon_cache_entries = i32; + g_writeln("xrdp_process_capset_window wnd_support_level %d " + "wnd_num_icon_caches %d wnd_num_icon_cache_entries %d", + self->client_info.wnd_support_level, + self->client_info.wnd_num_icon_caches, + self->client_info.wnd_num_icon_cache_entries); + return 0; +} + /*****************************************************************************/ int APP_CC xrdp_rdp_process_confirm_active(struct xrdp_rdp* self, struct stream* s) @@ -915,6 +973,12 @@ xrdp_rdp_process_confirm_active(struct xrdp_rdp* self, struct stream* s) case 22: /* 22 */ DEBUG(("--22")); break; + case 0x0017: /* 23 CAPSETTYPE_RAIL */ + xrdp_process_capset_rail(self, s, len); + break; + case 0x0018: /* 24 CAPSETTYPE_WINDOW */ + xrdp_process_capset_window(self, s, len); + break; case 26: /* 26 */ DEBUG(("--26")); break; From 31a5dd33ddfa86e195469dff776e7ca1cf4d7b06 Mon Sep 17 00:00:00 2001 From: norrarvid Date: Mon, 18 Jun 2012 08:11:26 +0200 Subject: [PATCH 14/17] minor layout fixes --- common/os_calls.c | 18 +++++++++++------- xrdp/xrdp_listen.c | 2 +- xrdp/xrdp_mm.c | 6 +++--- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/common/os_calls.c b/common/os_calls.c index ae48fc94..2a97fc69 100644 --- a/common/os_calls.c +++ b/common/os_calls.c @@ -1079,13 +1079,15 @@ g_obj_wait(tbus* read_objs, int rcount, tbus* write_objs, int wcount, FD_SET(sck, &rfds); if (sck > max) { - max = sck; /*max holds the highest socket/descriptor number */ + max = sck; /*max holds the highest socket/descriptor number */ } } } - }else if(rcount>0){ - g_writeln("Programming error read_objs is null"); - return 1; /*error*/ + } + else if(rcount>0) + { + g_writeln("Programming error read_objs is null"); + return 1; /*error*/ } if(write_objs!=NULL){ for (i = 0; i < wcount; i++) @@ -1099,9 +1101,11 @@ g_obj_wait(tbus* read_objs, int rcount, tbus* write_objs, int wcount, } } } - }else if(wcount>0){ - g_writeln("Programming error write_objs is null"); - return 1; /*error*/ + } + else if(wcount>0) + { + g_writeln("Programming error write_objs is null"); + return 1; /*error*/ } res = select(max + 1, &rfds, &wfds, 0, ptime); if (res < 0) diff --git a/xrdp/xrdp_listen.c b/xrdp/xrdp_listen.c index b79ce1c2..0270d337 100644 --- a/xrdp/xrdp_listen.c +++ b/xrdp/xrdp_listen.c @@ -334,7 +334,7 @@ xrdp_listen_main_loop(struct xrdp_listen* self) if (g_is_wait_obj_set(done_obj)) /* pro_done_event */ { g_reset_wait_obj(done_obj); - /* a process has died remove it from lists*/ + /* a process has died remove it from lists*/ xrdp_listen_delete_done_pro(self); } /* Run the callback when accept() returns a new socket*/ diff --git a/xrdp/xrdp_mm.c b/xrdp/xrdp_mm.c index 5c8d325f..84a4a851 100644 --- a/xrdp/xrdp_mm.c +++ b/xrdp/xrdp_mm.c @@ -305,7 +305,7 @@ xrdp_mm_setup_mod1(struct xrdp_mm* self) if (func == 0) { g_snprintf(text, 255, "error finding proc mod_exit in %s, not a valid " - "xrdp backend", lib); + "xrdp backend", lib); xrdp_wm_log_msg(self->wm, text); } self->mod_exit = (int (*)(struct xrdp_mod*))func; @@ -318,7 +318,7 @@ xrdp_mm_setup_mod1(struct xrdp_mm* self) self->mod->size, self->mod->version); } }else{ - g_writeln("no mod_init or mod_exit address found") ; + g_writeln("no mod_init or mod_exit address found"); } } else @@ -1058,7 +1058,7 @@ xrdp_mm_connect(struct xrdp_mm* self) rv = 1 ; /* failure */ } }else{ - g_writeln("Failure setting up module"); + g_writeln("Failure setting up module"); } if (self->wm->login_mode != 10) { From 9cad7e8563f8f896df8524fd1c09692cb9578d80 Mon Sep 17 00:00:00 2001 From: norrarvid Date: Mon, 18 Jun 2012 08:23:36 +0200 Subject: [PATCH 15/17] layout fix + fix potential memory leak --- freerdp1/xrdp-freerdp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/freerdp1/xrdp-freerdp.c b/freerdp1/xrdp-freerdp.c index 2b23194e..d8b5b286 100644 --- a/freerdp1/xrdp-freerdp.c +++ b/freerdp1/xrdp-freerdp.c @@ -1337,6 +1337,7 @@ mod_exit(struct mod* mod) if(mod->inst == NULL) { LLOGLN(0, ("mod_exit - null pointer for inst:")); + g_free(mod); return 0 ; } freerdp_disconnect(mod->inst); @@ -1345,7 +1346,7 @@ mod_exit(struct mod* mod) /* this version has a bug with double free in freerdp_free */ } else - { + { freerdp_context_free(mod->inst); } freerdp_free(mod->inst); From 67a2a3c4c7c2487dffd487a93d7bfe3e89f2328f Mon Sep 17 00:00:00 2001 From: norrarvid Date: Mon, 18 Jun 2012 08:48:51 +0200 Subject: [PATCH 16/17] layout fix --- libxrdp/xrdp_channel.c | 2 +- libxrdp/xrdp_mcs.c | 6 ++++-- libxrdp/xrdp_rdp.c | 8 ++++++-- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/libxrdp/xrdp_channel.c b/libxrdp/xrdp_channel.c index 4085f650..092cefa4 100644 --- a/libxrdp/xrdp_channel.c +++ b/libxrdp/xrdp_channel.c @@ -66,7 +66,7 @@ xrdp_channel_delete(struct xrdp_channel* self) { return; } - memset(self,0,sizeof(struct xrdp_channel)); + g_memset(self,0,sizeof(struct xrdp_channel)); g_free(self); } diff --git a/libxrdp/xrdp_mcs.c b/libxrdp/xrdp_mcs.c index 57494191..1a7a0411 100644 --- a/libxrdp/xrdp_mcs.c +++ b/libxrdp/xrdp_mcs.c @@ -141,14 +141,16 @@ xrdp_mcs_recv(struct xrdp_mcs* self, struct stream* s, int* chan) DEBUG(("xrdp_mcs_recv adding channel %4.4x", chanid)); if(xrdp_mcs_send_cjcf(self, userid, chanid)!=0) { - g_writeln("Non handled error from xrdp_mcs_send_cjcf") ; + g_writeln("Non handled error from xrdp_mcs_send_cjcf") ; } continue; } if(appid==MCS_SDRQ || appid==MCS_SDIN) { break ; - }else{ + } + else + { g_writeln("Recieved an unhandled appid:%d",appid); } break; diff --git a/libxrdp/xrdp_rdp.c b/libxrdp/xrdp_rdp.c index 54f8a24f..497b9c7d 100644 --- a/libxrdp/xrdp_rdp.c +++ b/libxrdp/xrdp_rdp.c @@ -251,7 +251,9 @@ xrdp_rdp_recv(struct xrdp_rdp* self, struct stream* s, int* code) { g_writeln("xrdp_channel_process returned unhandled error") ; } - }else{ + } + else + { g_writeln("Wrong channel Id to be handled by xrdp_channel_process %d",chan); } s->next_packet = 0; @@ -274,7 +276,9 @@ xrdp_rdp_recv(struct xrdp_rdp* self, struct stream* s, int* code) len = (int)(s->end - s->p); g_writeln("xrdp_rdp_recv: bad RDP packet, length [%d]", len); return 0; - }else{ + } + else + { in_uint16_le(s, len); /*g_writeln("New len received : %d next packet: %d s_end: %d",len,s->next_packet,s->end); */ in_uint16_le(s, pdu_code); From fc49bf6b48878e9514fee3e3c8eb13789aefc71f Mon Sep 17 00:00:00 2001 From: norrarvid Date: Mon, 18 Jun 2012 09:11:52 +0200 Subject: [PATCH 17/17] Fix layout --- xrdp/xrdp_mm.c | 2 +- xrdp/xrdp_wm.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/xrdp/xrdp_mm.c b/xrdp/xrdp_mm.c index 10148e60..2b89dd7a 100644 --- a/xrdp/xrdp_mm.c +++ b/xrdp/xrdp_mm.c @@ -1744,7 +1744,7 @@ server_send_to_channel(struct xrdp_mod* mod, int channel_id, } else { - return 1 ; + return 1; } } diff --git a/xrdp/xrdp_wm.c b/xrdp/xrdp_wm.c index 4bf9f1b4..52bbc420 100644 --- a/xrdp/xrdp_wm.c +++ b/xrdp/xrdp_wm.c @@ -1396,7 +1396,8 @@ xrdp_wm_process_channel_data(struct xrdp_wm* self, if (self->mm->mod != 0) { chanid = LOWORD(param1); - if(is_channel_allowed(self, chanid)){ + if(is_channel_allowed(self, chanid)) + { if (self->mm->usechansrv) { rv = xrdp_mm_process_channel_data(self->mm, param1, param2,