From a8e5b3fee51604d68d8ecd36065396ba42c7be3f Mon Sep 17 00:00:00 2001 From: speidy Date: Mon, 15 Jul 2013 10:13:03 +0300 Subject: [PATCH 01/13] 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); From 151cc7b5d11f6ca5eb60b86119037610070a0f1b Mon Sep 17 00:00:00 2001 From: speidy Date: Mon, 15 Jul 2013 10:14:48 +0300 Subject: [PATCH 02/13] libxrdp: add xrdp.ini multi-mon config --- xrdp/xrdp.ini | 2 ++ 1 file changed, 2 insertions(+) diff --git a/xrdp/xrdp.ini b/xrdp/xrdp.ini index ea6576cb..36106c1d 100644 --- a/xrdp/xrdp.ini +++ b/xrdp/xrdp.ini @@ -28,6 +28,8 @@ tcp_keepalive=yes # You can set the PAM error text in a gateway setup (MAX 256 chars) #pamerrortxt=change your password according to policy at http://url #new_cursors=no +#nego_sec_layer=0 +allow_multimon=true [Logging] LogFile=xrdp.log From 944f266a82c0f169402399f383893e872995d201 Mon Sep 17 00:00:00 2001 From: speidy Date: Mon, 15 Jul 2013 22:45:40 +0300 Subject: [PATCH 03/13] libxrdp: work on multi-mon, x.224 confirm packet --- libxrdp/xrdp_iso.c | 11 ++++++----- libxrdp/xrdp_sec.c | 8 ++++---- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/libxrdp/xrdp_iso.c b/libxrdp/xrdp_iso.c index 04186ea9..4d311784 100644 --- a/libxrdp/xrdp_iso.c +++ b/libxrdp/xrdp_iso.c @@ -126,16 +126,17 @@ xrdp_iso_send_msg(struct xrdp_iso *self, struct stream *s, int code) return 1; } - /* TPKT HEADER */ + /* TPKT HEADER - 4 bytes */ out_uint8(s, 3); /* version */ out_uint8(s, 0); /* RESERVED */ out_uint16_be(s, 19); /* length */ - /* ISO LAYER */ + /* ISO LAYER - X.224 - 7 bytes*/ out_uint8(s, 14); /* length */ - out_uint8(s, code); - out_uint16_le(s, 0); - out_uint16_le(s, 4660); + out_uint8(s, code); /* SHOULD BE 0xd for CC */ + out_uint16_be(s, 0); + out_uint16_be(s, 0x1234); out_uint8(s, 0); + /* RDP_NEG_RSP - 8 bytes*/ out_uint8(s, 2); /* TYPE_RDP_NEG_RSP */ out_uint8(s, 1); /* flags */ out_uint16_le(s, 8); /* length */ diff --git a/libxrdp/xrdp_sec.c b/libxrdp/xrdp_sec.c index 89a710c6..6cfd5ba1 100644 --- a/libxrdp/xrdp_sec.c +++ b/libxrdp/xrdp_sec.c @@ -880,10 +880,10 @@ xrdp_sec_process_mcs_data_monitors(struct xrdp_sec *self, struct stream *s) { 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->x); //TODO: change to signed 32 bit int. + in_uint32_le(s, monitor_item->y); //TODO: change to signed 32 bit int. + in_uint32_le(s, monitor_item->width); //TODO: change to signed 32 bit int. + in_uint32_le(s, monitor_item->height); //TODO: change to signed 32 bit int. in_uint32_le(s, monitor_item->is_primary); list_add_item(self->mcs_layer->monitor_list, (long)monitor_item); From 8914b523eecf850f6c6b754fbc572b95768bc2a6 Mon Sep 17 00:00:00 2001 From: speidy Date: Tue, 16 Jul 2013 21:46:49 +0300 Subject: [PATCH 04/13] X11rdp: makefile missing seperator fix --- xorg/X11R7.6/rdp/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xorg/X11R7.6/rdp/Makefile b/xorg/X11R7.6/rdp/Makefile index 755af882..e40b7473 100644 --- a/xorg/X11R7.6/rdp/Makefile +++ b/xorg/X11R7.6/rdp/Makefile @@ -112,4 +112,4 @@ fbcmap_mi.o: ../build_dir/xorg-server-1.9.3/fb/fbcmap_mi.c $(CC) $(CFLAGS) -c ../build_dir/xorg-server-1.9.3/fb/fbcmap_mi.c install: all - $(INSTALL) X11rdp $(X11RDPBASE)/bin/X11rdp + $(INSTALL) X11rdp $(X11RDPBASE)/bin/X11rdp From 2b0524ad7e4aa7183070c48370f97cdf785d450e Mon Sep 17 00:00:00 2001 From: speidy Date: Fri, 20 Sep 2013 00:06:04 +0300 Subject: [PATCH 05/13] libxrdp: work on RDP negotiation --- common/xrdp_constants.h | 23 ++++++++++++++++++++++ libxrdp/xrdp_iso.c | 42 ++++++++++++++++++++++++++++++++--------- 2 files changed, 56 insertions(+), 9 deletions(-) diff --git a/common/xrdp_constants.h b/common/xrdp_constants.h index 404e3b88..636337f8 100644 --- a/common/xrdp_constants.h +++ b/common/xrdp_constants.h @@ -31,6 +31,29 @@ #define ISO_PDU_DT 0xF0 /* Data */ #define ISO_PDU_ER 0x70 /* Error */ + +/* RDP Security Negotiation codes */ +#define RDP_NEG_REQ 0x01 +#define RDP_NEG_RSP 0x02 +#define RDP_NEG_FAILURE 0x03 +/* Protocol types codes */ +#define PROTOCOL_RDP 0x0 +#define PROTOCOL_SSL 0x1 +#define PROTOCOL_HYBRID 0x2 +#define PROTOCOL_HYBRID_EX 0x8 +/* Negotiation packet flags */ +#define EXTENDED_CLIENT_DATA_SUPPORTED 0x1 +#define DYNVC_GFX_PROTOCOL_SUPPORTED 0x2 +#define RDP_NEGRSP_RESERVED 0x4 +/* Failure Codes */ +#define SSL_REQUIRED_BY_SERVER 0x1 +#define SSL_NOT_ALLOWED_BY_SERVER 0x2 +#define SSL_CERT_NOT_ON_SERVER 0x3 +#define INCONSISTENT_FLAGS 0x4 +#define HYBRID_REQUIRED_BY_SERVER 0x5 +#define SSL_WITH_USER_AUTH_REQUIRED_BY_SERVER 0x6 + + /* MCS PDU codes */ #define MCS_EDRQ 1 /* Erect Domain Request */ #define MCS_DPUM 8 /* Disconnect Provider Ultimatum */ diff --git a/libxrdp/xrdp_iso.c b/libxrdp/xrdp_iso.c index 4d311784..3d332cd3 100644 --- a/libxrdp/xrdp_iso.c +++ b/libxrdp/xrdp_iso.c @@ -62,6 +62,9 @@ xrdp_iso_recv_msg(struct xrdp_iso *self, struct stream *s, int *code) return 1; } + // print CR packet hex dump + g_hexdump(s->p, 19); + in_uint8(s, ver); if (ver != 3) @@ -86,7 +89,7 @@ xrdp_iso_recv_msg(struct xrdp_iso *self, struct stream *s, int *code) } else { - in_uint8s(s, 13); + in_uint8s(s, 5+8); } return 0; @@ -119,7 +122,7 @@ xrdp_iso_recv(struct xrdp_iso *self, struct stream *s) /*****************************************************************************/ static int APP_CC -xrdp_iso_send_msg(struct xrdp_iso *self, struct stream *s, int code) +xrdp_iso_send_msg(struct xrdp_iso *self, struct stream *s, int code, int negostate) { if (xrdp_tcp_init(self->tcp_layer, s) != 0) { @@ -137,11 +140,23 @@ xrdp_iso_send_msg(struct xrdp_iso *self, struct stream *s, int code) out_uint16_be(s, 0x1234); out_uint8(s, 0); /* RDP_NEG_RSP - 8 bytes*/ - 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); + switch (negostate) + { + case RDP_NEG_FAILURE: + out_uint8(s, RDP_NEG_FAILURE); /* RDP_NEG_FAILURE */ + out_uint8(s, 0); /* no flags available */ + out_uint16_le(s, 8); /* fixed length */ + out_uint32_le(s, SSL_NOT_ALLOWED_BY_SERVER); /* failure code */ + break; + case RDP_NEG_RSP: + out_uint8(s, RDP_NEG_RSP); /* TYPE_RDP_NEG_RSP */ + out_uint8(s, EXTENDED_CLIENT_DATA_SUPPORTED); /* flags */ + out_uint16_le(s, 8); /* fixed length */ + out_uint32_le(s, PROTOCOL_RDP); /* selected protocol */ + break; + } + + s_mark_end(s); if (xrdp_tcp_send(self->tcp_layer, s) != 0) { @@ -157,8 +172,9 @@ int APP_CC xrdp_iso_incoming(struct xrdp_iso *self) { int code; + int negostate; struct stream *s; - +//todo: negostate init and change make_stream(s); init_stream(s, 8192); DEBUG((" in xrdp_iso_incoming")); @@ -175,7 +191,15 @@ xrdp_iso_incoming(struct xrdp_iso *self) return 1; } - if (xrdp_iso_send_msg(self, s, ISO_PDU_CC) != 0) + //RDP Negotiate Security Layer + +/* if (xrdp_nego_init(self, s, ISO_PDU_CC,init) != 0) + { + free_stream(s); + return 1; + }*/ + + if (xrdp_iso_send_msg(self, s, ISO_PDU_CC, negostate) != 0) { free_stream(s); return 1; From 9bf2d0dc60541832eb6280523ef1533d95143671 Mon Sep 17 00:00:00 2001 From: speidy Date: Wed, 25 Sep 2013 16:54:45 +0300 Subject: [PATCH 06/13] libxrdp: work on RDP negotiation, not working yet. --- libxrdp/xrdp_iso.c | 149 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 115 insertions(+), 34 deletions(-) diff --git a/libxrdp/xrdp_iso.c b/libxrdp/xrdp_iso.c index 3d332cd3..bd6c106e 100644 --- a/libxrdp/xrdp_iso.c +++ b/libxrdp/xrdp_iso.c @@ -2,6 +2,7 @@ * xrdp: A Remote Desktop Protocol server. * * Copyright (C) Jay Sorg 2004-2013 + * Copyright (C) Idan Freiberg 2013 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -47,6 +48,43 @@ xrdp_iso_delete(struct xrdp_iso *self) g_free(self); } +/*****************************************************************************/ +/* returns error */ +static int APP_CC +xrdp_iso_recv_rdpnegreq(struct xrdp_iso *self, struct stream *s, int *requestedProtocol) +{ + int type; + int flags; + int len; + + *requestedProtocol = 0; + + in_uint8(s, type); + if (type != RDP_NEG_REQ) + { + return 1; + } + + in_uint8(s, flags); + if (type != 0x0) + { + return 1; + } + + in_uint16_be(s, len); + if (len != 0x8) // fixed length + { + return 1; + } + + in_uint32_be(s, *requestedProtocol); + if (requestedProtocol != PROTOCOL_RDP || PROTOCOL_SSL || PROTOCOL_HYBRID || PROTOCOL_HYBRID_EX) + { + return 1; + } + + return 0; +} /*****************************************************************************/ /* returns error */ static int APP_CC @@ -62,9 +100,6 @@ xrdp_iso_recv_msg(struct xrdp_iso *self, struct stream *s, int *code) return 1; } - // print CR packet hex dump - g_hexdump(s->p, 19); - in_uint8(s, ver); if (ver != 3) @@ -75,6 +110,9 @@ xrdp_iso_recv_msg(struct xrdp_iso *self, struct stream *s, int *code) in_uint8s(s, 1); in_uint16_be(s, len); + // print CR packet hex dump + g_hexdump(s->p, len); + if (xrdp_tcp_recv(self->tcp_layer, s, len - 4) != 0) { return 1; @@ -89,12 +127,11 @@ xrdp_iso_recv_msg(struct xrdp_iso *self, struct stream *s, int *code) } else { - in_uint8s(s, 5+8); + in_uint8s(s, 5); } return 0; } - /*****************************************************************************/ /* returns error */ int APP_CC @@ -122,7 +159,7 @@ xrdp_iso_recv(struct xrdp_iso *self, struct stream *s) /*****************************************************************************/ static int APP_CC -xrdp_iso_send_msg(struct xrdp_iso *self, struct stream *s, int code, int negostate) +xrdp_iso_send_rdpnegrsp(struct xrdp_iso *self, struct stream *s, int code, int selectedProtocol) { if (xrdp_tcp_init(self->tcp_layer, s) != 0) { @@ -135,27 +172,15 @@ xrdp_iso_send_msg(struct xrdp_iso *self, struct stream *s, int code, int negosta out_uint16_be(s, 19); /* length */ /* ISO LAYER - X.224 - 7 bytes*/ out_uint8(s, 14); /* length */ - out_uint8(s, code); /* SHOULD BE 0xd for CC */ + out_uint8(s, code); /* SHOULD BE 0xD for CC */ out_uint16_be(s, 0); out_uint16_be(s, 0x1234); out_uint8(s, 0); /* RDP_NEG_RSP - 8 bytes*/ - switch (negostate) - { - case RDP_NEG_FAILURE: - out_uint8(s, RDP_NEG_FAILURE); /* RDP_NEG_FAILURE */ - out_uint8(s, 0); /* no flags available */ - out_uint16_le(s, 8); /* fixed length */ - out_uint32_le(s, SSL_NOT_ALLOWED_BY_SERVER); /* failure code */ - break; - case RDP_NEG_RSP: - out_uint8(s, RDP_NEG_RSP); /* TYPE_RDP_NEG_RSP */ - out_uint8(s, EXTENDED_CLIENT_DATA_SUPPORTED); /* flags */ - out_uint16_le(s, 8); /* fixed length */ - out_uint32_le(s, PROTOCOL_RDP); /* selected protocol */ - break; - } - + out_uint8(s, RDP_NEG_RSP); + out_uint8(s, EXTENDED_CLIENT_DATA_SUPPORTED); /* flags */ + out_uint16_le(s, 8); /* fixed length */ + out_uint32_le(s, selectedProtocol); /* selected protocol */ s_mark_end(s); if (xrdp_tcp_send(self->tcp_layer, s) != 0) @@ -165,16 +190,71 @@ xrdp_iso_send_msg(struct xrdp_iso *self, struct stream *s, int code, int negosta return 0; } +/*****************************************************************************/ +static int APP_CC +xrdp_iso_send_rdpnegfailure(struct xrdp_iso *self, struct stream *s, int code, int failureCode) +{ + if (xrdp_tcp_init(self->tcp_layer, s) != 0) + { + return 1; + } + /* TPKT HEADER - 4 bytes */ + out_uint8(s, 3); /* version */ + out_uint8(s, 0); /* RESERVED */ + out_uint16_be(s, 19); /* length */ + /* ISO LAYER - X.224 - 7 bytes*/ + out_uint8(s, 14); /* length */ + out_uint8(s, code); /* SHOULD BE 0xD for CC */ + out_uint16_be(s, 0); + out_uint16_be(s, 0x1234); + out_uint8(s, 0); + /* RDP_NEG_FAILURE - 8 bytes*/ + out_uint8(s, RDP_NEG_FAILURE); + out_uint8(s, 0); /* no flags available */ + out_uint16_le(s, 8); /* fixed length */ + out_uint32_le(s, failureCode); /* failure code */ + s_mark_end(s); + + if (xrdp_tcp_send(self->tcp_layer, s) != 0) + { + return 1; + } + + return 0; +} +/*****************************************************************************/ +static int APP_CC +xrdp_iso_proccess_nego(struct xrdp_iso *self, struct stream *s, int requstedProtocol) +{ + //TODO: negotiation logic here. + if (requstedProtocol != PROTOCOL_RDP) { + // Send RDP_NEG_Failure back to client + if (xrdp_iso_send_rdpnegfailure(self, s, ISO_PDU_CC, SSL_NOT_ALLOWED_BY_SERVER) != 0) + { + free_stream(s); + return 1; + } + } else { + // Send RDP_NEG_RSP back to client + if (xrdp_iso_send_rdpnegrsp(self, s, ISO_PDU_CC, PROTOCOL_RDP) != 0) + { + free_stream(s); + return 1; + } + } + + return 0; +} /*****************************************************************************/ /* returns error */ int APP_CC xrdp_iso_incoming(struct xrdp_iso *self) { int code; - int negostate; + int requestedProtocol; + int selectedProtocol; struct stream *s; -//todo: negostate init and change make_stream(s); init_stream(s, 8192); DEBUG((" in xrdp_iso_incoming")); @@ -191,20 +271,21 @@ xrdp_iso_incoming(struct xrdp_iso *self) return 1; } - //RDP Negotiate Security Layer - -/* if (xrdp_nego_init(self, s, ISO_PDU_CC,init) != 0) - { - free_stream(s); - return 1; - }*/ - - if (xrdp_iso_send_msg(self, s, ISO_PDU_CC, negostate) != 0) + // Receive RDP_NEG_REQ data + if (xrdp_iso_recv_rdpnegreq(self, s, &requestedProtocol) != 0) { free_stream(s); return 1; } + // Process negotiation request, should return protocol type. + if (xrdp_iso_proccess_nego(self, s, requestedProtocol) != 0) + { + free_stream(s); + return 1; + } + + DEBUG((" out xrdp_iso_incoming")); free_stream(s); return 0; From 24e4b8c937745ccd6855ce6e3d92c36a6f262c28 Mon Sep 17 00:00:00 2001 From: speidy Date: Wed, 25 Sep 2013 18:07:20 +0300 Subject: [PATCH 07/13] libxrdp: work on RDP negotiation part --- libxrdp/xrdp_iso.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/libxrdp/xrdp_iso.c b/libxrdp/xrdp_iso.c index bd6c106e..99920702 100644 --- a/libxrdp/xrdp_iso.c +++ b/libxrdp/xrdp_iso.c @@ -59,30 +59,39 @@ xrdp_iso_recv_rdpnegreq(struct xrdp_iso *self, struct stream *s, int *requestedP *requestedProtocol = 0; + DEBUG((" in xrdp_iso_recv_rdpnegreq")); + in_uint8(s, type); if (type != RDP_NEG_REQ) { + DEBUG((" xrdp_iso_recv_rdpnegreq: type: %x",type)); return 1; } in_uint8(s, flags); - if (type != 0x0) + if (flags != 0x0) { + DEBUG((" xrdp_iso_recv_rdpnegreq: flags: %x",flags)); return 1; } - in_uint16_be(s, len); - if (len != 0x8) // fixed length + in_uint16_le(s, len); + if (len != 8) // fixed length { + DEBUG((" xrdp_iso_recv_rdpnegreq: length: %x",len)); return 1; } - in_uint32_be(s, *requestedProtocol); - if (requestedProtocol != PROTOCOL_RDP || PROTOCOL_SSL || PROTOCOL_HYBRID || PROTOCOL_HYBRID_EX) - { - return 1; - } + in_uint32_le(s, *requestedProtocol); + //TODO: think of protocol verification logic +// if (requestedProtocol != PROTOCOL_RDP || PROTOCOL_SSL || PROTOCOL_HYBRID || PROTOCOL_HYBRID_EX) +// { +// DEBUG((" xrdp_iso_recv_rdpnegreq: wrong requestedProtocol: %x",requestedProtocol)); +// return 1; +// } + + DEBUG((" out xrdp_iso_recv_rdpnegreq")); return 0; } /*****************************************************************************/ From da62badee518fa31e3a4f9d7d5fb3ea32de40060 Mon Sep 17 00:00:00 2001 From: speidy Date: Tue, 1 Oct 2013 08:35:27 +0300 Subject: [PATCH 08/13] libxrdp: work on RDP negotiation, add clientRequestedProtocol to MCS response. (hardcoded values - temporarily) --- libxrdp/xrdp_iso.c | 3 --- libxrdp/xrdp_sec.c | 5 +++-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/libxrdp/xrdp_iso.c b/libxrdp/xrdp_iso.c index 99920702..dad2698f 100644 --- a/libxrdp/xrdp_iso.c +++ b/libxrdp/xrdp_iso.c @@ -119,9 +119,6 @@ xrdp_iso_recv_msg(struct xrdp_iso *self, struct stream *s, int *code) in_uint8s(s, 1); in_uint16_be(s, len); - // print CR packet hex dump - g_hexdump(s->p, len); - if (xrdp_tcp_recv(self->tcp_layer, s, len - 4) != 0) { return 1; diff --git a/libxrdp/xrdp_sec.c b/libxrdp/xrdp_sec.c index 6cfd5ba1..d7847eb7 100644 --- a/libxrdp/xrdp_sec.c +++ b/libxrdp/xrdp_sec.c @@ -984,13 +984,14 @@ xrdp_sec_out_mcs_data(struct xrdp_sec *self) out_uint8(s, 0x63); /* c */ out_uint8(s, 0x44); /* D */ out_uint8(s, 0x6e); /* n */ - out_uint16_be(s, 0x80fc + (num_channels_even * 2)); + out_uint16_be(s, 0x80fc + (num_channels_even * 2) + 4); out_uint16_le(s, SEC_TAG_SRV_INFO); - out_uint16_le(s, 8); /* len */ + out_uint16_le(s, 12); /* len */ out_uint8(s, 4); /* 4 = rdp5 1 = rdp4 */ out_uint8(s, 0); out_uint8(s, 8); out_uint8(s, 0); + out_uint32_le(s, PROTOCOL_RDP); /* clientReqeustedProtocol */ //TODO: pass it through sec_layer->selectedProtocol out_uint16_le(s, SEC_TAG_SRV_CHANNELS); out_uint16_le(s, 8 + (num_channels_even * 2)); /* len */ out_uint16_le(s, MCS_GLOBAL_CHANNEL); /* 1003, 0x03eb main channel */ From 0d8654481964bf13a4af5474ec37d44ef10320df Mon Sep 17 00:00:00 2001 From: speidy Date: Sat, 5 Oct 2013 12:03:15 +0300 Subject: [PATCH 09/13] libxrdp: work on multimon, added monitor data processing --- libxrdp/libxrdp.h | 10 ++++++---- libxrdp/xrdp_mcs.c | 15 +++++++++++++++ libxrdp/xrdp_sec.c | 36 +++++++++++++++++++----------------- 3 files changed, 40 insertions(+), 21 deletions(-) diff --git a/libxrdp/libxrdp.h b/libxrdp/libxrdp.h index 66b0cb61..88afae75 100644 --- a/libxrdp/libxrdp.h +++ b/libxrdp/libxrdp.h @@ -49,6 +49,8 @@ struct xrdp_iso { struct xrdp_mcs* mcs_layer; /* owner */ struct xrdp_tcp* tcp_layer; + int requestedProtocol; + int selectedProtocol; }; /* used in mcs */ @@ -62,10 +64,10 @@ struct mcs_channel_item /* used in mcs - client monitor data */ struct mcs_monitor_item { - int x; - int y; - int width; - int height; + int left; + int top; + int right; + int bottom; int is_primary; }; diff --git a/libxrdp/xrdp_mcs.c b/libxrdp/xrdp_mcs.c index 7d89766d..e7c5dee3 100644 --- a/libxrdp/xrdp_mcs.c +++ b/libxrdp/xrdp_mcs.c @@ -38,6 +38,7 @@ xrdp_mcs_create(struct xrdp_sec *owner, struct trans *trans, self->server_mcs_data = server_mcs_data; self->iso_layer = xrdp_iso_create(self, trans); self->channel_list = list_create(); + self->monitor_list = list_create(); DEBUG((" out xrdp_mcs_create")); return self; } @@ -47,6 +48,7 @@ void APP_CC xrdp_mcs_delete(struct xrdp_mcs *self) { struct mcs_channel_item *channel_item; + struct mcs_monitor_item *monitor_item; int index; int count; @@ -66,6 +68,19 @@ xrdp_mcs_delete(struct xrdp_mcs *self) } list_delete(self->channel_list); + + /* here we have to free the monitor items and anything in them */ + count = self->monitor_list->count; + + for (index = count - 1; index >= 0; index--) + { + monitor_item = (struct mcs_monitor_item *) + list_get_item(self->monitor_list, index); + g_free(monitor_item); + } + + list_delete(self->monitor_list); + xrdp_iso_delete(self->iso_layer); /* make sure we get null pointer exception if struct is used again. */ DEBUG(("xrdp_mcs_delete processed")) diff --git a/libxrdp/xrdp_sec.c b/libxrdp/xrdp_sec.c index d7847eb7..cacd7b8e 100644 --- a/libxrdp/xrdp_sec.c +++ b/libxrdp/xrdp_sec.c @@ -852,7 +852,7 @@ 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 */ +/* reads the client monitors data */ static int APP_CC xrdp_sec_process_mcs_data_monitors(struct xrdp_sec *self, struct stream *s) { @@ -862,33 +862,36 @@ xrdp_sec_process_mcs_data_monitors(struct xrdp_sec *self, struct stream *s) 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 ? */ + if (self->multimon != 1) /* are multi-monitors allowed ? */ { - g_writeln("Processing monitor data from client - Multimon is not allowed"); + DEBUG(("[INFO] xrdp_sec_process_mcs_data_monitors: multimon is not allowed, skipping")); return 0; } - in_uint32_le(s, flags); /* flags */ - DEBUG(("xrdp_sec_process_mcs_data_monitors: monitor flags is %s", flags)); - + //verify flags - must be 0x0 + if (flags != 0){ + DEBUG(("[ERROR] xrdp_sec_process_mcs_data_monitors: flags MUST be zero, detected: %d", flags)); + return 0; + } in_uint32_le(s, monitorCount); - DEBUG(("xrdp_sec_process_mcs_data_monitors: monitor count is %s", monitorCount)); - + //verify monitorCount - max 16 + if (monitorCount > 16){ + DEBUG(("[ERROR] xrdp_sec_process_mcs_data_monitors: max allowed monitors is 16, detected: %d", monitorCount)); + return 0; + } 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); //TODO: change to signed 32 bit int. - in_uint32_le(s, monitor_item->y); //TODO: change to signed 32 bit int. - in_uint32_le(s, monitor_item->width); //TODO: change to signed 32 bit int. - in_uint32_le(s, monitor_item->height); //TODO: change to signed 32 bit int. + in_uint32_le(s, monitor_item->left); + in_uint32_le(s, monitor_item->top); + in_uint32_le(s, monitor_item->right); + in_uint32_le(s, monitor_item->bottom); 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)); + DEBUG(("got monitor: x: %d, y: %d, width: %d, height: %d, is primary: %d", + monitor_item->x, monitor_item->y, monitor_item->width, monitor_item->height, monitor_item->is_primary)); } return 0; @@ -935,7 +938,6 @@ xrdp_sec_process_mcs_data(struct xrdp_sec *self) 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: From a581dc28bb6bff8e62356cf28be9d9c6986382d9 Mon Sep 17 00:00:00 2001 From: speidy Date: Sat, 5 Oct 2013 12:17:54 +0300 Subject: [PATCH 10/13] libxrdp: work on multimon, fix monitor debug msg --- libxrdp/xrdp_sec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libxrdp/xrdp_sec.c b/libxrdp/xrdp_sec.c index cacd7b8e..85b332ba 100644 --- a/libxrdp/xrdp_sec.c +++ b/libxrdp/xrdp_sec.c @@ -890,8 +890,8 @@ xrdp_sec_process_mcs_data_monitors(struct xrdp_sec *self, struct stream *s) in_uint32_le(s, monitor_item->bottom); in_uint32_le(s, monitor_item->is_primary); list_add_item(self->mcs_layer->monitor_list, (long)monitor_item); - DEBUG(("got monitor: x: %d, y: %d, width: %d, height: %d, is primary: %d", - monitor_item->x, monitor_item->y, monitor_item->width, monitor_item->height, monitor_item->is_primary)); + DEBUG(("got monitor: left: %d, top: %d, right: %d, bottom: %d, is primary: %d", + monitor_item->left, monitor_item->top, monitor_item->right, monitor_item->bottom, monitor_item->is_primary)); } return 0; From a8ab4cb5d1fa5d297b33e5802bf261707482f31e Mon Sep 17 00:00:00 2001 From: speidy Date: Wed, 9 Oct 2013 22:41:24 +0300 Subject: [PATCH 11/13] libxrdp: work on RDP negotiation, add legacy non-nego support. --- libxrdp/xrdp_iso.c | 96 +++++++++++++++++++++++++++++++--------------- 1 file changed, 65 insertions(+), 31 deletions(-) diff --git a/libxrdp/xrdp_iso.c b/libxrdp/xrdp_iso.c index dad2698f..0691468e 100644 --- a/libxrdp/xrdp_iso.c +++ b/libxrdp/xrdp_iso.c @@ -97,12 +97,13 @@ xrdp_iso_recv_rdpnegreq(struct xrdp_iso *self, struct stream *s, int *requestedP /*****************************************************************************/ /* returns error */ static int APP_CC -xrdp_iso_recv_msg(struct xrdp_iso *self, struct stream *s, int *code) +xrdp_iso_recv_msg(struct xrdp_iso *self, struct stream *s, int *code, int *len) { - int ver; - int len; + int ver; // TPKT Version + int plen; // TPKT PacketLength - *code = 0; + *code = 0; // X.224 Packet Type + *len = 0; // X.224 Length Indicator if (xrdp_tcp_recv(self->tcp_layer, s, 4) != 0) { @@ -117,14 +118,14 @@ xrdp_iso_recv_msg(struct xrdp_iso *self, struct stream *s, int *code) } in_uint8s(s, 1); - in_uint16_be(s, len); + in_uint16_be(s, plen); - if (xrdp_tcp_recv(self->tcp_layer, s, len - 4) != 0) + if (xrdp_tcp_recv(self->tcp_layer, s, plen - 4) != 0) { return 1; } - in_uint8s(s, 1); + in_uint8(s, *len); in_uint8(s, *code); if (*code == ISO_PDU_DT) @@ -144,18 +145,19 @@ int APP_CC xrdp_iso_recv(struct xrdp_iso *self, struct stream *s) { int code; + int len; DEBUG((" in xrdp_iso_recv")); - if (xrdp_iso_recv_msg(self, s, &code) != 0) + if (xrdp_iso_recv_msg(self, s, &code, &len) != 0) { DEBUG((" out xrdp_iso_recv xrdp_iso_recv_msg return non zero")); return 1; } - if (code != ISO_PDU_DT) + if (code != ISO_PDU_DT || len != 2) { - DEBUG((" out xrdp_iso_recv code != ISO_PDU_DT")); + DEBUG((" out xrdp_iso_recv code != ISO_PDU_DT or length != 2")); return 1; } @@ -167,26 +169,49 @@ xrdp_iso_recv(struct xrdp_iso *self, struct stream *s) static int APP_CC xrdp_iso_send_rdpnegrsp(struct xrdp_iso *self, struct stream *s, int code, int selectedProtocol) { - if (xrdp_tcp_init(self->tcp_layer, s) != 0) + int send_rdpnegdata; + + if (xrdp_tcp_init(self->tcp_layer, s) != 0) { return 1; } + //check for RDPNEGDATA + send_rdpnegdata = 1; + if (selectedProtocol == -1) { + send_rdpnegdata = 0; + } + /* TPKT HEADER - 4 bytes */ out_uint8(s, 3); /* version */ out_uint8(s, 0); /* RESERVED */ - out_uint16_be(s, 19); /* length */ + if (send_rdpnegdata == 1) { + out_uint16_be(s, 19); /* length */ + } + else + { + out_uint16_be(s, 11); /* length */ + } /* ISO LAYER - X.224 - 7 bytes*/ - out_uint8(s, 14); /* length */ + if (send_rdpnegdata == 1) { + out_uint8(s, 14); /* length */ + } + else + { + out_uint8(s, 6); /* length */ + } out_uint8(s, code); /* SHOULD BE 0xD for CC */ out_uint16_be(s, 0); out_uint16_be(s, 0x1234); out_uint8(s, 0); - /* RDP_NEG_RSP - 8 bytes*/ - out_uint8(s, RDP_NEG_RSP); - out_uint8(s, EXTENDED_CLIENT_DATA_SUPPORTED); /* flags */ - out_uint16_le(s, 8); /* fixed length */ - out_uint32_le(s, selectedProtocol); /* selected protocol */ + if (send_rdpnegdata == 1) { + /* RDP_NEG_RSP - 8 bytes*/ + out_uint8(s, RDP_NEG_RSP); + out_uint8(s, EXTENDED_CLIENT_DATA_SUPPORTED); /* flags */ + out_uint16_le(s, 8); /* fixed length */ + out_uint32_le(s, selectedProtocol); /* selected protocol */ + } + s_mark_end(s); if (xrdp_tcp_send(self->tcp_layer, s) != 0) @@ -235,7 +260,7 @@ xrdp_iso_proccess_nego(struct xrdp_iso *self, struct stream *s, int requstedProt { //TODO: negotiation logic here. if (requstedProtocol != PROTOCOL_RDP) { - // Send RDP_NEG_Failure back to client + // Send RDP_NEG_FAILURE back to client if (xrdp_iso_send_rdpnegfailure(self, s, ISO_PDU_CC, SSL_NOT_ALLOWED_BY_SERVER) != 0) { free_stream(s); @@ -258,6 +283,7 @@ int APP_CC xrdp_iso_incoming(struct xrdp_iso *self) { int code; + int len; int requestedProtocol; int selectedProtocol; struct stream *s; @@ -265,8 +291,9 @@ xrdp_iso_incoming(struct xrdp_iso *self) init_stream(s, 8192); DEBUG((" in xrdp_iso_incoming")); - if (xrdp_iso_recv_msg(self, s, &code) != 0) + if (xrdp_iso_recv_msg(self, s, &code, &len) != 0) { + DEBUG((" in xrdp_iso_recv_msg error!!")); free_stream(s); return 1; } @@ -277,18 +304,25 @@ xrdp_iso_incoming(struct xrdp_iso *self) return 1; } - // Receive RDP_NEG_REQ data - if (xrdp_iso_recv_rdpnegreq(self, s, &requestedProtocol) != 0) - { - free_stream(s); - return 1; + if (len > 6) { + // Receive RDP_NEG_REQ data + if (xrdp_iso_recv_rdpnegreq(self, s, &requestedProtocol) != 0) + { + free_stream(s); + return 1; + } + // Process negotiation request, should return protocol type. + if (xrdp_iso_proccess_nego(self, s, requestedProtocol) != 0) + { + free_stream(s); + return 1; + } } - - // Process negotiation request, should return protocol type. - if (xrdp_iso_proccess_nego(self, s, requestedProtocol) != 0) - { - free_stream(s); - return 1; + else if (len == 6) { + xrdp_iso_send_rdpnegrsp(self, s, ISO_PDU_CC, -1); + } + else { + DEBUG((" error in xrdp_iso_incoming: unknown length detected")); } From c2e7da84d416000a0b08ee561498044196437462 Mon Sep 17 00:00:00 2001 From: speidy Date: Wed, 9 Oct 2013 23:00:05 +0300 Subject: [PATCH 12/13] libxrdp: add clientRequestedProtocol only when RDPNEGDATA occurs. --- libxrdp/xrdp_iso.c | 26 ++++++++++++++------------ libxrdp/xrdp_sec.c | 20 +++++++++++++++++--- 2 files changed, 31 insertions(+), 15 deletions(-) diff --git a/libxrdp/xrdp_iso.c b/libxrdp/xrdp_iso.c index 0691468e..04e19983 100644 --- a/libxrdp/xrdp_iso.c +++ b/libxrdp/xrdp_iso.c @@ -51,13 +51,13 @@ xrdp_iso_delete(struct xrdp_iso *self) /*****************************************************************************/ /* returns error */ static int APP_CC -xrdp_iso_recv_rdpnegreq(struct xrdp_iso *self, struct stream *s, int *requestedProtocol) +xrdp_iso_recv_rdpnegreq(struct xrdp_iso *self, struct stream *s) { int type; int flags; int len; - *requestedProtocol = 0; + self->requestedProtocol = 0; DEBUG((" in xrdp_iso_recv_rdpnegreq")); @@ -82,7 +82,7 @@ xrdp_iso_recv_rdpnegreq(struct xrdp_iso *self, struct stream *s, int *requestedP return 1; } - in_uint32_le(s, *requestedProtocol); + in_uint32_le(s, self->requestedProtocol); //TODO: think of protocol verification logic // if (requestedProtocol != PROTOCOL_RDP || PROTOCOL_SSL || PROTOCOL_HYBRID || PROTOCOL_HYBRID_EX) @@ -167,7 +167,7 @@ xrdp_iso_recv(struct xrdp_iso *self, struct stream *s) /*****************************************************************************/ static int APP_CC -xrdp_iso_send_rdpnegrsp(struct xrdp_iso *self, struct stream *s, int code, int selectedProtocol) +xrdp_iso_send_rdpnegrsp(struct xrdp_iso *self, struct stream *s, int code) { int send_rdpnegdata; @@ -178,7 +178,7 @@ xrdp_iso_send_rdpnegrsp(struct xrdp_iso *self, struct stream *s, int code, int s //check for RDPNEGDATA send_rdpnegdata = 1; - if (selectedProtocol == -1) { + if (self->selectedProtocol == -1) { send_rdpnegdata = 0; } @@ -209,7 +209,7 @@ xrdp_iso_send_rdpnegrsp(struct xrdp_iso *self, struct stream *s, int code, int s out_uint8(s, RDP_NEG_RSP); out_uint8(s, EXTENDED_CLIENT_DATA_SUPPORTED); /* flags */ out_uint16_le(s, 8); /* fixed length */ - out_uint32_le(s, selectedProtocol); /* selected protocol */ + out_uint32_le(s, self->selectedProtocol); /* selected protocol */ } s_mark_end(s); @@ -256,10 +256,10 @@ xrdp_iso_send_rdpnegfailure(struct xrdp_iso *self, struct stream *s, int code, i } /*****************************************************************************/ static int APP_CC -xrdp_iso_proccess_nego(struct xrdp_iso *self, struct stream *s, int requstedProtocol) +xrdp_iso_proccess_nego(struct xrdp_iso *self, struct stream *s) { //TODO: negotiation logic here. - if (requstedProtocol != PROTOCOL_RDP) { + if (self->requestedProtocol != PROTOCOL_RDP) { // Send RDP_NEG_FAILURE back to client if (xrdp_iso_send_rdpnegfailure(self, s, ISO_PDU_CC, SSL_NOT_ALLOWED_BY_SERVER) != 0) { @@ -267,8 +267,9 @@ xrdp_iso_proccess_nego(struct xrdp_iso *self, struct stream *s, int requstedProt return 1; } } else { + self->selectedProtocol = PROTOCOL_RDP; // Send RDP_NEG_RSP back to client - if (xrdp_iso_send_rdpnegrsp(self, s, ISO_PDU_CC, PROTOCOL_RDP) != 0) + if (xrdp_iso_send_rdpnegrsp(self, s, ISO_PDU_CC) != 0) { free_stream(s); return 1; @@ -306,20 +307,21 @@ xrdp_iso_incoming(struct xrdp_iso *self) if (len > 6) { // Receive RDP_NEG_REQ data - if (xrdp_iso_recv_rdpnegreq(self, s, &requestedProtocol) != 0) + if (xrdp_iso_recv_rdpnegreq(self, s) != 0) { free_stream(s); return 1; } // Process negotiation request, should return protocol type. - if (xrdp_iso_proccess_nego(self, s, requestedProtocol) != 0) + if (xrdp_iso_proccess_nego(self, s) != 0) { free_stream(s); return 1; } } else if (len == 6) { - xrdp_iso_send_rdpnegrsp(self, s, ISO_PDU_CC, -1); + self->selectedProtocol = -1; //we are not doing negotiation + xrdp_iso_send_rdpnegrsp(self, s, ISO_PDU_CC); } else { DEBUG((" error in xrdp_iso_incoming: unknown length detected")); diff --git a/libxrdp/xrdp_sec.c b/libxrdp/xrdp_sec.c index 85b332ba..3d06c0f3 100644 --- a/libxrdp/xrdp_sec.c +++ b/libxrdp/xrdp_sec.c @@ -986,14 +986,28 @@ xrdp_sec_out_mcs_data(struct xrdp_sec *self) out_uint8(s, 0x63); /* c */ out_uint8(s, 0x44); /* D */ out_uint8(s, 0x6e); /* n */ - out_uint16_be(s, 0x80fc + (num_channels_even * 2) + 4); + if (self->mcs_layer->iso_layer->selectedProtocol != -1) { // Check for RDPNEGDATA availability + out_uint16_be(s, 0x80fc + (num_channels_even * 2) + 4); + } + else + { + out_uint16_be(s, 0x80fc + (num_channels_even * 2)); + } out_uint16_le(s, SEC_TAG_SRV_INFO); - out_uint16_le(s, 12); /* len */ + if (self->mcs_layer->iso_layer->selectedProtocol != -1) { + out_uint16_le(s, 12); /* len */ + } + else + { + out_uint16_le(s, 8); /* len */ + } out_uint8(s, 4); /* 4 = rdp5 1 = rdp4 */ out_uint8(s, 0); out_uint8(s, 8); out_uint8(s, 0); - out_uint32_le(s, PROTOCOL_RDP); /* clientReqeustedProtocol */ //TODO: pass it through sec_layer->selectedProtocol + if (self->mcs_layer->iso_layer->selectedProtocol != -1) { + out_uint32_le(s, self->mcs_layer->iso_layer->selectedProtocol); /* clientReqeustedProtocol */ + } out_uint16_le(s, SEC_TAG_SRV_CHANNELS); out_uint16_le(s, 8 + (num_channels_even * 2)); /* len */ out_uint16_le(s, MCS_GLOBAL_CHANNEL); /* 1003, 0x03eb main channel */ From a4d2917a0a169c0672dc61be4f7b4689a02278b3 Mon Sep 17 00:00:00 2001 From: speidy Date: Wed, 9 Oct 2013 23:06:45 +0300 Subject: [PATCH 13/13] libxrdp: iso_send_rdpnegrdp fix + notes. --- libxrdp/xrdp_iso.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/libxrdp/xrdp_iso.c b/libxrdp/xrdp_iso.c index 04e19983..e77f5316 100644 --- a/libxrdp/xrdp_iso.c +++ b/libxrdp/xrdp_iso.c @@ -176,24 +176,18 @@ xrdp_iso_send_rdpnegrsp(struct xrdp_iso *self, struct stream *s, int code) return 1; } - //check for RDPNEGDATA - send_rdpnegdata = 1; - if (self->selectedProtocol == -1) { - send_rdpnegdata = 0; - } - /* TPKT HEADER - 4 bytes */ out_uint8(s, 3); /* version */ out_uint8(s, 0); /* RESERVED */ - if (send_rdpnegdata == 1) { - out_uint16_be(s, 19); /* length */ + if (self->selectedProtocol != -1) { + out_uint16_be(s, 19); /* length */ //rdp negotiation happens. } else { - out_uint16_be(s, 11); /* length */ + out_uint16_be(s, 11); /* length */ //rdp negotiation doesn't happen. } /* ISO LAYER - X.224 - 7 bytes*/ - if (send_rdpnegdata == 1) { + if (self->selectedProtocol != -1) { out_uint8(s, 14); /* length */ } else @@ -204,7 +198,7 @@ xrdp_iso_send_rdpnegrsp(struct xrdp_iso *self, struct stream *s, int code) out_uint16_be(s, 0); out_uint16_be(s, 0x1234); out_uint8(s, 0); - if (send_rdpnegdata == 1) { + if (self->selectedProtocol != -1) { /* RDP_NEG_RSP - 8 bytes*/ out_uint8(s, RDP_NEG_RSP); out_uint8(s, EXTENDED_CLIENT_DATA_SUPPORTED); /* flags */