From a8e5b3fee51604d68d8ecd36065396ba42c7be3f Mon Sep 17 00:00:00 2001 From: speidy Date: Mon, 15 Jul 2013 10:13:03 +0300 Subject: [PATCH] libxrdp: work on multi-mon support --- common/xrdp_client_info.h | 5 +++- common/xrdp_constants.h | 5 ++-- libxrdp/libxrdp.h | 14 ++++++++++- libxrdp/xrdp_iso.c | 18 +++++++++----- libxrdp/xrdp_mcs.c | 4 ++++ libxrdp/xrdp_rdp.c | 10 +++++++- libxrdp/xrdp_sec.c | 50 +++++++++++++++++++++++++++++++++++++-- 7 files changed, 93 insertions(+), 13 deletions(-) diff --git a/common/xrdp_client_info.h b/common/xrdp_client_info.h index 86d0dc25..c942aa70 100644 --- a/common/xrdp_client_info.h +++ b/common/xrdp_client_info.h @@ -38,6 +38,7 @@ struct xrdp_client_info int bitmap_cache_version; /* ored 1 = original version, 2 = v2, 4 = v3 */ /* pointer info */ int pointer_cache_entries; + int pointer_flags; /* 0 color, 1 new, 2 no new */ /* other */ int use_bitmap_comp; int use_bitmap_cache; @@ -69,6 +70,9 @@ struct xrdp_client_info int offscreen_cache_size; int offscreen_cache_entries; int rfx; + int nego_sec_layer; /* 0, 1, 2 = RDP security layer, TLS , Negotiate */ + int multimon; /* 0 = deny , 1 = allow */ + /* CAPSETTYPE_RAIL */ int rail_support_level; /* CAPSETTYPE_WINDOW */ @@ -90,7 +94,6 @@ struct xrdp_client_info char orders[32]; int order_flags_ex; int use_bulk_comp; - int pointer_flags; /* 0 color, 1 new, 2 no new */ }; #endif diff --git a/common/xrdp_constants.h b/common/xrdp_constants.h index b978d2de..404e3b88 100644 --- a/common/xrdp_constants.h +++ b/common/xrdp_constants.h @@ -25,8 +25,8 @@ /* TCP port for Remote Desktop Protocol */ #define TCP_PORT_RDP 3389 -#define ISO_PDU_CR 0xE0 /* Connection Request */ -#define ISO_PDU_CC 0xD0 /* Connection Confirm */ +#define ISO_PDU_CR 0xE0 /* X.224 Connection Request */ +#define ISO_PDU_CC 0xD0 /* X.224 Connection Confirm */ #define ISO_PDU_DR 0x80 /* Disconnect Request */ #define ISO_PDU_DT 0xF0 /* Data */ #define ISO_PDU_ER 0x70 /* Error */ @@ -72,6 +72,7 @@ #define SEC_TAG_CLI_CRYPT 0xc002 #define SEC_TAG_CLI_CHANNELS 0xc003 #define SEC_TAG_CLI_4 0xc004 +#define SEC_TAG_CLI_MONITOR 0xc005 #define SEC_TAG_PUBKEY 0x0006 #define SEC_TAG_KEYSIG 0x0008 diff --git a/libxrdp/libxrdp.h b/libxrdp/libxrdp.h index d31edbb4..66b0cb61 100644 --- a/libxrdp/libxrdp.h +++ b/libxrdp/libxrdp.h @@ -59,6 +59,16 @@ struct mcs_channel_item int chanid; }; +/* used in mcs - client monitor data */ +struct mcs_monitor_item +{ + int x; + int y; + int width; + int height; + int is_primary; +}; + /* mcs */ struct xrdp_mcs { @@ -69,6 +79,7 @@ struct xrdp_mcs struct stream* client_mcs_data; struct stream* server_mcs_data; struct list* channel_list; + struct list* monitor_list; }; /* sec */ @@ -99,6 +110,7 @@ struct xrdp_sec char pub_sig[64]; char pri_exp[64]; int channel_code; + int multimon; }; /* channel */ @@ -285,7 +297,7 @@ xrdp_mcs_disconnect(struct xrdp_mcs* self); /* xrdp_sec.c */ struct xrdp_sec* APP_CC xrdp_sec_create(struct xrdp_rdp* owner, struct trans* trans, int crypt_level, - int channel_code); + int channel_code, int multimon); void APP_CC xrdp_sec_delete(struct xrdp_sec* self); int APP_CC diff --git a/libxrdp/xrdp_iso.c b/libxrdp/xrdp_iso.c index d851c1bb..04186ea9 100644 --- a/libxrdp/xrdp_iso.c +++ b/libxrdp/xrdp_iso.c @@ -86,7 +86,7 @@ xrdp_iso_recv_msg(struct xrdp_iso *self, struct stream *s, int *code) } else { - in_uint8s(s, 5); + in_uint8s(s, 13); } return 0; @@ -126,14 +126,20 @@ xrdp_iso_send_msg(struct xrdp_iso *self, struct stream *s, int code) return 1; } - out_uint8(s, 3); - out_uint8(s, 0); - out_uint16_be(s, 11); /* length */ - out_uint8(s, 6); + /* TPKT HEADER */ + out_uint8(s, 3); /* version */ + out_uint8(s, 0); /* RESERVED */ + out_uint16_be(s, 19); /* length */ + /* ISO LAYER */ + out_uint8(s, 14); /* length */ out_uint8(s, code); out_uint16_le(s, 0); - out_uint16_le(s, 0); + out_uint16_le(s, 4660); out_uint8(s, 0); + out_uint8(s, 2); /* TYPE_RDP_NEG_RSP */ + out_uint8(s, 1); /* flags */ + out_uint16_le(s, 8); /* length */ + out_uint32_le(s, 0); /* selectedProtocol: 0 = RDP , 1 = TLS , 2 = CREDSSP */ s_mark_end(s); if (xrdp_tcp_send(self->tcp_layer, s) != 0) diff --git a/libxrdp/xrdp_mcs.c b/libxrdp/xrdp_mcs.c index 4bf3d025..7d89766d 100644 --- a/libxrdp/xrdp_mcs.c +++ b/libxrdp/xrdp_mcs.c @@ -364,6 +364,7 @@ xrdp_mcs_recv_edrq(struct xrdp_mcs *self) int opcode; struct stream *s; + DEBUG((" in xrdp_mcs_recv_edrq")); make_stream(s); init_stream(s, 8192); @@ -396,6 +397,7 @@ xrdp_mcs_recv_edrq(struct xrdp_mcs *self) } free_stream(s); + DEBUG((" out xrdp_mcs_recv_edrq")); return 0; } @@ -407,6 +409,7 @@ xrdp_mcs_recv_aurq(struct xrdp_mcs *self) int opcode; struct stream *s; + DEBUG((" in xrdp_mcs_recv_aurq")); make_stream(s); init_stream(s, 8192); @@ -436,6 +439,7 @@ xrdp_mcs_recv_aurq(struct xrdp_mcs *self) } free_stream(s); + DEBUG((" out xrdp_mcs_recv_aurq")); return 0; } diff --git a/libxrdp/xrdp_rdp.c b/libxrdp/xrdp_rdp.c index 624b3b5d..876958db 100644 --- a/libxrdp/xrdp_rdp.c +++ b/libxrdp/xrdp_rdp.c @@ -127,6 +127,14 @@ xrdp_rdp_read_config(struct xrdp_client_info *client_info) log_message(LOG_LEVEL_DEBUG,"Info - All channels are disabled"); } } + else if (g_strcasecmp(item, "allow_multimon") == 0) + { + client_info->multimon = text2bool(value); + if (client_info->multimon == 0) + { + log_message(LOG_LEVEL_DEBUG,"Info - Multi monitor server support disabled"); + } + } else if (g_strcasecmp(item, "max_bpp") == 0) { client_info->max_bpp = g_atoi(value); @@ -211,7 +219,7 @@ xrdp_rdp_create(struct xrdp_session *session, struct trans *trans) xrdp_rdp_read_config(&self->client_info); /* create sec layer */ self->sec_layer = xrdp_sec_create(self, trans, self->client_info.crypt_level, - self->client_info.channel_code); + self->client_info.channel_code, self->client_info.multimon); /* default 8 bit v1 color bitmap cache entries and size */ self->client_info.cache1_entries = 600; self->client_info.cache1_size = 256; diff --git a/libxrdp/xrdp_sec.c b/libxrdp/xrdp_sec.c index 54d5d0de..89a710c6 100644 --- a/libxrdp/xrdp_sec.c +++ b/libxrdp/xrdp_sec.c @@ -138,7 +138,7 @@ hex_str_to_bin(char *in, char *out, int out_len) /*****************************************************************************/ struct xrdp_sec *APP_CC xrdp_sec_create(struct xrdp_rdp *owner, struct trans *trans, int crypt_level, - int channel_code) + int channel_code, int multimon) { struct xrdp_sec *self; @@ -168,6 +168,7 @@ xrdp_sec_create(struct xrdp_rdp *owner, struct trans *trans, int crypt_level, } self->channel_code = channel_code; + self->multimon = multimon; if (self->decrypt_rc4_info != NULL) { @@ -465,7 +466,7 @@ xrdp_sec_process_logon_info(struct xrdp_sec *self, struct stream *s) unicode_in(s, len_ip - 2, tmpdata, 255); in_uint16_le(s, len_dll); unicode_in(s, len_dll - 2, tmpdata, 255); - in_uint32_le(s, tzone); /* len of timetone */ + in_uint32_le(s, tzone); /* len of timezone */ in_uint8s(s, 62); /* skip */ in_uint8s(s, 22); /* skip misc. */ in_uint8s(s, 62); /* skip */ @@ -850,7 +851,48 @@ xrdp_sec_process_mcs_data_channels(struct xrdp_sec *self, struct stream *s) return 0; } +/*****************************************************************************/ +/* reads the client monitors data, in order to send it to X11rdp */ +static int APP_CC +xrdp_sec_process_mcs_data_monitors(struct xrdp_sec *self, struct stream *s) +{ + int index; + int monitorCount; + int flags; + struct mcs_monitor_item *monitor_item; + + DEBUG(("processing monitors data, allow_multimon is %d", self->multimon)); + + /* this is an option set in xrdp.ini */ + if (self->multimon != 1) /* is multi-monitors allowed ? */ + { + g_writeln("Processing monitor data from client - Multimon is not allowed"); + return 0; + } + in_uint32_le(s, flags); /* flags */ + DEBUG(("xrdp_sec_process_mcs_data_monitors: monitor flags is %s", flags)); + + in_uint32_le(s, monitorCount); + DEBUG(("xrdp_sec_process_mcs_data_monitors: monitor count is %s", monitorCount)); + + for (index = 0; index < monitorCount; index++) + { + monitor_item = (struct mcs_monitor_item *) + g_malloc(sizeof(struct mcs_monitor_item), 1); + in_uint32_le(s, monitor_item->x); + in_uint32_le(s, monitor_item->y); + in_uint32_le(s, monitor_item->width); + in_uint32_le(s, monitor_item->height); + in_uint32_le(s, monitor_item->is_primary); + + list_add_item(self->mcs_layer->monitor_list, (long)monitor_item); + DEBUG(("got monitor: flags %8.8x is primary? %s", monitor_item->height, + monitor_item->is_primary)); + } + + return 0; +} /*****************************************************************************/ /* process client mcs data, we need some things in here to create the server mcs data */ @@ -892,6 +934,10 @@ xrdp_sec_process_mcs_data(struct xrdp_sec *self) break; case SEC_TAG_CLI_4: break; + case SEC_TAG_CLI_MONITOR: + DEBUG((" in CS_MONITOR !!!")); + xrdp_sec_process_mcs_data_monitors(self, s); + break; default: g_writeln("error unknown xrdp_sec_process_mcs_data tag %d size %d", tag, size);