a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* -*- c-basic-offset: 8 -*-
a180a41bba1d50822df23fff0099e90b86638b89vboxsync rdesktop: A Remote Desktop Protocol client.
a180a41bba1d50822df23fff0099e90b86638b89vboxsync Protocol services - RDP layer
a180a41bba1d50822df23fff0099e90b86638b89vboxsync Copyright (C) Matthew Chapman <matthewc.unsw.edu.au> 1999-2008
a180a41bba1d50822df23fff0099e90b86638b89vboxsync Copyright 2003-2011 Peter Astrand <astrand@cendio.se> for Cendio AB
a180a41bba1d50822df23fff0099e90b86638b89vboxsync Copyright 2011-2014 Henrik Andersson <hean01@cendio.se> for Cendio AB
a180a41bba1d50822df23fff0099e90b86638b89vboxsync This program is free software: you can redistribute it and/or modify
a180a41bba1d50822df23fff0099e90b86638b89vboxsync it under the terms of the GNU General Public License as published by
a180a41bba1d50822df23fff0099e90b86638b89vboxsync the Free Software Foundation, either version 3 of the License, or
a180a41bba1d50822df23fff0099e90b86638b89vboxsync (at your option) any later version.
a180a41bba1d50822df23fff0099e90b86638b89vboxsync This program is distributed in the hope that it will be useful,
a180a41bba1d50822df23fff0099e90b86638b89vboxsync but WITHOUT ANY WARRANTY; without even the implied warranty of
a180a41bba1d50822df23fff0099e90b86638b89vboxsync MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
a180a41bba1d50822df23fff0099e90b86638b89vboxsync GNU General Public License for more details.
a180a41bba1d50822df23fff0099e90b86638b89vboxsync You should have received a copy of the GNU General Public License
a180a41bba1d50822df23fff0099e90b86638b89vboxsync along with this program. If not, see <http://www.gnu.org/licenses/>.
6e9aa255e3376b2da5824c09c4c62bc233463bfevboxsync * Oracle GPL Disclaimer: For the avoidance of doubt, except that if any license choice
6e9aa255e3376b2da5824c09c4c62bc233463bfevboxsync * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
6e9aa255e3376b2da5824c09c4c62bc233463bfevboxsync * the General Public License version 2 (GPLv2) at this time for any software where
6e9aa255e3376b2da5824c09c4c62bc233463bfevboxsync * a choice of GPL license versions is made available with the language indicating
6e9aa255e3376b2da5824c09c4c62bc233463bfevboxsync * that GPLv2 or any later version may be used, or where a choice of which version
6e9aa255e3376b2da5824c09c4c62bc233463bfevboxsync * of the GPL is applied is otherwise unspecified.
6e9aa255e3376b2da5824c09c4c62bc233463bfevboxsync#if defined(RT_OS_SOLARIS) && defined(__USE_LEGACY_PROTOTYPES__)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* Session Directory support */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* END Session Directory support */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* Receive an RDP packet */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if ((rdp_s == NULL) || (g_next_packet >= rdp_s->end) || (g_next_packet == NULL))
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* rdp5_process should move g_next_packet ok */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* 32k packets are really 8, keepalive fix */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync DEBUG(("RDP packet #%d, (type %x)\n", ++g_packetno, *type));
a180a41bba1d50822df23fff0099e90b86638b89vboxsync#endif /* */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* Initialise an RDP data packet */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync s = sec_init(g_encryption ? SEC_ENCRYPT : 0, maxlen + 18);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* Send an RDP data packet */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* Output a string in Unicode */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if ((iconv_h = iconv_open(WINDOWS_CODEPAGE, g_codepage)) == (iconv_t) - 1)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync warning("rdp_out_unistr: iconv_open[%s -> %s] fail %p\n",
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (iconv(iconv_h, (ICONV_CONST char **) &pin, &i, &pout, &o) ==
a180a41bba1d50822df23fff0099e90b86638b89vboxsync warning("rdp_out_unistr: iconv(1) fail, errno %d\n", errno);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync pout = (char *) s->p;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (iconv(iconv_h, (ICONV_CONST char **) &pin, &ibl, &pout, &obl) == (size_t) - 1)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync warning("rdp_out_unistr: iconv(2) fail, errno %d\n", errno);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync int i = 0, j = 0;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync while (i < len)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync s->p[i++] = string[j++];
a180a41bba1d50822df23fff0099e90b86638b89vboxsync s->p[i++] = 0;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* Input a string in Unicode
a180a41bba1d50822df23fff0099e90b86638b89vboxsync * Returns str_len of string
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncrdp_in_unistr(STREAM s, int in_len, char **string, uint32 * str_size)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* Dynamic allocate of destination string if not provided */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if ((iconv_h = iconv_open(g_codepage, WINDOWS_CODEPAGE)) == (iconv_t) - 1)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync warning("rdp_in_unistr: iconv_open[%s -> %s] fail %p\n",
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (iconv(iconv_h, (ICONV_CONST char **) &pin, &ibl, &pout, &obl) == (size_t) - 1)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync warning("server sent an unexpectedly long string, truncating\n");
a180a41bba1d50822df23fff0099e90b86638b89vboxsync warning("rdp_in_unistr: iconv fail, errno %d\n", errno);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* we must update the location of the current STREAM for future reads of s->p */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync warning("server sent an unexpectedly long string, truncating\n");
a180a41bba1d50822df23fff0099e90b86638b89vboxsync while (i < len)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* Parse a logon info packet */
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncrdp_send_logon_info(uint32 flags, char *domain, char *user,
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* length of string in TS_INFO_PACKET excludes null terminator */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* length of strings in TS_EXTENDED_PACKET includes null terminator */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync int len_dll = 2 * strlen("C:\\WINNT\\System32\\mstscax.dll") + 2;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync uint32 sec_flags = g_encryption ? (SEC_LOGON_INFO | SEC_ENCRYPT) : SEC_LOGON_INFO;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (g_rdp_version == RDP_V4 || 1 == g_server_rdp_version)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync s = sec_init(sec_flags, 18 + len_domain + len_user + len_password
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (g_redirect == True && g_redirect_cookie_len > 0)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync len_password -= 2; /* substract 2 bytes which is added below */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* size of TS_INFO_PACKET */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* size of TS_EXTENDED_INFO_PACKET */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* size of TS_TIME_ZONE_INFORMATION */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync 64 + /* StandardName, 32 unicode char array, Descriptive standard time on client */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync 2 + /* cbAutoReconnectCookie, either 0 or 0x001c */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* size of ARC_CS_PRIVATE_PACKET */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync DEBUG_RDP5(("Called sec_init with packetlen %d\n", packetlen));
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* TS_INFO_PACKET */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint16_le(s, 0); /* mandatory 2 bytes null terminator */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint16_le(s, 0); /* mandatory 2 bytes null terminator */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (g_redirect == True && 0 < g_redirect_cookie_len)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint8p(s, g_redirect_cookie, g_redirect_cookie_len);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint16_le(s, 0); /* mandatory 2 bytes null terminator */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint16_le(s, 0); /* mandatory 2 bytes null terminator */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint16_le(s, 0); /* mandatory 2 bytes null terminator */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* TS_EXTENDED_INFO_PACKET */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint16_le(s, 2); /* clientAddressFamily = AF_INET */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint16_le(s, len_ip); /* cbClientAddress, Length of client ip */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync rdp_out_unistr(s, ipaddr, len_ip - 2); /* clientAddress */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync rdp_out_unistr(s, "C:\\WINNT\\System32\\mstscax.dll", len_dll - 2); /* clientDir */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* TS_TIME_ZONE_INFORMATION */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync tzone = (mktime(gmtime(&t)) - mktime(localtime(&t))) / 60;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync rdp_out_unistr(s, "GTB, normaltid", 2 * strlen("GTB, normaltid"));
a180a41bba1d50822df23fff0099e90b86638b89vboxsync rdp_out_unistr(s, "GTB, sommartid", 2 * strlen("GTB, sommartid"));
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* Rest of TS_EXTENDED_INFO_PACKET */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint32_le(s, 0); /* clientSessionId (Ignored by server MUST be 0) */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* Client Auto-Reconnect */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* ARC_CS_PRIVATE_PACKET */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint32_le(s, g_reconnect_logonid); /* LogonId */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync rdssl_hmac_md5(g_reconnect_random, sizeof(g_reconnect_random),
a180a41bba1d50822df23fff0099e90b86638b89vboxsync g_client_random, SEC_RANDOM_SIZE, security_verifier);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint8a(s, security_verifier, sizeof(security_verifier));
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* clear the redirect flag */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* Send a control PDU */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* Send a synchronisation PDU */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* Send a single input event */
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncrdp_send_input(uint32 time, uint16 message_type, uint16 device_flags, uint16 param1, uint16 param2)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* Send a client window information PDU */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync case 0: /* shut the server up */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync rdp_send_data(s, RDP_DATA_PDU_CLIENT_WINDOW_STATUS);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* Send persistent bitmap cache enumeration PDU's */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* header */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint8a(s, keylist[offset], count * sizeof(HASH_KEY));
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* Send an (empty) font information PDU */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* Output general capability set */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint16_le(s, (g_rdp_version >= RDP_V5) ? 0x40d : 0);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* Pad, according to T.128. 0x40d seems to
a180a41bba1d50822df23fff0099e90b86638b89vboxsync the server to start sending RDP5 packets.
a180a41bba1d50822df23fff0099e90b86638b89vboxsync However, the value is 0x1d04 with W2KTSK and
a180a41bba1d50822df23fff0099e90b86638b89vboxsync NT4MS. Hmm.. Anyway, thankyou, Microsoft,
a180a41bba1d50822df23fff0099e90b86638b89vboxsync for sending such information in a padding
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* Output bitmap capability set */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint16_le(s, g_server_depth); /* Preferred colour depth */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint16_le(s, g_bitmap_compression ? 1 : 0); /* Support compression */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* Output order capability set */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync order_caps[3] = (g_bitmap_cache ? 1 : 0); /* memblt */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync order_caps[11] = (g_desktop_save ? 1 : 0); /* desksave */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync order_caps[20] = (g_polygon_ellipse_orders ? 1 : 0); /* polygon */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync order_caps[21] = (g_polygon_ellipse_orders ? 1 : 0); /* polygon2 */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync order_caps[25] = (g_polygon_ellipse_orders ? 1 : 0); /* ellipse */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync order_caps[26] = (g_polygon_ellipse_orders ? 1 : 0); /* ellipse2 */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint8p(s, order_caps, 32); /* Orders supported */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint16_le(s, 0x6a1); /* Text capability flags */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint32_le(s, g_desktop_save == False ? 0 : 0x38400); /* Desktop cache size */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* Output bitmap cache capability set */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync Bpp = (g_server_depth + 7) / 8; /* bytes per pixel */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint16_le(s, 0x1000 * Bpp); /* max cell size */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* Output bitmap cache v2 capability set */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint16_le(s, g_bitmap_cache_persist_enable ? 2 : 0); /* version */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint16_be(s, 3); /* number of caches in this set */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* max cell size for cache 0 is 16x16, 1 = 32x32, 2 = 64x64, etc */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint32_le(s, BMPCACHE2_NUM_PSTCELLS | BMPCACHE2_FLAG_PERSIST);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint8s(s, 20); /* other bitmap caches not used */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* Output control capability set */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* Output activation capability set */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* Output pointer capability set */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* Output new pointer capability set */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint16_le(s, 20); /* Cache size for new pointers */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* Output share capability set */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* Output colour cache capability set */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* Output brush cache capability set */
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncstatic uint8 caps_0x0c[] = { 0x01, 0x00, 0x00, 0x00 };
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncstatic uint8 caps_0x0e[] = { 0x01, 0x00, 0x00, 0x00 };
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* Output unknown capability sets */
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncrdp_out_unknown_caps(STREAM s, uint16 id, uint16 length, uint8 * caps)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* Send a confirm active PDU */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync uint32 sec_flags = g_encryption ? (RDP5_FLAG | SEC_ENCRYPT) : RDP5_FLAG;
a180a41bba1d50822df23fff0099e90b86638b89vboxsync RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER +
a180a41bba1d50822df23fff0099e90b86638b89vboxsync RDP_CAPLEN_BRUSHCACHE + 0x58 + 0x08 + 0x08 + 0x34 /* unknown caps */ +
a180a41bba1d50822df23fff0099e90b86638b89vboxsync s = sec_init(sec_flags, 6 + 14 + caplen + sizeof(RDP_SOURCE));
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint16_le(s, 2 + 14 + caplen + sizeof(RDP_SOURCE));
a180a41bba1d50822df23fff0099e90b86638b89vboxsync out_uint16_le(s, (RDP_PDU_CONFIRM_ACTIVE | 0x10)); /* Version 1 */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync rdp_out_unknown_caps(s, 0x0d, 0x58, caps_0x0d); /* CAPSTYPE_INPUT */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync rdp_out_unknown_caps(s, 0x0c, 0x08, caps_0x0c); /* CAPSTYPE_SOUND */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync rdp_out_unknown_caps(s, 0x0e, 0x08, caps_0x0e); /* CAPSTYPE_FONT */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync rdp_out_unknown_caps(s, 0x10, 0x34, caps_0x10); /* CAPSTYPE_GLYPHCACHE */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* Process a general capability set */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* Process a bitmap capability set */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync DEBUG(("setting desktop size and depth to: %dx%dx%d\n", width, height, depth));
a180a41bba1d50822df23fff0099e90b86638b89vboxsync * The server may limit depth and change the size of the desktop (for
a180a41bba1d50822df23fff0099e90b86638b89vboxsync * example when shadowing another session).
a180a41bba1d50822df23fff0099e90b86638b89vboxsync warning("Remote desktop does not support colour depth %d; falling back to %d\n",
a180a41bba1d50822df23fff0099e90b86638b89vboxsync warning("Remote desktop changed from %dx%d to %dx%d.\n", g_width, g_height,
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* Process server capabilities */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync for (n = 0; n < ncapsets; n++)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* Respond to a demand active PDU */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* at this point we need to ensure that we have ui created */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync DEBUG(("DEMAND_ACTIVE(id=0x%x)\n", g_rdp_shareid));
a180a41bba1d50822df23fff0099e90b86638b89vboxsync g_numlock_sync ? ui_get_numlock_state(read_keyboard_state()) : 0, 0);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync rdp_recv(&type); /* RDP_PDU_UNKNOWN 0x28 (Fonts?) */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* Process a colour pointer PDU */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync warning("process_colour_pointer_common: " "width %d height %d\n", width, height);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* keep hotspot within cursor bounding box */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync cursor = ui_create_cursor(x, y, width, height, mask, data, bpp);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* Process a colour pointer PDU */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* Process a New Pointer PDU - these pointers have variable bit depth */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* Process a cached pointer PDU */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* Process a system pointer PDU */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync unimpl("System pointer message 0x%x\n", system_pointer_type);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* Process a pointer PDU */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* Process bitmap updates */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync for (i = 0; i < num_updates; i++)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync DEBUG(("BITMAP_UPDATE(l=%d,t=%d,r=%d,b=%d,w=%d,h=%d,Bpp=%d,cmp=%d)\n",
a180a41bba1d50822df23fff0099e90b86638b89vboxsync left, top, right, bottom, width, height, Bpp, compress));
a180a41bba1d50822df23fff0099e90b86638b89vboxsync for (y = 0; y < height; y++)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync in_uint8a(s, &bmpdata[(height - y - 1) * (width * Bpp)],
a180a41bba1d50822df23fff0099e90b86638b89vboxsync ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (bitmap_decompress(bmpdata, width, height, data, size, Bpp))
a180a41bba1d50822df23fff0099e90b86638b89vboxsync ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* Process a palette update */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync map.colours = (COLOURENTRY *) xmalloc(sizeof(COLOURENTRY) * map.ncolours);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* Process an update PDU */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* Process a Save Session Info PDU */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* TS_LOGON_INFO_FIELD */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* ARC_SC_PRIVATE_PACKET */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync warning("Invalid length in Auto-Reconnect packet\n");
a180a41bba1d50822df23fff0099e90b86638b89vboxsync warning("Unsupported version of Auto-Reconnect packet\n");
a180a41bba1d50822df23fff0099e90b86638b89vboxsync DEBUG(("Saving auto-reconnect cookie, id=%u\n", g_reconnect_logonid));
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* Process a disconnect PDU */
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncprocess_disconnect_pdu(STREAM s, uint32 * ext_disc_reason)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* Process data PDU */
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncprocess_data_pdu(STREAM s, uint32 * ext_disc_reason)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync error("error decompressed packet size exceeds max\n");
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (mppc_expand(s->p, clen, ctype, &roff, &rlen) == -1)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* len -= 18; */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* allocate memory and copy the uncompressed data into the temporary stream */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync memcpy((ns->data), (unsigned char *) (g_mppc_dict.hist + roff), rlen);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* User logged on */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* We used to return true and disconnect immediately here, but
a180a41bba1d50822df23fff0099e90b86638b89vboxsync * Windows Vista sends a disconnect PDU with reason 0 when
a180a41bba1d50822df23fff0099e90b86638b89vboxsync * reconnecting to a disconnected session, and MSTSC doesn't
a180a41bba1d50822df23fff0099e90b86638b89vboxsync * drop the connection. I think we should just save the status.
a180a41bba1d50822df23fff0099e90b86638b89vboxsync warning("Automatic reconnect using cookie, failed.\n");
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* Process redirect PDU from Session Directory */
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncprocess_redirect_pdu(STREAM s, RD_BOOL enhanced_redirect /*, uint32 * ext_disc_reason */ )
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* reset any previous redirection information */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* these 2 bytes are unknown, seem to be zeros */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* FIXME: Previous implementation only reads 4 bytes which has been working
a180a41bba1d50822df23fff0099e90b86638b89vboxsync but todays spec says something different. Investigate and retest
a180a41bba1d50822df23fff0099e90b86638b89vboxsync server redirection using WTS 2003 cluster.
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* read identifier */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync error("Protocol error in server redirection, unexpected data.");
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* FIXME: skip total length */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* read session_id */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* read connection flags */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* read length of ip string */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* read ip string */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync rdp_in_unistr(s, len, &g_redirect_server, &g_redirect_server_len);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (g_redirect_flags & PDU_REDIRECT_HAS_LOAD_BALANCE_INFO)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* read length of load balance info blob */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* reallocate a loadbalance info blob */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync g_redirect_lb_info = xmalloc(g_redirect_lb_info_len);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* read load balance info blob */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync in_uint8p(s, g_redirect_lb_info, g_redirect_lb_info_len);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* read length of username string */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* read username string */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync rdp_in_unistr(s, len, &g_redirect_username, &g_redirect_username_len);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* read length of domain string */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* read domain string */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync rdp_in_unistr(s, len, &g_redirect_domain, &g_redirect_domain_len);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* the information in this blob is either a password or a cookie that
a180a41bba1d50822df23fff0099e90b86638b89vboxsync should be passed though as blob and not parsed as a unicode string */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* read blob length */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* reallocate cookie blob */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync g_redirect_cookie = xmalloc(g_redirect_cookie_len);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* read cookie as is */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync in_uint8p(s, g_redirect_cookie, g_redirect_cookie_len);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (g_redirect_flags & PDU_REDIRECT_DONT_STORE_USERNAME)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* By spec this is only for information and doesn't mean that an actual
a180a41bba1d50822df23fff0099e90b86638b89vboxsync redirect should be performed. How it should be used is not mentioned. */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (g_redirect_flags & PDU_REDIRECT_HAS_TARGET_FQDN)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* Let target fqdn replace target ip address */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* read fqdn string */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync rdp_in_unistr(s, len, &g_redirect_server, &g_redirect_server_len);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (g_redirect_flags & PDU_REDIRECT_HAS_TARGET_NETBIOS)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (g_redirect_flags & PDU_REDIRECT_HAS_TARGET_IP_ARRAY)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* Process incoming packets */
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncrdp_main_loop(RD_BOOL * deactivated, uint32 * ext_disc_reason)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* used in uiports and rdp_main_loop, processes the rdp packets waiting */
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncrdp_loop(RD_BOOL * deactivated, uint32 * ext_disc_reason)
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* If we got a data PDU, we don't need to keep the password in memory
a180a41bba1d50822df23fff0099e90b86638b89vboxsync anymore and therefor we should clear it for security reasons. */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* Establish a connection up to the RDP layer */
a180a41bba1d50822df23fff0099e90b86638b89vboxsyncrdp_connect(char *server, uint32 flags, char *domain, char *password,
a180a41bba1d50822df23fff0099e90b86638b89vboxsync if (!sec_connect(server, g_username, domain, password, reconnect))
a180a41bba1d50822df23fff0099e90b86638b89vboxsync rdp_send_logon_info(flags, domain, g_username, password, command, directory);
a180a41bba1d50822df23fff0099e90b86638b89vboxsync /* run RDP loop until first licence demand active PDU */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* Called during redirection to reset the state to support redirection */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync g_next_packet = NULL; /* reset the packet information */
a180a41bba1d50822df23fff0099e90b86638b89vboxsync/* Disconnect from the RDP layer */