Merge pull request #168 from derfian/issue66-ts_fp_update_pdu

Clarify capability sets and Fast-Path code
This commit is contained in:
Henrik Andersson 2017-10-16 12:34:45 +02:00 committed by GitHub
commit 0e530e6095
5 changed files with 347 additions and 155 deletions

View File

@ -23,6 +23,40 @@
#define DEFAULT_CODEPAGE "UTF-8"
#define WINDOWS_CODEPAGE "UTF-16LE"
/* T-REC-T.123-200701, section 8 */
#define T123_HEADER_VERSION 0x3
/* [MS-RDPBCGR] 2.2.9.1.2 */
#define FASTPATH_OUTPUT_ACTION_FASTPATH 0x0
#define FASTPATH_OUTPUT_ACTION_X224 T123_HEADER_VERSION
#define FASTPATH_OUTPUT_SECURE_CHECKSUM 0x1
#define FASTPATH_OUTPUT_ENCRYPTED 0x2
#define IS_FASTPATH(hdr) ((hdr & 0x03) == FASTPATH_OUTPUT_ACTION_FASTPATH)
#define IS_SLOWPATH(hdr) ((hdr) == FASTPATH_OUTPUT_ACTION_X224)
/* [MS-RDPBCGR] 2.2.9.1.2.1 */
/* adjusted for position in updateHeader */
#define FASTPATH_UPDATETYPE_ORDERS 0x0
#define FASTPATH_UPDATETYPE_BITMAP 0x1
#define FASTPATH_UPDATETYPE_PALETTE 0x2
#define FASTPATH_UPDATETYPE_SYNCHRONIZE 0x3
#define FASTPATH_UPDATETYPE_SURFCMDS 0x4
#define FASTPATH_UPDATETYPE_PTR_NULL 0x5
#define FASTPATH_UPDATETYPE_PTR_DEFAULT 0x6
#define FASTPATH_UPDATETYPE_PTR_POSITION 0x8
#define FASTPATH_UPDATETYPE_COLOR 0x9
#define FASTPATH_UPDATETYPE_CACHED 0xA
#define FASTPATH_UPDATETYPE_POINTER 0xB
#define FASTPATH_FRAGMENT_SINGLE (0x0 << 4)
#define FASTPATH_FRAGMENT_LAST (0x1 << 4)
#define FASTPATH_FRAGMENT_FIRST (0x2 << 4)
#define FASTPATH_FRAGMENT_NEXT (0x3 << 4)
#define FASTPATH_OUTPUT_COMPRESSION_USED (0x2 << 6)
/* ISO PDU codes */
enum ISO_PDU_CODE
{
@ -220,10 +254,11 @@ enum RDP_POINTER_PDU_TYPE
RDP_POINTER_NEW = 8
};
/* [MS-RDPBCGR] 2.2.9.1.1.4.3 */
enum RDP_SYSTEM_POINTER_TYPE
{
RDP_NULL_POINTER = 0,
RDP_DEFAULT_POINTER = 0x7F00
SYSPTR_NULL = 0x00000000,
SYSPTR_DEFAULT = 0x00007F00
};
enum RDP_INPUT_DEVICE
@ -324,9 +359,21 @@ enum RDP_INPUT_DEVICE
#define RDP_CAPSET_COLCACHE 10
#define RDP_CAPLEN_COLCACHE 0x08
#define RDP_CAPSET_SOUND 12
#define RDP_CAPLEN_SOUND 8
#define RDP_CAPSET_INPUT 13
#define RDP_CAPLEN_INPUT 88
#define RDP_CAPSET_FONT 14
#define RDP_CAPLEN_FONT 8
#define RDP_CAPSET_BRUSHCACHE 15
#define RDP_CAPLEN_BRUSHCACHE 0x08
#define RDP_CAPSET_GLYPHCACHE 16
#define RDP_CAPLEN_GLYPHCACHE 52
#define RDP_CAPSET_BMPCACHE2 19
#define RDP_CAPLEN_BMPCACHE2 0x28
#define BMPCACHE2_FLAG_PERSIST ((uint32)1<<31)
@ -626,3 +673,70 @@ enum RDP_PDU_REDIRECT_FLAGS
LB_REDIRECTION_GUID = 0x8000,
LB_TARGET_CERTIFICATE = 0x10000
};
/* [MS-RDPBCGR] 2.2.7.1.1 */
#define OSMAJORTYPE_WINDOWS 0x0001
#define OSMINORTYPE_WINDOWSNT 0x0003
#define TS_CAPS_PROTOCOLVERSION 0x0200
/* extraFlags, [MS-RDPBCGR] 2.2.7.1.1 */
#define FASTPATH_OUTPUT_SUPPORTED 0x0001
#define LONG_CREDENTIALS_SUPPORTED 0x0004
#define AUTORECONNECT_SUPPORTED 0x0008
#define ENC_SALTED_CHECKSUM 0x0010
#define NO_BITMAP_COMPRESSION_HDR 0x0400
/* orderFlags, [MS-RDPBCGR] 2.2.7.1.3 */
#define NEGOTIATEORDERSUPPORT 0x0002
#define ZEROBOUNDSDELTASSUPPORT 0x0008
#define COLORINDEXSUPPORT 0x0020
#define SOLIDPATTERNBRUSHONLY 0x0040
#define ORDERFLAGS_EXTRA_FLAGS 0x0080
/* orderSupport index, [MS-RDPBCGR] 2.2.7.1.3 */
#define TS_NEG_DSTBLT_INDEX 0x00
#define TS_NEG_PATBLT_INDEX 0x01
#define TS_NEG_SCRBLT_INDEX 0x02
#define TS_NEG_MEMBLT_INDEX 0x03
#define TS_NEG_MEM3BLT_INDEX 0x04
#define TS_NEG_DRAWNINEGRID_INDEX 0x07
#define TS_NEG_LINETO_INDEX 0x08
#define TS_NEG_MULTI_DRAWNINEGRID_INDEX 0x09
#define TS_NEG_SAVEBITMAP_INDEX 0x0B
#define TS_NEG_MULTIDSTBLT_INDEX 0x0F
#define TS_NEG_MULTIPATBLT_INDEX 0x10
#define TS_NEG_MULTISCRBLT_INDEX 0x11
#define TS_NEG_MULTIOPAQUERECT_INDEX 0x12
#define TS_NEG_FAST_INDEX_INDEX 0x13
#define TS_NEG_POLYGON_SC_INDEX 0x14
#define TS_NEG_POLYGON_CB_INDEX 0x15
#define TS_NEG_POLYLINE_INDEX 0x16
#define TS_NEG_FAST_GLYPH_INDEX 0x18
#define TS_NEG_ELLIPSE_SC_INDEX 0x19
#define TS_NEG_ELLIPSE_CB_INDEX 0x1A
#define TS_NEG_INDEX_INDEX 0x1B
/* [MS-RDPBCGR] 2.2.7.1.6 */
#define INPUT_FLAG_SCANCODES 0x0001
#define INPUT_FLAG_MOUSEX 0x0004
#define INPUT_FLAG_FASTPATH_INPUT 0x0008
#define INPUT_FLAG_UNICODE 0x0010
#define INPUT_FLAG_FASTPATH_INPUT2 0x0020
#define INPUT_FLAG_UNUSED1 0x0040
#define INPUT_FLAG_UNUSED2 0x0080
#define TS_INPUT_FLAG_MOUSE_HWHEEL 0x0100
#define TS_INPUT_FLAG_QOE_TIMESTAMPS 0x0200
/* [MS-RDPBCGR] 2.2.7.1.8 */
#define GLYPH_SUPPORT_NONE 0x0000
#define GLYPH_SUPPORT_PARTIAL 0x0001
#define GLYPH_SUPPORT_FULL 0x0002
#define GLYPH_SUPPORT_ENCODE 0x0003
/* [MS-RDPBCGR] 2.2.7.1.11 */
#define SOUND_BEEPS_FLAG 0x0001
/* [MS-RDPBCGR] 2.2.7.2.5 */
#define FONTSUPPORT_FONTLIST 0x0001

