From b8cffeefe1c13838271cf517dfb255785aab5685 Mon Sep 17 00:00:00 2001 From: speidy Date: Wed, 5 Feb 2014 10:36:58 +0200 Subject: [PATCH 01/12] neutirnordp: changes for rail proxy --- neutrinordp/xrdp-neutrinordp.c | 86 +++++++++++++++++++++------------- 1 file changed, 53 insertions(+), 33 deletions(-) diff --git a/neutrinordp/xrdp-neutrinordp.c b/neutrinordp/xrdp-neutrinordp.c index 3602e57c..8e8f3cac 100644 --- a/neutrinordp/xrdp-neutrinordp.c +++ b/neutrinordp/xrdp-neutrinordp.c @@ -27,7 +27,7 @@ #ifdef XRDP_DEBUG #define LOG_LEVEL 99 #else -#define LOG_LEVEL 10 +#define LOG_LEVEL 11 #endif #define LLOG(_level, _args) \ @@ -256,11 +256,13 @@ lxrdp_event(struct mod *mod, int msg, long param1, long param2, case 107: /* wheel up */ flags = PTR_FLAGS_WHEEL | 0x0078; mod->inst->input->MouseEvent(mod->inst->input, flags, 0, 0); + break; case 108: break; case 109: /* wheel down */ flags = PTR_FLAGS_WHEEL | PTR_FLAGS_WHEEL_NEGATIVE | 0x0088; mod->inst->input->MouseEvent(mod->inst->input, flags, 0, 0); + break; case 110: break; case 200: @@ -277,8 +279,9 @@ lxrdp_event(struct mod *mod, int msg, long param1, long param2, size = (int)param2; data = (char *)param3; total_size = (int)param4; - LLOGLN(12, ("lxrdp_event: client to server flags %d", flags)); + LLOGLN(10, ("lxrdp_event: client to server ,chanid= %d flags= %d", chanid, flags)); + g_hexdump(data, size); // for debugging if ((chanid < 0) || (chanid >= mod->inst->settings->num_channels)) { LLOGLN(0, ("lxrdp_event: error chanid %d", chanid)); @@ -472,7 +475,7 @@ lfreerdp_begin_paint(rdpContext *context) { struct mod *mod; - LLOGLN(10, ("lfreerdp_begin_paint:")); + LLOGLN(12, ("lfreerdp_begin_paint:")); mod = ((struct mod_context *)context)->modi; mod->server_begin_update(mod); } @@ -483,7 +486,7 @@ lfreerdp_end_paint(rdpContext *context) { struct mod *mod; - LLOGLN(10, ("lfreerdp_end_paint:")); + LLOGLN(12, ("lfreerdp_end_paint:")); mod = ((struct mod_context *)context)->modi; mod->server_end_update(mod); } @@ -498,7 +501,7 @@ lfreerdp_set_bounds(rdpContext *context, rdpBounds *bounds) int cx; int cy; - LLOGLN(10, ("lfreerdp_set_bounds: %p", bounds)); + LLOGLN(12, ("lfreerdp_set_bounds: %p", bounds)); mod = ((struct mod_context *)context)->modi; if (bounds != 0) @@ -715,7 +718,7 @@ lfreerdp_mem_blt(rdpContext *context, MEMBLT_ORDER *memblt) struct bitmap_item *bi; mod = ((struct mod_context *)context)->modi; - LLOGLN(10, ("lfreerdp_mem_blt: cacheId %d cacheIndex %d", + LLOGLN(12, ("lfreerdp_mem_blt: cacheId %d cacheIndex %d", memblt->cacheId, memblt->cacheIndex)); id = memblt->cacheId; @@ -1334,7 +1337,7 @@ static void DEFAULT_CC lfreerdp_syncronize(rdpContext* context) { struct mod *mod; mod = ((struct mod_context *)context)->modi; - LLOGLN(0, ("lfreerdp_synchronize received - not handled")); + LLOGLN(12, ("lfreerdp_synchronize received - not handled")); } /******************************************************************************/ @@ -1359,8 +1362,8 @@ lfreerdp_pre_connect(freerdp *instance) while (error == 0) { num_chans++; - LLOGLN(10, ("lfreerdp_pre_connect: got channel [%s], flags [0x%8.8x]", - ch_name, ch_flags)); + LLOGLN(10, ("lfreerdp_pre_connect: got channel [%s], id [%d], flags [0x%8.8x]", + ch_name, index, ch_flags)); dst_ch_name = instance->settings->channels[index].name; g_memset(dst_ch_name, 0, 8); g_snprintf(dst_ch_name, 8, "%s", ch_name); @@ -1389,24 +1392,25 @@ lfreerdp_pre_connect(freerdp *instance) instance->settings->order_support[NEG_MEM3BLT_INDEX] = 0; instance->settings->order_support[NEG_MEM3BLT_V2_INDEX] = 0; instance->settings->bitmapCacheV2NumCells = 3; // 5; - instance->settings->bitmapCacheV2CellInfo[0].numEntries = 0x78; // 600; + instance->settings->bitmapCacheV2CellInfo[0].numEntries = 600; // 0x78; instance->settings->bitmapCacheV2CellInfo[0].persistent = 0; - instance->settings->bitmapCacheV2CellInfo[1].numEntries = 0x78; // 600; + instance->settings->bitmapCacheV2CellInfo[1].numEntries = 600; //0x78; // 600; instance->settings->bitmapCacheV2CellInfo[1].persistent = 0; - instance->settings->bitmapCacheV2CellInfo[2].numEntries = 0x150; // 2048; + instance->settings->bitmapCacheV2CellInfo[2].numEntries = 2048; //0x150; // 2048; instance->settings->bitmapCacheV2CellInfo[2].persistent = 0; - instance->settings->bitmapCacheV2CellInfo[3].numEntries = 0; // 4096; + instance->settings->bitmapCacheV2CellInfo[3].numEntries = 4096; // 4096; instance->settings->bitmapCacheV2CellInfo[3].persistent = 0; - instance->settings->bitmapCacheV2CellInfo[4].numEntries = 0; // 2048; + instance->settings->bitmapCacheV2CellInfo[4].numEntries = 2048; // 2048; instance->settings->bitmapCacheV2CellInfo[4].persistent = 0; - // instance->settings->BitmapCacheV3Enabled = FALSE; + instance->settings->bitmap_cache_v3 = 1; instance->settings->order_support[NEG_MULTIDSTBLT_INDEX] = 0; instance->settings->order_support[NEG_MULTIPATBLT_INDEX] = 0; instance->settings->order_support[NEG_MULTISCRBLT_INDEX] = 0; instance->settings->order_support[NEG_MULTIOPAQUERECT_INDEX] = 0; instance->settings->order_support[NEG_POLYLINE_INDEX] = 0; + instance->settings->username = g_strdup(mod->username); instance->settings->password = g_strdup(mod->password); @@ -1417,6 +1421,10 @@ lfreerdp_pre_connect(freerdp *instance) instance->settings->rail_langbar_supported = 1; instance->settings->workarea = 1; instance->settings->performance_flags = PERF_DISABLE_WALLPAPER | PERF_DISABLE_FULLWINDOWDRAG; + instance->settings->num_icon_caches = mod->client_info.wnd_num_icon_caches; + instance->settings->num_icon_cache_entries = mod->client_info.wnd_num_icon_cache_entries; + + } else { @@ -1429,8 +1437,16 @@ lfreerdp_pre_connect(freerdp *instance) instance->settings->compression = 0; instance->settings->ignore_certificate = 1; - // here - //instance->settings->RdpVersion = 4; + // Multi Monitor Settings + instance->settings->num_monitors = mod->client_info.monitorCount; + for (index = 0; index < mod->client_info.monitorCount; index++) + { + instance->settings->monitors[index].x = mod->client_info.minfo[index].left; + instance->settings->monitors[index].y = mod->client_info.minfo[index].top; + instance->settings->monitors[index].width = mod->client_info.minfo[index].right; + instance->settings->monitors[index].height = mod->client_info.minfo[index].bottom; + instance->settings->monitors[index].is_primary = mod->client_info.minfo[index].is_primary; + } instance->update->BeginPaint = lfreerdp_begin_paint; instance->update->EndPaint = lfreerdp_end_paint; @@ -1457,6 +1473,7 @@ lfreerdp_pre_connect(freerdp *instance) instance->update->pointer->PointerNew = lfreerdp_pointer_new; instance->update->pointer->PointerCached = lfreerdp_pointer_cached; + if ((mod->username[0] != 0) && (mod->password[0] != 0)) { /* since we have username and password, we can try nla */ @@ -1629,21 +1646,21 @@ lrail_NotifyIconCreate(rdpContext *context, WINDOW_ORDER_INFO *orderInfo, rnso.version = notify_icon_state->version; if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_TIP) - { - rnso.tool_tip = freerdp_uniconv_in(uniconv, - notify_icon_state->toolTip.string, notify_icon_state->toolTip.length); - } - if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_INFO_TIP) - { - rnso.infotip.timeout = notify_icon_state->infoTip.timeout; - rnso.infotip.flags = notify_icon_state->infoTip.flags; - rnso.infotip.text = freerdp_uniconv_in(uniconv, - notify_icon_state->infoTip.text.string, - notify_icon_state->infoTip.text.length); - rnso.infotip.title = freerdp_uniconv_in(uniconv, - notify_icon_state->infoTip.title.string, - notify_icon_state->infoTip.title.length); - } + { + rnso.tool_tip = freerdp_uniconv_in(uniconv, + notify_icon_state->toolTip.string, notify_icon_state->toolTip.length); + } + if (orderInfo->fieldFlags & WINDOW_ORDER_FIELD_NOTIFY_INFO_TIP) + { + rnso.infotip.timeout = notify_icon_state->infoTip.timeout; + rnso.infotip.flags = notify_icon_state->infoTip.flags; + rnso.infotip.text = freerdp_uniconv_in(uniconv, + notify_icon_state->infoTip.text.string, + notify_icon_state->infoTip.text.length); + rnso.infotip.title = freerdp_uniconv_in(uniconv, + notify_icon_state->infoTip.title.string, + notify_icon_state->infoTip.title.length); + } rnso.state = notify_icon_state->state; rnso.icon_cache_entry = notify_icon_state->icon.cacheEntry; @@ -1744,6 +1761,7 @@ lfreerdp_post_connect(freerdp *instance) mod = ((struct mod_context *)(instance->context))->modi; g_memset(mod->password, 0, sizeof(mod->password)); + mod->inst->update->window->WindowCreate = lrail_WindowCreate; mod->inst->update->window->WindowUpdate = lrail_WindowUpdate; mod->inst->update->window->WindowDelete = lrail_WindowDelete; @@ -1755,6 +1773,7 @@ lfreerdp_post_connect(freerdp *instance) mod->inst->update->window->MonitoredDesktop = lrail_MonitoredDesktop; mod->inst->update->window->NonMonitoredDesktop = lrail_NonMonitoredDesktop; + return 1; } @@ -1796,7 +1815,8 @@ lfreerdp_receive_channel_data(freerdp *instance, int channelId, uint8 *data, if (lchid >= 0) { - LLOGLN(10, ("lfreerdp_receive_channel_data: server to client")); + LLOGLN(10, ("lfreerdp_receive_channel_data: server to client, chanid: %d", lchid)); + g_hexdump(data, size); // for debugging error = mod->server_send_to_channel(mod, lchid, (char *)data, size, total_size, flags); From 423c583cddc31df98a01c8b5ed39558d691c19eb Mon Sep 17 00:00:00 2001 From: speidy Date: Wed, 5 Feb 2014 10:38:25 +0200 Subject: [PATCH 02/12] libxrdp: xrdp_sec: added CS_CORE process func for future use. --- libxrdp/xrdp_sec.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/libxrdp/xrdp_sec.c b/libxrdp/xrdp_sec.c index d1bd49de..df2cc653 100644 --- a/libxrdp/xrdp_sec.c +++ b/libxrdp/xrdp_sec.c @@ -901,7 +901,39 @@ xrdp_sec_send(struct xrdp_sec *self, struct stream *s, int chan) DEBUG((" out xrdp_sec_send")); return 0; } +/*****************************************************************************/ +/* returns error */ +static int APP_CC +xrdp_sec_process_mcs_cli_info(struct xrdp_sec *self, struct stream *s) +{ + in_uint8s(s, 4); /* RDP client version */ + in_uint8s(s, 2); /* desktopWidth */ + in_uint8s(s, 2); /* desktopHeight */ + in_uint8s(s, 2); /* colorDepth */ + in_uint8s(s, 2); + in_uint8s(s, 4); + in_uint8s(s, 4); + in_uint8s(s, 32); + in_uint8s(s, 4); + in_uint8s(s, 4); + in_uint8s(s, 64); + in_uint8s(s, 2); + in_uint8s(s, 2); + in_uint8s(s, 4); + in_uint8s(s, 2); + in_uint8s(s, 2); + in_uint8s(s, 2); /* earlyCapabilityFlags */ + in_uint8s(s, 64); + in_uint8s(s, 1); + in_uint8s(s, 1); /* pad1octet */ + in_uint8s(s, 4); + in_uint8s(s, 4); + in_uint8s(s, 4); + in_uint8s(s, 2); + in_uint8s(s, 4); + in_uint8s(s, 4); +} /*****************************************************************************/ /* this adds the mcs channels in the list of channels to be used when creating the server mcs data */ @@ -1043,6 +1075,10 @@ xrdp_sec_process_mcs_data(struct xrdp_sec *self) switch (tag) { case SEC_TAG_CLI_INFO: + if (xrdp_sec_process_mcs_cli_info(self, s) != 0) + { + return 1; + } break; case SEC_TAG_CLI_CRYPT: break; From 113f2696fe4103474cb2703e3d2f8848304fdd3d Mon Sep 17 00:00:00 2001 From: speidy Date: Sat, 8 Feb 2014 13:34:01 +0200 Subject: [PATCH 03/12] libxrdp: work on fastpath --- common/parse.h | 3 +- libxrdp/libxrdp.c | 3 +- libxrdp/libxrdp.h | 2 + libxrdp/xrdp_fastpath.c | 2 +- libxrdp/xrdp_iso.c | 200 +++++++++++++++++++++++++++------------- libxrdp/xrdp_mcs.c | 61 ++++++++---- libxrdp/xrdp_rdp.c | 24 ++++- libxrdp/xrdp_sec.c | 8 +- libxrdp/xrdp_tcp.c | 4 +- 9 files changed, 213 insertions(+), 94 deletions(-) diff --git a/common/parse.h b/common/parse.h index 69a57ff8..97911abb 100644 --- a/common/parse.h +++ b/common/parse.h @@ -116,7 +116,8 @@ struct stream (v) = *((unsigned char*)((s)->p)); \ (s)->p++; \ } while (0) - +/******************************************************************************/ +#define in_uint8_peek(s, v) do { v = *s->p; } while (0) /******************************************************************************/ #if defined(B_ENDIAN) || defined(NEED_ALIGN) #define in_sint16_le(s, v) do \ diff --git a/libxrdp/libxrdp.c b/libxrdp/libxrdp.c index ac5bbe98..c220f56f 100644 --- a/libxrdp/libxrdp.c +++ b/libxrdp/libxrdp.c @@ -128,7 +128,6 @@ libxrdp_process_data(struct xrdp_session *session) session->s); break; case RDP_PDU_DATA: /* 7 */ - if (xrdp_rdp_process_data((struct xrdp_rdp *)session->rdp, session->s) != 0) { @@ -139,7 +138,7 @@ libxrdp_process_data(struct xrdp_session *session) break; default: - g_writeln("unknown in libxrdp_process_data"); + g_writeln("unknown in libxrdp_process_data: code= %d", code); dead_lock_counter++; break; } diff --git a/libxrdp/libxrdp.h b/libxrdp/libxrdp.h index 70c8a124..a9150111 100644 --- a/libxrdp/libxrdp.h +++ b/libxrdp/libxrdp.h @@ -290,6 +290,8 @@ int APP_CC xrdp_iso_send(struct xrdp_iso* self, struct stream* s); int APP_CC xrdp_iso_incoming(struct xrdp_iso* self); +int APP_CC +xrdp_iso_detect_tpkt(struct xrdp_iso *self, struct stream *s); /* xrdp_mcs.c */ struct xrdp_mcs* APP_CC diff --git a/libxrdp/xrdp_fastpath.c b/libxrdp/xrdp_fastpath.c index 10f844e5..96d84972 100644 --- a/libxrdp/xrdp_fastpath.c +++ b/libxrdp/xrdp_fastpath.c @@ -2,7 +2,7 @@ * xrdp: A Remote Desktop Protocol server. * * Copyright (C) Jay Sorg 2012-2013 - * Copyright (C) Kevin Zhou 2012 + * Copyright (C) Idan Freiberg 2013-2014 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/libxrdp/xrdp_iso.c b/libxrdp/xrdp_iso.c index 69c242d3..09c08f94 100644 --- a/libxrdp/xrdp_iso.c +++ b/libxrdp/xrdp_iso.c @@ -89,44 +89,125 @@ xrdp_iso_recv_rdpnegreq(struct xrdp_iso *self, struct stream *s) static int APP_CC xrdp_iso_recv_msg(struct xrdp_iso *self, struct stream *s, int *code, int *len) { - int ver; // TPKT Version - int plen; // TPKT PacketLength + int plen; // PacketLength *code = 0; // X.224 Packet Type *len = 0; // X.224 Length Indicator - if (xrdp_tcp_recv(self->tcp_layer, s, 4) != 0) + plen = xrdp_iso_recv_tpkt_header(self, s); + if (plen == 1) { + DEBUG((" xrdp_iso_recv_msg: error in tpkt header reading")); return 1; } - in_uint8(s, ver); - - if (ver != 3) + // receive the left bytes + if (xrdp_tcp_recv(self->tcp_layer, s, plen - 4) != 0) { return 1; } - in_uint8s(s, 1); - in_uint16_be(s, plen); + xrdp_iso_read_x224_header(s, code, len); - if (plen < 4) + return 0; +} +/*****************************************************************************/ +/* returns error */ +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, &len) != 0) { + DEBUG((" out xrdp_iso_recv xrdp_iso_recv_msg return non zero")); return 1; } - if (xrdp_tcp_recv(self->tcp_layer, s, plen - 4) != 0) + if (code != ISO_PDU_DT || len != 2) { + DEBUG((" out xrdp_iso_recv code != ISO_PDU_DT or length != 2")); return 1; } + DEBUG((" out xrdp_iso_recv")); + return 0; +} +/*****************************************************************************/ +/* returns error */ +int APP_CC +xrdp_iso_detect_tpkt(struct xrdp_iso *self, struct stream *s) +{ + int ver; + + DEBUG((" in xrdp_iso_detect_tpkt")); + if (xrdp_tcp_recv(self->tcp_layer, s, 1) != 0) + { + return 1; + } + + in_uint8_peek(s, ver); + g_writeln("tpkt version: %x", ver); + + if (ver != 3) + { + return 1; + } + + DEBUG((" out xrdp_iso_detect_tpkt")); + return 0; +} +/*****************************************************************************/ +/* returns packet length or error (1) */ +int APP_CC +xrdp_iso_recv_tpkt_header(struct xrdp_iso *self, struct stream *s) +{ + int plen; + + DEBUG((" in xrdp_iso_recv_tpkt_header")); + + if (xrdp_tcp_recv(self->tcp_layer, s, 3) != 0) + { + return 1; + } + + in_uint8s(s, 1); + in_uint16_be(s, plen); + + if (plen < 4) + { + return 1; // tpkt must be >= 4 bytes length + } + + DEBUG((" out xrdp_iso_recv_tpkt_header")); + + return plen; +} +/*****************************************************************************/ +void APP_CC +xrdp_iso_write_tpkt_header(struct stream *s, int len) +{ + /* TPKT HEADER - 4 bytes */ + out_uint8(s, 3); /* version */ + out_uint8(s, 0); /* RESERVED */ + out_uint16_be(s, len); /* length */ +} +/*****************************************************************************/ +/* returns error */ +int APP_CC +xrdp_iso_read_x224_header(struct stream *s, int *code, int *len) +{ + DEBUG((" in xrdp_iso_read_x224_header")); if (!s_check_rem(s, 2)) { return 1; } - in_uint8(s, *len); - in_uint8(s, *code); + in_uint8(s, *len); /* length */ + in_uint8(s, *code); /* code */ if (*code == ISO_PDU_DT) { @@ -144,68 +225,59 @@ xrdp_iso_recv_msg(struct xrdp_iso *self, struct stream *s, int *code, int *len) } in_uint8s(s, 5); } + DEBUG((" out xrdp_iso_read_x224_header")); return 0; } /*****************************************************************************/ -/* returns error */ -int APP_CC -xrdp_iso_recv(struct xrdp_iso *self, struct stream *s) +void APP_CC +xrdp_iso_write_x224_header(struct stream *s, int len, int code) { - int code; - int len; - - DEBUG((" in xrdp_iso_recv")); - - if (xrdp_iso_recv_msg(self, s, &code, &len) != 0) - { - DEBUG((" out xrdp_iso_recv xrdp_iso_recv_msg return non zero")); - return 1; - } + /* ISO LAYER - X.224 - 7 bytes*/ + out_uint8(s, len); /* length */ + out_uint8(s, code); /* code */ - if (code != ISO_PDU_DT || len != 2) + if (code == ISO_PDU_DT) { - DEBUG((" out xrdp_iso_recv code != ISO_PDU_DT or length != 2")); - return 1; + out_uint8(s, 0x80); + } else { + out_uint16_be(s, 0); + out_uint16_be(s, 0x1234); + out_uint8(s, 0); } - - DEBUG((" out xrdp_iso_recv")); - return 0; } - /*****************************************************************************/ static int APP_CC -xrdp_iso_send_rdpnegrsp(struct xrdp_iso *self, struct stream *s, int code) +xrdp_iso_send_rdpnegrsp(struct xrdp_iso *self, struct stream *s) { 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 */ + // Write TPKT Header if (self->selectedProtocol != -1) { - out_uint16_be(s, 19); /* length */ //rdp negotiation happens. + //rdp negotiation happens. + xrdp_iso_write_tpkt_header(s, 19); } else { - out_uint16_be(s, 11); /* length */ //rdp negotiation doesn't happen. + //rdp negotiation doesn't happen. + xrdp_iso_write_tpkt_header(s, 11); } - /* ISO LAYER - X.224 - 7 bytes*/ + + // Write x224 header if (self->selectedProtocol != -1) { - out_uint8(s, 14); /* length */ + xrdp_iso_write_x224_header(s, 14, ISO_PDU_CC); } else { - out_uint8(s, 6); /* length */ + xrdp_iso_write_x224_header(s, 6, ISO_PDU_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 */ if (self->selectedProtocol != -1) { /* RDP_NEG_RSP - 8 bytes*/ @@ -226,23 +298,17 @@ xrdp_iso_send_rdpnegrsp(struct xrdp_iso *self, struct stream *s, int code) } /*****************************************************************************/ static int APP_CC -xrdp_iso_send_rdpnegfailure(struct xrdp_iso *self, struct stream *s, int code, int failureCode) +xrdp_iso_send_rdpnegfailure(struct xrdp_iso *self, struct stream *s, 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); + xrdp_iso_write_tpkt_header(s, 19); + + xrdp_iso_write_x224_header(s, 14, ISO_PDU_CC); + /* RDP_NEG_FAILURE - 8 bytes*/ out_uint8(s, RDP_NEG_FAILURE); out_uint8(s, 0); /* no flags available */ @@ -271,8 +337,7 @@ xrdp_iso_send_nego(struct xrdp_iso *self) 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) + if (xrdp_iso_send_rdpnegfailure(self, s, SSL_NOT_ALLOWED_BY_SERVER) != 0) { free_stream(s); return 1; @@ -282,7 +347,7 @@ xrdp_iso_send_nego(struct xrdp_iso *self) { self->selectedProtocol = PROTOCOL_RDP; // Send RDP_NEG_RSP back to client - if (xrdp_iso_send_rdpnegrsp(self, s, ISO_PDU_CC) != 0) + if (xrdp_iso_send_rdpnegrsp(self, s) != 0) { free_stream(s); return 1; @@ -309,6 +374,13 @@ xrdp_iso_incoming(struct xrdp_iso *self) init_stream(s, 8192); DEBUG((" in xrdp_iso_incoming")); + if (xrdp_iso_detect_tpkt(self, s) != 0) + { + g_writeln("xrdp_iso_incoming: TPKT not detected"); + free_stream(s); + return 1; + } + if (xrdp_iso_recv_msg(self, s, &code, &len) != 0) { DEBUG((" in xrdp_iso_recv_msg error!!")); @@ -318,6 +390,7 @@ xrdp_iso_incoming(struct xrdp_iso *self) if ((code != ISO_PDU_CR) || (len < 6)) { + DEBUG((" in xrdp_iso_recv_msg error: non iso_pdu_cr msg")); free_stream(s); return 1; } @@ -394,12 +467,9 @@ xrdp_iso_send(struct xrdp_iso *self, struct stream *s) DEBUG((" in xrdp_iso_send")); s_pop_layer(s, iso_hdr); len = (int)(s->end - s->p); - out_uint8(s, 3); - out_uint8(s, 0); - out_uint16_be(s, len); - out_uint8(s, 2); - out_uint8(s, ISO_PDU_DT); - out_uint8(s, 0x80); + + xrdp_iso_write_tpkt_header(s, len); + xrdp_iso_write_x224_header(s, 2, ISO_PDU_DT); if (xrdp_tcp_send(self->tcp_layer, s) != 0) { diff --git a/libxrdp/xrdp_mcs.c b/libxrdp/xrdp_mcs.c index c145158c..1828b28b 100644 --- a/libxrdp/xrdp_mcs.c +++ b/libxrdp/xrdp_mcs.c @@ -127,12 +127,14 @@ xrdp_mcs_recv(struct xrdp_mcs *self, struct stream *s, int *chan) while (1) { + if (xrdp_iso_recv(self->iso_layer, s) != 0) { - DEBUG((" out xrdp_mcs_recv xrdp_iso_recv returned non zero")); + free_stream(s); return 1; } + if (!s_check_rem(s, 1)) { return 1; @@ -320,10 +322,16 @@ xrdp_mcs_recv_connect_initial(struct xrdp_mcs *self) make_stream(s); init_stream(s, 16 * 1024); - if (xrdp_iso_recv(self->iso_layer, s) != 0) - { - free_stream(s); - return 1; + if (xrdp_iso_detect_tpkt(self->iso_layer, s) == 0) { + if (xrdp_iso_recv(self->iso_layer, s) != 0) + { + free_stream(s); + return 1; + } + } else { + g_writeln("xrdp_mcs_recv_connect_initial: TPKT not detected"); + free_stream(s); + return 1; } if (xrdp_mcs_ber_parse_header(self, s, MCS_CONNECT_INITIAL, &len) != 0) @@ -441,10 +449,16 @@ xrdp_mcs_recv_edrq(struct xrdp_mcs *self) make_stream(s); init_stream(s, 8192); - if (xrdp_iso_recv(self->iso_layer, s) != 0) - { - free_stream(s); - return 1; + if (xrdp_iso_detect_tpkt(self->iso_layer, s) == 0) { + if (xrdp_iso_recv(self->iso_layer, s) != 0) + { + free_stream(s); + return 1; + } + } else { + g_writeln("xrdp_mcs_recv_edrq: TPKT not detected"); + free_stream(s); + return 1; } if (!s_check_rem(s, 1)) @@ -503,12 +517,19 @@ xrdp_mcs_recv_aurq(struct xrdp_mcs *self) make_stream(s); init_stream(s, 8192); - if (xrdp_iso_recv(self->iso_layer, s) != 0) - { - free_stream(s); - return 1; + if (xrdp_iso_detect_tpkt(self->iso_layer, s) == 0) { + if (xrdp_iso_recv(self->iso_layer, s) != 0) + { + free_stream(s); + return 1; + } + } else { + g_writeln("xrdp_mcs_recv_aurq: TPKT not detected"); + free_stream(s); + return 1; } + if (!s_check_rem(s, 1)) { free_stream(s); @@ -590,10 +611,16 @@ xrdp_mcs_recv_cjrq(struct xrdp_mcs *self) make_stream(s); init_stream(s, 8192); - if (xrdp_iso_recv(self->iso_layer, s) != 0) - { - free_stream(s); - return 1; + if (xrdp_iso_detect_tpkt(self->iso_layer, s) == 0) { + if (xrdp_iso_recv(self->iso_layer, s) != 0) + { + free_stream(s); + return 1; + } + } else { + g_writeln("xrdp_mcs_recv_cjrq: TPKT not detected"); + free_stream(s); + return 1; } if (!s_check_rem(s, 1)) diff --git a/libxrdp/xrdp_rdp.c b/libxrdp/xrdp_rdp.c index 7e68ec1f..fa62c9c2 100644 --- a/libxrdp/xrdp_rdp.c +++ b/libxrdp/xrdp_rdp.c @@ -259,9 +259,22 @@ xrdp_rdp_init_data(struct xrdp_rdp *self, struct stream *s) } /*****************************************************************************/ -/* returns erros */ +/* returns error */ int APP_CC xrdp_rdp_recv(struct xrdp_rdp *self, struct stream *s, int *code) +{ + // Detect TPKT or FastPath + if (xrdp_iso_detect_tpkt(self->sec_layer->mcs_layer->iso_layer, s) == 0) { + return xrdp_rdp_recv_tpkt(self, s, code); + } else { + return xrdp_rdp_recv_fastpath(self, s, code); + } + +} +/*****************************************************************************/ +/* returns error */ +int APP_CC +xrdp_rdp_recv_tpkt(struct xrdp_rdp *self, struct stream *s, int *code) { int error = 0; int len = 0; @@ -338,7 +351,14 @@ xrdp_rdp_recv(struct xrdp_rdp *self, struct stream *s, int *code) return 0; } } - +/*****************************************************************************/ +/* returns error */ +int APP_CC +xrdp_rdp_recv_fastpath(struct xrdp_rdp *self, struct stream *s, int *code) +{ + g_writeln("Booyah!"); + return 0; +} /*****************************************************************************/ int APP_CC xrdp_rdp_send(struct xrdp_rdp *self, struct stream *s, int pdu_type) diff --git a/libxrdp/xrdp_sec.c b/libxrdp/xrdp_sec.c index df2cc653..38ee93f3 100644 --- a/libxrdp/xrdp_sec.c +++ b/libxrdp/xrdp_sec.c @@ -1075,10 +1075,10 @@ xrdp_sec_process_mcs_data(struct xrdp_sec *self) switch (tag) { case SEC_TAG_CLI_INFO: - if (xrdp_sec_process_mcs_cli_info(self, s) != 0) - { - return 1; - } +// if (xrdp_sec_process_mcs_cli_info(self, s) != 0) +// { +// return 1; +// } break; case SEC_TAG_CLI_CRYPT: break; diff --git a/libxrdp/xrdp_tcp.c b/libxrdp/xrdp_tcp.c index 473f3deb..384556ba 100644 --- a/libxrdp/xrdp_tcp.c +++ b/libxrdp/xrdp_tcp.c @@ -56,7 +56,7 @@ xrdp_tcp_init(struct xrdp_tcp *self, struct stream *s) int APP_CC xrdp_tcp_recv(struct xrdp_tcp *self, struct stream *s, int len) { - DEBUG((" in xrdp_tcp_recv, gota get %d bytes", len)); + DEBUG((" in xrdp_tcp_recv, gota get %d bytes", len)); init_stream(s, len); if (trans_force_read_s(self->trans, s, len) != 0) @@ -65,7 +65,7 @@ xrdp_tcp_recv(struct xrdp_tcp *self, struct stream *s, int len) return 1; } - DEBUG((" out xrdp_tcp_recv")); + DEBUG((" out xrdp_tcp_recv")); return 0; } From 9a98299e2b3bb0c3e4f047efa4ad8f8450656dda Mon Sep 17 00:00:00 2001 From: speidy Date: Sat, 8 Feb 2014 20:55:41 +0200 Subject: [PATCH 04/12] libxrdp: work on fastpath --- libxrdp/xrdp_iso.c | 55 ++++++++++++++++++----------------- libxrdp/xrdp_mcs.c | 72 +++++++++++++++++----------------------------- libxrdp/xrdp_rdp.c | 25 +++++++--------- libxrdp/xrdp_sec.c | 14 +++++++-- 4 files changed, 77 insertions(+), 89 deletions(-) diff --git a/libxrdp/xrdp_iso.c b/libxrdp/xrdp_iso.c index 09c08f94..82a76e5f 100644 --- a/libxrdp/xrdp_iso.c +++ b/libxrdp/xrdp_iso.c @@ -95,9 +95,14 @@ xrdp_iso_recv_msg(struct xrdp_iso *self, struct stream *s, int *code, int *len) *len = 0; // X.224 Length Indicator plen = xrdp_iso_recv_tpkt_header(self, s); - if (plen == 1) + + if (plen == 2) { - DEBUG((" xrdp_iso_recv_msg: error in tpkt header reading")); + DEBUG((" xrdp_iso_recv_msg: non-TPKT header detected, we try fastpath")); + return plen; + } + + if (plen == 1) { return 1; } @@ -118,10 +123,19 @@ xrdp_iso_recv(struct xrdp_iso *self, struct stream *s) { int code; int len; + int iso_msg; DEBUG((" in xrdp_iso_recv")); - if (xrdp_iso_recv_msg(self, s, &code, &len) != 0) + iso_msg = xrdp_iso_recv_msg(self, s, &code, &len); + + if (iso_msg == 2) // non-TPKT header + { + DEBUG((" out xrdp_iso_recv xrdp_iso_recv_msg return 2, non-TPKT header detected")); + return iso_msg; + } + + if (iso_msg == 1) // error { DEBUG((" out xrdp_iso_recv xrdp_iso_recv_msg return non zero")); return 1; @@ -137,38 +151,32 @@ xrdp_iso_recv(struct xrdp_iso *self, struct stream *s) return 0; } /*****************************************************************************/ -/* returns error */ +/* returns packet length or error (1) */ int APP_CC -xrdp_iso_detect_tpkt(struct xrdp_iso *self, struct stream *s) +xrdp_iso_recv_tpkt_header(struct xrdp_iso *self, struct stream *s) { + int plen; int ver; - DEBUG((" in xrdp_iso_detect_tpkt")); + DEBUG((" in xrdp_iso_recv_tpkt_header")); + if (xrdp_tcp_recv(self->tcp_layer, s, 1) != 0) { return 1; } in_uint8_peek(s, ver); - g_writeln("tpkt version: %x", ver); + g_writeln(" tpkt version: %x", ver); if (ver != 3) { - return 1; + /* + * special error code that means we got non-TPKT header, + * so we gonna try fastpath input. + */ + return 2; } - DEBUG((" out xrdp_iso_detect_tpkt")); - return 0; -} -/*****************************************************************************/ -/* returns packet length or error (1) */ -int APP_CC -xrdp_iso_recv_tpkt_header(struct xrdp_iso *self, struct stream *s) -{ - int plen; - - DEBUG((" in xrdp_iso_recv_tpkt_header")); - if (xrdp_tcp_recv(self->tcp_layer, s, 3) != 0) { return 1; @@ -374,13 +382,6 @@ xrdp_iso_incoming(struct xrdp_iso *self) init_stream(s, 8192); DEBUG((" in xrdp_iso_incoming")); - if (xrdp_iso_detect_tpkt(self, s) != 0) - { - g_writeln("xrdp_iso_incoming: TPKT not detected"); - free_stream(s); - return 1; - } - if (xrdp_iso_recv_msg(self, s, &code, &len) != 0) { DEBUG((" in xrdp_iso_recv_msg error!!")); diff --git a/libxrdp/xrdp_mcs.c b/libxrdp/xrdp_mcs.c index 1828b28b..81e8b758 100644 --- a/libxrdp/xrdp_mcs.c +++ b/libxrdp/xrdp_mcs.c @@ -122,18 +122,25 @@ xrdp_mcs_recv(struct xrdp_mcs *self, struct stream *s, int *chan) int len; int userid; int chanid; - + int iso_msg; DEBUG((" in xrdp_mcs_recv")); while (1) { - if (xrdp_iso_recv(self->iso_layer, s) != 0) + iso_msg = xrdp_iso_recv(self->iso_layer, s); + + if (iso_msg == 2) // non-TPKT header { - free_stream(s); - return 1; + DEBUG((" out xrdp_mcs_recv, non-TPKT header detected, we try fastpath")); + return iso_msg; } + if (iso_msg == 1) // error + { + DEBUG((" out xrdp_mcs_recv, xrdp_iso_recv return non zero")); + return 1; + } if (!s_check_rem(s, 1)) { @@ -322,16 +329,10 @@ xrdp_mcs_recv_connect_initial(struct xrdp_mcs *self) make_stream(s); init_stream(s, 16 * 1024); - if (xrdp_iso_detect_tpkt(self->iso_layer, s) == 0) { - if (xrdp_iso_recv(self->iso_layer, s) != 0) - { - free_stream(s); - return 1; - } - } else { - g_writeln("xrdp_mcs_recv_connect_initial: TPKT not detected"); - free_stream(s); - return 1; + if (xrdp_iso_recv(self->iso_layer, s) != 0) + { + free_stream(s); + return 1; } if (xrdp_mcs_ber_parse_header(self, s, MCS_CONNECT_INITIAL, &len) != 0) @@ -449,16 +450,10 @@ xrdp_mcs_recv_edrq(struct xrdp_mcs *self) make_stream(s); init_stream(s, 8192); - if (xrdp_iso_detect_tpkt(self->iso_layer, s) == 0) { - if (xrdp_iso_recv(self->iso_layer, s) != 0) - { - free_stream(s); - return 1; - } - } else { - g_writeln("xrdp_mcs_recv_edrq: TPKT not detected"); - free_stream(s); - return 1; + if (xrdp_iso_recv(self->iso_layer, s) != 0) + { + free_stream(s); + return 1; } if (!s_check_rem(s, 1)) @@ -517,19 +512,12 @@ xrdp_mcs_recv_aurq(struct xrdp_mcs *self) make_stream(s); init_stream(s, 8192); - if (xrdp_iso_detect_tpkt(self->iso_layer, s) == 0) { - if (xrdp_iso_recv(self->iso_layer, s) != 0) - { - free_stream(s); - return 1; - } - } else { - g_writeln("xrdp_mcs_recv_aurq: TPKT not detected"); - free_stream(s); - return 1; + if (xrdp_iso_recv(self->iso_layer, s) != 0) + { + free_stream(s); + return 1; } - if (!s_check_rem(s, 1)) { free_stream(s); @@ -611,16 +599,10 @@ xrdp_mcs_recv_cjrq(struct xrdp_mcs *self) make_stream(s); init_stream(s, 8192); - if (xrdp_iso_detect_tpkt(self->iso_layer, s) == 0) { - if (xrdp_iso_recv(self->iso_layer, s) != 0) - { - free_stream(s); - return 1; - } - } else { - g_writeln("xrdp_mcs_recv_cjrq: TPKT not detected"); - free_stream(s); - return 1; + if (xrdp_iso_recv(self->iso_layer, s) != 0) + { + free_stream(s); + return 1; } if (!s_check_rem(s, 1)) diff --git a/libxrdp/xrdp_rdp.c b/libxrdp/xrdp_rdp.c index fa62c9c2..923b0358 100644 --- a/libxrdp/xrdp_rdp.c +++ b/libxrdp/xrdp_rdp.c @@ -262,19 +262,6 @@ xrdp_rdp_init_data(struct xrdp_rdp *self, struct stream *s) /* returns error */ int APP_CC xrdp_rdp_recv(struct xrdp_rdp *self, struct stream *s, int *code) -{ - // Detect TPKT or FastPath - if (xrdp_iso_detect_tpkt(self->sec_layer->mcs_layer->iso_layer, s) == 0) { - return xrdp_rdp_recv_tpkt(self, s, code); - } else { - return xrdp_rdp_recv_fastpath(self, s, code); - } - -} -/*****************************************************************************/ -/* returns error */ -int APP_CC -xrdp_rdp_recv_tpkt(struct xrdp_rdp *self, struct stream *s, int *code) { int error = 0; int len = 0; @@ -288,6 +275,11 @@ xrdp_rdp_recv_tpkt(struct xrdp_rdp *self, struct stream *s, int *code) chan = 0; error = xrdp_sec_recv(self->sec_layer, s, &chan); + if (error == 2) /* we have fastpath packet! */ + { + return xrdp_rdp_recv_fastpath(self, s, code); + } + if (error == -1) /* special code for send demand active */ { s->next_packet = 0; @@ -357,7 +349,10 @@ int APP_CC xrdp_rdp_recv_fastpath(struct xrdp_rdp *self, struct stream *s, int *code) { g_writeln("Booyah!"); - return 0; + int msg; + in_uint8(s, msg); + g_writeln("msg= %x", msg); + return 1; } /*****************************************************************************/ int APP_CC @@ -793,7 +788,7 @@ xrdp_rdp_send_demand_active(struct xrdp_rdp *self) INPUT_FLAG_FASTPATH_INPUT 0x0008 INPUT_FLAG_FASTPATH_INPUT2 0x0020 */ flags = 0x0001 | 0x0004; - if (self->client_info.use_fast_path & 2) +// if (self->client_info.use_fast_path & 2) flags |= 0x0008 | 0x0020; out_uint16_le(s, flags); out_uint8s(s, 82); diff --git a/libxrdp/xrdp_sec.c b/libxrdp/xrdp_sec.c index 38ee93f3..40fedb85 100644 --- a/libxrdp/xrdp_sec.c +++ b/libxrdp/xrdp_sec.c @@ -740,12 +740,22 @@ xrdp_sec_recv(struct xrdp_sec *self, struct stream *s, int *chan) { int flags; int len; + int mcs_msg; DEBUG((" in xrdp_sec_recv")); - if (xrdp_mcs_recv(self->mcs_layer, s, chan) != 0) + mcs_msg = xrdp_mcs_recv(self->mcs_layer, s, chan); + + if (mcs_msg == 2) + { + DEBUG((" out xrdp_sec_recv : non-TPKT msg detected, we try fastpath")); +// xrdp_sec_recv_fastpath(self->mcs_layer->iso_layer, s); + return mcs_msg; + } + + if (mcs_msg == 1) { - DEBUG((" out xrdp_sec_recv error")); + DEBUG((" out xrdp_sec_recv : error")); return 1; } From cbf5d50a5c96de83178e910318db540334f289b1 Mon Sep 17 00:00:00 2001 From: speidy Date: Sun, 9 Feb 2014 01:42:04 +0200 Subject: [PATCH 05/12] libxrdp: work on fastpath input --- common/xrdp_constants.h | 18 ++++++++++++ libxrdp/Makefile.am | 3 +- libxrdp/libxrdp.h | 20 +++++++++++++ libxrdp/xrdp_fastpath.c | 62 ++++++++++++++++++++++++++++++++++------- libxrdp/xrdp_iso.c | 10 ++----- libxrdp/xrdp_rdp.c | 11 +++++--- libxrdp/xrdp_sec.c | 29 ++++++++++++++++++- 7 files changed, 129 insertions(+), 24 deletions(-) diff --git a/common/xrdp_constants.h b/common/xrdp_constants.h index ed74fd01..0dc327df 100644 --- a/common/xrdp_constants.h +++ b/common/xrdp_constants.h @@ -560,6 +560,24 @@ #define RDP_CAPSET_LPOINTER 0x27 #define RDP_CAPLEN_LPOINTER 0x06 +/* fastpath input */ +#define FASTPATH_INPUT_SECURE_CHECKSUM 0x1 +#define FASTPATH_INPUT_ENCRYPTED 0x2 + +#define FASTPATH_INPUT_ACTION_FASTPATH 0x0 +#define FASTPATH_INPUT_ACTION_X224 0x3 + +#define FASTPATH_INPUT_EVENT_SCANCODE 0x0 +#define FASTPATH_INPUT_EVENT_MOUSE 0x1 +#define FASTPATH_INPUT_EVENT_MOUSEX 0x2 +#define FASTPATH_INPUT_EVENT_SYNC 0x3 +#define FASTPATH_INPUT_EVENT_UNICODE 0x4 + +#define FASTPATH_INPUT_KBDFLAGS_RELEASE 0x01 +#define FASTPATH_INPUT_KBDFLAGS_EXTENDED 0x02 + + +/* fastpath output */ #define FASTPATH_OUTPUT_ACTION_FASTPATH 0x0 #define FASTPATH_OUTPUT_ACTION_X224 0x3 diff --git a/libxrdp/Makefile.am b/libxrdp/Makefile.am index 6564da36..3fdc963d 100644 --- a/libxrdp/Makefile.am +++ b/libxrdp/Makefile.am @@ -59,7 +59,8 @@ libxrdp_la_SOURCES = \ xrdp_bitmap_compress.c \ xrdp_jpeg_compress.c \ xrdp_orders_rail.c \ - xrdp_mppc_enc.c + xrdp_mppc_enc.c \ + xrdp_fastpath.c libxrdp_la_LDFLAGS = \ $(EXTRA_FLAGS) diff --git a/libxrdp/libxrdp.h b/libxrdp/libxrdp.h index a9150111..b15cc989 100644 --- a/libxrdp/libxrdp.h +++ b/libxrdp/libxrdp.h @@ -42,6 +42,8 @@ struct xrdp_tcp { struct trans* trans; struct xrdp_iso* iso_layer; /* owner */ + struct xrdp_fastpath* fastpath_layer; /* owner */ + }; /* iso */ @@ -73,11 +75,21 @@ struct xrdp_mcs struct list* channel_list; }; +/* fastpath */ +struct xrdp_fastpath +{ + struct xrdp_sec* sec_layer; /* owner */ + struct xrdp_tcp* tcp_layer; + int numEvents; + int secFlags; +}; + /* sec */ struct xrdp_sec { struct xrdp_rdp* rdp_layer; /* owner */ struct xrdp_mcs* mcs_layer; + struct xrdp_fastpath* fastpath_layer; struct xrdp_channel* chan_layer; char server_random[32]; char client_random[64]; @@ -494,4 +506,12 @@ int APP_CC xrdp_channel_process(struct xrdp_channel* self, struct stream* s, int chanid); +/* xrdp_fastpath.c */ +struct xrdp_fastpath *APP_CC +xrdp_fastpath_create(struct xrdp_sec *owner, struct trans *trans); +void APP_CC +xrdp_fastpath_delete(struct xrdp_fastpath *self); +int APP_CC +xrdp_fastpath_recv(struct xrdp_fastpath *self, struct stream *s); + #endif diff --git a/libxrdp/xrdp_fastpath.c b/libxrdp/xrdp_fastpath.c index 96d84972..c8b4927d 100644 --- a/libxrdp/xrdp_fastpath.c +++ b/libxrdp/xrdp_fastpath.c @@ -21,16 +21,15 @@ /*****************************************************************************/ struct xrdp_fastpath *APP_CC -xrdp_fastpath_create(struct xrdp_session *session) +xrdp_fastpath_create(struct xrdp_sec *owner, struct trans *trans) { struct xrdp_fastpath *self; + DEBUG((" in xrdp_fastpath_create")); self = (struct xrdp_fastpath *)g_malloc(sizeof(struct xrdp_fastpath), 1); - self->tcp_layer = - ((struct xrdp_rdp *)session->rdp)->sec_layer-> - mcs_layer->iso_layer->tcp_layer; - make_stream(self->out_s); - init_stream(self->out_s, FASTPATH_MAX_PACKET_SIZE); + self->sec_layer = owner; + self->tcp_layer = owner->mcs_layer->iso_layer->tcp_layer; + DEBUG((" out xrdp_fastpath_create")); return self; } @@ -42,8 +41,6 @@ xrdp_fastpath_delete(struct xrdp_fastpath *self) { return; } - - free_stream(self->out_s); g_free(self); } @@ -54,7 +51,52 @@ xrdp_fastpath_reset(struct xrdp_fastpath *self) { return 0; } +/*****************************************************************************/ +int APP_CC +xrdp_fastpath_recv(struct xrdp_fastpath *self, struct stream *s) +{ + int fp_hdr; + int len; + int byte; + DEBUG((" in xrdp_fastpath_recv")); + + /* read the first fastpath byte + * (we already received it via iso layer */ + in_uint8(s, fp_hdr); /* fpInputHeader (1 byte) */ + + self->numEvents = (fp_hdr & 0x3C) >> 2; + self->secFlags = (fp_hdr & 0xC0) >> 6; + + // receive fastpath packet length + if (xrdp_tcp_recv(self->tcp_layer, s, 1) != 0) + { + return 1; + } + + in_uint8(s, byte); /* length 1 */ + + if (byte & 0x80) + { + byte &= ~(0x80); + len = (byte << 8); + in_uint8(s, byte); /* length 2 */ + len += byte; + } + else + { + len = byte; + } + // receive the left bytes + if (xrdp_tcp_recv(self->tcp_layer, s, len) != 0) + { + return 1; + } + DEBUG((" out xrdp_fastpath_recv")); + + return 0; +} +/*****************************************************************************/ int APP_CC xrdp_fastpath_init(struct xrdp_fastpath *self) { @@ -76,7 +118,7 @@ xrdp_fastpath_send_update_pdu(struct xrdp_fastpath *self, tui8 updateCode, int i32; compression = 0; - s_send = self->out_s; +// s_send = self->out_s; maxLen = FASTPATH_MAX_PACKET_SIZE - 6; /* 6 bytes for header */ payloadLeft = (s->end - s->data); @@ -112,7 +154,7 @@ xrdp_fastpath_send_update_pdu(struct xrdp_fastpath *self, tui8 updateCode, ((compression & 0x03) << 6); out_uint8(s_send, i32); out_uint16_le(s_send, len); - s_copy(s_send, s, len); +// s_copy(s_send, s, len); s_mark_end(s_send); if (xrdp_tcp_send(self->tcp_layer, s_send) != 0) diff --git a/libxrdp/xrdp_iso.c b/libxrdp/xrdp_iso.c index 82a76e5f..f29cbf23 100644 --- a/libxrdp/xrdp_iso.c +++ b/libxrdp/xrdp_iso.c @@ -158,15 +158,13 @@ xrdp_iso_recv_tpkt_header(struct xrdp_iso *self, struct stream *s) int plen; int ver; - DEBUG((" in xrdp_iso_recv_tpkt_header")); - if (xrdp_tcp_recv(self->tcp_layer, s, 1) != 0) { return 1; } - in_uint8_peek(s, ver); - g_writeln(" tpkt version: %x", ver); + in_uint8_peek(s, ver); // Peek only so we can use it later in fastpath layer, if needed + g_writeln(" tpkt version: %x", ver); // TODO: delete it if (ver != 3) { @@ -190,8 +188,6 @@ xrdp_iso_recv_tpkt_header(struct xrdp_iso *self, struct stream *s) return 1; // tpkt must be >= 4 bytes length } - DEBUG((" out xrdp_iso_recv_tpkt_header")); - return plen; } /*****************************************************************************/ @@ -208,7 +204,6 @@ xrdp_iso_write_tpkt_header(struct stream *s, int len) int APP_CC xrdp_iso_read_x224_header(struct stream *s, int *code, int *len) { - DEBUG((" in xrdp_iso_read_x224_header")); if (!s_check_rem(s, 2)) { return 1; @@ -233,7 +228,6 @@ xrdp_iso_read_x224_header(struct stream *s, int *code, int *len) } in_uint8s(s, 5); } - DEBUG((" out xrdp_iso_read_x224_header")); return 0; } diff --git a/libxrdp/xrdp_rdp.c b/libxrdp/xrdp_rdp.c index 923b0358..f98a5dce 100644 --- a/libxrdp/xrdp_rdp.c +++ b/libxrdp/xrdp_rdp.c @@ -348,10 +348,13 @@ xrdp_rdp_recv(struct xrdp_rdp *self, struct stream *s, int *code) int APP_CC xrdp_rdp_recv_fastpath(struct xrdp_rdp *self, struct stream *s, int *code) { - g_writeln("Booyah!"); - int msg; - in_uint8(s, msg); - g_writeln("msg= %x", msg); + int i; + DEBUG(("in xrdp_rdp_recv_fastpath")); +// for (i = 0 ; i < self->sec_layer->fastpath_layer->numEvents ; i++) { +// +// } + g_hexdump(s->data, 7); + DEBUG(("out xrdp_rdp_recv_fastpath")); return 1; } /*****************************************************************************/ diff --git a/libxrdp/xrdp_sec.c b/libxrdp/xrdp_sec.c index 40fedb85..44eb5812 100644 --- a/libxrdp/xrdp_sec.c +++ b/libxrdp/xrdp_sec.c @@ -185,6 +185,7 @@ xrdp_sec_create(struct xrdp_rdp *owner, struct trans *trans, int crypt_level, self->encrypt_rc4_info = ssl_rc4_info_create(); self->mcs_layer = xrdp_mcs_create(self, trans, &self->client_mcs_data, &self->server_mcs_data); + self->fastpath_layer = xrdp_fastpath_create(self, trans); self->chan_layer = xrdp_channel_create(self, self->mcs_layer); DEBUG((" out xrdp_sec_create")); return self; @@ -202,6 +203,7 @@ xrdp_sec_delete(struct xrdp_sec *self) xrdp_channel_delete(self->chan_layer); xrdp_mcs_delete(self->mcs_layer); + xrdp_fastpath_delete(self->fastpath_layer); 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); @@ -732,7 +734,32 @@ xrdp_sec_establish_keys(struct xrdp_sec *self) ssl_rc4_set_key(self->decrypt_rc4_info, self->decrypt_key, self->rc4_key_len); ssl_rc4_set_key(self->encrypt_rc4_info, self->encrypt_key, self->rc4_key_len); } +/*****************************************************************************/ +/* returns error */ +int APP_CC +xrdp_sec_recv_fastpath(struct xrdp_sec *self, struct stream *s) +{ + if (xrdp_fastpath_recv(self->fastpath_layer, s) != 0) { + return 1; + } + + in_uint8s(s, 8); /* dataSignature, skip for now */ + + if (self->fastpath_layer->secFlags & FASTPATH_INPUT_ENCRYPTED) { + xrdp_sec_decrypt(self, s->p, (int)(s->end - s->p)); + } + + if (self->fastpath_layer->numEvents == 0) { + /** + * If numberEvents is not provided in fpInputHeader, it will be provided + * as one additional byte here. + */ + in_uint8(s, self->fastpath_layer->numEvents); /* numEvents (optional) */ + } + + return 0; +} /*****************************************************************************/ /* returns error */ int APP_CC @@ -749,7 +776,7 @@ xrdp_sec_recv(struct xrdp_sec *self, struct stream *s, int *chan) if (mcs_msg == 2) { DEBUG((" out xrdp_sec_recv : non-TPKT msg detected, we try fastpath")); -// xrdp_sec_recv_fastpath(self->mcs_layer->iso_layer, s); + xrdp_sec_recv_fastpath(self, s); return mcs_msg; } From f525c0f8e76b1e2b8294c4a61c0da4d24e0406b4 Mon Sep 17 00:00:00 2001 From: speidy Date: Mon, 10 Feb 2014 05:48:03 +0200 Subject: [PATCH 06/12] libxrdp: work on fastpath input --- libxrdp/libxrdp.c | 9 +++++ libxrdp/libxrdp.h | 3 ++ libxrdp/xrdp_fastpath.c | 2 +- libxrdp/xrdp_rdp.c | 88 ++++++++++++++++++++++++++++++++++------- libxrdp/xrdp_sec.c | 1 - 5 files changed, 86 insertions(+), 17 deletions(-) diff --git a/libxrdp/libxrdp.c b/libxrdp/libxrdp.c index c220f56f..5e7e72a1 100644 --- a/libxrdp/libxrdp.c +++ b/libxrdp/libxrdp.c @@ -137,6 +137,15 @@ libxrdp_process_data(struct xrdp_session *session) } break; + case 2: /* FASTPATH_INPUT_EVENT */ + if (xrdp_rdp_process_fastpath_data_input((struct xrdp_rdp *)session->rdp, + session->s) != 0) + { + DEBUG(("libxrdp_process_data returned non zero")); + cont = 0; + term = 1; + } + break; default: g_writeln("unknown in libxrdp_process_data: code= %d", code); dead_lock_counter++; diff --git a/libxrdp/libxrdp.h b/libxrdp/libxrdp.h index b15cc989..4059dbed 100644 --- a/libxrdp/libxrdp.h +++ b/libxrdp/libxrdp.h @@ -82,6 +82,7 @@ struct xrdp_fastpath struct xrdp_tcp* tcp_layer; int numEvents; int secFlags; + int firstPacket; }; /* sec */ @@ -373,6 +374,8 @@ xrdp_rdp_process_confirm_active(struct xrdp_rdp* self, struct stream* s); int APP_CC xrdp_rdp_process_data(struct xrdp_rdp* self, struct stream* s); int APP_CC +xrdp_rdp_process_fastpath_data_input(struct xrdp_rdp *self, struct stream *s); +int APP_CC xrdp_rdp_disconnect(struct xrdp_rdp* self); int APP_CC xrdp_rdp_send_deactive(struct xrdp_rdp* self); diff --git a/libxrdp/xrdp_fastpath.c b/libxrdp/xrdp_fastpath.c index c8b4927d..0d5c58c3 100644 --- a/libxrdp/xrdp_fastpath.c +++ b/libxrdp/xrdp_fastpath.c @@ -88,7 +88,7 @@ xrdp_fastpath_recv(struct xrdp_fastpath *self, struct stream *s) } // receive the left bytes - if (xrdp_tcp_recv(self->tcp_layer, s, len) != 0) + if (xrdp_tcp_recv(self->tcp_layer, s, len - (s->p - s->data)) != 0) { return 1; } diff --git a/libxrdp/xrdp_rdp.c b/libxrdp/xrdp_rdp.c index f98a5dce..e4d79159 100644 --- a/libxrdp/xrdp_rdp.c +++ b/libxrdp/xrdp_rdp.c @@ -277,7 +277,9 @@ xrdp_rdp_recv(struct xrdp_rdp *self, struct stream *s, int *code) if (error == 2) /* we have fastpath packet! */ { - return xrdp_rdp_recv_fastpath(self, s, code); + s->next_packet = 0; + *code = 2; + return 0; } if (error == -1) /* special code for send demand active */ @@ -344,20 +346,6 @@ xrdp_rdp_recv(struct xrdp_rdp *self, struct stream *s, int *code) } } /*****************************************************************************/ -/* returns error */ -int APP_CC -xrdp_rdp_recv_fastpath(struct xrdp_rdp *self, struct stream *s, int *code) -{ - int i; - DEBUG(("in xrdp_rdp_recv_fastpath")); -// for (i = 0 ; i < self->sec_layer->fastpath_layer->numEvents ; i++) { -// -// } - g_hexdump(s->data, 7); - DEBUG(("out xrdp_rdp_recv_fastpath")); - return 1; -} -/*****************************************************************************/ int APP_CC xrdp_rdp_send(struct xrdp_rdp *self, struct stream *s, int pdu_type) { @@ -1711,7 +1699,77 @@ xrdp_rdp_send_disconnect_reason(struct xrdp_rdp *self, int reason) return 0; } #endif +/*****************************************************************************/ +/* FASTPATH_INPUT_EVENT */ +int APP_CC +xrdp_rdp_process_fastpath_data_input(struct xrdp_rdp *self, struct stream *s) +{ + int i; + int eventHeader; + int eventCode; + int eventFlags; + int code; + int flags; + + // process fastpath input events + for (i = 0 ; i < self->sec_layer->fastpath_layer->numEvents ; i++) { + in_uint8(s, eventHeader); + + eventFlags = (eventHeader & 0x1F); + eventCode = (eventHeader >> 5); + g_writeln("eventCode= %d, eventFlags= %d, numEvents= %d", eventCode, eventFlags, self->sec_layer->fastpath_layer->numEvents); + switch (eventCode) + { + case FASTPATH_INPUT_EVENT_SCANCODE: + in_uint8(s, code); /* keyCode (1 byte) */ + g_writeln("scan code detected: %d", code); + flags = 0; + if ((eventFlags & FASTPATH_INPUT_KBDFLAGS_RELEASE)) + flags |= KBD_FLAG_UP; + else + flags |= KBD_FLAG_DOWN; + + if ((eventFlags & FASTPATH_INPUT_KBDFLAGS_EXTENDED)) + flags |= KBD_FLAG_EXT; + + if (self->session->callback != 0) + { + /* msg_type can be + RDP_INPUT_SYNCHRONIZE - 0 + RDP_INPUT_SCANCODE - 4 + RDP_INPUT_MOUSE - 0x8001 + RDP_INPUT_MOUSEX - 0x8002 */ + /* call to xrdp_wm.c : callback */ + self->session->callback(self->session->id, RDP_INPUT_SCANCODE, flags, 0, + code, time); + } + break; + + case FASTPATH_INPUT_EVENT_MOUSE: + in_uint8s(s, 6); + break; + + case FASTPATH_INPUT_EVENT_MOUSEX: + in_uint8s(s, 6); + break; + + case FASTPATH_INPUT_EVENT_SYNC: + + break; + + case FASTPATH_INPUT_EVENT_UNICODE: + in_uint8s(s, 2); + break; + + default: + printf("Unknown eventCode %d\n", eventCode); + break; + } + + } + return 0; +} /*****************************************************************************/ /* RDP_PDU_DATA */ int APP_CC diff --git a/libxrdp/xrdp_sec.c b/libxrdp/xrdp_sec.c index 44eb5812..4846c356 100644 --- a/libxrdp/xrdp_sec.c +++ b/libxrdp/xrdp_sec.c @@ -743,7 +743,6 @@ xrdp_sec_recv_fastpath(struct xrdp_sec *self, struct stream *s) return 1; } - in_uint8s(s, 8); /* dataSignature, skip for now */ if (self->fastpath_layer->secFlags & FASTPATH_INPUT_ENCRYPTED) { From f8d26973d09f2139f696f3ae1ebdde602ecf820c Mon Sep 17 00:00:00 2001 From: speidy Date: Mon, 10 Feb 2014 06:26:55 +0200 Subject: [PATCH 07/12] libxrdp: work on fastpath input, fix length issue in fastpath_recv --- libxrdp/libxrdp.h | 1 - libxrdp/xrdp_fastpath.c | 15 ++++++++++++--- libxrdp/xrdp_rdp.c | 5 +++-- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/libxrdp/libxrdp.h b/libxrdp/libxrdp.h index 4059dbed..91f21974 100644 --- a/libxrdp/libxrdp.h +++ b/libxrdp/libxrdp.h @@ -82,7 +82,6 @@ struct xrdp_fastpath struct xrdp_tcp* tcp_layer; int numEvents; int secFlags; - int firstPacket; }; /* sec */ diff --git a/libxrdp/xrdp_fastpath.c b/libxrdp/xrdp_fastpath.c index 0d5c58c3..71e7f7c6 100644 --- a/libxrdp/xrdp_fastpath.c +++ b/libxrdp/xrdp_fastpath.c @@ -56,8 +56,9 @@ int APP_CC xrdp_fastpath_recv(struct xrdp_fastpath *self, struct stream *s) { int fp_hdr; - int len; + int len = 0; int byte; + int hdr_len = 2; DEBUG((" in xrdp_fastpath_recv")); /* read the first fastpath byte @@ -67,7 +68,7 @@ xrdp_fastpath_recv(struct xrdp_fastpath *self, struct stream *s) self->numEvents = (fp_hdr & 0x3C) >> 2; self->secFlags = (fp_hdr & 0xC0) >> 6; - // receive fastpath packet length + // receive fastpath first packet length if (xrdp_tcp_recv(self->tcp_layer, s, 1) != 0) { return 1; @@ -79,6 +80,12 @@ xrdp_fastpath_recv(struct xrdp_fastpath *self, struct stream *s) { byte &= ~(0x80); len = (byte << 8); + // receive fastpath second packet length + if (xrdp_tcp_recv(self->tcp_layer, s, 1) != 0) + { + return 1; + } + hdr_len++; in_uint8(s, byte); /* length 2 */ len += byte; } @@ -87,8 +94,10 @@ xrdp_fastpath_recv(struct xrdp_fastpath *self, struct stream *s) len = byte; } + g_writeln("len= %d , numEvents= %d, secFlags= %d, bytesleft: %d", len, self->numEvents, self->secFlags, (s->p - s->data)); + // receive the left bytes - if (xrdp_tcp_recv(self->tcp_layer, s, len - (s->p - s->data)) != 0) + if (xrdp_tcp_recv(self->tcp_layer, s, len - hdr_len) != 0) { return 1; } diff --git a/libxrdp/xrdp_rdp.c b/libxrdp/xrdp_rdp.c index e4d79159..7bcdab62 100644 --- a/libxrdp/xrdp_rdp.c +++ b/libxrdp/xrdp_rdp.c @@ -277,7 +277,6 @@ xrdp_rdp_recv(struct xrdp_rdp *self, struct stream *s, int *code) if (error == 2) /* we have fastpath packet! */ { - s->next_packet = 0; *code = 2; return 0; } @@ -1710,6 +1709,8 @@ xrdp_rdp_process_fastpath_data_input(struct xrdp_rdp *self, struct stream *s) int eventFlags; int code; int flags; + int param2; + int time; // process fastpath input events for (i = 0 ; i < self->sec_layer->fastpath_layer->numEvents ; i++) { @@ -1740,7 +1741,7 @@ xrdp_rdp_process_fastpath_data_input(struct xrdp_rdp *self, struct stream *s) RDP_INPUT_MOUSE - 0x8001 RDP_INPUT_MOUSEX - 0x8002 */ /* call to xrdp_wm.c : callback */ - self->session->callback(self->session->id, RDP_INPUT_SCANCODE, flags, 0, + self->session->callback(self->session->id, RDP_INPUT_SCANCODE, flags, param2, code, time); } break; From d36336b7b5abcd04c5607bd5fa1d46d889098b57 Mon Sep 17 00:00:00 2001 From: speidy Date: Mon, 10 Feb 2014 06:42:55 +0200 Subject: [PATCH 08/12] libxrdp: work on fastpath input, fix callback params --- libxrdp/xrdp_rdp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libxrdp/xrdp_rdp.c b/libxrdp/xrdp_rdp.c index 7bcdab62..226b1b52 100644 --- a/libxrdp/xrdp_rdp.c +++ b/libxrdp/xrdp_rdp.c @@ -1741,8 +1741,8 @@ xrdp_rdp_process_fastpath_data_input(struct xrdp_rdp *self, struct stream *s) RDP_INPUT_MOUSE - 0x8001 RDP_INPUT_MOUSEX - 0x8002 */ /* call to xrdp_wm.c : callback */ - self->session->callback(self->session->id, RDP_INPUT_SCANCODE, flags, param2, - code, time); + self->session->callback(self->session->id, RDP_INPUT_SCANCODE, code, 0, + flags, 0); } break; From 80204e2536327f46610d5925c552aff235e9f447 Mon Sep 17 00:00:00 2001 From: speidy Date: Tue, 11 Feb 2014 00:28:43 +0200 Subject: [PATCH 09/12] libxrdp: work on fastpath input, added fastpath option to xrdp.ini --- common/xrdp_constants.h | 1 + libxrdp/xrdp_fastpath.c | 8 ++-- libxrdp/xrdp_iso.c | 3 +- libxrdp/xrdp_mcs.c | 2 +- libxrdp/xrdp_rdp.c | 88 +++++++++++++++++++++++++++++++++++++---- libxrdp/xrdp_sec.c | 2 +- xrdp/xrdp.ini | 3 ++ 7 files changed, 92 insertions(+), 15 deletions(-) diff --git a/common/xrdp_constants.h b/common/xrdp_constants.h index 0dc327df..d3f20a46 100644 --- a/common/xrdp_constants.h +++ b/common/xrdp_constants.h @@ -161,6 +161,7 @@ #define RDP_INPUT_VIRTKEY 2 #define RDP_INPUT_SCANCODE 4 #define RDP_INPUT_MOUSE 0x8001 +#define RDP_INPUT_MOUSEX 0x8002 /* Device flags */ #define KBD_FLAG_RIGHT 0x0001 diff --git a/libxrdp/xrdp_fastpath.c b/libxrdp/xrdp_fastpath.c index 71e7f7c6..fcd7ac72 100644 --- a/libxrdp/xrdp_fastpath.c +++ b/libxrdp/xrdp_fastpath.c @@ -58,7 +58,7 @@ xrdp_fastpath_recv(struct xrdp_fastpath *self, struct stream *s) int fp_hdr; int len = 0; int byte; - int hdr_len = 2; + int hdr_len = 2; /* fastpath header lenght - can be 2 or 3 bytes long, depends on length */ DEBUG((" in xrdp_fastpath_recv")); /* read the first fastpath byte @@ -68,7 +68,7 @@ xrdp_fastpath_recv(struct xrdp_fastpath *self, struct stream *s) self->numEvents = (fp_hdr & 0x3C) >> 2; self->secFlags = (fp_hdr & 0xC0) >> 6; - // receive fastpath first packet length + // receive fastpath first length packet if (xrdp_tcp_recv(self->tcp_layer, s, 1) != 0) { return 1; @@ -80,7 +80,7 @@ xrdp_fastpath_recv(struct xrdp_fastpath *self, struct stream *s) { byte &= ~(0x80); len = (byte << 8); - // receive fastpath second packet length + // receive fastpath second length packet if (xrdp_tcp_recv(self->tcp_layer, s, 1) != 0) { return 1; @@ -94,7 +94,7 @@ xrdp_fastpath_recv(struct xrdp_fastpath *self, struct stream *s) len = byte; } - g_writeln("len= %d , numEvents= %d, secFlags= %d, bytesleft: %d", len, self->numEvents, self->secFlags, (s->p - s->data)); + //g_writeln("len= %d , numEvents= %d, secFlags= %d, bytesleft: %d", len, self->numEvents, self->secFlags, (s->p - s->data)); // receive the left bytes if (xrdp_tcp_recv(self->tcp_layer, s, len - hdr_len) != 0) diff --git a/libxrdp/xrdp_iso.c b/libxrdp/xrdp_iso.c index f29cbf23..1f546b0b 100644 --- a/libxrdp/xrdp_iso.c +++ b/libxrdp/xrdp_iso.c @@ -98,7 +98,7 @@ xrdp_iso_recv_msg(struct xrdp_iso *self, struct stream *s, int *code, int *len) if (plen == 2) { - DEBUG((" xrdp_iso_recv_msg: non-TPKT header detected, we try fastpath")); + DEBUG(("xrdp_iso_recv_msg: non-TPKT header detected, we try fastpath")); return plen; } @@ -164,7 +164,6 @@ xrdp_iso_recv_tpkt_header(struct xrdp_iso *self, struct stream *s) } in_uint8_peek(s, ver); // Peek only so we can use it later in fastpath layer, if needed - g_writeln(" tpkt version: %x", ver); // TODO: delete it if (ver != 3) { diff --git a/libxrdp/xrdp_mcs.c b/libxrdp/xrdp_mcs.c index 81e8b758..2c643373 100644 --- a/libxrdp/xrdp_mcs.c +++ b/libxrdp/xrdp_mcs.c @@ -132,7 +132,7 @@ xrdp_mcs_recv(struct xrdp_mcs *self, struct stream *s, int *chan) if (iso_msg == 2) // non-TPKT header { - DEBUG((" out xrdp_mcs_recv, non-TPKT header detected, we try fastpath")); + DEBUG((" out xrdp_mcs_recv, non-TPKT header detected, we try fastpath")); return iso_msg; } diff --git a/libxrdp/xrdp_rdp.c b/libxrdp/xrdp_rdp.c index 226b1b52..a98d507e 100644 --- a/libxrdp/xrdp_rdp.c +++ b/libxrdp/xrdp_rdp.c @@ -118,6 +118,31 @@ xrdp_rdp_read_config(struct xrdp_client_info *client_info) { client_info->require_credentials = g_text2bool(value); } + else if (g_strcasecmp(item, "use_fastpath") == 0) + { + if (g_strcasecmp(value, "output") == 0) + { + client_info->use_fast_path = 1; + } + else if (g_strcasecmp(value, "input") == 0) + { + client_info->use_fast_path = 2; + } + else if (g_strcasecmp(value, "both") == 0) + { + client_info->use_fast_path = 3; + } + else if (g_strcasecmp(value, "none") == 0) + { + client_info->use_fast_path = 0; + } + else + { + log_message(LOG_LEVEL_ALWAYS,"Warning: Your configured fastpath level is" + "undefined, fastpath will not be used"); + client_info->use_fast_path = 0; + } + } } list_delete(items); @@ -778,7 +803,7 @@ xrdp_rdp_send_demand_active(struct xrdp_rdp *self) INPUT_FLAG_FASTPATH_INPUT 0x0008 INPUT_FLAG_FASTPATH_INPUT2 0x0020 */ flags = 0x0001 | 0x0004; -// if (self->client_info.use_fast_path & 2) + if (self->client_info.use_fast_path & 2) flags |= 0x0008 | 0x0020; out_uint16_le(s, flags); out_uint8s(s, 82); @@ -1711,6 +1736,9 @@ xrdp_rdp_process_fastpath_data_input(struct xrdp_rdp *self, struct stream *s) int flags; int param2; int time; + int pointerFlags; + int xPos; + int yPos; // process fastpath input events for (i = 0 ; i < self->sec_layer->fastpath_layer->numEvents ; i++) { @@ -1718,12 +1746,15 @@ xrdp_rdp_process_fastpath_data_input(struct xrdp_rdp *self, struct stream *s) eventFlags = (eventHeader & 0x1F); eventCode = (eventHeader >> 5); - g_writeln("eventCode= %d, eventFlags= %d, numEvents= %d", eventCode, eventFlags, self->sec_layer->fastpath_layer->numEvents); + + //g_writeln("eventCode= %d, eventFlags= %d, numEvents= %d", + // eventCode, eventFlags, self->sec_layer->fastpath_layer->numEvents); + switch (eventCode) { case FASTPATH_INPUT_EVENT_SCANCODE: in_uint8(s, code); /* keyCode (1 byte) */ - g_writeln("scan code detected: %d", code); + //g_writeln("scan code detected: %d", code); flags = 0; if ((eventFlags & FASTPATH_INPUT_KBDFLAGS_RELEASE)) flags |= KBD_FLAG_UP; @@ -1747,15 +1778,58 @@ xrdp_rdp_process_fastpath_data_input(struct xrdp_rdp *self, struct stream *s) break; case FASTPATH_INPUT_EVENT_MOUSE: - in_uint8s(s, 6); + in_uint16_le(s, pointerFlags); /* pointerFlags (2 bytes) */ + in_uint16_le(s, xPos); /* xPos (2 bytes) */ + in_uint16_le(s, yPos); /* yPos (2 bytes) */ + + if (self->session->callback != 0) + { + /* msg_type can be + RDP_INPUT_SYNCHRONIZE - 0 + RDP_INPUT_SCANCODE - 4 + RDP_INPUT_MOUSE - 0x8001 + RDP_INPUT_MOUSEX - 0x8002 */ + /* call to xrdp_wm.c : callback */ + self->session->callback(self->session->id, RDP_INPUT_MOUSE, xPos, yPos, + pointerFlags, 0); + } break; case FASTPATH_INPUT_EVENT_MOUSEX: - in_uint8s(s, 6); + in_uint16_le(s, pointerFlags); /* pointerFlags (2 bytes) */ + in_uint16_le(s, xPos); /* xPos (2 bytes) */ + in_uint16_le(s, yPos); /* yPos (2 bytes) */ + + if (self->session->callback != 0) + { + /* msg_type can be + RDP_INPUT_SYNCHRONIZE - 0 + RDP_INPUT_SCANCODE - 4 + RDP_INPUT_MOUSE - 0x8001 + RDP_INPUT_MOUSEX - 0x8002 */ + /* call to xrdp_wm.c : callback */ + self->session->callback(self->session->id, RDP_INPUT_MOUSEX, xPos, yPos, + pointerFlags, 0); + } break; case FASTPATH_INPUT_EVENT_SYNC: - + /* + * The eventCode bitfield (3 bits in size) MUST be set to FASTPATH_INPUT_EVENT_SYNC (3). + * The eventFlags bitfield (5 bits in size) contains flags indicating the "on" + * status of the keyboard toggle keys. + */ + if (self->session->callback != 0) + { + /* msg_type can be + RDP_INPUT_SYNCHRONIZE - 0 + RDP_INPUT_SCANCODE - 4 + RDP_INPUT_MOUSE - 0x8001 + RDP_INPUT_MOUSEX - 0x8002 */ + /* call to xrdp_wm.c : callback */ + self->session->callback(self->session->id, RDP_INPUT_SYNCHRONIZE, eventCode, 0, + eventFlags, 0); + } break; case FASTPATH_INPUT_EVENT_UNICODE: @@ -1763,7 +1837,7 @@ xrdp_rdp_process_fastpath_data_input(struct xrdp_rdp *self, struct stream *s) break; default: - printf("Unknown eventCode %d\n", eventCode); + g_writeln("xrdp_rdp_process_fastpath_data_input: unknown eventCode %d", eventCode); break; } diff --git a/libxrdp/xrdp_sec.c b/libxrdp/xrdp_sec.c index 4846c356..37209772 100644 --- a/libxrdp/xrdp_sec.c +++ b/libxrdp/xrdp_sec.c @@ -774,8 +774,8 @@ xrdp_sec_recv(struct xrdp_sec *self, struct stream *s, int *chan) if (mcs_msg == 2) { - DEBUG((" out xrdp_sec_recv : non-TPKT msg detected, we try fastpath")); xrdp_sec_recv_fastpath(self, s); + DEBUG((" out xrdp_sec_recv : non-TPKT msg detected, we try fastpath")); return mcs_msg; } diff --git a/xrdp/xrdp.ini b/xrdp/xrdp.ini index 0e8d302b..f89e78d9 100644 --- a/xrdp/xrdp.ini +++ b/xrdp/xrdp.ini @@ -37,6 +37,9 @@ tcp_keepalive=yes #nego_sec_layer=0 allow_multimon=true +# fastpath - can be set to input / output / both / none +use_fastpath=input + [Logging] LogFile=xrdp.log LogLevel=DEBUG From 43f4d439ec52616ccf6380374e21bce0b7087694 Mon Sep 17 00:00:00 2001 From: speidy Date: Tue, 4 Mar 2014 10:19:19 +0200 Subject: [PATCH 10/12] libxrdp: work on fastpath, length issue --- libxrdp/libxrdp.c | 1 + libxrdp/xrdp_fastpath.c | 35 +++++++++++++++++++---------------- libxrdp/xrdp_iso.c | 2 +- libxrdp/xrdp_mcs.c | 12 +----------- libxrdp/xrdp_rdp.c | 22 ++++++++++++++++------ libxrdp/xrdp_sec.c | 13 +------------ xrdp/xrdp_process.c | 1 + 7 files changed, 40 insertions(+), 46 deletions(-) diff --git a/libxrdp/libxrdp.c b/libxrdp/libxrdp.c index ae2690f2..dc7a9869 100644 --- a/libxrdp/libxrdp.c +++ b/libxrdp/libxrdp.c @@ -29,6 +29,7 @@ libxrdp_init(tbus id, struct trans *trans) session = (struct xrdp_session *)g_malloc(sizeof(struct xrdp_session), 1); session->id = id; + session->trans = trans; session->rdp = xrdp_rdp_create(session, trans); session->orders = xrdp_orders_create(session, (struct xrdp_rdp *)session->rdp); session->client_info = &(((struct xrdp_rdp *)session->rdp)->client_info); diff --git a/libxrdp/xrdp_fastpath.c b/libxrdp/xrdp_fastpath.c index bc6f49d2..e7308ba0 100644 --- a/libxrdp/xrdp_fastpath.c +++ b/libxrdp/xrdp_fastpath.c @@ -58,22 +58,23 @@ xrdp_fastpath_recv(struct xrdp_fastpath *self, struct stream *s) int fp_hdr; int len = 0; int byte; - int hdr_len = 2; /* fastpath header lenght - can be 2 or 3 bytes long, depends on length */ + int hdr_len = 2; /* fastpath header length - can be 2 or 3 bytes long, depends on length */ DEBUG((" in xrdp_fastpath_recv")); /* read the first fastpath byte * (we already received it via iso layer */ + // receive fastpath first length packet + init_stream(s, hdr_len); + if (trans_force_read_s(self->trans, s, hdr_len) != 0) + { + return 1; + } in_uint8(s, fp_hdr); /* fpInputHeader (1 byte) */ self->numEvents = (fp_hdr & 0x3C) >> 2; self->secFlags = (fp_hdr & 0xC0) >> 6; // receive fastpath first length packet - if (trans_force_read_s(self->trans, s, 1) != 0) - { - return 1; - } - in_uint8(s, byte); /* length 1 */ if (byte & 0x80) @@ -81,7 +82,8 @@ xrdp_fastpath_recv(struct xrdp_fastpath *self, struct stream *s) byte &= ~(0x80); len = (byte << 8); // receive fastpath second length packet - if (xrdp_tcp_recv(self->tcp_layer, s, 1) != 0) + init_stream(s, 1); + if (trans_force_read_s(self->trans, s, 1) != 0) { return 1; } @@ -94,10 +96,11 @@ xrdp_fastpath_recv(struct xrdp_fastpath *self, struct stream *s) len = byte; } - //g_writeln("len= %d , numEvents= %d, secFlags= %d, bytesleft: %d", len, self->numEvents, self->secFlags, (s->p - s->data)); + g_writeln("len= %d , numEvents= %d, secFlags= %d, bytesleft: %d", len, self->numEvents, self->secFlags, (s->p - s->data)); // receive the left bytes - if (xrdp_tcp_recv(self->tcp_layer, s, len - hdr_len) != 0) + init_stream(s, len - hdr_len); + if (trans_force_read_s(self->trans, s, len - hdr_len) != 0) { return 1; } @@ -166,10 +169,10 @@ xrdp_fastpath_send_update_pdu(struct xrdp_fastpath *self, tui8 updateCode, // s_copy(s_send, s, len); s_mark_end(s_send); - if (xrdp_tcp_send(self->tcp_layer, s_send) != 0) - { - return 1; - } +// if (xrdp_tcp_send(self->tcp_layer, s_send) != 0) +// { +// return 1; +// } } return 0; @@ -220,12 +223,12 @@ xrdp_fastpath_process_data(struct xrdp_fastpath *self, struct stream *s, encryptionFlags = (header & 0xc0) >> 6; numberEvents = (header & 0x3c) >> 2; - xrdp_tcp_recv(self->tcp_layer, s, 1); +// xrdp_tcp_recv(self->tcp_layer, s, 1); in_uint8(s, length); if (length & 0x80) { - xrdp_tcp_recv(self->tcp_layer, s, 1); +// xrdp_tcp_recv(self->tcp_layer, s, 1); in_uint8(s, length2); length = (length & 0x7f) << 8 + length2 - 3; } @@ -234,7 +237,7 @@ xrdp_fastpath_process_data(struct xrdp_fastpath *self, struct stream *s, length -= 2; } - xrdp_tcp_recv(self->tcp_layer, s, length); +// xrdp_tcp_recv(self->tcp_layer, s, length); if (encryptionFlags != 0) { diff --git a/libxrdp/xrdp_iso.c b/libxrdp/xrdp_iso.c index df00f52b..31c279b5 100644 --- a/libxrdp/xrdp_iso.c +++ b/libxrdp/xrdp_iso.c @@ -111,7 +111,7 @@ xrdp_iso_recv_msg(struct xrdp_iso *self, struct stream *s, int *code, int *len) if (ver != 3) { - return 2; // special code for fastpath + return 1; } in_uint8s(s, 1); diff --git a/libxrdp/xrdp_mcs.c b/libxrdp/xrdp_mcs.c index 526587d5..08055191 100644 --- a/libxrdp/xrdp_mcs.c +++ b/libxrdp/xrdp_mcs.c @@ -122,21 +122,11 @@ xrdp_mcs_recv(struct xrdp_mcs *self, struct stream *s, int *chan) int len; int userid; int chanid; - int iso_msg; DEBUG((" in xrdp_mcs_recv")); while (1) { - - iso_msg = xrdp_iso_recv(self->iso_layer, s); - - if (iso_msg == 2) // non-TPKT header - { - DEBUG((" out xrdp_mcs_recv, non-TPKT header detected, we try fastpath")); - return iso_msg; - } - - if (iso_msg == 1) // error + if (xrdp_iso_recv(self->iso_layer, s) != 0) { DEBUG((" out xrdp_mcs_recv, xrdp_iso_recv return non zero")); return 1; diff --git a/libxrdp/xrdp_rdp.c b/libxrdp/xrdp_rdp.c index 85ca15d7..ea2204f5 100644 --- a/libxrdp/xrdp_rdp.c +++ b/libxrdp/xrdp_rdp.c @@ -299,20 +299,30 @@ xrdp_rdp_recv(struct xrdp_rdp *self, struct stream *s, int *code) int len = 0; int pdu_code = 0; int chan = 0; + const tui8 *header; + header = (const tui8 *) (self->session->trans->in_s->p); DEBUG(("in xrdp_rdp_recv")); + /* not fastpath, do tpkt */ if (s->next_packet == 0 || s->next_packet >= s->end) { - chan = 0; - error = xrdp_sec_recv(self->sec_layer, s, &chan); + /* check for fastpath first */ + g_writeln("xrdp_rdp_recv: header= 0x%8.8x", header[0]); - if (error == 2) /* we have fastpath packet! */ + if ((header[0] & 0x3) == 0 && (header[0] != 0x3c)) { - *code = 2; + if (xrdp_sec_recv_fastpath(self->sec_layer, s) != 0) + { + return 1; + } + *code = 2; // special code for fastpath return 0; } + chan = 0; + error = xrdp_sec_recv(self->sec_layer, s, &chan); + if (error == -1) /* special code for send demand active */ { s->next_packet = 0; @@ -1691,8 +1701,8 @@ xrdp_rdp_process_fastpath_data_input(struct xrdp_rdp *self, struct stream *s) eventFlags = (eventHeader & 0x1F); eventCode = (eventHeader >> 5); - //g_writeln("eventCode= %d, eventFlags= %d, numEvents= %d", - // eventCode, eventFlags, self->sec_layer->fastpath_layer->numEvents); +// g_writeln("eventCode= %d, eventFlags= %d, numEvents= %d", +// eventCode, eventFlags, self->sec_layer->fastpath_layer->numEvents); switch (eventCode) { diff --git a/libxrdp/xrdp_sec.c b/libxrdp/xrdp_sec.c index ec9b5711..6b8dbbc4 100644 --- a/libxrdp/xrdp_sec.c +++ b/libxrdp/xrdp_sec.c @@ -972,23 +972,12 @@ xrdp_sec_recv(struct xrdp_sec *self, struct stream *s, int *chan) { int flags; int len; - int mcs_msg; int ver; int pad; - DEBUG((" in xrdp_sec_recv")); - mcs_msg = xrdp_mcs_recv(self->mcs_layer, s, chan); - - if (mcs_msg == 2) - { - xrdp_sec_recv_fastpath(self, s); - DEBUG((" out xrdp_sec_recv : non-TPKT msg detected, we try fastpath")); - return mcs_msg; - } - - if (mcs_msg == 1) + if (xrdp_mcs_recv(self->mcs_layer, s, chan) != 0) { DEBUG((" out xrdp_sec_recv : error")); return 1; diff --git a/xrdp/xrdp_process.c b/xrdp/xrdp_process.c index 78576f1f..fe6e2c4b 100644 --- a/xrdp/xrdp_process.c +++ b/xrdp/xrdp_process.c @@ -123,6 +123,7 @@ xrdp_process_get_pdu_bytes(const char *aheader) rv = -1; header = (const tui8 *) aheader; + if (header[0] == 0x03) { /* TPKT */ From 08baf1a5bca7ed41cd9809118f01ba583f5e160b Mon Sep 17 00:00:00 2001 From: speidy Date: Tue, 4 Mar 2014 23:25:49 +0200 Subject: [PATCH 11/12] libxrdp: fastpath input working --- libxrdp/xrdp_fastpath.c | 26 ++++---------------------- libxrdp/xrdp_rdp.c | 9 ++++----- 2 files changed, 8 insertions(+), 27 deletions(-) diff --git a/libxrdp/xrdp_fastpath.c b/libxrdp/xrdp_fastpath.c index e7308ba0..843fdc1b 100644 --- a/libxrdp/xrdp_fastpath.c +++ b/libxrdp/xrdp_fastpath.c @@ -59,17 +59,10 @@ xrdp_fastpath_recv(struct xrdp_fastpath *self, struct stream *s) int len = 0; int byte; int hdr_len = 2; /* fastpath header length - can be 2 or 3 bytes long, depends on length */ - DEBUG((" in xrdp_fastpath_recv")); + DEBUG((" in xrdp_fastpath_recv")); - /* read the first fastpath byte - * (we already received it via iso layer */ - // receive fastpath first length packet - init_stream(s, hdr_len); - if (trans_force_read_s(self->trans, s, hdr_len) != 0) - { - return 1; - } in_uint8(s, fp_hdr); /* fpInputHeader (1 byte) */ + g_writeln("xrdp_fastpath_recv: header= 0x%8.8x", fp_hdr); self->numEvents = (fp_hdr & 0x3C) >> 2; self->secFlags = (fp_hdr & 0xC0) >> 6; @@ -82,13 +75,8 @@ xrdp_fastpath_recv(struct xrdp_fastpath *self, struct stream *s) byte &= ~(0x80); len = (byte << 8); // receive fastpath second length packet - init_stream(s, 1); - if (trans_force_read_s(self->trans, s, 1) != 0) - { - return 1; - } - hdr_len++; in_uint8(s, byte); /* length 2 */ + hdr_len++; len += byte; } else @@ -96,14 +84,8 @@ xrdp_fastpath_recv(struct xrdp_fastpath *self, struct stream *s) len = byte; } - g_writeln("len= %d , numEvents= %d, secFlags= %d, bytesleft: %d", len, self->numEvents, self->secFlags, (s->p - s->data)); +// g_writeln("len= %d , numEvents= %d, secFlags= %d, bytesleft: %d", len, self->numEvents, self->secFlags, (s->p - s->data)); - // receive the left bytes - init_stream(s, len - hdr_len); - if (trans_force_read_s(self->trans, s, len - hdr_len) != 0) - { - return 1; - } DEBUG((" out xrdp_fastpath_recv")); return 0; diff --git a/libxrdp/xrdp_rdp.c b/libxrdp/xrdp_rdp.c index ea2204f5..d909abd9 100644 --- a/libxrdp/xrdp_rdp.c +++ b/libxrdp/xrdp_rdp.c @@ -303,23 +303,22 @@ xrdp_rdp_recv(struct xrdp_rdp *self, struct stream *s, int *code) header = (const tui8 *) (self->session->trans->in_s->p); DEBUG(("in xrdp_rdp_recv")); - - /* not fastpath, do tpkt */ if (s->next_packet == 0 || s->next_packet >= s->end) { - /* check for fastpath first */ - g_writeln("xrdp_rdp_recv: header= 0x%8.8x", header[0]); - if ((header[0] & 0x3) == 0 && (header[0] != 0x3c)) + /* check for fastpath first */ + if ((header[0] != 0x3) && (header[0] != 0x3c)) { if (xrdp_sec_recv_fastpath(self->sec_layer, s) != 0) { return 1; } *code = 2; // special code for fastpath + DEBUG(("out (fastpath) xrdp_rdp_recv")); return 0; } + /* not fastpath, do tpkt */ chan = 0; error = xrdp_sec_recv(self->sec_layer, s, &chan); From 866fde498efe893144b0b596999f18af90a743c3 Mon Sep 17 00:00:00 2001 From: speidy Date: Tue, 4 Mar 2014 23:56:26 +0200 Subject: [PATCH 12/12] libxrdp: move fastpath callback calls from xrdp_rdp to xrdp_fastpath --- libxrdp/libxrdp.c | 2 +- libxrdp/libxrdp.h | 6 +- libxrdp/xrdp_fastpath.c | 181 ++++++++++++++++++++++++++++++++++++++++ libxrdp/xrdp_rdp.c | 126 +--------------------------- libxrdp/xrdp_sec.c | 12 ++- 5 files changed, 195 insertions(+), 132 deletions(-) diff --git a/libxrdp/libxrdp.c b/libxrdp/libxrdp.c index dc7a9869..9d584244 100644 --- a/libxrdp/libxrdp.c +++ b/libxrdp/libxrdp.c @@ -152,7 +152,7 @@ libxrdp_process_data(struct xrdp_session *session, struct stream *s) } break; case 2: /* FASTPATH_INPUT_EVENT */ - if (xrdp_rdp_process_fastpath_data_input(rdp, s) != 0) + if (xrdp_fastpath_process_input_event(rdp->sec_layer->fastpath_layer, s) != 0) { DEBUG(("libxrdp_process_data returned non zero")); cont = 0; diff --git a/libxrdp/libxrdp.h b/libxrdp/libxrdp.h index 2843089b..4e7218d6 100644 --- a/libxrdp/libxrdp.h +++ b/libxrdp/libxrdp.h @@ -72,6 +72,7 @@ struct xrdp_fastpath { struct xrdp_sec* sec_layer; /* owner */ struct trans* trans; + struct xrdp_session* session; int numEvents; int secFlags; }; @@ -386,8 +387,6 @@ xrdp_rdp_process_confirm_active(struct xrdp_rdp* self, struct stream* s); int APP_CC xrdp_rdp_process_data(struct xrdp_rdp* self, struct stream* s); int APP_CC -xrdp_rdp_process_fastpath_data_input(struct xrdp_rdp *self, struct stream *s); -int APP_CC xrdp_rdp_disconnect(struct xrdp_rdp* self); int APP_CC xrdp_rdp_send_deactive(struct xrdp_rdp* self); @@ -551,5 +550,6 @@ void APP_CC xrdp_fastpath_delete(struct xrdp_fastpath *self); int APP_CC xrdp_fastpath_recv(struct xrdp_fastpath *self, struct stream *s); - +int APP_CC +xrdp_fastpath_process_input_event(struct xrdp_fastpath *self, struct stream *s); #endif diff --git a/libxrdp/xrdp_fastpath.c b/libxrdp/xrdp_fastpath.c index 843fdc1b..572b5a98 100644 --- a/libxrdp/xrdp_fastpath.c +++ b/libxrdp/xrdp_fastpath.c @@ -29,6 +29,7 @@ xrdp_fastpath_create(struct xrdp_sec *owner, struct trans *trans) self = (struct xrdp_fastpath *)g_malloc(sizeof(struct xrdp_fastpath), 1); self->sec_layer = owner; self->trans = trans; + self->session = owner->rdp_layer->session; DEBUG((" out xrdp_fastpath_create")); return self; } @@ -243,3 +244,183 @@ xrdp_fastpath_process_data(struct xrdp_fastpath *self, struct stream *s, in_uint16_le(s, size); return xrdp_fastpath_process_update(self, updateCode, size, s); } + +/*****************************************************************************/ +/* FASTPATH_INPUT_EVENT_SCANCODE */ +int APP_CC +xrdp_fastpath_process_EVENT_SCANCODE(struct xrdp_fastpath *self, int eventFlags, struct stream *s) +{ + int flags; + int code; + flags = 0; + + in_uint8(s, code); /* keyCode (1 byte) */ + //g_writeln("scan code detected: %d", code); + + if ((eventFlags & FASTPATH_INPUT_KBDFLAGS_RELEASE)) + flags |= KBD_FLAG_UP; + else + flags |= KBD_FLAG_DOWN; + + if ((eventFlags & FASTPATH_INPUT_KBDFLAGS_EXTENDED)) + flags |= KBD_FLAG_EXT; + + if (self->session->callback != 0) + { + /* msg_type can be + RDP_INPUT_SYNCHRONIZE - 0 + RDP_INPUT_SCANCODE - 4 + RDP_INPUT_MOUSE - 0x8001 + RDP_INPUT_MOUSEX - 0x8002 */ + /* call to xrdp_wm.c : callback */ + self->session->callback(self->session->id, RDP_INPUT_SCANCODE, code, 0, + flags, 0); + } + return 0; +} +/*****************************************************************************/ +/* FASTPATH_INPUT_EVENT_MOUSE */ +int APP_CC +xrdp_fastpath_process_EVENT_MOUSE(struct xrdp_fastpath *self, int eventFlags, struct stream *s) +{ + int pointerFlags; + int xPos; + int yPos; + + in_uint16_le(s, pointerFlags); /* pointerFlags (2 bytes) */ + in_uint16_le(s, xPos); /* xPos (2 bytes) */ + in_uint16_le(s, yPos); /* yPos (2 bytes) */ + + if (self->session->callback != 0) + { + /* msg_type can be + RDP_INPUT_SYNCHRONIZE - 0 + RDP_INPUT_SCANCODE - 4 + RDP_INPUT_MOUSE - 0x8001 + RDP_INPUT_MOUSEX - 0x8002 */ + /* call to xrdp_wm.c : callback */ + self->session->callback(self->session->id, RDP_INPUT_MOUSE, xPos, yPos, + pointerFlags, 0); + } + return 0; +} +/*****************************************************************************/ +/* FASTPATH_INPUT_EVENT_MOUSEX */ +int APP_CC +xrdp_fastpath_process_EVENT_MOUSEX(struct xrdp_fastpath *self, int eventFlags, struct stream *s) +{ + int pointerFlags; + int xPos; + int yPos; + + in_uint16_le(s, pointerFlags); /* pointerFlags (2 bytes) */ + in_uint16_le(s, xPos); /* xPos (2 bytes) */ + in_uint16_le(s, yPos); /* yPos (2 bytes) */ + + if (self->session->callback != 0) + { + /* msg_type can be + RDP_INPUT_SYNCHRONIZE - 0 + RDP_INPUT_SCANCODE - 4 + RDP_INPUT_MOUSE - 0x8001 + RDP_INPUT_MOUSEX - 0x8002 */ + /* call to xrdp_wm.c : callback */ + self->session->callback(self->session->id, RDP_INPUT_MOUSEX, xPos, yPos, + pointerFlags, 0); + } + return 0; +} +/*****************************************************************************/ +/* FASTPATH_INPUT_EVENT_SYNC */ +int APP_CC +xrdp_fastpath_process_EVENT_SYNC(struct xrdp_fastpath *self, int eventCode, int eventFlags, struct stream *s) +{ + /* + * The eventCode bitfield (3 bits in size) MUST be set to FASTPATH_INPUT_EVENT_SYNC (3). + * The eventFlags bitfield (5 bits in size) contains flags indicating the "on" + * status of the keyboard toggle keys. + */ + if (self->session->callback != 0) + { + /* msg_type can be + RDP_INPUT_SYNCHRONIZE - 0 + RDP_INPUT_SCANCODE - 4 + RDP_INPUT_MOUSE - 0x8001 + RDP_INPUT_MOUSEX - 0x8002 */ + /* call to xrdp_wm.c : callback */ + self->session->callback(self->session->id, RDP_INPUT_SYNCHRONIZE, eventCode, 0, + eventFlags, 0); + } + return 0; +} +/*****************************************************************************/ +/* FASTPATH_INPUT_EVENT_UNICODE */ +int APP_CC +xrdp_fastpath_process_EVENT_UNICODE(struct xrdp_fastpath *self, int eventFlags, struct stream *s) +{ + in_uint8s(s, 2); + return 0; +} +/*****************************************************************************/ +/* FASTPATH_INPUT_EVENT */ +int APP_CC +xrdp_fastpath_process_input_event(struct xrdp_fastpath *self, struct stream *s) +{ + int i; + int eventHeader; + int eventCode; + int eventFlags; + + // process fastpath input events + for (i = 0 ; i < self->numEvents ; i++) { + in_uint8(s, eventHeader); + + eventFlags = (eventHeader & 0x1F); + eventCode = (eventHeader >> 5); + +// g_writeln("eventCode= %d, eventFlags= %d, numEvents= %d", +// eventCode, eventFlags, self->sec_layer->fastpath_layer->numEvents); + + switch (eventCode) + { + case FASTPATH_INPUT_EVENT_SCANCODE: + if (xrdp_fastpath_process_EVENT_SCANCODE(self, eventFlags, s) != 0) + { + return 1; + } + break; + + case FASTPATH_INPUT_EVENT_MOUSE: + if (xrdp_fastpath_process_EVENT_MOUSE(self, eventFlags, s) != 0) + { + return 1; + } + break; + case FASTPATH_INPUT_EVENT_MOUSEX: + if (xrdp_fastpath_process_EVENT_MOUSEX(self, eventFlags, s) != 0) + { + return 1; + } + break; + case FASTPATH_INPUT_EVENT_SYNC: + if (xrdp_fastpath_process_EVENT_SYNC(self, eventCode, eventFlags, s) != 0) + { + return 1; + } + break; + case FASTPATH_INPUT_EVENT_UNICODE: + if (xrdp_fastpath_process_EVENT_UNICODE(self, eventFlags, s) != 0) + { + return 1; + } + + break; + default: + g_writeln("xrdp_rdp_process_fastpath_data_input: unknown eventCode %d", eventCode); + break; + } + + } + + return 0; +} diff --git a/libxrdp/xrdp_rdp.c b/libxrdp/xrdp_rdp.c index d909abd9..787b6e6c 100644 --- a/libxrdp/xrdp_rdp.c +++ b/libxrdp/xrdp_rdp.c @@ -289,7 +289,6 @@ xrdp_rdp_init_data(struct xrdp_rdp *self, struct stream *s) s_push_layer(s, rdp_hdr, 18); return 0; } - /*****************************************************************************/ /* returns error */ int APP_CC @@ -305,7 +304,6 @@ xrdp_rdp_recv(struct xrdp_rdp *self, struct stream *s, int *code) DEBUG(("in xrdp_rdp_recv")); if (s->next_packet == 0 || s->next_packet >= s->end) { - /* check for fastpath first */ if ((header[0] != 0x3) && (header[0] != 0x3c)) { @@ -313,7 +311,7 @@ xrdp_rdp_recv(struct xrdp_rdp *self, struct stream *s, int *code) { return 1; } - *code = 2; // special code for fastpath + *code = 2; // special code for fastpath input DEBUG(("out (fastpath) xrdp_rdp_recv")); return 0; } @@ -1676,128 +1674,7 @@ xrdp_rdp_send_disconnect_reason(struct xrdp_rdp *self, int reason) return 0; } #endif -/*****************************************************************************/ -/* FASTPATH_INPUT_EVENT */ -int APP_CC -xrdp_rdp_process_fastpath_data_input(struct xrdp_rdp *self, struct stream *s) -{ - int i; - int eventHeader; - int eventCode; - int eventFlags; - int code; - int flags; - int param2; - int time; - int pointerFlags; - int xPos; - int yPos; - - // process fastpath input events - for (i = 0 ; i < self->sec_layer->fastpath_layer->numEvents ; i++) { - in_uint8(s, eventHeader); - - eventFlags = (eventHeader & 0x1F); - eventCode = (eventHeader >> 5); - -// g_writeln("eventCode= %d, eventFlags= %d, numEvents= %d", -// eventCode, eventFlags, self->sec_layer->fastpath_layer->numEvents); - - switch (eventCode) - { - case FASTPATH_INPUT_EVENT_SCANCODE: - in_uint8(s, code); /* keyCode (1 byte) */ - //g_writeln("scan code detected: %d", code); - flags = 0; - if ((eventFlags & FASTPATH_INPUT_KBDFLAGS_RELEASE)) - flags |= KBD_FLAG_UP; - else - flags |= KBD_FLAG_DOWN; - - if ((eventFlags & FASTPATH_INPUT_KBDFLAGS_EXTENDED)) - flags |= KBD_FLAG_EXT; - - if (self->session->callback != 0) - { - /* msg_type can be - RDP_INPUT_SYNCHRONIZE - 0 - RDP_INPUT_SCANCODE - 4 - RDP_INPUT_MOUSE - 0x8001 - RDP_INPUT_MOUSEX - 0x8002 */ - /* call to xrdp_wm.c : callback */ - self->session->callback(self->session->id, RDP_INPUT_SCANCODE, code, 0, - flags, 0); - } - break; - - case FASTPATH_INPUT_EVENT_MOUSE: - in_uint16_le(s, pointerFlags); /* pointerFlags (2 bytes) */ - in_uint16_le(s, xPos); /* xPos (2 bytes) */ - in_uint16_le(s, yPos); /* yPos (2 bytes) */ - - if (self->session->callback != 0) - { - /* msg_type can be - RDP_INPUT_SYNCHRONIZE - 0 - RDP_INPUT_SCANCODE - 4 - RDP_INPUT_MOUSE - 0x8001 - RDP_INPUT_MOUSEX - 0x8002 */ - /* call to xrdp_wm.c : callback */ - self->session->callback(self->session->id, RDP_INPUT_MOUSE, xPos, yPos, - pointerFlags, 0); - } - break; - - case FASTPATH_INPUT_EVENT_MOUSEX: - in_uint16_le(s, pointerFlags); /* pointerFlags (2 bytes) */ - in_uint16_le(s, xPos); /* xPos (2 bytes) */ - in_uint16_le(s, yPos); /* yPos (2 bytes) */ - - if (self->session->callback != 0) - { - /* msg_type can be - RDP_INPUT_SYNCHRONIZE - 0 - RDP_INPUT_SCANCODE - 4 - RDP_INPUT_MOUSE - 0x8001 - RDP_INPUT_MOUSEX - 0x8002 */ - /* call to xrdp_wm.c : callback */ - self->session->callback(self->session->id, RDP_INPUT_MOUSEX, xPos, yPos, - pointerFlags, 0); - } - break; - - case FASTPATH_INPUT_EVENT_SYNC: - /* - * The eventCode bitfield (3 bits in size) MUST be set to FASTPATH_INPUT_EVENT_SYNC (3). - * The eventFlags bitfield (5 bits in size) contains flags indicating the "on" - * status of the keyboard toggle keys. - */ - if (self->session->callback != 0) - { - /* msg_type can be - RDP_INPUT_SYNCHRONIZE - 0 - RDP_INPUT_SCANCODE - 4 - RDP_INPUT_MOUSE - 0x8001 - RDP_INPUT_MOUSEX - 0x8002 */ - /* call to xrdp_wm.c : callback */ - self->session->callback(self->session->id, RDP_INPUT_SYNCHRONIZE, eventCode, 0, - eventFlags, 0); - } - break; - - case FASTPATH_INPUT_EVENT_UNICODE: - in_uint8s(s, 2); - break; - - default: - g_writeln("xrdp_rdp_process_fastpath_data_input: unknown eventCode %d", eventCode); - break; - } - - } - return 0; -} /*****************************************************************************/ /* RDP_PDU_DATA */ int APP_CC @@ -1854,7 +1731,6 @@ xrdp_rdp_process_data(struct xrdp_rdp *self, struct stream *s) return 0; } - /*****************************************************************************/ int APP_CC xrdp_rdp_disconnect(struct xrdp_rdp *self) diff --git a/libxrdp/xrdp_sec.c b/libxrdp/xrdp_sec.c index 6b8dbbc4..76df3cae 100644 --- a/libxrdp/xrdp_sec.c +++ b/libxrdp/xrdp_sec.c @@ -949,9 +949,15 @@ xrdp_sec_recv_fastpath(struct xrdp_sec *self, struct stream *s) return 1; } - in_uint8s(s, 8); /* dataSignature, skip for now */ + if (self->crypt_level == CRYPT_LEVEL_FIPS) + { + in_uint8s(s, 4); /* fipsInformation (4 bytes) */ + } + + in_uint8s(s, 8); /* dataSignature (8 bytes), skip for now */ - if (self->fastpath_layer->secFlags & FASTPATH_INPUT_ENCRYPTED) { + if (self->fastpath_layer->secFlags & FASTPATH_INPUT_ENCRYPTED) + { xrdp_sec_decrypt(self, s->p, (int)(s->end - s->p)); } @@ -960,7 +966,7 @@ xrdp_sec_recv_fastpath(struct xrdp_sec *self, struct stream *s) * If numberEvents is not provided in fpInputHeader, it will be provided * as one additional byte here. */ - in_uint8(s, self->fastpath_layer->numEvents); /* numEvents (optional) */ + in_uint8(s, self->fastpath_layer->numEvents); /* numEvents (1 byte) (optional) */ } return 0;