--- /dev/null
+/*
+ rdesktop: A Remote Desktop Protocol client.
+ Miscellaneous protocol constants
+ Copyright (C) Matthew Chapman 1999-2002
+
+ 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
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/* TCP port for Remote Desktop Protocol */
+#define TCP_PORT_RDP 3389
+
+/* ISO PDU codes */
+enum ISO_PDU_CODE
+{
+ ISO_PDU_CR = 0xE0, /* Connection Request */
+ ISO_PDU_CC = 0xD0, /* Connection Confirm */
+ ISO_PDU_DR = 0x80, /* Disconnect Request */
+ ISO_PDU_DT = 0xF0, /* Data */
+ ISO_PDU_ER = 0x70 /* Error */
+};
+
+/* MCS PDU codes */
+enum MCS_PDU_TYPE
+{
+ MCS_EDRQ = 1, /* Erect Domain Request */
+ MCS_DPUM = 8, /* Disconnect Provider Ultimatum */
+ MCS_AURQ = 10, /* Attach User Request */
+ MCS_AUCF = 11, /* Attach User Confirm */
+ MCS_CJRQ = 14, /* Channel Join Request */
+ MCS_CJCF = 15, /* Channel Join Confirm */
+ MCS_SDRQ = 25, /* Send Data Request */
+ MCS_SDIN = 26 /* Send Data Indication */
+};
+
+#define MCS_CONNECT_INITIAL 0x7f65
+#define MCS_CONNECT_RESPONSE 0x7f66
+
+#define BER_TAG_BOOLEAN 1
+#define BER_TAG_INTEGER 2
+#define BER_TAG_OCTET_STRING 4
+#define BER_TAG_RESULT 10
+#define MCS_TAG_DOMAIN_PARAMS 0x30
+
+#define MCS_GLOBAL_CHANNEL 1003
+#define MCS_USERCHANNEL_BASE 1001
+
+/* RDP secure transport constants */
+#define SEC_RANDOM_SIZE 32
+#define SEC_MODULUS_SIZE 64
+#define SEC_PADDING_SIZE 8
+#define SEC_EXPONENT_SIZE 4
+
+#define SEC_CLIENT_RANDOM 0x0001
+#define SEC_ENCRYPT 0x0008
+#define SEC_LOGON_INFO 0x0040
+#define SEC_LICENCE_NEG 0x0080
+
+#define SEC_TAG_SRV_INFO 0x0c01
+#define SEC_TAG_SRV_CRYPT 0x0c02
+#define SEC_TAG_SRV_CHANNELS 0x0c03
+
+#define SEC_TAG_CLI_INFO 0xc001
+#define SEC_TAG_CLI_CRYPT 0xc002
+#define SEC_TAG_CLI_CHANNELS 0xc003
+#define SEC_TAG_CLI_4 0xc004
+
+#define SEC_TAG_PUBKEY 0x0006
+#define SEC_TAG_KEYSIG 0x0008
+
+#define SEC_RSA_MAGIC 0x31415352 /* RSA1 */
+
+/* RDP licensing constants */
+#define LICENCE_TOKEN_SIZE 10
+#define LICENCE_HWID_SIZE 20
+#define LICENCE_SIGNATURE_SIZE 16
+
+#define LICENCE_TAG_DEMAND 0x01
+#define LICENCE_TAG_AUTHREQ 0x02
+#define LICENCE_TAG_ISSUE 0x03
+#define LICENCE_TAG_REISSUE 0x04
+#define LICENCE_TAG_PRESENT 0x12
+#define LICENCE_TAG_REQUEST 0x13
+#define LICENCE_TAG_AUTHRESP 0x15
+#define LICENCE_TAG_RESULT 0xff
+
+#define LICENCE_TAG_USER 0x000f
+#define LICENCE_TAG_HOST 0x0010
+
+/* RDP PDU codes */
+enum RDP_PDU_TYPE
+{
+ RDP_PDU_DEMAND_ACTIVE = 1,
+ RDP_PDU_CONFIRM_ACTIVE = 3,
+ RDP_PDU_DEACTIVATE = 6,
+ RDP_PDU_DATA = 7
+};
+
+enum RDP_DATA_PDU_TYPE
+{
+ RDP_DATA_PDU_UPDATE = 2,
+ RDP_DATA_PDU_CONTROL = 20,
+ RDP_DATA_PDU_POINTER = 27,
+ RDP_DATA_PDU_INPUT = 28,
+ RDP_DATA_PDU_SYNCHRONISE = 31,
+ RDP_DATA_PDU_BELL = 34,
+ RDP_DATA_PDU_LOGON = 38,
+ RDP_DATA_PDU_FONT2 = 39,
+ RDP_DATA_PDU_DISCONNECT = 47
+};
+
+enum RDP_CONTROL_PDU_TYPE
+{
+ RDP_CTL_REQUEST_CONTROL = 1,
+ RDP_CTL_GRANT_CONTROL = 2,
+ RDP_CTL_DETACH = 3,
+ RDP_CTL_COOPERATE = 4
+};
+
+enum RDP_UPDATE_PDU_TYPE
+{
+ RDP_UPDATE_ORDERS = 0,
+ RDP_UPDATE_BITMAP = 1,
+ RDP_UPDATE_PALETTE = 2,
+ RDP_UPDATE_SYNCHRONIZE = 3
+};
+
+enum RDP_POINTER_PDU_TYPE
+{
+ RDP_POINTER_SYSTEM = 1,
+ RDP_POINTER_MOVE = 3,
+ RDP_POINTER_COLOR = 6,
+ RDP_POINTER_CACHED = 7
+};
+
+enum RDP_SYSTEM_POINTER_TYPE
+{
+ RDP_NULL_POINTER = 0,
+ RDP_DEFAULT_POINTER = 0x7F00
+};
+
+enum RDP_INPUT_DEVICE
+{
+ RDP_INPUT_SYNCHRONIZE = 0,
+ RDP_INPUT_CODEPOINT = 1,
+ RDP_INPUT_VIRTKEY = 2,
+ RDP_INPUT_SCANCODE = 4,
+ RDP_INPUT_MOUSE = 0x8001
+};
+
+/* Device flags */
+#define KBD_FLAG_RIGHT 0x0001
+#define KBD_FLAG_EXT 0x0100
+#define KBD_FLAG_QUIET 0x1000
+#define KBD_FLAG_DOWN 0x4000
+#define KBD_FLAG_UP 0x8000
+
+/* These are for synchronization; not for keystrokes */
+#define KBD_FLAG_SCROLL 0x0001
+#define KBD_FLAG_NUMLOCK 0x0002
+#define KBD_FLAG_CAPITAL 0x0004
+
+/* See T.128 */
+#define RDP_KEYPRESS 0
+#define RDP_KEYRELEASE (KBD_FLAG_DOWN | KBD_FLAG_UP)
+
+#define MOUSE_FLAG_MOVE 0x0800
+#define MOUSE_FLAG_BUTTON1 0x1000
+#define MOUSE_FLAG_BUTTON2 0x2000
+#define MOUSE_FLAG_BUTTON3 0x4000
+#define MOUSE_FLAG_BUTTON4 0x0280
+#define MOUSE_FLAG_BUTTON5 0x0380
+#define MOUSE_FLAG_DOWN 0x8000
+
+/* Raster operation masks */
+#define ROP2_S(rop3) (rop3 & 0xf)
+#define ROP2_P(rop3) ((rop3 & 0x3) | ((rop3 & 0x30) >> 2))
+
+#define ROP2_COPY 0xc
+#define ROP2_XOR 0x6
+#define ROP2_AND 0x8
+#define ROP2_NXOR 0x9
+#define ROP2_OR 0xe
+
+#define MIX_TRANSPARENT 0
+#define MIX_OPAQUE 1
+
+#define TEXT2_VERTICAL 0x04
+#define TEXT2_IMPLICIT_X 0x20
+
+/* RDP capabilities */
+#define RDP_CAPSET_GENERAL 1 /* Maps to generalCapabilitySet in T.128 page 138 */
+#define RDP_CAPLEN_GENERAL 0x18
+#define OS_MAJOR_TYPE_UNIX 4
+#define OS_MINOR_TYPE_XSERVER 7
+
+#define RDP_CAPSET_BITMAP 2
+#define RDP_CAPLEN_BITMAP 0x1C
+
+#define RDP_CAPSET_ORDER 3
+#define RDP_CAPLEN_ORDER 0x58
+#define ORDER_CAP_NEGOTIATE 2
+#define ORDER_CAP_NOSUPPORT 4
+
+#define RDP_CAPSET_BMPCACHE 4
+#define RDP_CAPLEN_BMPCACHE 0x28
+
+#define RDP_CAPSET_CONTROL 5
+#define RDP_CAPLEN_CONTROL 0x0C
+
+#define RDP_CAPSET_ACTIVATE 7
+#define RDP_CAPLEN_ACTIVATE 0x0C
+
+#define RDP_CAPSET_POINTER 8
+#define RDP_CAPLEN_POINTER 0x08
+
+#define RDP_CAPSET_SHARE 9
+#define RDP_CAPLEN_SHARE 0x08
+
+#define RDP_CAPSET_COLCACHE 10
+#define RDP_CAPLEN_COLCACHE 0x08
+
+#define RDP_CAPSET_UNKNOWN 13
+#define RDP_CAPLEN_UNKNOWN 0x9C
+
+#define RDP_SOURCE "MSTSC"
+
+/* Logon flags */
+#define RDP_LOGON_NORMAL 0x33
+#define RDP_LOGON_AUTO 0x8
+#define RDP_LOGON_BLOB 0x100
+
+/* Keymap flags */
+#define MapRightShiftMask (1<<0)
+#define MapLeftShiftMask (1<<1)
+#define MapShiftMask (MapRightShiftMask | MapLeftShiftMask)
+
+#define MapRightAltMask (1<<2)
+#define MapLeftAltMask (1<<3)
+#define MapAltGrMask MapRightAltMask
+
+#define MapRightCtrlMask (1<<4)
+#define MapLeftCtrlMask (1<<5)
+#define MapCtrlMask (MapRightCtrlMask | MapLeftCtrlMask)
+
+#define MapRightWinMask (1<<6)
+#define MapLeftWinMask (1<<7)
+#define MapWinMask (MapRightWinMask | MapLeftWinMask)
+
+#define MapNumLockMask (1<<8)
+#define MapCapsLockMask (1<<9)
+
+#define MapLocalStateMask (1<<10)
+
+#define MapInhibitMask (1<<11)
+
+#define MASK_ADD_BITS(var, mask) (var |= mask)
+#define MASK_REMOVE_BITS(var, mask) (var &= ~mask)
+#define MASK_HAS_BITS(var, mask) ((var & mask)>0)
+#define MASK_CHANGE_BIT(var, mask, active) (var = ((var & ~mask) | (active ? mask : 0)))
+
+/* Clipboard constants, "borrowed" from GCC system headers in
+ the w32 cross compiler */
+
+#define CF_TEXT 1
+#define CF_BITMAP 2
+#define CF_METAFILEPICT 3
+#define CF_SYLK 4
+#define CF_DIF 5
+#define CF_TIFF 6
+#define CF_OEMTEXT 7
+#define CF_DIB 8
+#define CF_PALETTE 9
+#define CF_PENDATA 10
+#define CF_RIFF 11
+#define CF_WAVE 12
+#define CF_UNICODETEXT 13
+#define CF_ENHMETAFILE 14
+#define CF_HDROP 15
+#define CF_LOCALE 16
+#define CF_MAX 17
+#define CF_OWNERDISPLAY 128
+#define CF_DSPTEXT 129
+#define CF_DSPBITMAP 130
+#define CF_DSPMETAFILEPICT 131
+#define CF_DSPENHMETAFILE 142
+#define CF_PRIVATEFIRST 512
+#define CF_PRIVATELAST 767
+#define CF_GDIOBJFIRST 768
+#define CF_GDIOBJLAST 1023
+
+/* Sound format constants */
+#define WAVE_FORMAT_PCM 1
+#define WAVE_FORMAT_ADPCM 2
+#define WAVE_FORMAT_ALAW 6
+#define WAVE_FORMAT_MULAW 7
+
+/* Virtual channel options */
+#define CHANNEL_OPTION_INITIALIZED 0x80000000
+#define CHANNEL_OPTION_ENCRYPT_RDP 0x40000000
+#define CHANNEL_OPTION_COMPRESS_RDP 0x00800000
+#define CHANNEL_OPTION_SHOW_PROTOCOL 0x00200000
+
+/* NT status codes for RDPDR */
+#define STATUS_SUCCESS 0x00000000
+#define STATUS_INVALID_PARAMETER 0xc000000d
+#define STATUS_INVALID_DEVICE_REQUEST 0xc0000010
+#define STATUS_ACCESS_DENIED 0xc0000022
--- /dev/null
+/*
+ rdesktop: A Remote Desktop Protocol client.
+ Parsing primitives
+ Copyright (C) Matthew Chapman 1999-2002
+
+ 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
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/* Parser state */
+typedef struct stream
+{
+ unsigned char *p;
+ unsigned char *end;
+ unsigned char *data;
+ unsigned int size;
+
+ /* Offsets of various headers */
+ unsigned char *iso_hdr;
+ unsigned char *mcs_hdr;
+ unsigned char *sec_hdr;
+ unsigned char *rdp_hdr;
+ unsigned char *channel_hdr;
+
+}
+ *STREAM;
+
+#define s_push_layer(s,h,n) { (s)->h = (s)->p; (s)->p += n; }
+#define s_pop_layer(s,h) (s)->p = (s)->h;
+#define s_mark_end(s) (s)->end = (s)->p;
+#define s_check(s) ((s)->p <= (s)->end)
+#define s_check_rem(s,n) ((s)->p + n <= (s)->end)
+#define s_check_end(s) ((s)->p == (s)->end)
+
+#if defined(L_ENDIAN) && !defined(NEED_ALIGN)
+#define in_uint16_le(s,v) { v = *(uint16 *)((s)->p); (s)->p += 2; }
+#define in_uint32_le(s,v) { v = *(uint32 *)((s)->p); (s)->p += 4; }
+#define out_uint16_le(s,v) { *(uint16 *)((s)->p) = v; (s)->p += 2; }
+#define out_uint32_le(s,v) { *(uint32 *)((s)->p) = v; (s)->p += 4; }
+
+#else
+#define in_uint16_le(s,v) { v = *((s)->p++); v += *((s)->p++) << 8; }
+#define in_uint32_le(s,v) { in_uint16_le(s,v) \
+ v += *((s)->p++) << 16; v += *((s)->p++) << 24; }
+#define out_uint16_le(s,v) { *((s)->p++) = (v) & 0xff; *((s)->p++) = ((v) >> 8) & 0xff; }
+#define out_uint32_le(s,v) { out_uint16_le(s, (v) & 0xffff); out_uint16_le(s, ((v) >> 16) & 0xffff); }
+#endif
+
+#if defined(B_ENDIAN) && !defined(NEED_ALIGN)
+#define in_uint16_be(s,v) { v = *(uint16 *)((s)->p); (s)->p += 2; }
+#define in_uint32_be(s,v) { v = *(uint32 *)((s)->p); (s)->p += 4; }
+#define out_uint16_be(s,v) { *(uint16 *)((s)->p) = v; (s)->p += 2; }
+#define out_uint32_be(s,v) { *(uint32 *)((s)->p) = v; (s)->p += 4; }
+
+#define B_ENDIAN_PREFERRED
+#define in_uint16(s,v) in_uint16_be(s,v)
+#define in_uint32(s,v) in_uint32_be(s,v)
+#define out_uint16(s,v) out_uint16_be(s,v)
+#define out_uint32(s,v) out_uint32_be(s,v)
+
+#else
+#define next_be(s,v) v = ((v) << 8) + *((s)->p++);
+#define in_uint16_be(s,v) { v = *((s)->p++); next_be(s,v); }
+#define in_uint32_be(s,v) { in_uint16_be(s,v); next_be(s,v); next_be(s,v); }
+#define out_uint16_be(s,v) { *((s)->p++) = ((v) >> 8) & 0xff; *((s)->p++) = (v) & 0xff; }
+#define out_uint32_be(s,v) { out_uint16_be(s, ((v) >> 16) & 0xffff); out_uint16_be(s, (v) & 0xffff); }
+#endif
+
+#ifndef B_ENDIAN_PREFERRED
+#define in_uint16(s,v) in_uint16_le(s,v)
+#define in_uint32(s,v) in_uint32_le(s,v)
+#define out_uint16(s,v) out_uint16_le(s,v)
+#define out_uint32(s,v) out_uint32_le(s,v)
+#endif
+
+#define in_uint8(s,v) v = *((s)->p++);
+#define in_uint8p(s,v,n) { v = (s)->p; (s)->p += n; }
+#define in_uint8a(s,v,n) { memcpy(v,(s)->p,n); (s)->p += n; }
+#define in_uint8s(s,n) (s)->p += n;
+#define out_uint8(s,v) *((s)->p++) = v;
+#define out_uint8p(s,v,n) { memcpy((s)->p,v,n); (s)->p += n; }
+#define out_uint8a(s,v,n) out_uint8p(s,v,n);
+#define out_uint8s(s,n) { memset((s)->p,0,n); (s)->p += n; }
--- /dev/null
+/* bitmap.c */
+BOOL bitmap_decompress(unsigned char *output, int width, int height, unsigned char *input, int size,
+ int Bpp);
+/* cache.c */
+HBITMAP cache_get_bitmap(uint8 cache_id, uint16 cache_idx);
+void cache_put_bitmap(uint8 cache_id, uint16 cache_idx, HBITMAP bitmap);
+FONTGLYPH *cache_get_font(uint8 font, uint16 character);
+void cache_put_font(uint8 font, uint16 character, uint16 offset, uint16 baseline, uint16 width,
+ uint16 height, HGLYPH pixmap);
+DATABLOB *cache_get_text(uint8 cache_id);
+void cache_put_text(uint8 cache_id, void *data, int length);
+uint8 *cache_get_desktop(uint32 offset, int cx, int cy, int bytes_per_pixel);
+void cache_put_desktop(uint32 offset, int cx, int cy, int scanline, int bytes_per_pixel,
+ uint8 * data);
+HCURSOR cache_get_cursor(uint16 cache_idx);
+void cache_put_cursor(uint16 cache_idx, HCURSOR cursor);
+/* channels.c */
+VCHANNEL *channel_register(char *name, uint32 flags, void (*callback) (STREAM));
+STREAM channel_init(VCHANNEL * channel, uint32 length);
+void channel_send(STREAM s, VCHANNEL * channel);
+void channel_process(STREAM s, uint16 mcs_channel);
+/* cliprdr.c */
+void cliprdr_send_text_format_announce(void);
+void cliprdr_send_blah_format_announce(void);
+void cliprdr_send_native_format_announce(uint8 * data, uint32 length);
+void cliprdr_send_data_request(uint32 format);
+void cliprdr_send_data(uint8 * data, uint32 length);
+BOOL cliprdr_init(void);
+/* ewmhints.c */
+int get_current_workarea(uint32 * x, uint32 * y, uint32 * width, uint32 * height);
+/* iso.c */
+STREAM iso_init(int length);
+void iso_send(STREAM s);
+STREAM iso_recv(void);
+BOOL iso_connect(char *server, char *username);
+void iso_disconnect(void);
+/* licence.c */
+void licence_process(STREAM s);
+/* mcs.c */
+STREAM mcs_init(int length);
+void mcs_send_to_channel(STREAM s, uint16 channel);
+void mcs_send(STREAM s);
+STREAM mcs_recv(uint16 * channel);
+BOOL mcs_connect(char *server, STREAM mcs_data, char *username);
+void mcs_disconnect(void);
+/* orders.c */
+void process_orders(STREAM s, uint16 num_orders);
+void reset_order_state(void);
+/* printer.c */
+/* rdesktop.c */
+int main(int argc, char *argv[]);
+void generate_random(uint8 * random);
+void *xmalloc(int size);
+void *xrealloc(void *oldmem, int size);
+void xfree(void *mem);
+void error(char *format, ...);
+void warning(char *format, ...);
+void unimpl(char *format, ...);
+void hexdump(unsigned char *p, int len);
+int load_licence(unsigned char **data);
+void save_licence(unsigned char *data, int length);
+/* rdp5.c */
+void rdp5_process(STREAM s, BOOL encryption);
+/* rdp.c */
+void rdp_out_unistr(STREAM s, char *string, int len);
+void rdp_send_input(uint32 time, uint16 message_type, uint16 device_flags, uint16 param1,
+ uint16 param2);
+void process_colour_pointer_pdu(STREAM s);
+void process_cached_pointer_pdu(STREAM s);
+void process_system_pointer_pdu(STREAM s);
+void process_bitmap_updates(STREAM s);
+void process_palette(STREAM s);
+BOOL rdp_main_loop(void);
+BOOL rdp_connect(char *server, uint32 flags, char *domain, char *password, char *command,
+ char *directory);
+void rdp_disconnect(void);
+/* rdpdr.c */
+void rdpdr_send_connect(void);
+void rdpdr_send_name(void);
+void rdpdr_send_available(void);
+void rdpdr_send_completion(uint32 device, uint32 id, uint32 status, uint32 result, uint8 * buffer,
+ uint32 length);
+BOOL rdpdr_init(void);
+/* rdpsnd.c */
+STREAM rdpsnd_init_packet(uint16 type, uint16 size);
+void rdpsnd_send(STREAM s);
+void rdpsnd_send_completion(uint16 tick, uint8 packet_index);
+void rdpsnd_process_negotiate(STREAM in);
+void rdpsnd_process_unknown6(STREAM in);
+void rdpsnd_process(STREAM s);
+BOOL rdpsnd_init(void);
+/* rdpsnd_oss.c */
+BOOL wave_out_open(void);
+void wave_out_close(void);
+BOOL wave_out_format_supported(WAVEFORMATEX * pwfx);
+BOOL wave_out_set_format(WAVEFORMATEX * pwfx);
+void wave_out_volume(uint16 left, uint16 right);
+void wave_out_write(STREAM s, uint16 tick, uint8 index);
+void wave_out_play(void);
+/* secure.c */
+void sec_hash_48(uint8 * out, uint8 * in, uint8 * salt1, uint8 * salt2, uint8 salt);
+void sec_hash_16(uint8 * out, uint8 * in, uint8 * salt1, uint8 * salt2);
+void buf_out_uint32(uint8 * buffer, uint32 value);
+void sec_sign(uint8 * signature, int siglen, uint8 * session_key, int keylen, uint8 * data,
+ int datalen);
+void sec_decrypt(uint8 * data, int length);
+STREAM sec_init(uint32 flags, int maxlen);
+void sec_send_to_channel(STREAM s, uint32 flags, uint16 channel);
+void sec_send(STREAM s, uint32 flags);
+void sec_process_mcs_data(STREAM s);
+STREAM sec_recv(void);
+BOOL sec_connect(char *server, char *username);
+void sec_disconnect(void);
+/* serial.c */
+/* tcp.c */
+STREAM tcp_init(uint32 maxlen);
+void tcp_send(STREAM s);
+STREAM tcp_recv(STREAM s, uint32 length);
+BOOL tcp_connect(char *server);
+void tcp_disconnect(void);
+/* xclip.c */
+void ui_clip_format_announce(uint8 * data, uint32 length);
+void ui_clip_handle_data(uint8 * data, uint32 length);
+void ui_clip_request_data(uint32 format);
+void ui_clip_sync(void);
+void xclip_init(void);
+/* xkeymap.c */
+void xkeymap_init(void);
+BOOL handle_special_keys(uint32 keysym, unsigned int state, uint32 ev_time, BOOL pressed);
+key_translation xkeymap_translate_key(uint32 keysym, unsigned int keycode, unsigned int state);
+uint16 xkeymap_translate_button(unsigned int button);
+char *get_ksname(uint32 keysym);
+void save_remote_modifiers(uint8 scancode);
+void restore_remote_modifiers(uint32 ev_time, uint8 scancode);
+void ensure_remote_modifiers(uint32 ev_time, key_translation tr);
+unsigned int read_keyboard_state(void);
+uint16 ui_get_numlock_state(unsigned int state);
+void reset_modifier_keys(void);
+void rdp_send_scancode(uint32 time, uint16 flags, uint8 scancode);
+/* xwin.c */
+BOOL get_key_state(unsigned int state, uint32 keysym);
+BOOL ui_init(void);
+void ui_deinit(void);
+BOOL ui_create_window(void);
+void ui_destroy_window(void);
+void xwin_toggle_fullscreen(void);
+int ui_select(int rdp_socket);
+void ui_move_pointer(int x, int y);
+HBITMAP ui_create_bitmap(int width, int height, uint8 * data);
+void ui_paint_bitmap(int x, int y, int cx, int cy, int width, int height, uint8 * data);
+void ui_destroy_bitmap(HBITMAP bmp);
+HGLYPH ui_create_glyph(int width, int height, uint8 * data);
+void ui_destroy_glyph(HGLYPH glyph);
+HCURSOR ui_create_cursor(unsigned int x, unsigned int y, int width, int height, uint8 * andmask,
+ uint8 * xormask);
+void ui_set_cursor(HCURSOR cursor);
+void ui_destroy_cursor(HCURSOR cursor);
+void ui_set_null_cursor(void);
+HCOLOURMAP ui_create_colourmap(COLOURMAP * colours);
+void ui_destroy_colourmap(HCOLOURMAP map);
+void ui_set_colourmap(HCOLOURMAP map);
+void ui_set_clip(int x, int y, int cx, int cy);
+void ui_reset_clip(void);
+void ui_bell(void);
+void ui_destblt(uint8 opcode, int x, int y, int cx, int cy);
+void ui_patblt(uint8 opcode, int x, int y, int cx, int cy, BRUSH * brush, int bgcolour,
+ int fgcolour);
+void ui_screenblt(uint8 opcode, int x, int y, int cx, int cy, int srcx, int srcy);
+void ui_memblt(uint8 opcode, int x, int y, int cx, int cy, HBITMAP src, int srcx, int srcy);
+void ui_triblt(uint8 opcode, int x, int y, int cx, int cy, HBITMAP src, int srcx, int srcy,
+ BRUSH * brush, int bgcolour, int fgcolour);
+void ui_line(uint8 opcode, int startx, int starty, int endx, int endy, PEN * pen);
+void ui_rect(int x, int y, int cx, int cy, int colour);
+void ui_draw_glyph(int mixmode, int x, int y, int cx, int cy, HGLYPH glyph, int srcx, int srcy,
+ int bgcolour, int fgcolour);
+void ui_draw_text(uint8 font, uint8 flags, int mixmode, int x, int y, int clipx, int clipy,
+ int clipcx, int clipcy, int boxx, int boxy, int boxcx, int boxcy, int bgcolour,
+ int fgcolour, uint8 * text, uint8 length);
+void ui_desktop_save(uint32 offset, int x, int y, int cx, int cy);
+void ui_desktop_restore(uint32 offset, int x, int y, int cx, int cy);
--- /dev/null
+/*
+ rdesktop: A Remote Desktop Protocol client.
+ Master include file
+ Copyright (C) Matthew Chapman 1999-2004
+
+ 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
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#define VERSION "1.3.1"
+
+#define WITH_DEBUG 1
+#define WITH_DEBUG_RDP5 1
+
+#ifdef WITH_DEBUG
+#define DEBUG(args) printf args;
+#else
+#define DEBUG(args)
+#endif
+
+#ifdef WITH_DEBUG_KBD
+#define DEBUG_KBD(args) printf args;
+#else
+#define DEBUG_KBD(args)
+#endif
+
+#ifdef WITH_DEBUG_RDP5
+#define DEBUG_RDP5(args) printf args;
+#else
+#define DEBUG_RDP5(args)
+#endif
+
+#ifdef WITH_DEBUG_CLIPBOARD
+#define DEBUG_CLIPBOARD(args) printf args;
+#else
+#define DEBUG_CLIPBOARD(args)
+#endif
+
+#define STRNCPY(dst,src,n) { strncpy(dst,src,n-1); dst[n-1] = 0; }
+#ifndef MIN
+#define MIN(x,y) (((x) < (y)) ? (x) : (y))
+#endif
+#ifndef MAX
+#define MAX(x,y) (((x) > (y)) ? (x) : (y))
+#endif
+
+#include "parse.h"
+#include "constants.h"
+#include "types.h"
+
+#ifndef MAKE_PROTO
+#include "proto.h"
+#endif
--- /dev/null
+/*
+ rdesktop: A Remote Desktop Protocol client.
+ Protocol services - TCP layer
+ Copyright (C) Matthew Chapman 1999-2002
+
+ 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
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <unistd.h> /* select read write close */
+#include <sys/socket.h> /* socket connect setsockopt */
+#include <sys/time.h> /* timeval */
+#include <netdb.h> /* gethostbyname */
+#include <netinet/in.h> /* sockaddr_in */
+#include <netinet/tcp.h> /* TCP_NODELAY */
+#include <arpa/inet.h> /* inet_addr */
+#include <errno.h> /* errno */
+#include "rdesktop.h"
+
+#ifndef INADDR_NONE
+#define INADDR_NONE ((unsigned long) -1)
+#endif
+
+static int sock;
+static struct stream in;
+static struct stream out;
+extern int tcp_port_rdp;
+
+/* Initialise TCP transport data packet */
+STREAM
+tcp_init(uint32 maxlen)
+{
+ if (maxlen > out.size)
+ {
+ out.data = (uint8 *) xrealloc(out.data, maxlen);
+ out.size = maxlen;
+ }
+
+ out.p = out.data;
+ out.end = out.data + out.size;
+ return &out;
+}
+
+/* Send TCP transport data packet */
+void
+tcp_send(STREAM s)
+{
+ int length = s->end - s->data;
+ int sent, total = 0;
+
+ while (total < length)
+ {
+ sent = send(sock, s->data + total, length - total, 0);
+ if (sent <= 0)
+ {
+ error("send: %s\n", strerror(errno));
+ return;
+ }
+
+ total += sent;
+ }
+}
+
+/* Receive a message on the TCP layer */
+STREAM
+tcp_recv(STREAM s, uint32 length)
+{
+ unsigned int new_length, end_offset, p_offset;
+ int rcvd = 0;
+
+ if (s == NULL)
+ {
+ /* read into "new" stream */
+ if (length > in.size)
+ {
+ in.data = (uint8 *) xrealloc(in.data, length);
+ in.size = length;
+ }
+ in.end = in.p = in.data;
+ s = ∈
+ }
+ else
+ {
+ /* append to existing stream */
+ new_length = (s->end - s->data) + length;
+ if (new_length > s->size)
+ {
+ p_offset = s->p - s->data;
+ end_offset = s->end - s->data;
+ s->data = (uint8 *) xrealloc(s->data, new_length);
+ s->size = new_length;
+ s->p = s->data + p_offset;
+ s->end = s->data + end_offset;
+ }
+ }
+
+ while (length > 0)
+ {
+#if 0
+ if (!ui_select(sock))
+ /* User quit */
+ return NULL;
+#endif
+
+ rcvd = recv(sock, s->end, length, 0);
+ if (rcvd < 0)
+ {
+ error("recv: %s\n", strerror(errno));
+ return NULL;
+ }
+ else if (rcvd == 0)
+ {
+ error("Connection closed\n");
+ return NULL;
+ }
+
+ s->end += rcvd;
+ length -= rcvd;
+ }
+
+ return s;
+}
+
+/* Establish a connection on the TCP layer */
+BOOL
+tcp_connect(char *server)
+{
+ int true_value = 1;
+
+#ifdef IPv6
+
+ int n;
+ struct addrinfo hints, *res, *ressave;
+ char tcp_port_rdp_s[10];
+
+ snprintf(tcp_port_rdp_s, 10, "%d", tcp_port_rdp);
+
+ memset(&hints, 0, sizeof(struct addrinfo));
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+
+ n = getaddrinfo(server, tcp_port_rdp_s, &hints, &res);
+
+ if (n < 0)
+ {
+ error("getaddrinfo: %s\n", gai_strerror(n));
+ return False;
+ }
+
+ ressave = res;
+ sock = -1;
+ while (res)
+ {
+ sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
+ if (!(sock < 0))
+ {
+ if (connect(sock, res->ai_addr, res->ai_addrlen) == 0)
+ break;
+ close(sock);
+ sock = -1;
+ }
+ res = res->ai_next;
+ }
+ freeaddrinfo(ressave);
+
+ if (sock == -1)
+ {
+ error("%s: unable to connect\n", server);
+ return False;
+ }
+
+#else /* no IPv6 support */
+
+ struct hostent *nslookup;
+ struct sockaddr_in servaddr;
+
+ if ((nslookup = gethostbyname(server)) != NULL)
+ {
+ memcpy(&servaddr.sin_addr, nslookup->h_addr, sizeof(servaddr.sin_addr));
+ }
+ else if ((servaddr.sin_addr.s_addr = inet_addr(server)) == INADDR_NONE)
+ {
+ error("%s: unable to resolve host\n", server);
+ return False;
+ }
+
+ if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
+ {
+ error("socket: %s\n", strerror(errno));
+ return False;
+ }
+
+ servaddr.sin_family = AF_INET;
+ servaddr.sin_port = htons(tcp_port_rdp);
+
+ if (connect(sock, (struct sockaddr *) &servaddr, sizeof(struct sockaddr)) < 0)
+ {
+ error("connect: %s\n", strerror(errno));
+ close(sock);
+ return False;
+ }
+
+#endif /* IPv6 */
+
+ setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (void *) &true_value, sizeof(true_value));
+
+ in.size = 4096;
+ in.data = (uint8 *) xmalloc(in.size);
+
+ out.size = 4096;
+ out.data = (uint8 *) xmalloc(out.size);
+
+ return True;
+}
+
+/* Disconnect on the TCP layer */
+void
+tcp_disconnect(void)
+{
+ close(sock);
+}
--- /dev/null
+/*
+ rdesktop: A Remote Desktop Protocol client.
+ Common data types
+ Copyright (C) Matthew Chapman 1999-2002
+
+ 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
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+typedef int BOOL;
+
+#ifndef True
+#define True (1)
+#define False (0)
+#endif
+
+typedef unsigned char uint8;
+typedef signed char sint8;
+typedef unsigned short uint16;
+typedef signed short sint16;
+typedef unsigned int uint32;
+typedef signed int sint32;
+
+typedef void *HBITMAP;
+typedef void *HGLYPH;
+typedef void *HCOLOURMAP;
+typedef void *HCURSOR;
+
+typedef struct _COLOURENTRY
+{
+ uint8 red;
+ uint8 green;
+ uint8 blue;
+
+}
+COLOURENTRY;
+
+typedef struct _COLOURMAP
+{
+ uint16 ncolours;
+ COLOURENTRY *colours;
+
+}
+COLOURMAP;
+
+typedef struct _BOUNDS
+{
+ sint16 left;
+ sint16 top;
+ sint16 right;
+ sint16 bottom;
+
+}
+BOUNDS;
+
+typedef struct _PEN
+{
+ uint8 style;
+ uint8 width;
+ uint32 colour;
+
+}
+PEN;
+
+typedef struct _BRUSH
+{
+ uint8 xorigin;
+ uint8 yorigin;
+ uint8 style;
+ uint8 pattern[8];
+
+}
+BRUSH;
+
+typedef struct _FONTGLYPH
+{
+ sint16 offset;
+ sint16 baseline;
+ uint16 width;
+ uint16 height;
+ HBITMAP pixmap;
+
+}
+FONTGLYPH;
+
+typedef struct _DATABLOB
+{
+ void *data;
+ int size;
+
+}
+DATABLOB;
+
+typedef struct _key_translation
+{
+ uint8 scancode;
+ uint16 modifiers;
+}
+key_translation;
+
+typedef struct _VCHANNEL
+{
+ uint16 mcs_id;
+ char name[8];
+ uint32 flags;
+ struct stream in;
+ void (*process) (STREAM);
+}
+VCHANNEL;
+
+#define MAX_CBSIZE 256
+
+/* RDPSND */
+typedef struct
+{
+ uint16 wFormatTag;
+ uint16 nChannels;
+ uint32 nSamplesPerSec;
+ uint32 nAvgBytesPerSec;
+ uint16 nBlockAlign;
+ uint16 wBitsPerSample;
+ uint16 cbSize;
+ uint8 cb[MAX_CBSIZE];
+} WAVEFORMATEX;
+
+/* RDPDR */
+typedef uint32 NTSTATUS;
+typedef uint32 HANDLE;
+
+typedef struct _DEVICE_FNS
+{
+ NTSTATUS(*create) (HANDLE * handle);
+ NTSTATUS(*close) (HANDLE handle);
+ NTSTATUS(*read) (HANDLE handle, uint8 * data, uint32 length, uint32 * result);
+ NTSTATUS(*write) (HANDLE handle, uint8 * data, uint32 length, uint32 * result);
+ NTSTATUS(*device_control) (HANDLE handle, uint32 request, STREAM in, STREAM out);
+}
+DEVICE_FNS;
--- /dev/null
+/* -*- c-basic-offset: 8 -*-
+ rdesktop: A Remote Desktop Protocol client.
+ Entrypoint and utility functions
+ Copyright (C) Matthew Chapman 1999-2004
+
+ 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
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <stdarg.h> /* va_list va_start va_end */
+#include <unistd.h> /* read close getuid getgid getpid getppid gethostname */
+#include <fcntl.h> /* open */
+#include <pwd.h> /* getpwuid */
+#include <termios.h> /* tcgetattr tcsetattr */
+#include <sys/stat.h> /* stat */
+#include <sys/time.h> /* gettimeofday */
+#include <sys/times.h> /* times */
+#include <errno.h>
+#include <X11/Xlib.h> /* Window */
+#include "rdesktop.h"
+
+#ifdef EGD_SOCKET
+#include <sys/socket.h> /* socket connect */
+#include <sys/un.h> /* sockaddr_un */
+#endif
+
+#include <openssl/md5.h>
+
+#ifdef EGD_SOCKET
+/* Read 32 random bytes from PRNGD or EGD socket (based on OpenSSL RAND_egd) */
+static BOOL
+generate_random_egd(uint8 * buf)
+{
+ struct sockaddr_un addr;
+ BOOL ret = False;
+ int fd;
+
+ fd = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (fd == -1)
+ return False;
+
+ addr.sun_family = AF_UNIX;
+ memcpy(addr.sun_path, EGD_SOCKET, sizeof(EGD_SOCKET));
+ if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) == -1)
+ goto err;
+
+ /* PRNGD and EGD use a simple communications protocol */
+ buf[0] = 1; /* Non-blocking (similar to /dev/urandom) */
+ buf[1] = 32; /* Number of requested random bytes */
+ if (write(fd, buf, 2) != 2)
+ goto err;
+
+ if ((read(fd, buf, 1) != 1) || (buf[0] == 0)) /* Available? */
+ goto err;
+
+ if (read(fd, buf, 32) != 32)
+ goto err;
+
+ ret = True;
+
+ err:
+ close(fd);
+ return ret;
+}
+#endif
+
+/* malloc; exit if out of memory */
+void *
+xmalloc(int size)
+{
+ void *mem = malloc(size);
+ if (mem == NULL)
+ {
+ error("xmalloc %d\n", size);
+ exit(1);
+ }
+ return mem;
+}
+
+/* realloc; exit if out of memory */
+void *
+xrealloc(void *oldmem, int size)
+{
+ void *mem = realloc(oldmem, size);
+ if (mem == NULL)
+ {
+ error("xrealloc %d\n", size);
+ exit(1);
+ }
+ return mem;
+}
+
+/* free */
+void
+xfree(void *mem)
+{
+ free(mem);
+}
+
+/* report an error */
+void
+error(char *format, ...)
+{
+ va_list ap;
+
+ fprintf(stderr, "ERROR: ");
+
+ va_start(ap, format);
+ vfprintf(stderr, format, ap);
+ va_end(ap);
+}
+
+/* report a warning */
+void
+warning(char *format, ...)
+{
+ va_list ap;
+
+ fprintf(stderr, "WARNING: ");
+
+ va_start(ap, format);
+ vfprintf(stderr, format, ap);
+ va_end(ap);
+}
+
+/* report an unimplemented protocol feature */
+void
+unimpl(char *format, ...)
+{
+ va_list ap;
+
+ fprintf(stderr, "NOT IMPLEMENTED: ");
+
+ va_start(ap, format);
+ vfprintf(stderr, format, ap);
+ va_end(ap);
+}
+
+/* produce a hex dump */
+void
+hexdump(unsigned char *p, int len)
+{
+ unsigned char *line = p;
+ int i, thisline, offset = 0;
+
+ while (offset < len)
+ {
+ printf("%04x ", offset);
+ thisline = len - offset;
+ if (thisline > 16)
+ thisline = 16;
+
+ for (i = 0; i < thisline; i++)
+ printf("%02x ", line[i]);
+
+ for (; i < 16; i++)
+ printf(" ");
+
+ for (i = 0; i < thisline; i++)
+ printf("%c", (line[i] >= 0x20 && line[i] < 0x7f) ? line[i] : '.');
+
+ printf("\n");
+ offset += thisline;
+ line += thisline;
+ }
+}
+