15
iso.c
View File

@ -110,16 +110,17 @@ iso_recv_msg(uint8 * code, uint8 * rdpver)
in_uint8(s, version);
if (rdpver != NULL)
*rdpver = version;
if (version == 3)
if (IS_SLOWPATH(version))
{
in_uint8s(s, 1); /* pad */
in_uint16_be(s, length);
in_uint8s(s, 1); /* reserved */
in_uint16_be(s, length); /* length */
}
else
{
in_uint8(s, length);
in_uint8(s, length); /* length1 */
if (length & 0x80)
{
/* length2 is only present if the most significant bit of length1 is set */
length &= ~0x80;
next_be(s, length);
}
@ -132,7 +133,7 @@ iso_recv_msg(uint8 * code, uint8 * rdpver)
s = tcp_recv(s, length - 4);
if (s == NULL)
return NULL;
if (version != 3)
if (IS_FASTPATH(version))
return s;
in_uint8s(s, 1); /* hdrlen */
in_uint8(s, *code);
@ -166,7 +167,7 @@ iso_send(STREAM s)
s_pop_layer(s, iso_hdr);
length = s->end - s->p;
out_uint8(s, 3); /* version */
out_uint8(s, T123_HEADER_VERSION); /* version */
out_uint8(s, 0); /* reserved */
out_uint16_be(s, length);
@ -188,7 +189,7 @@ iso_recv(uint8 * rdpver)
if (s == NULL)
return NULL;
if (rdpver != NULL)
if (*rdpver != 3)
if (IS_FASTPATH(*rdpver))
return s;
if (code != ISO_PDU_DT)
{

View File

@ -144,7 +144,7 @@ int rd_write_file(int fd, void *ptr, int len);
int rd_lseek_file(int fd, int offset);
RD_BOOL rd_lock_file(int fd, int start, int len);
/* rdp5.c */
void rdp5_process(STREAM s);
void process_ts_fp_updates(STREAM s);
/* rdp.c */
void rdp_in_unistr(STREAM s, int in_len, char **string, uint32 * str_size);
void rdp_send_input(uint32 time, uint16 message_type, uint16 device_flags, uint16 param1,
@ -154,6 +154,7 @@ void process_colour_pointer_pdu(STREAM s);
void process_new_pointer_pdu(STREAM s);
void process_cached_pointer_pdu(STREAM s);
void process_system_pointer_pdu(STREAM s);
void set_system_pointer(uint32 ptr);
void process_bitmap_updates(STREAM s);
void process_palette(STREAM s);
void process_disconnect_pdu(STREAM s, uint32 * ext_disc_reason);

307
rdp.c
View File

@ -4,6 +4,7 @@
Copyright (C) Matthew Chapman <matthewc.unsw.edu.au> 1999-2008
Copyright 2003-2011 Peter Astrand <astrand@cendio.se> for Cendio AB
Copyright 2011-2017 Henrik Andersson <hean01@cendio.se> for Cendio AB
Copyright 2017 Karl Mikaelsson <derfian@cendio.se> for Cendio AB
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -103,8 +104,8 @@ rdp_recv(uint8 * type)
}
else if (rdpver != 3)
{
/* rdp5_process should move g_next_packet ok */
rdp5_process(rdp_s);
/* process_ts_fp_updates moves g_next_packet */
process_ts_fp_updates(rdp_s);
*type = 0;
return rdp_s;
}
@ -624,93 +625,112 @@ rdp_send_fonts(uint16 seq)
rdp_send_data(s, RDP_DATA_PDU_FONT2);
}
/* Output general capability set */
/* Output general capability set (TS_GENERAL_CAPABILITYSET) */
static void
rdp_out_general_caps(STREAM s)
rdp_out_ts_general_capabilityset(STREAM s)
{
uint16 extraFlags = 0;
if (g_rdp_version >= RDP_V5)
{
extraFlags |= NO_BITMAP_COMPRESSION_HDR;
extraFlags |= AUTORECONNECT_SUPPORTED;
extraFlags |= LONG_CREDENTIALS_SUPPORTED;
extraFlags |= FASTPATH_OUTPUT_SUPPORTED;
}
out_uint16_le(s, RDP_CAPSET_GENERAL);
out_uint16_le(s, RDP_CAPLEN_GENERAL);
out_uint16_le(s, 1); /* OS major type */
out_uint16_le(s, 3); /* OS minor type */
out_uint16_le(s, 0x200); /* Protocol version */
out_uint16(s, 0); /* Pad */
out_uint16(s, 0); /* Compression types */
out_uint16_le(s, (g_rdp_version >= RDP_V5) ? 0x40d : 0);
/* Pad, according to T.128. 0x40d seems to
trigger
the server to start sending RDP5 packets.
However, the value is 0x1d04 with W2KTSK and
NT4MS. Hmm.. Anyway, thankyou, Microsoft,
for sending such information in a padding
field.. */
out_uint16(s, 0); /* Update capability */
out_uint16(s, 0); /* Remote unshare capability */
out_uint16(s, 0); /* Compression level */
out_uint16(s, 0); /* Pad */
out_uint16_le(s, OSMAJORTYPE_WINDOWS); /* osMajorType */
out_uint16_le(s, OSMINORTYPE_WINDOWSNT); /* osMinorType */
out_uint16_le(s, TS_CAPS_PROTOCOLVERSION); /* protocolVersion (must be TS_CAPS_PROTOCOLVERSION) */
out_uint16_le(s, 0); /* pad2OctetsA */
out_uint16_le(s, 0); /* generalCompressionTypes (must be 0) */
out_uint16_le(s, extraFlags); /* extraFlags */
out_uint16_le(s, 0); /* updateCapabilityFlag (must be 0) */
out_uint16_le(s, 0); /* remoteUnshareFlag (must be 0) */
out_uint16_le(s, 0); /* generalCompressionLevel (must be 0) */
out_uint8(s, 0); /* refreshRectSupport */
out_uint8(s, 0); /* suppressOutputSupport */
}
/* Output bitmap capability set */
static void
rdp_out_bitmap_caps(STREAM s)
rdp_out_ts_bitmap_capabilityset(STREAM s)
{
out_uint16_le(s, RDP_CAPSET_BITMAP);
out_uint16_le(s, RDP_CAPLEN_BITMAP);
out_uint16_le(s, g_server_depth); /* Preferred colour depth */
out_uint16_le(s, 1); /* Receive 1 BPP */
out_uint16_le(s, 1); /* Receive 4 BPP */
out_uint16_le(s, 1); /* Receive 8 BPP */
out_uint16_le(s, 800); /* Desktop width */
out_uint16_le(s, 600); /* Desktop height */
out_uint16(s, 0); /* Pad */
out_uint16(s, 1); /* Allow resize */
out_uint16_le(s, g_bitmap_compression ? 1 : 0); /* Support compression */
out_uint16(s, 0); /* Unknown */
out_uint16_le(s, 1); /* Unknown */
out_uint16(s, 0); /* Pad */
out_uint16_le(s, g_server_depth); /* preferredBitsPerPixel */
out_uint16_le(s, 1); /* receive1BitPerPixel (ignored, should be 1) */
out_uint16_le(s, 1); /* receive4BitPerPixel (ignored, should be 1) */
out_uint16_le(s, 1); /* receive8BitPerPixel (ignored, should be 1) */
out_uint16_le(s, 800); /* desktopWidth */
out_uint16_le(s, 600); /* desktopHeight */
out_uint16_le(s, 0); /* pad2Octets */
out_uint16_le(s, 1); /* desktopResizeFlag */
out_uint16_le(s, 1); /* bitmapCompressionFlag (must be 1) */
out_uint8(s, 0); /* highColorFlags (ignored, should be 0) */
out_uint8(s, 0); /* drawingFlags */
out_uint16_le(s, 1); /* multipleRectangleSupport (must be 1) */
out_uint16_le(s, 0); /* pad2OctetsB */
}
/* Output order capability set */
static void
rdp_out_order_caps(STREAM s)
rdp_out_ts_order_capabilityset(STREAM s)
{
uint8 order_caps[32];
uint16 orderflags = 0;
uint32 cachesize = 0;
orderflags |= (NEGOTIATEORDERSUPPORT | ZEROBOUNDSDELTASSUPPORT); /* mandatory flags */
orderflags |= COLORINDEXSUPPORT;
memset(order_caps, 0, 32);
order_caps[0] = 1; /* dest blt */
order_caps[1] = 1; /* pat blt */
order_caps[2] = 1; /* screen blt */
order_caps[3] = (g_bitmap_cache ? 1 : 0); /* memblt */
order_caps[4] = 0; /* triblt */
order_caps[8] = 1; /* line */
order_caps[9] = 1; /* line */
order_caps[10] = 1; /* rect */
order_caps[11] = (g_desktop_save ? 1 : 0); /* desksave */
order_caps[13] = 1; /* memblt */
order_caps[14] = 1; /* triblt */
order_caps[20] = (g_polygon_ellipse_orders ? 1 : 0); /* polygon */
order_caps[21] = (g_polygon_ellipse_orders ? 1 : 0); /* polygon2 */
order_caps[22] = 1; /* polyline */
order_caps[25] = (g_polygon_ellipse_orders ? 1 : 0); /* ellipse */
order_caps[26] = (g_polygon_ellipse_orders ? 1 : 0); /* ellipse2 */
order_caps[27] = 1; /* text2 */
order_caps[TS_NEG_DSTBLT_INDEX] = 1;
order_caps[TS_NEG_PATBLT_INDEX] = 1;
order_caps[TS_NEG_SCRBLT_INDEX] = 1;
order_caps[TS_NEG_LINETO_INDEX] = 1;
order_caps[TS_NEG_MULTI_DRAWNINEGRID_INDEX] = 1;
order_caps[TS_NEG_POLYLINE_INDEX] = 1;
order_caps[TS_NEG_INDEX_INDEX] = 1;
if (g_bitmap_cache)
order_caps[TS_NEG_MEMBLT_INDEX] = 1;
if (g_desktop_save)
{
cachesize = 230400;
order_caps[TS_NEG_SAVEBITMAP_INDEX] = 1;
}
if (g_polygon_ellipse_orders)
{
order_caps[TS_NEG_POLYGON_SC_INDEX] = 1;
order_caps[TS_NEG_POLYGON_CB_INDEX] = 1;
order_caps[TS_NEG_ELLIPSE_SC_INDEX] = 1;
order_caps[TS_NEG_ELLIPSE_CB_INDEX] = 1;
}
out_uint16_le(s, RDP_CAPSET_ORDER);
out_uint16_le(s, RDP_CAPLEN_ORDER);
out_uint8s(s, 20); /* Terminal desc, pad */
out_uint16_le(s, 1); /* Cache X granularity */
out_uint16_le(s, 20); /* Cache Y granularity */
out_uint16(s, 0); /* Pad */
out_uint16_le(s, 1); /* Max order level */
out_uint16_le(s, 0x147); /* Number of fonts */
out_uint16_le(s, 0x2a); /* Capability flags */
out_uint8p(s, order_caps, 32); /* Orders supported */
out_uint16_le(s, 0x6a1); /* Text capability flags */
out_uint8s(s, 6); /* Pad */
out_uint32_le(s, g_desktop_save == False ? 0 : 0x38400); /* Desktop cache size */
out_uint32(s, 0); /* Unknown */
out_uint32_le(s, 0x4e4); /* Unknown */
out_uint8s(s, 16); /* terminalDescriptor (ignored, should be 0) */
out_uint8s(s, 4); /* pad4OctetsA */
out_uint16_le(s, 1); /* desktopSaveXGranularity (ignored, assumed to be 1) */
out_uint16_le(s, 20); /* desktopSaveYGranularity (ignored, assumed to be 20) */
out_uint16_le(s, 0); /* Pad */
out_uint16_le(s, 1); /* maximumOrderLevel (ignored, should be 1) */
out_uint16_le(s, 0); /* numberFonts (ignored, should be 0) */
out_uint16_le(s, orderflags); /* orderFlags */
out_uint8p(s, order_caps, 32); /* orderSupport */
out_uint16_le(s, 0); /* textFlags (ignored) */
out_uint16_le(s, 0); /* orderSupportExFlags */
out_uint32_le(s, 0); /* pad4OctetsB */
out_uint32_le(s, cachesize); /* desktopSaveSize */
out_uint16_le(s, 0); /* pad2OctetsC */
out_uint16_le(s, 0); /* pad2OctetsD */
out_uint16_le(s, 1252); /* textANSICodePage */
out_uint16_le(s, 0); /* pad2OctetsE */
}
/* Output bitmap cache capability set */
@ -836,41 +856,82 @@ rdp_out_brushcache_caps(STREAM s)
out_uint32_le(s, 1); /* cache type */
}
static uint8 caps_0x0d[] = {
0x01, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00,
0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00
};
static uint8 caps_0x0c[] = { 0x01, 0x00, 0x00, 0x00 };
static uint8 caps_0x0e[] = { 0x01, 0x00, 0x00, 0x00 };
static uint8 caps_0x10[] = {
0xFE, 0x00, 0x04, 0x00, 0xFE, 0x00, 0x04, 0x00,
0xFE, 0x00, 0x08, 0x00, 0xFE, 0x00, 0x08, 0x00,
0xFE, 0x00, 0x10, 0x00, 0xFE, 0x00, 0x20, 0x00,
0xFE, 0x00, 0x40, 0x00, 0xFE, 0x00, 0x80, 0x00,
0xFE, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x08,
0x00, 0x01, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00
};
/* Output unknown capability sets */
/* Output Input Capability Set */
static void
rdp_out_unknown_caps(STREAM s, uint16 id, uint16 length, uint8 * caps)
rdp_out_ts_input_capabilityset(STREAM s)
{
out_uint16_le(s, id);
out_uint16_le(s, length);
uint16 inputflags = 0;
inputflags |= INPUT_FLAG_SCANCODES;
out_uint8p(s, caps, length - 4);
out_uint16_le(s, RDP_CAPSET_INPUT);
out_uint16_le(s, RDP_CAPLEN_INPUT);
out_uint16_le(s, inputflags); /* inputFlags */
out_uint16_le(s, 0); /* pad2OctetsA */
out_uint32_le(s, 0x409); /* keyboardLayout */
out_uint32_le(s, 0x4); /* keyboardType */
out_uint32_le(s, 0); /* keyboardSubtype */
out_uint32_le(s, 0xC); /* keyboardFunctionKey */
out_utf16s_padded(s, "", 64, 0); /* imeFileName */
}
/* Output Sound Capability Set */
static void
rdp_out_ts_sound_capabilityset(STREAM s)
{
uint16 soundflags = SOUND_BEEPS_FLAG;
out_uint16_le(s, RDP_CAPSET_SOUND);
out_uint16_le(s, RDP_CAPLEN_SOUND);
out_uint16_le(s, soundflags); /* soundFlags */
out_uint16_le(s, 0); /* pad2OctetsA */
}
/* Output Font Capability Set */
static void
rdp_out_ts_font_capabilityset(STREAM s)
{
uint16 flags = FONTSUPPORT_FONTLIST;
out_uint16_le(s, RDP_CAPSET_FONT);
out_uint16_le(s, RDP_CAPLEN_FONT);
out_uint16_le(s, flags); /* fontSupportFlags */
out_uint16_le(s, 0); /* pad2octets */
}
static void
rdp_out_ts_cache_definition(STREAM s, uint16 entries, uint16 maxcellsize)
{
out_uint16_le(s, entries);
out_uint16_le(s, maxcellsize);
}
/* Output Glyph Cache Capability Set */
static void
rdp_out_ts_glyphcache_capabilityset(STREAM s)
{
uint16 supportlvl = GLYPH_SUPPORT_FULL;
uint32 fragcache = 0x01000100;
out_uint16_le(s, RDP_CAPSET_GLYPHCACHE);
out_uint16_le(s, RDP_CAPLEN_GLYPHCACHE);
/* GlyphCache - 10 TS_CACHE_DEFINITION structures */
rdp_out_ts_cache_definition(s, 254, 4);
rdp_out_ts_cache_definition(s, 254, 4);
rdp_out_ts_cache_definition(s, 254, 8);
rdp_out_ts_cache_definition(s, 254, 8);
rdp_out_ts_cache_definition(s, 254, 16);
rdp_out_ts_cache_definition(s, 254, 32);
rdp_out_ts_cache_definition(s, 254, 64);
rdp_out_ts_cache_definition(s, 254, 128);
rdp_out_ts_cache_definition(s, 254, 256);
rdp_out_ts_cache_definition(s, 64, 2048);
out_uint32_le(s, fragcache); /* FragCache */
out_uint16_le(s, supportlvl); /* GlyphSupportLevel */
out_uint16_le(s, 0); /* pad2octets */
}
#define RDP5_FLAG 0x0030
@ -881,11 +942,18 @@ rdp_send_confirm_active(void)
STREAM s;
uint32 sec_flags = g_encryption ? (RDP5_FLAG | SEC_ENCRYPT) : RDP5_FLAG;
uint16 caplen =
RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER +
RDP_CAPLEN_GENERAL +
RDP_CAPLEN_BITMAP +
RDP_CAPLEN_ORDER +
RDP_CAPLEN_COLCACHE +
RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL +
RDP_CAPLEN_ACTIVATE +
RDP_CAPLEN_CONTROL +
RDP_CAPLEN_SHARE +
RDP_CAPLEN_BRUSHCACHE + 0x58 + 0x08 + 0x08 + 0x34 /* unknown caps */ +
RDP_CAPLEN_BRUSHCACHE +
RDP_CAPLEN_INPUT +
RDP_CAPLEN_FONT +
RDP_CAPLEN_SOUND +
RDP_CAPLEN_GLYPHCACHE +
4 /* w2k fix, sessionid */ ;
if (g_rdp_version >= RDP_V5)
@ -914,9 +982,9 @@ rdp_send_confirm_active(void)
out_uint16_le(s, 0xe); /* num_caps */
out_uint8s(s, 2); /* pad */
rdp_out_general_caps(s);
rdp_out_bitmap_caps(s);
rdp_out_order_caps(s);
rdp_out_ts_general_capabilityset(s);
rdp_out_ts_bitmap_capabilityset(s);
rdp_out_ts_order_capabilityset(s);
if (g_rdp_version >= RDP_V5)
{
rdp_out_bmpcache2_caps(s);
@ -933,10 +1001,10 @@ rdp_send_confirm_active(void)
rdp_out_share_caps(s);
rdp_out_brushcache_caps(s);
rdp_out_unknown_caps(s, 0x0d, 0x58, caps_0x0d); /* CAPSTYPE_INPUT */
rdp_out_unknown_caps(s, 0x0c, 0x08, caps_0x0c); /* CAPSTYPE_SOUND */
rdp_out_unknown_caps(s, 0x0e, 0x08, caps_0x0e); /* CAPSTYPE_FONT */
rdp_out_unknown_caps(s, 0x10, 0x34, caps_0x10); /* CAPSTYPE_GLYPHCACHE */
rdp_out_ts_input_capabilityset(s);
rdp_out_ts_sound_capabilityset(s);
rdp_out_ts_font_capabilityset(s);
rdp_out_ts_glyphcache_capabilityset(s);
s_mark_end(s);
sec_send(s, sec_flags);
@ -1139,19 +1207,26 @@ process_cached_pointer_pdu(STREAM s)
void
process_system_pointer_pdu(STREAM s)
{
uint16 system_pointer_type;
uint32 system_pointer_type;
in_uint32_le(s, system_pointer_type);
in_uint16_le(s, system_pointer_type);
switch (system_pointer_type)
set_system_pointer(system_pointer_type);
}
/* Set a given system pointer */
void
set_system_pointer(uint32 ptr)
{
switch (ptr)
{
case RDP_NULL_POINTER:
case SYSPTR_NULL:
ui_set_null_cursor();
break;
default:
logger(Protocol, Warning,
"process_system_pointer_pdu(), unhandled pointer type 0x%x",
system_pointer_type);
"set_system_pointer(), unhandled pointer type 0x%x",
ptr);
}
}

