]> git.sesse.net Git - rdpsrv/commitdiff
Pull in even more rdesktop source.
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Thu, 3 Feb 2005 22:36:06 +0000 (22:36 +0000)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Thu, 3 Feb 2005 22:36:06 +0000 (22:36 +0000)
constants.h [new file with mode: 0644]
parse.h [new file with mode: 0644]
proto.h [new file with mode: 0644]
rdesktop.h [new file with mode: 0644]
tcp.c [new file with mode: 0644]
types.h [new file with mode: 0644]
util.c [new file with mode: 0644]

diff --git a/constants.h b/constants.h
new file mode 100644 (file)
index 0000000..15b6bb3
--- /dev/null
@@ -0,0 +1,319 @@
+/*
+   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
diff --git a/parse.h b/parse.h
new file mode 100644 (file)
index 0000000..cacea51
--- /dev/null
+++ b/parse.h
@@ -0,0 +1,94 @@
+/*
+   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; }
diff --git a/proto.h b/proto.h
new file mode 100644 (file)
index 0000000..b08a977
--- /dev/null
+++ b/proto.h
@@ -0,0 +1,180 @@
+/* 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);
diff --git a/rdesktop.h b/rdesktop.h
new file mode 100644 (file)
index 0000000..3aa8982
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+   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
diff --git a/tcp.c b/tcp.c
new file mode 100644 (file)
index 0000000..4e11422
--- /dev/null
+++ b/tcp.c
@@ -0,0 +1,232 @@
+/*
+   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 = &in;
+       }
+       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);
+}
diff --git a/types.h b/types.h
new file mode 100644 (file)
index 0000000..ac038e3
--- /dev/null
+++ b/types.h
@@ -0,0 +1,149 @@
+/*
+   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;
diff --git a/util.c b/util.c
new file mode 100644 (file)
index 0000000..2376a61
--- /dev/null
+++ b/util.c
@@ -0,0 +1,178 @@
+/* -*- 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;
+       }
+}
+