diff options
Diffstat (limited to 'libxrdp')
-rw-r--r-- | libxrdp/Makefile.am | 5 | ||||
-rw-r--r-- | libxrdp/libxrdp.c | 152 | ||||
-rw-r--r-- | libxrdp/libxrdp.h | 14 | ||||
-rw-r--r-- | libxrdp/libxrdpinc.h | 40 | ||||
-rw-r--r-- | libxrdp/xrdp_channel.c | 16 | ||||
-rw-r--r-- | libxrdp/xrdp_fastpath.c | 6 | ||||
-rw-r--r-- | libxrdp/xrdp_jpeg_compress.c | 18 | ||||
-rw-r--r-- | libxrdp/xrdp_mcs.c | 27 | ||||
-rw-r--r-- | libxrdp/xrdp_orders.c | 266 | ||||
-rw-r--r-- | libxrdp/xrdp_orders_rail.c | 625 | ||||
-rw-r--r-- | libxrdp/xrdp_orders_rail.h | 50 | ||||
-rw-r--r-- | libxrdp/xrdp_rdp.c | 323 | ||||
-rw-r--r-- | libxrdp/xrdp_sec.c | 19 |
13 files changed, 1460 insertions, 101 deletions
diff --git a/libxrdp/Makefile.am b/libxrdp/Makefile.am index 08fb7130..11d1d836 100644 --- a/libxrdp/Makefile.am +++ b/libxrdp/Makefile.am @@ -50,11 +50,12 @@ 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) libxrdp_la_LIBADD = \ - $(top_srcdir)/common/libcommon.la \ + $(top_builddir)/common/libcommon.la \ $(EXTRA_LIBS) diff --git a/libxrdp/libxrdp.c b/libxrdp/libxrdp.c index 05e67eb7..3f8307c2 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) @@ -89,7 +91,8 @@ libxrdp_process_data(struct xrdp_session* session) } } code = 0; - if (xrdp_rdp_recv((struct xrdp_rdp*)session->rdp, session->s, &code) != 0) + if (xrdp_rdp_recv((struct xrdp_rdp*)(session->rdp), + session->s, &code) != 0) { rv = 1; break; @@ -102,6 +105,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,8 +122,17 @@ 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) { cont = (session->s->next_packet != 0) && @@ -616,7 +629,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; } @@ -635,11 +651,22 @@ libxrdp_orders_send_raw_bitmap2(struct xrdp_session* session, int EXPORT_CC libxrdp_orders_send_bitmap2(struct xrdp_session* session, int width, int height, int bpp, char* data, - int cache_id, int cache_idx) + int cache_id, int cache_idx, int hints) { return xrdp_orders_send_bitmap2((struct xrdp_orders*)session->orders, width, height, bpp, data, - cache_id, cache_idx); + cache_id, cache_idx, hints); +} + +/*****************************************************************************/ +int EXPORT_CC +libxrdp_orders_send_bitmap3(struct xrdp_session* session, + int width, int height, int bpp, char* data, + int cache_id, int cache_idx, int hints) +{ + return xrdp_orders_send_bitmap3((struct xrdp_orders*)session->orders, + width, height, bpp, data, + cache_id, cache_idx, hints); } /*****************************************************************************/ @@ -658,6 +685,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 +700,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 +728,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 +775,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; } @@ -754,3 +793,108 @@ libxrdp_orders_send_brush(struct xrdp_session* session, width, height, bpp, type, size, data, cache_id); } + +/*****************************************************************************/ +int EXPORT_CC +libxrdp_orders_send_create_os_surface(struct xrdp_session* session, int id, + int width, int height, + struct list* del_list) +{ + return xrdp_orders_send_create_os_surface + ((struct xrdp_orders*)(session->orders), id, + width, height, del_list); +} + +/*****************************************************************************/ +int EXPORT_CC +libxrdp_orders_send_switch_os_surface(struct xrdp_session* session, int id) +{ + return xrdp_orders_send_switch_os_surface + ((struct xrdp_orders*)(session->orders), id); +} + +/*****************************************************************************/ +int EXPORT_CC +libxrdp_window_new_update(struct xrdp_session* session, int window_id, + struct rail_window_state_order* window_state, + int flags) +{ + struct xrdp_orders* orders; + + orders = (struct xrdp_orders*)(session->orders); + return xrdp_orders_send_window_new_update(orders, window_id, + window_state, flags); +} + +/*****************************************************************************/ +int EXPORT_CC +libxrdp_window_delete(struct xrdp_session* session, int window_id) +{ + struct xrdp_orders* orders; + + orders = (struct xrdp_orders*)(session->orders); + return xrdp_orders_send_window_delete(orders, window_id); +} + +/*****************************************************************************/ +int EXPORT_CC +libxrdp_window_icon(struct xrdp_session* session, int window_id, + int cache_entry, int cache_id, + struct rail_icon_info* icon_info, int flags) +{ + struct xrdp_orders* orders; + + orders = (struct xrdp_orders*)(session->orders); + return xrdp_orders_send_window_icon(orders, window_id, cache_entry, + cache_id, icon_info, flags); +} + +/*****************************************************************************/ +int EXPORT_CC +libxrdp_window_cached_icon(struct xrdp_session* session, int window_id, + int cache_entry, int cache_id, + int flags) +{ + struct xrdp_orders* orders; + + orders = (struct xrdp_orders*)(session->orders); + return xrdp_orders_send_window_cached_icon(orders, window_id, cache_entry, + cache_id, flags); +} + +/*****************************************************************************/ +int EXPORT_CC +libxrdp_notify_new_update(struct xrdp_session* session, + int window_id, int notify_id, + struct rail_notify_state_order* notify_state, + int flags) +{ + struct xrdp_orders* orders; + + orders = (struct xrdp_orders*)(session->orders); + return xrdp_orders_send_notify_new_update(orders, window_id, notify_id, + notify_state, flags); +} + +/*****************************************************************************/ +int DEFAULT_CC +libxrdp_notify_delete(struct xrdp_session* session, + int window_id, int notify_id) +{ + struct xrdp_orders* orders; + + orders = (struct xrdp_orders*)(session->orders); + return xrdp_orders_send_notify_delete(orders, window_id, notify_id); +} + +/*****************************************************************************/ +int DEFAULT_CC +libxrdp_monitored_desktop(struct xrdp_session* session, + struct rail_monitored_desktop_order* mdo, + int flags) +{ + struct xrdp_orders* orders; + + orders = (struct xrdp_orders*)(session->orders); + return xrdp_orders_send_monitored_desktop(orders, mdo, flags); +} diff --git a/libxrdp/libxrdp.h b/libxrdp/libxrdp.h index 35a38190..b066db95 100644 --- a/libxrdp/libxrdp.h +++ b/libxrdp/libxrdp.h @@ -119,6 +119,7 @@ struct xrdp_rdp int mcs_channel; struct xrdp_client_info client_info; void* mppc_enc; + void* rfx_enc; }; /* state */ @@ -325,6 +326,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 @@ -383,13 +386,18 @@ xrdp_orders_send_raw_bitmap2(struct xrdp_orders* self, int APP_CC xrdp_orders_send_bitmap2(struct xrdp_orders* self, int width, int height, int bpp, char* data, - int cache_id, int cache_idx); + int cache_id, int cache_idx, int hints); +int APP_CC +xrdp_orders_send_bitmap3(struct xrdp_orders* self, + int width, int height, int bpp, char* data, + int cache_id, int cache_idx, int hints); int APP_CC xrdp_orders_send_brush(struct xrdp_orders* self, int width, int height, int bpp, int type, int size, char* data, int cache_id); int APP_CC xrdp_orders_send_create_os_surface(struct xrdp_orders* self, int id, - int width, int height); + int width, int height, + struct list* del_list); int APP_CC xrdp_orders_send_switch_os_surface(struct xrdp_orders* self, int id); @@ -403,7 +411,7 @@ int APP_CC xrdp_jpeg_compress(char* in_data, int width, int height, struct stream* s, int bpp, int byte_limit, int start_line, struct stream* temp_s, - int e); + int e, int quality); /* xrdp_channel.c */ struct xrdp_channel* APP_CC diff --git a/libxrdp/libxrdpinc.h b/libxrdp/libxrdpinc.h index 82ac9ad0..4f3504e6 100644 --- a/libxrdp/libxrdpinc.h +++ b/libxrdp/libxrdpinc.h @@ -23,6 +23,8 @@ #ifndef LIBXRDPINC_H #define LIBXRDPINC_H +#include "xrdp_rail.h" + /* struct xrdp_client_info moved to xrdp_client_info.h */ struct xrdp_brush @@ -162,7 +164,11 @@ libxrdp_orders_send_raw_bitmap2(struct xrdp_session* session, int DEFAULT_CC libxrdp_orders_send_bitmap2(struct xrdp_session* session, int width, int height, int bpp, char* data, - int cache_id, int cache_idx); + int cache_id, int cache_idx, int hints); +int DEFAULT_CC +libxrdp_orders_send_bitmap3(struct xrdp_session* session, + int width, int height, int bpp, char* data, + int cache_id, int cache_idx, int hints); int DEFAULT_CC libxrdp_query_channel(struct xrdp_session* session, int index, char* channel_name, int* channel_flags); @@ -176,5 +182,37 @@ int DEFAULT_CC libxrdp_orders_send_brush(struct xrdp_session* session, int width, int height, int bpp, int type, int size, char* data, int cache_id); +int DEFAULT_CC +libxrdp_orders_send_create_os_surface(struct xrdp_session* session, int id, + int width, int height, + struct list* del_list); +int DEFAULT_CC +libxrdp_orders_send_switch_os_surface(struct xrdp_session* session, int id); +int DEFAULT_CC +libxrdp_window_new_update(struct xrdp_session* session, int window_id, + struct rail_window_state_order* window_state, + int flags); +int DEFAULT_CC +libxrdp_window_delete(struct xrdp_session* session, int window_id); +int DEFAULT_CC +libxrdp_window_icon(struct xrdp_session* session, int window_id, + int cache_entry, int cache_id, + struct rail_icon_info* icon_info, int flags); +int DEFAULT_CC +libxrdp_window_cached_icon(struct xrdp_session* session, int window_id, + int cache_entry, int cache_id, + int flags); +int DEFAULT_CC +libxrdp_notify_new_update(struct xrdp_session* session, + int window_id, int notify_id, + struct rail_notify_state_order* notify_state, + int flags); +int DEFAULT_CC +libxrdp_notify_delete(struct xrdp_session* session, + int window_id, int notify_id); +int DEFAULT_CC +libxrdp_monitored_desktop(struct xrdp_session* session, + struct rail_monitored_desktop_order* mdo, + int flags); #endif diff --git a/libxrdp/xrdp_channel.c b/libxrdp/xrdp_channel.c index 00497c35..2b3d23a5 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; } + g_memset(self,0,sizeof(struct xrdp_channel)); g_free(self); } @@ -88,19 +93,21 @@ 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); out_uint32_le(s, total_data_len); - if (channel->flags & CHANNEL_OPTION_SHOW_PROTOCOL) + if (channel->flags & XR_CHANNEL_OPTION_SHOW_PROTOCOL) { flags |= CHANNEL_FLAG_SHOW_PROTOCOL; } 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_fastpath.c b/libxrdp/xrdp_fastpath.c index 5ce07861..9a147b1b 100644 --- a/libxrdp/xrdp_fastpath.c +++ b/libxrdp/xrdp_fastpath.c @@ -76,7 +76,7 @@ xrdp_fastpath_send_update_pdu(struct xrdp_fastpath* self, tui8 updateCode, compression = 0; s_send = self->out_s; - maxLen = FASTPATH_MAX_PACKET_SIZE - 6 ; /* 6 bytes for header */ + maxLen = FASTPATH_MAX_PACKET_SIZE - 6; /* 6 bytes for header */ payloadLeft = (s->end - s->data); for (i = 0; payloadLeft > 0; i++) { @@ -143,7 +143,7 @@ xrdp_fastpath_process_update(struct xrdp_fastpath* self, tui8 updateCode, } return 0; -} +} /*****************************************************************************/ int APP_CC @@ -192,5 +192,5 @@ xrdp_fastpath_process_data(struct xrdp_fastpath* self, struct stream* s, return 1; } in_uint16_le(s, size); - return xrdp_fastpath_process_update(self, updateCode, size, s); + return xrdp_fastpath_process_update(self, updateCode, size, s); } diff --git a/libxrdp/xrdp_jpeg_compress.c b/libxrdp/xrdp_jpeg_compress.c index 48f12359..8561982f 100644 --- a/libxrdp/xrdp_jpeg_compress.c +++ b/libxrdp/xrdp_jpeg_compress.c @@ -148,9 +148,8 @@ jp_do_compress(char* data, int width, int height, int bpp, int quality, /*****************************************************************************/ static int APP_CC jpeg_compress(char* in_data, int width, int height, - struct stream* s, int bpp, int byte_limit, - int start_line, struct stream* temp_s, - int e) + struct stream* s, struct stream* temp_s, int bpp, + int byte_limit, int e, int quality) { char* data; tui32* src32; @@ -164,7 +163,7 @@ jpeg_compress(char* in_data, int width, int height, int i; int cdata_bytes; - data = g_malloc((width + e) * height * 3, 0); + data = temp_s->data; dst8 = data; if (bpp == 24) { @@ -192,9 +191,8 @@ jpeg_compress(char* in_data, int width, int height, g_writeln("bpp wrong %d", bpp); } cdata_bytes = byte_limit; - jp_do_compress(data, width + e, height, 24, JP_QUALITY, s->p, &cdata_bytes); + jp_do_compress(data, width + e, height, 24, quality, s->p, &cdata_bytes); s->p += cdata_bytes; - g_free(data); return cdata_bytes; } @@ -203,10 +201,10 @@ int APP_CC xrdp_jpeg_compress(char* in_data, int width, int height, struct stream* s, int bpp, int byte_limit, int start_line, struct stream* temp_s, - int e) + int e, int quality) { - jpeg_compress(in_data, width, height, s, bpp, byte_limit, - start_line, temp_s, e); + jpeg_compress(in_data, width, height, s, temp_s, bpp, byte_limit, + e, quality); return height; } @@ -217,7 +215,7 @@ int APP_CC xrdp_jpeg_compress(char* in_data, int width, int height, struct stream* s, int bpp, int byte_limit, int start_line, struct stream* temp_s, - int e) + int e, int quality) { return height; } diff --git a/libxrdp/xrdp_mcs.c b/libxrdp/xrdp_mcs.c index af65faf2..618a3433 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,33 @@ 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_orders.c b/libxrdp/xrdp_orders.c index 925c52aa..e7739e3e 100644 --- a/libxrdp/xrdp_orders.c +++ b/libxrdp/xrdp_orders.c @@ -22,6 +22,20 @@ #include "libxrdp.h" +#if defined(XRDP_FREERDP1) +#include <freerdp/codec/rfx.h> +#endif + +#define LLOG_LEVEL 2 +#define LLOGLN(_log_level, _params) \ +{ \ + if (_log_level < LLOG_LEVEL) \ + { \ + g_write("xrdp_orders.c [%10.10u]: ", g_time3()); \ + g_writeln _params ; \ + } \ +} + /*****************************************************************************/ struct xrdp_orders* APP_CC xrdp_orders_create(struct xrdp_session* session, struct xrdp_rdp* rdp_layer) @@ -152,7 +166,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; @@ -1829,32 +1843,12 @@ xrdp_orders_send_raw_bitmap2(struct xrdp_orders* self, } /*****************************************************************************/ -static int -xrdp_orders_send_as_jpeg(struct xrdp_orders* self, - int width, int height, int bpp) -{ - if (bpp != 24) - { - return 0; - } - if (self->rdp_layer->client_info.jpeg == 0) - { - return 0; - } - if (width * height < 64) - { - return 0; - } - return 1; -} - -/*****************************************************************************/ /* returns error */ /* max size width * height * Bpp + 14 */ int APP_CC xrdp_orders_send_bitmap2(struct xrdp_orders* self, int width, int height, int bpp, char* data, - int cache_id, int cache_idx) + int cache_id, int cache_idx, int hints) { int order_flags = 0; int len = 0; @@ -1863,7 +1857,6 @@ xrdp_orders_send_bitmap2(struct xrdp_orders* self, int i = 0; int lines_sending = 0; int e = 0; - int is_jpeg; struct stream* s = NULL; struct stream* temp_s = NULL; char* p = NULL; @@ -1889,18 +1882,8 @@ xrdp_orders_send_bitmap2(struct xrdp_orders* self, init_stream(temp_s, 16384); p = s->p; i = height; - is_jpeg = 0; - if (xrdp_orders_send_as_jpeg(self, width, height, bpp)) - { - lines_sending = xrdp_jpeg_compress(data, width, height, s, bpp, 16384, - i - 1, temp_s, e); - is_jpeg = 1; - } - else - { - lines_sending = xrdp_bitmap_compress(data, width, height, s, bpp, 16384, + lines_sending = xrdp_bitmap_compress(data, width, height, s, bpp, 16384, i - 1, temp_s, e); - } if (lines_sending != height) { free_stream(s); @@ -1919,10 +1902,6 @@ height(%d)", lines_sending, height); out_uint16_le(self->out_s, len); i = (((Bpp + 2) << 3) & 0x38) | (cache_id & 7); i = i | (0x08 << 7); /* CBR2_NO_BITMAP_COMPRESSION_HDR */ - if (is_jpeg) - { - i = i | (0x80 << 7); /* unsed flag, jpeg hack */ - } out_uint16_le(self->out_s, i); /* flags */ out_uint8(self->out_s, RDP_ORDER_BMPCACHE2); /* type */ out_uint8(self->out_s, width + e); @@ -1939,6 +1918,182 @@ height(%d)", lines_sending, height); } /*****************************************************************************/ +static int +xrdp_orders_send_as_jpeg(struct xrdp_orders* self, + int width, int height, int bpp, int hints) +{ + if (hints & 1) + { + return 0; + } + if (bpp != 24) + { + return 0; + } + if (width * height < 64) + { + return 0; + } + return 1; +} + +#if defined(XRDP_FREERDP1) +/*****************************************************************************/ +/* secondary drawing order (bitmap v3) using remotefx compression */ +static int APP_CC +xrdp_orders_send_as_rfx(struct xrdp_orders* self, + int width, int height, int bpp, + int hints) +{ + if (hints & 1) + { + return 0; + } + if (bpp != 24) + { + return 0; + } + if (width * height < 64) + { + return 0; + } + return 1; +} +#endif + +/*****************************************************************************/ +static int APP_CC +xrdp_orders_out_v3(struct xrdp_orders* self, int cache_id, int cache_idx, + char* buf, int bufsize, int width, int height, int bpp, + int codec_id) +{ + int Bpp; + int order_flags; + int len; + int i; + + Bpp = (bpp + 7) / 8; + xrdp_orders_check(self, bufsize + 30); + self->order_count++; + order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY; + out_uint8(self->out_s, order_flags); + len = (bufsize + 22) - 7; /* length after type minus 7 */ + out_uint16_le(self->out_s, len); + i = (((Bpp + 2) << 3) & 0x38) | (cache_id & 7); + out_uint16_le(self->out_s, i); /* flags */ + out_uint8(self->out_s, RDP_ORDER_BMPCACHE3); /* type */ + /* cache index */ + out_uint16_le(self->out_s, cache_idx); + /* persistant cache key 1/2 */ + out_uint32_le(self->out_s, 0); + out_uint32_le(self->out_s, 0); + /* bitmap data */ + out_uint8(self->out_s, bpp); + out_uint8(self->out_s, 0); /* reserved */ + out_uint8(self->out_s, 0); /* reserved */ + out_uint8(self->out_s, codec_id); + out_uint16_le(self->out_s, width); + out_uint16_le(self->out_s, height); + out_uint32_le(self->out_s, bufsize); + out_uint8a(self->out_s, buf, bufsize); + return 0; +} + +/*****************************************************************************/ +/* secondary drawing order (bitmap v3) using remotefx compression */ +int APP_CC +xrdp_orders_send_bitmap3(struct xrdp_orders* self, + int width, int height, int bpp, char* data, + int cache_id, int cache_idx, int hints) +{ + int e; + int bufsize; + int quality; + struct stream* xr_s; /* xrdp stream */ + struct stream* temp_s; /* xrdp stream */ + struct xrdp_client_info* ci; +#if defined(XRDP_FREERDP1) + STREAM* fr_s; /* FreeRDP stream */ + RFX_CONTEXT* context; + RFX_RECT rect; +#endif + + ci = &(self->rdp_layer->client_info); + if (ci->v3_codec_id == 0) + { + return 2; + } + if (ci->v3_codec_id == ci->rfx_codec_id) + { +#if defined(XRDP_FREERDP1) + if (!xrdp_orders_send_as_rfx(self, width, height, bpp, hints)) + { + return 2; + } + LLOGLN(10, ("xrdp_orders_send_bitmap3: rfx")); + context = (RFX_CONTEXT*)(self->rdp_layer->rfx_enc); + make_stream(xr_s); + init_stream(xr_s, 16384); + fr_s = stream_new(0); + stream_attach(fr_s, (tui8*)(xr_s->data), 16384); + rect.x = 0; + rect.y = 0; + rect.width = width; + rect.height = height; + rfx_compose_message(context, fr_s, &rect, 1, (tui8*)data, width, + height, width * 4); + bufsize = stream_get_length(fr_s); + xrdp_orders_out_v3(self, cache_id, cache_idx, (char*)(fr_s->data), bufsize, + width, height, bpp,ci->v3_codec_id); + stream_detach(fr_s); + stream_free(fr_s); + free_stream(xr_s); + return 0; +#else + return 2; +#endif + } + else if (ci->v3_codec_id == ci->jpeg_codec_id) + { +#if defined(XRDP_JPEG) + if (!xrdp_orders_send_as_jpeg(self, width, height, bpp, hints)) + { + LLOGLN(10, ("xrdp_orders_send_bitmap3: jpeg skipped")); + return 2; + } + LLOGLN(10, ("xrdp_orders_send_bitmap3: jpeg")); + e = width % 4; + if (e != 0) + { + e = 4 - e; + } + make_stream(xr_s); + init_stream(xr_s, 16384); + make_stream(temp_s); + init_stream(temp_s, 16384); + quality = ci->jpeg_prop[0]; + xrdp_jpeg_compress(data, width, height, xr_s, bpp, 16384, + height - 1, temp_s, e, quality); + s_mark_end(xr_s); + bufsize = (int)(xr_s->end - xr_s->data); + xrdp_orders_out_v3(self, cache_id, cache_idx, (char*)(xr_s->data), bufsize, + width + e, height, bpp,ci->v3_codec_id); + free_stream(xr_s); + free_stream(temp_s); + return 0; +#else + return 2; +#endif + } + else + { + g_writeln("xrdp_orders_send_bitmap3: todo unknown codec"); + return 1; + } + return 0; +} + +/*****************************************************************************/ /* returns error */ /* send a brush cache entry */ int APP_CC @@ -1971,21 +2126,47 @@ xrdp_orders_send_brush(struct xrdp_orders* self, int width, int height, /* send an off screen bitmap entry */ int APP_CC xrdp_orders_send_create_os_surface(struct xrdp_orders* self, int id, - int width, int height) + int width, int height, + struct list* del_list) { int order_flags; int cache_id; + int flags; + int index; + int bytes; + int num_del_list; - g_writeln("xrdp_orders_send_create_os_surface:"); - xrdp_orders_check(self, 7); + bytes = 7; + num_del_list = del_list->count; + if (num_del_list > 0) + { + bytes += 2; + bytes += num_del_list * 2; + } + xrdp_orders_check(self, bytes); self->order_count++; order_flags = RDP_ORDER_SECONDARY; order_flags |= 1 << 2; /* type RDP_ORDER_ALTSEC_CREATE_OFFSCR_BITMAP */ out_uint8(self->out_s, order_flags); cache_id = id & 0x7fff; - out_uint16_le(self->out_s, cache_id); + flags = cache_id; + if (num_del_list > 0) + { + flags |= 0x8000; + } + out_uint16_le(self->out_s, flags); out_uint16_le(self->out_s, width); out_uint16_le(self->out_s, height); + if (num_del_list > 0) + { + /* delete list */ + out_uint16_le(self->out_s, num_del_list); + for (index = 0; index < num_del_list; index++) + { + cache_id = list_get_item(del_list, index) & 0x7fff; + out_uint16_le(self->out_s, cache_id); + } + } return 0; } @@ -1997,7 +2178,6 @@ xrdp_orders_send_switch_os_surface(struct xrdp_orders* self, int id) int order_flags; int cache_id; - g_writeln("xrdp_orders_send_switch_os_surface:"); xrdp_orders_check(self, 3); self->order_count++; order_flags = RDP_ORDER_SECONDARY; diff --git a/libxrdp/xrdp_orders_rail.c b/libxrdp/xrdp_orders_rail.c new file mode 100644 index 00000000..62f9b8ea --- /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 "xrdp_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 diff --git a/libxrdp/xrdp_rdp.c b/libxrdp/xrdp_rdp.c index bdbeed48..53e3ddc2 100644 --- a/libxrdp/xrdp_rdp.c +++ b/libxrdp/xrdp_rdp.c @@ -24,6 +24,7 @@ #if defined(XRDP_FREERDP1) #include <freerdp/codec/mppc_enc.h> +#include <freerdp/codec/rfx.h> #endif /* some compilers need unsigned char to avoid warnings */ @@ -113,13 +114,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) { @@ -131,11 +144,66 @@ xrdp_rdp_read_config(struct xrdp_client_info* client_info) return 0; } +#if defined(XRDP_FREERDP1) +/*****************************************************************************/ +static void +cpuid(tui32 info, tui32* eax, tui32* ebx, tui32* ecx, tui32* edx) +{ +#ifdef __GNUC__ +#if defined(__i386__) || defined(__x86_64__) + __asm volatile + ( + /* The EBX (or RBX register on x86_64) is used for the PIC base address + and must not be corrupted by our inline assembly. */ +#if defined(__i386__) + "mov %%ebx, %%esi;" + "cpuid;" + "xchg %%ebx, %%esi;" +#else + "mov %%rbx, %%rsi;" + "cpuid;" + "xchg %%rbx, %%rsi;" +#endif + : "=a" (*eax), "=S" (*ebx), "=c" (*ecx), "=d" (*edx) + : "0" (info) + ); +#endif +#endif +} + +/*****************************************************************************/ +static tui32 +xrdp_rdp_detect_cpu(void) +{ + tui32 eax; + tui32 ebx; + tui32 ecx; + tui32 edx; + tui32 cpu_opt; + + eax = 0; + ebx = 0; + ecx = 0; + edx = 0; + cpu_opt = 0; + cpuid(1, &eax, &ebx, &ecx, &edx); + + if (edx & (1 << 26)) + { + DEBUG("SSE2 detected"); + cpu_opt |= CPU_SSE2; + } + + return cpu_opt; +} +#endif + /*****************************************************************************/ struct xrdp_rdp* APP_CC xrdp_rdp_create(struct xrdp_session* session, struct trans* trans) { struct xrdp_rdp* self = (struct xrdp_rdp *)NULL; + int bytes; DEBUG(("in xrdp_rdp_create")); self = (struct xrdp_rdp*)g_malloc(sizeof(struct xrdp_rdp), 1); @@ -153,9 +221,13 @@ xrdp_rdp_create(struct xrdp_session* session, struct trans* trans) self->client_info.cache2_size = 1024; self->client_info.cache3_entries = 262; self->client_info.cache3_size = 4096; - g_write_ip_address(trans->sck, self->client_info.client_ip); /* load client ip info */ + /* load client ip info */ + bytes = sizeof(self->client_info.client_ip) - 1; + g_write_ip_address(trans->sck, self->client_info.client_ip, bytes); #if defined(XRDP_FREERDP1) self->mppc_enc = mppc_enc_new(PROTO_RDP_50); + self->rfx_enc = rfx_context_new(); + rfx_context_set_cpu_opt(self->rfx_enc, xrdp_rdp_detect_cpu()); #endif self->client_info.size = sizeof(self->client_info); DEBUG(("out xrdp_rdp_create")); @@ -173,6 +245,7 @@ xrdp_rdp_delete(struct xrdp_rdp* self) xrdp_sec_delete(self->sec_layer); #if defined(XRDP_FREERDP1) mppc_enc_free((struct rdp_mppc_enc*)(self->mppc_enc)); + rfx_context_free((RFX_CONTEXT*)(self->rfx_enc)); #endif g_free(self); } @@ -220,7 +293,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) @@ -232,35 +305,47 @@ 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; } - 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; + 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; + } } /*****************************************************************************/ @@ -318,7 +403,7 @@ xrdp_rdp_send_data(struct xrdp_rdp* self, struct stream* s, if (self->client_info.rdp_compression && self->session->up_and_running) { mppc_enc = (struct rdp_mppc_enc*)(self->mppc_enc); - if (compress_rdp(mppc_enc, s->p + 18, tocomplen)) + if (compress_rdp(mppc_enc, (tui8*)(s->p + 18), tocomplen)) { DEBUG(("mppc_encode ok flags 0x%x bytes_in_opb %d historyOffset %d " "tocomplen %d", mppc_enc->flags, mppc_enc->bytes_in_opb, @@ -474,9 +559,13 @@ xrdp_rdp_send_demand_active(struct xrdp_rdp* self) struct stream* s; int caps_count; int caps_size; + int codec_caps_count; + int codec_caps_size; char* caps_count_ptr; char* caps_size_ptr; char* caps_ptr; + char* codec_caps_count_ptr; + char* codec_caps_size_ptr; make_stream(s); init_stream(s, 8192); @@ -589,12 +678,48 @@ xrdp_rdp_send_demand_active(struct xrdp_rdp* self) out_uint8(s, 0); /* unused */ out_uint8(s, 0); /* unused */ out_uint16_le(s, 0x6a1); - out_uint8s(s, 2); /* ? */ + /* declare support of bitmap cache rev3 */ + out_uint16_le(s, XR_ORDERFLAGS_EX_CACHE_BITMAP_REV3_SUPPORT); out_uint32_le(s, 0x0f4240); /* desk save */ out_uint32_le(s, 0x0f4240); /* desk save */ out_uint32_le(s, 1); /* ? */ out_uint32_le(s, 0); /* ? */ + /* Output bmpcodecs capability set */ + caps_count++; + out_uint16_le(s, RDP_CAPSET_BMPCODECS); + codec_caps_size_ptr = s->p; + out_uint8s(s, 2); /* cap len set later */ + codec_caps_count = 0; + codec_caps_count_ptr = s->p; + out_uint8s(s, 1); /* bitmapCodecCount set later */ + /* nscodec */ + codec_caps_count++; + out_uint8a(s, XR_CODEC_GUID_NSCODEC, 16); + out_uint8(s, 1); /* codec id, must be 1 */ + out_uint16_le(s, 3); + out_uint8(s, 0x01); /* fAllowDynamicFidelity */ + out_uint8(s, 0x01); /* fAllowSubsampling */ + out_uint8(s, 0x03); /* colorLossLevel */ + /* remotefx */ + codec_caps_count++; + out_uint8a(s, XR_CODEC_GUID_REMOTEFX, 16); + out_uint8(s, 0); /* codec id, client sets */ + out_uint16_le(s, 256); + out_uint8s(s, 256); + /* jpeg */ + codec_caps_count++; + out_uint8a(s, XR_CODEC_GUID_JPEG, 16); + out_uint8(s, 0); /* codec id, client sets */ + out_uint16_le(s, 1); /* ext length */ + out_uint8(s, 75); + /* calculate and set size and count */ + codec_caps_size = (int)(s->p - codec_caps_size_ptr); + codec_caps_size += 2; /* 2 bytes for RDP_CAPSET_BMPCODECS above */ + codec_caps_size_ptr[0] = codec_caps_size; + codec_caps_size_ptr[1] = codec_caps_size >> 8; + codec_caps_count_ptr[0] = codec_caps_count; + /* Output color cache capability set */ caps_count++; out_uint16_le(s, RDP_CAPSET_COLCACHE); @@ -617,6 +742,27 @@ 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 */ + + /* 6 - bitmap cache v3 codecid */ + caps_count++; + out_uint16_le(s, 0x0006); + out_uint16_le(s, 5); + out_uint8(s, 0); /* client sets */ + out_uint8s(s, 4); /* pad */ s_mark_end(s); @@ -664,6 +810,7 @@ xrdp_process_capset_order(struct xrdp_rdp* self, struct stream* s, { int i; char order_caps[32]; + int ex_flags; DEBUG(("order capabilities")); in_uint8s(s, 20); /* Terminal desc, pad */ @@ -694,7 +841,15 @@ xrdp_process_capset_order(struct xrdp_rdp* self, struct stream* s, g_hexdump(order_caps, 32); #endif in_uint8s(s, 2); /* Text capability flags */ - in_uint8s(s, 6); /* Pad */ + /* read extended order support flags */ + in_uint16_le(s, ex_flags); /* Ex flags */ + if (ex_flags & XR_ORDERFLAGS_EX_CACHE_BITMAP_REV3_SUPPORT) + { + g_writeln("xrdp_process_capset_order: bitmap cache v3 supported"); + self->client_info.bitmap_cache_version |= 4; + } + in_uint8s(s, 4); /* Pad */ + in_uint32_le(s, i); /* desktop cache size, usually 0x38400 */ self->client_info.desktop_cache = i; DEBUG(("desktop cache size %d", i)); @@ -709,6 +864,7 @@ static int APP_CC xrdp_process_capset_bmpcache(struct xrdp_rdp* self, struct stream* s, int len) { + self->client_info.bitmap_cache_version |= 1; in_uint8s(s, 24); in_uint16_le(s, self->client_info.cache1_entries); in_uint16_le(s, self->client_info.cache1_size); @@ -734,16 +890,9 @@ xrdp_process_capset_bmpcache2(struct xrdp_rdp* self, struct stream* s, int Bpp = 0; int i = 0; - self->client_info.bitmap_cache_version = 2; + self->client_info.bitmap_cache_version |= 2; Bpp = (self->client_info.bpp + 7) / 8; in_uint16_le(s, i); /* cache flags */ -#if defined(XRDP_JPEG) - if (i & 0x80) - { - g_writeln("xrdp_process_capset_bmpcache2: client supports jpeg"); - self->client_info.jpeg = 1; - } -#endif self->client_info.bitmap_cache_persist_enable = i; in_uint8s(s, 2); /* number of caches in set, 3 */ in_uint32_le(s, i); @@ -769,6 +918,20 @@ xrdp_process_capset_bmpcache2(struct xrdp_rdp* self, struct stream* s, } /*****************************************************************************/ +static int +xrdp_process_capset_cache_v3_codec_id(struct xrdp_rdp* self, struct stream* s, + int len) +{ + int codec_id; + + in_uint8(s, codec_id); + g_writeln("xrdp_process_capset_cache_v3_codec_id: cache_v3_codec_id %d", + codec_id); + self->client_info.v3_codec_id = codec_id; + return 0; +} + +/*****************************************************************************/ /* get the number of client cursor cache */ static int APP_CC xrdp_process_capset_pointercache(struct xrdp_rdp* self, struct stream* s, @@ -823,6 +986,106 @@ xrdp_process_offscreen_bmpcache(struct xrdp_rdp* self, struct stream* s, } /*****************************************************************************/ +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; +} + +/*****************************************************************************/ +static int APP_CC +xrdp_process_capset_codecs(struct xrdp_rdp* self, struct stream* s, int len) +{ + int codec_id; + int codec_count; + int index; + int codec_properties_length; + int i1; + char* codec_guid; + char* next_guid; + + in_uint8(s, codec_count); + for (index = 0; index < codec_count; index++) + { + codec_guid = s->p; + in_uint8s(s, 16); + in_uint8(s, codec_id); + in_uint16_le(s, codec_properties_length); + next_guid = s->p + codec_properties_length; + if (g_memcmp(codec_guid, XR_CODEC_GUID_NSCODEC, 16) == 0) + { + g_writeln("xrdp_process_capset_codecs: nscodec codec id %d prop len %d", + codec_id, codec_properties_length); + self->client_info.ns_codec_id = codec_id; + i1 = MIN(64, codec_properties_length); + g_memcpy(self->client_info.ns_prop, s->p, i1); + self->client_info.ns_prop_len = i1; + } + else if (g_memcmp(codec_guid, XR_CODEC_GUID_REMOTEFX, 16) == 0) + { + g_writeln("xrdp_process_capset_codecs: rfx codec id %d prop len %d", + codec_id, codec_properties_length); + self->client_info.rfx_codec_id = codec_id; + i1 = MIN(64, codec_properties_length); + g_memcpy(self->client_info.rfx_prop, s->p, i1); + self->client_info.rfx_prop_len = i1; + } + else if (g_memcmp(codec_guid, XR_CODEC_GUID_JPEG, 16) == 0) + { + g_writeln("xrdp_process_capset_codecs: jpeg codec id %d prop len %d", + codec_id, codec_properties_length); + self->client_info.jpeg_codec_id = codec_id; + i1 = MIN(64, codec_properties_length); + g_memcpy(self->client_info.jpeg_prop, s->p, i1); + self->client_info.jpeg_prop_len = i1; + g_writeln(" jpeg quality %d", self->client_info.jpeg_prop[0]); + } + else + { + g_writeln("xrdp_process_capset_codecs: unknown codec id %d", codec_id); + } + s->p = next_guid; + } + return 0; +} + +/*****************************************************************************/ int APP_CC xrdp_rdp_process_confirm_active(struct xrdp_rdp* self, struct stream* s) { @@ -867,6 +1130,9 @@ xrdp_rdp_process_confirm_active(struct xrdp_rdp* self, struct stream* s) case RDP_CAPSET_CONTROL: /* 5 */ DEBUG(("RDP_CAPSET_CONTROL")); break; + case 6: + xrdp_process_capset_cache_v3_codec_id(self, s, len); + break; case RDP_CAPSET_ACTIVATE: /* 7 */ DEBUG(("RDP_CAPSET_ACTIVATE")); break; @@ -912,9 +1178,18 @@ 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; + case RDP_CAPSET_BMPCODECS: /* 0x1d(29) */ + xrdp_process_capset_codecs(self, s, len); + break; default: g_writeln("unknown in xrdp_rdp_process_confirm_active %d", type); break; 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); |