59
rdp5.c
View File

@ -1,8 +1,9 @@
/* -*- c-basic-offset: 8 -*-
rdesktop: A Remote Desktop Protocol client.
Protocol services - RDP5 short form PDU processing
Protocol services - RDP Fast-Path PDU processing
Copyright (C) Matthew Chapman <matthewc.unsw.edu.au> 1999-2008
Copyright 2003-2008 Erik Forsberg <forsberg@cendio.se> for Cendio AB
Copyright 2017 Karl Mikaelsson <derfian@cendio.se> for Cendio AB
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -25,10 +26,10 @@ extern uint8 *g_next_packet;
extern RDPCOMP g_mppc_dict;
void
rdp5_process(STREAM s)
process_ts_fp_updates(STREAM s)
{
uint16 length, count, x, y;
uint8 type, ctype;
uint8 hdr, code, frag, comp, ctype = 0;
uint8 *next;
uint32 roff, rlen;
@ -38,25 +39,24 @@ rdp5_process(STREAM s)
ui_begin_update();
while (s->p < s->end)
{
in_uint8(s, type);
if (type & RDP5_COMPRESSED)
{
in_uint8(s, ctype);
in_uint16_le(s, length);
type ^= RDP5_COMPRESSED;
}
else
{
ctype = 0;
in_uint16_le(s, length);
}
/* Reading a number of TS_FP_UPDATE structures from the stream here.. */
in_uint8(s, hdr); /* updateHeader */
code = hdr & 0x0F; /* |- updateCode */
frag = hdr & 0x30; /* |- fragmentation */
comp = hdr & 0xC0; /* `- compression */
if (comp & FASTPATH_OUTPUT_COMPRESSION_USED)
in_uint8(s, ctype); /* compressionFlags */
in_uint16_le(s, length); /* length */
g_next_packet = next = s->p + length;
if (ctype & RDP_MPPC_COMPRESSED)
{
if (mppc_expand(s->p, length, ctype, &roff, &rlen) == -1)
logger(Protocol, Error,
"rdp5_process(), error while decompressing packet");
"process_ts_fp_update_pdu(), error while decompressing packet");
/* allocate memory and copy the uncompressed data into the temporary stream */
ns->data = (uint8 *) xrealloc(ns->data, rlen);
@ -73,45 +73,46 @@ rdp5_process(STREAM s)
else
ts = s;
switch (type)
switch (code)
{
case 0: /* update orders */
case FASTPATH_UPDATETYPE_ORDERS:
in_uint16_le(ts, count);
process_orders(ts, count);
break;
case 1: /* update bitmap */
case FASTPATH_UPDATETYPE_BITMAP:
in_uint8s(ts, 2); /* part length */
process_bitmap_updates(ts);
break;
case 2: /* update palette */
case FASTPATH_UPDATETYPE_PALETTE:
in_uint8s(ts, 2); /* uint16 = 2 */
process_palette(ts);
break;
case 3: /* update synchronize */
case FASTPATH_UPDATETYPE_SYNCHRONIZE:
break;
case 5: /* null pointer */
case FASTPATH_UPDATETYPE_PTR_NULL:
ui_set_null_cursor();
break;
case 6: /* default pointer */
case FASTPATH_UPDATETYPE_PTR_DEFAULT:
set_system_pointer(SYSPTR_DEFAULT);
break;
case 8: /* pointer position */
case FASTPATH_UPDATETYPE_PTR_POSITION:
in_uint16_le(ts, x);
in_uint16_le(ts, y);
if (s_check(ts))
ui_move_pointer(x, y);
break;
case 9: /* color pointer */
case FASTPATH_UPDATETYPE_COLOR:
process_colour_pointer_pdu(ts);
break;
case 10: /* cached pointer */
case FASTPATH_UPDATETYPE_CACHED:
process_cached_pointer_pdu(ts);
break;
case 11:
case FASTPATH_UPDATETYPE_POINTER:
process_new_pointer_pdu(ts);
break;
default:
logger(Protocol, Warning, "rdp5_process(), unhandled opcode %d",
type);
logger(Protocol, Warning, "process_ts_fp_updates(), unhandled opcode %d",
code);
}
s->p = next;