ReactOS  0.4.11-dev-946-g431643b
rdp.c
Go to the documentation of this file.
1 /* -*- c-basic-offset: 8 -*-
2  rdesktop: A Remote Desktop Protocol client.
3  Protocol services - RDP layer
4  Copyright (C) Matthew Chapman <matthewc.unsw.edu.au> 1999-2008
5  Copyright 2003-2011 Peter Astrand <astrand@cendio.se> for Cendio AB
6  Copyright 2011-2014 Henrik Andersson <hean01@cendio.se> for Cendio AB
7 
8  This program is free software: you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation, either version 3 of the License, or
11  (at your option) any later version.
12 
13  This program is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21 
22 #include "precomp.h"
23 
24 extern uint16 g_mcs_userid;
25 extern char g_username[256];
26 extern char g_password[256];
27 char g_codepage[16];
29 extern RD_BOOL g_orders;
30 extern RD_BOOL g_encryption;
31 extern RD_BOOL g_desktop_save;
36 extern int g_server_depth;
37 extern int g_width;
38 extern int g_height;
39 extern RD_BOOL g_bitmap_cache;
41 extern RD_BOOL g_numlock_sync;
44 
47 
48 extern RDPCOMP g_mppc_dict;
49 
50 /* Session Directory support */
51 extern RD_BOOL g_redirect;
52 extern char *g_redirect_server;
54 extern char *g_redirect_domain;
56 extern char *g_redirect_username;
60 extern uint8 *g_redirect_cookie;
64 
65 /* END Session Directory support */
66 
68 extern char g_reconnect_random[16];
72 
73 void rdssl_hmac_md5(char* key, int keylen, char* data, int len, char* output);
74 
75 #if WITH_DEBUG
76 static uint32 g_packetno;
77 #endif
78 
79 #ifdef HAVE_ICONV
80 static RD_BOOL g_iconv_works = True;
81 #endif
82 
83 /* Receive an RDP packet */
84 static STREAM
86 {
87  static STREAM rdp_s;
88  uint16 length, pdu_type;
89  uint8 rdpver;
90 
91  if ((rdp_s == NULL) || (g_next_packet >= rdp_s->end) || (g_next_packet == NULL))
92  {
93  rdp_s = sec_recv(&rdpver);
94  if (rdp_s == NULL)
95  return NULL;
96  if (rdpver == 0xff)
97  {
98  g_next_packet = rdp_s->end;
99  *type = 0;
100  return rdp_s;
101  }
102  else if (rdpver != 3)
103  {
104  /* rdp5_process should move g_next_packet ok */
105  rdp5_process(rdp_s);
106  *type = 0;
107  return rdp_s;
108  }
109 
110  g_next_packet = rdp_s->p;
111  }
112  else
113  {
114  rdp_s->p = g_next_packet;
115  }
116 
117  in_uint16_le(rdp_s, length);
118  /* 32k packets are really 8, keepalive fix */
119  if (length == 0x8000)
120  {
121  g_next_packet += 8;
122  *type = 0;
123  return rdp_s;
124  }
125  in_uint16_le(rdp_s, pdu_type);
126  in_uint8s(rdp_s, 2); /* userid */
127  *type = pdu_type & 0xf;
128 
129 #ifdef WITH_DEBUG
130  DEBUG(("RDP packet #%d, (type %x)\n", ++g_packetno, *type));
131  hexdump(g_next_packet, length);
132 #endif /* */
133 
135  return rdp_s;
136 }
137 
138 /* Initialise an RDP data packet */
139 static STREAM
140 rdp_init_data(int maxlen)
141 {
142  STREAM s;
143 
144  s = sec_init(g_encryption ? SEC_ENCRYPT : 0, maxlen + 18);
145  s_push_layer(s, rdp_hdr, 18);
146 
147  return s;
148 }
149 
150 /* Send an RDP data packet */
151 static void
152 rdp_send_data(STREAM s, uint8 data_pdu_type)
153 {
154  uint16 length;
155 
156  s_pop_layer(s, rdp_hdr);
157  length = s->end - s->p;
158 
159  out_uint16_le(s, length);
160  out_uint16_le(s, (RDP_PDU_DATA | 0x10));
161  out_uint16_le(s, (g_mcs_userid + 1001));
162 
164  out_uint8(s, 0); /* pad */
165  out_uint8(s, 1); /* streamid */
166  out_uint16_le(s, (length - 14));
167  out_uint8(s, data_pdu_type);
168  out_uint8(s, 0); /* compress_type */
169  out_uint16(s, 0); /* compress_len */
170 
172 }
173 
174 /* Output a string in Unicode with mandatory null termination. If
175  string is NULL or len is 0, write an unicode null termination to
176  stream. */
177 void
179 {
180  if (string && len > 0)
181  rdp_out_unistr(s, string, len);
182  else
183  out_uint16_le(s, 0);
184 }
185 
186 /* Output a string in Unicode */
187 void
188 rdp_out_unistr(STREAM s, char *string, int len)
189 {
190  if (string == NULL || len == 0)
191  return;
192 
193 #ifdef HAVE_ICONV
194  size_t ibl = strlen(string), obl = len + 2;
195  static iconv_t iconv_h = (iconv_t) - 1;
196  char *pin = string, *pout = (char *) s->p;
197 
198  memset(pout, 0, len + 4);
199 
200  if (g_iconv_works)
201  {
202  if (iconv_h == (iconv_t) - 1)
203  {
204  size_t i = 1, o = 4;
205  if ((iconv_h = iconv_open(WINDOWS_CODEPAGE, g_codepage)) == (iconv_t) - 1)
206  {
207  warning("rdp_out_unistr: iconv_open[%s -> %s] fail %d\n",
208  g_codepage, WINDOWS_CODEPAGE, (int) iconv_h);
209 
210  g_iconv_works = False;
211  rdp_out_unistr(s, string, len);
212  return;
213  }
214  if (iconv(iconv_h, (ICONV_CONST char **) &pin, &i, &pout, &o) ==
215  (size_t) - 1)
216  {
217  iconv_close(iconv_h);
218  iconv_h = (iconv_t) - 1;
219  warning("rdp_out_unistr: iconv(1) fail, errno %d\n", errno);
220 
221  g_iconv_works = False;
222  rdp_out_unistr(s, string, len);
223  return;
224  }
225  pin = string;
226  pout = (char *) s->p;
227  }
228 
229  if (iconv(iconv_h, (ICONV_CONST char **) &pin, &ibl, &pout, &obl) == (size_t) - 1)
230  {
231  iconv_close(iconv_h);
232  iconv_h = (iconv_t) - 1;
233  warning("rdp_out_unistr: iconv(2) fail, errno %d\n", errno);
234 
235  g_iconv_works = False;
236  rdp_out_unistr(s, string, len);
237  return;
238  }
239 
240  s->p += len + 2;
241 
242  }
243  else
244 #endif
245  {
246  int i = 0, j = 0;
247 
248  len += 2;
249 
250  while (i < len)
251  {
252  s->p[i++] = string[j++];
253  s->p[i++] = 0;
254  }
255 
256  s->p += len;
257  }
258 }
259 
260 /* Input a string in Unicode
261  *
262  * Returns str_len of string
263  */
264 void
265 rdp_in_unistr(STREAM s, int in_len, char **string, uint32 * str_size)
266 {
267  /* Dynamic allocate of destination string if not provided */
268  *string = xmalloc(in_len * 2);
269  *str_size = in_len * 2;
270 
271 #ifdef HAVE_ICONV
272  size_t ibl = in_len, obl = *str_size - 1;
273  char *pin = (char *) s->p, *pout = *string;
274  static iconv_t iconv_h = (iconv_t) - 1;
275 
276  if (g_iconv_works)
277  {
278  if (iconv_h == (iconv_t) - 1)
279  {
280  if ((iconv_h = iconv_open(g_codepage, WINDOWS_CODEPAGE)) == (iconv_t) - 1)
281  {
282  warning("rdp_in_unistr: iconv_open[%s -> %s] fail %d\n",
283  WINDOWS_CODEPAGE, g_codepage, (int) iconv_h);
284 
285  g_iconv_works = False;
286  return rdp_in_unistr(s, in_len, string, str_size);
287  }
288  }
289 
290  if (iconv(iconv_h, (ICONV_CONST char **) &pin, &ibl, &pout, &obl) == (size_t) - 1)
291  {
292  if (errno == E2BIG)
293  {
294  warning("server sent an unexpectedly long string, truncating\n");
295  }
296  else
297  {
298  warning("rdp_in_unistr: iconv fail, errno %d\n", errno);
299 
300  free(*string);
301  *string = NULL;
302  *str_size = 0;
303  }
304  }
305 
306  /* we must update the location of the current STREAM for future reads of s->p */
307  s->p += in_len;
308 
309  *pout = 0;
310 
311  if (*string)
312  *str_size = pout - *string;
313  }
314  else
315 #endif
316  {
317  int i = 0;
318  int rem = 0;
319  uint32 len = in_len / 2;
320 
321  if (len > *str_size - 1)
322  {
323  warning("server sent an unexpectedly long string, truncating\n");
324  len = *str_size - 1;
325  rem = in_len - 2 * len;
326  }
327 
328  while (i < len)
329  {
330  in_uint8a(s, &string[i++], 1);
331  in_uint8s(s, 1);
332  }
333 
334  in_uint8s(s, rem);
335  string[len] = 0;
336  *str_size = len;
337  }
338 }
339 
340 
341 /* Parse a logon info packet */
342 static void
343 rdp_send_logon_info(uint32 flags, char *domain, char *user,
344  char *password, char *program, char *directory)
345 {
346  char *ipaddr = tcp_get_address();
347  /* length of string in TS_INFO_PACKET excludes null terminator */
348  int len_domain = 2 * strlen(domain);
349  int len_user = 2 * strlen(user);
350  int len_password = 2 * strlen(password);
351  int len_program = 2 * strlen(program);
352  int len_directory = 2 * strlen(directory);
353 
354  /* length of strings in TS_EXTENDED_PACKET includes null terminator */
355  char dllName[MAX_PATH];
356  int len_ip = 2 * strlen(ipaddr) + 2;
357  int len_dll = 0;
358 
359  int packetlen = 0;
361  STREAM s;
362  time_t t = time(NULL);
363  time_t tzone;
364  uint8 security_verifier[16];
365 
366  GetModuleFileNameA(NULL, dllName, ARRAYSIZE(dllName));
367  len_dll = 2 * strlen(dllName) + 2;
368 
370  {
371  DEBUG_RDP5(("Sending RDP4-style Logon packet\n"));
372 
373  s = sec_init(sec_flags, 18 + len_domain + len_user + len_password
374  + len_program + len_directory + 10);
375 
376  out_uint32(s, 0);
377  out_uint32_le(s, flags);
378  out_uint16_le(s, len_domain);
379  out_uint16_le(s, len_user);
380  out_uint16_le(s, len_password);
381  out_uint16_le(s, len_program);
382  out_uint16_le(s, len_directory);
383 
384  rdp_out_unistr_mandatory_null(s, domain, len_domain);
385  rdp_out_unistr_mandatory_null(s, user, len_user);
386  rdp_out_unistr_mandatory_null(s, password, len_password);
387  rdp_out_unistr_mandatory_null(s, program, len_program);
388  rdp_out_unistr_mandatory_null(s, directory, len_directory);
389  }
390  else
391  {
392  DEBUG_RDP5(("Sending RDP5-style Logon packet\n"));
393 
394  if (g_redirect == True && g_redirect_cookie_len > 0)
395  {
396  flags |= RDP_INFO_AUTOLOGON;
397  len_password = g_redirect_cookie_len;
398  len_password -= 2; /* substract 2 bytes which is added below */
399  }
400 
401  packetlen =
402  /* size of TS_INFO_PACKET */
403  4 + /* CodePage */
404  4 + /* flags */
405  2 + /* cbDomain */
406  2 + /* cbUserName */
407  2 + /* cbPassword */
408  2 + /* cbAlternateShell */
409  2 + /* cbWorkingDir */
410  2 + len_domain + /* Domain */
411  2 + len_user + /* UserName */
412  2 + len_password + /* Password */
413  2 + len_program + /* AlternateShell */
414  2 + len_directory + /* WorkingDir */
415  /* size of TS_EXTENDED_INFO_PACKET */
416  2 + /* clientAddressFamily */
417  2 + /* cbClientAddress */
418  len_ip + /* clientAddress */
419  2 + /* cbClientDir */
420  len_dll + /* clientDir */
421  /* size of TS_TIME_ZONE_INFORMATION */
422  4 + /* Bias, (UTC = local time + bias */
423  64 + /* StandardName, 32 unicode char array, Descriptive standard time on client */
424  16 + /* StandardDate */
425  4 + /* StandardBias */
426  64 + /* DaylightName, 32 unicode char array */
427  16 + /* DaylightDate */
428  4 + /* DaylightBias */
429  4 + /* clientSessionId */
430  4 + /* performanceFlags */
431  2 + /* cbAutoReconnectCookie, either 0 or 0x001c */
432  /* size of ARC_CS_PRIVATE_PACKET */
433  28; /* autoReconnectCookie */
434 
435 
436  s = sec_init(sec_flags, packetlen);
437  DEBUG_RDP5(("Called sec_init with packetlen %d\n", packetlen));
438 
439  /* TS_INFO_PACKET */
440  out_uint32(s, 0); /* Code Page */
441  out_uint32_le(s, flags);
442  out_uint16_le(s, len_domain);
443  out_uint16_le(s, len_user);
444  out_uint16_le(s, len_password);
445  out_uint16_le(s, len_program);
446  out_uint16_le(s, len_directory);
447 
448  rdp_out_unistr_mandatory_null(s, domain, len_domain);
449  rdp_out_unistr_mandatory_null(s, user, len_user);
450 
451  if (g_redirect == True && 0 < g_redirect_cookie_len)
452  {
454  }
455  else
456  {
457  rdp_out_unistr_mandatory_null(s, password, len_password);
458  }
459 
460 
461  rdp_out_unistr_mandatory_null(s, program, len_program);
462  rdp_out_unistr_mandatory_null(s, directory, len_directory);
463 
464  /* TS_EXTENDED_INFO_PACKET */
465  out_uint16_le(s, 2); /* clientAddressFamily = AF_INET */
466  out_uint16_le(s, len_ip); /* cbClientAddress */
467  rdp_out_unistr_mandatory_null(s, ipaddr, len_ip - 2); /* clientAddress */
468  out_uint16_le(s, len_dll); /* cbClientDir */
469  rdp_out_unistr(s, dllName, len_dll - 2); /* clientDir */
470 
471  /* TS_TIME_ZONE_INFORMATION */
472  tzone = (mktime(gmtime(&t)) - mktime(localtime(&t))) / 60;
473  out_uint32_le(s, tzone);
474  rdp_out_unistr(s, "GTB, normaltid", 2 * strlen("GTB, normaltid"));
475  out_uint8s(s, 62 - 2 * strlen("GTB, normaltid"));
476  out_uint32_le(s, 0x0a0000);
477  out_uint32_le(s, 0x050000);
478  out_uint32_le(s, 3);
479  out_uint32_le(s, 0);
480  out_uint32_le(s, 0);
481  rdp_out_unistr(s, "GTB, sommartid", 2 * strlen("GTB, sommartid"));
482  out_uint8s(s, 62 - 2 * strlen("GTB, sommartid"));
483  out_uint32_le(s, 0x30000);
484  out_uint32_le(s, 0x050000);
485  out_uint32_le(s, 2);
486  out_uint32(s, 0);
487  out_uint32_le(s, 0xffffffc4); /* DaylightBias */
488 
489  /* Rest of TS_EXTENDED_INFO_PACKET */
490  out_uint32_le(s, 0); /* clientSessionId (Ignored by server MUST be 0) */
492 
493  /* Client Auto-Reconnect */
495  {
496  out_uint16_le(s, 28); /* cbAutoReconnectLen */
497  /* ARC_CS_PRIVATE_PACKET */
498  out_uint32_le(s, 28); /* cbLen */
499  out_uint32_le(s, 1); /* Version */
500  out_uint32_le(s, g_reconnect_logonid); /* LogonId */
502  (char *)g_client_random, SEC_RANDOM_SIZE, (char *)security_verifier);
503  out_uint8a(s, security_verifier, sizeof(security_verifier));
504  }
505  else
506  {
507  out_uint16_le(s, 0); /* cbAutoReconnectLen */
508  }
509  }
510  s_mark_end(s);
511 
512  /* clear the redirect flag */
513  g_redirect = False;
514 
515  sec_send(s, sec_flags);
516 }
517 
518 /* Send a control PDU */
519 static void
521 {
522  STREAM s;
523 
524  s = rdp_init_data(8);
525 
526  out_uint16_le(s, action);
527  out_uint16(s, 0); /* userid */
528  out_uint32(s, 0); /* control id */
529 
530  s_mark_end(s);
532 }
533 
534 /* Send a synchronisation PDU */
535 static void
537 {
538  STREAM s;
539 
540  s = rdp_init_data(4);
541 
542  out_uint16_le(s, 1); /* type */
543  out_uint16_le(s, 1002);
544 
545  s_mark_end(s);
547 }
548 
549 /* Send a single input event */
550 void
551 rdp_send_input(uint32 time, uint16 message_type, uint16 device_flags, uint16 param1, uint16 param2)
552 {
553  STREAM s;
554 
555  s = rdp_init_data(16);
556 
557  out_uint16_le(s, 1); /* number of events */
558  out_uint16(s, 0); /* pad */
559 
560  out_uint32_le(s, time);
561  out_uint16_le(s, message_type);
562  out_uint16_le(s, device_flags);
563  out_uint16_le(s, param1);
564  out_uint16_le(s, param2);
565 
566  s_mark_end(s);
568 }
569 
570 /* Send a client window information PDU */
571 void
573 {
574  STREAM s;
575  static int current_status = 1;
576 
577  if (current_status == status)
578  return;
579 
580  s = rdp_init_data(12);
581 
582  out_uint32_le(s, status);
583 
584  switch (status)
585  {
586  case 0: /* shut the server up */
587  break;
588 
589  case 1: /* receive data again */
590  out_uint32_le(s, 0); /* unknown */
593  break;
594  }
595 
596  s_mark_end(s);
598  current_status = status;
599 }
600 
601 /* Send persistent bitmap cache enumeration PDU's */
602 static void
604 {
605  STREAM s;
607  uint32 num_keys, offset, count, flags;
608 
609  offset = 0;
610  num_keys = pstcache_enumerate(2, keylist);
611 
612  while (offset < num_keys)
613  {
614  count = MIN(num_keys - offset, 169);
615 
616  s = rdp_init_data(24 + count * sizeof(HASH_KEY));
617 
618  flags = 0;
619  if (offset == 0)
620  flags |= PDU_FLAG_FIRST;
621  if (num_keys - offset <= 169)
622  flags |= PDU_FLAG_LAST;
623 
624  /* header */
625  out_uint32_le(s, 0);
626  out_uint16_le(s, count);
627  out_uint16_le(s, 0);
628  out_uint16_le(s, 0);
629  out_uint16_le(s, 0);
630  out_uint16_le(s, 0);
631  out_uint16_le(s, num_keys);
632  out_uint32_le(s, 0);
633  out_uint32_le(s, flags);
634 
635  /* list */
636  out_uint8a(s, keylist[offset], count * sizeof(HASH_KEY));
637 
638  s_mark_end(s);
639  rdp_send_data(s, 0x2b);
640 
641  offset += 169;
642  }
643 }
644 
645 /* Send an (empty) font information PDU */
646 static void
648 {
649  STREAM s;
650 
651  s = rdp_init_data(8);
652 
653  out_uint16(s, 0); /* number of fonts */
654  out_uint16_le(s, 0); /* pad? */
655  out_uint16_le(s, seq); /* unknown */
656  out_uint16_le(s, 0x32); /* entry size */
657 
658  s_mark_end(s);
660 }
661 
662 /* Output general capability set */
663 static void
665 {
668 
669  out_uint16_le(s, 1); /* OS major type */
670  out_uint16_le(s, 3); /* OS minor type */
671  out_uint16_le(s, 0x200); /* Protocol version */
672  out_uint16(s, 0); /* Pad */
673  out_uint16(s, 0); /* Compression types */
674  out_uint16_le(s, (g_rdp_version >= RDP_V5) ? 0x40d : 0);
675  /* Pad, according to T.128. 0x40d seems to
676  trigger
677  the server to start sending RDP5 packets.
678  However, the value is 0x1d04 with W2KTSK and
679  NT4MS. Hmm.. Anyway, thankyou, Microsoft,
680  for sending such information in a padding
681  field.. */
682  out_uint16(s, 0); /* Update capability */
683  out_uint16(s, 0); /* Remote unshare capability */
684  out_uint16(s, 0); /* Compression level */
685  out_uint16(s, 0); /* Pad */
686 }
687 
688 /* Output bitmap capability set */
689 static void
691 {
694 
695  out_uint16_le(s, g_server_depth); /* Preferred colour depth */
696  out_uint16_le(s, 1); /* Receive 1 BPP */
697  out_uint16_le(s, 1); /* Receive 4 BPP */
698  out_uint16_le(s, 1); /* Receive 8 BPP */
699  out_uint16_le(s, 800); /* Desktop width */
700  out_uint16_le(s, 600); /* Desktop height */
701  out_uint16(s, 0); /* Pad */
702  out_uint16(s, 1); /* Allow resize */
703  out_uint16_le(s, g_bitmap_compression ? 1 : 0); /* Support compression */
704  out_uint16(s, 0); /* Unknown */
705  out_uint16_le(s, 1); /* Unknown */
706  out_uint16(s, 0); /* Pad */
707 }
708 
709 /* Output order capability set */
710 static void
712 {
713  uint8 order_caps[32];
714 
715  memset(order_caps, 0, 32);
716  order_caps[0] = 1; /* dest blt */
717  order_caps[1] = 1; /* pat blt */
718  order_caps[2] = 1; /* screen blt */
719  order_caps[3] = (g_bitmap_cache ? 1 : 0); /* memblt */
720  order_caps[4] = 0; /* triblt */
721  order_caps[8] = 1; /* line */
722  order_caps[9] = 1; /* line */
723  order_caps[10] = 1; /* rect */
724  order_caps[11] = (g_desktop_save ? 1 : 0); /* desksave */
725  order_caps[13] = 1; /* memblt */
726  order_caps[14] = 1; /* triblt */
727  order_caps[20] = (g_polygon_ellipse_orders ? 1 : 0); /* polygon */
728  order_caps[21] = (g_polygon_ellipse_orders ? 1 : 0); /* polygon2 */
729  order_caps[22] = 1; /* polyline */
730  order_caps[25] = (g_polygon_ellipse_orders ? 1 : 0); /* ellipse */
731  order_caps[26] = (g_polygon_ellipse_orders ? 1 : 0); /* ellipse2 */
732  order_caps[27] = 1; /* text2 */
735 
736  out_uint8s(s, 20); /* Terminal desc, pad */
737  out_uint16_le(s, 1); /* Cache X granularity */
738  out_uint16_le(s, 20); /* Cache Y granularity */
739  out_uint16(s, 0); /* Pad */
740  out_uint16_le(s, 1); /* Max order level */
741  out_uint16_le(s, 0x147); /* Number of fonts */
742  out_uint16_le(s, 0x2a); /* Capability flags */
743  out_uint8p(s, order_caps, 32); /* Orders supported */
744  out_uint16_le(s, 0x6a1); /* Text capability flags */
745  out_uint8s(s, 6); /* Pad */
746  out_uint32_le(s, g_desktop_save == False ? 0 : 0x38400); /* Desktop cache size */
747  out_uint32(s, 0); /* Unknown */
748  out_uint32_le(s, 0x4e4); /* Unknown */
749 }
750 
751 /* Output bitmap cache capability set */
752 static void
754 {
755  int Bpp;
758 
759  Bpp = (g_server_depth + 7) / 8; /* bytes per pixel */
760  out_uint8s(s, 24); /* unused */
761  out_uint16_le(s, 0x258); /* entries */
762  out_uint16_le(s, 0x100 * Bpp); /* max cell size */
763  out_uint16_le(s, 0x12c); /* entries */
764  out_uint16_le(s, 0x400 * Bpp); /* max cell size */
765  out_uint16_le(s, 0x106); /* entries */
766  out_uint16_le(s, 0x1000 * Bpp); /* max cell size */
767 }
768 
769 /* Output bitmap cache v2 capability set */
770 static void
772 {
775 
776  out_uint16_le(s, g_bitmap_cache_persist_enable ? 2 : 0); /* version */
777 
778  out_uint16_be(s, 3); /* number of caches in this set */
779 
780  /* max cell size for cache 0 is 16x16, 1 = 32x32, 2 = 64x64, etc */
783  if (pstcache_init(2))
784  {
786  }
787  else
788  {
790  }
791  out_uint8s(s, 20); /* other bitmap caches not used */
792 }
793 
794 /* Output control capability set */
795 static void
797 {
800 
801  out_uint16(s, 0); /* Control capabilities */
802  out_uint16(s, 0); /* Remote detach */
803  out_uint16_le(s, 2); /* Control interest */
804  out_uint16_le(s, 2); /* Detach interest */
805 }
806 
807 /* Output activation capability set */
808 static void
810 {
813 
814  out_uint16(s, 0); /* Help key */
815  out_uint16(s, 0); /* Help index key */
816  out_uint16(s, 0); /* Extended help key */
817  out_uint16(s, 0); /* Window activate */
818 }
819 
820 /* Output pointer capability set */
821 static void
823 {
826 
827  out_uint16(s, 0); /* Colour pointer */
828  out_uint16_le(s, 20); /* Cache size */
829 }
830 
831 /* Output new pointer capability set */
832 static void
834 {
837 
838  out_uint16_le(s, 1); /* Colour pointer */
839  out_uint16_le(s, 20); /* Cache size */
840  out_uint16_le(s, 20); /* Cache size for new pointers */
841 }
842 
843 /* Output share capability set */
844 static void
846 {
849 
850  out_uint16(s, 0); /* userid */
851  out_uint16(s, 0); /* pad */
852 }
853 
854 /* Output colour cache capability set */
855 static void
857 {
860 
861  out_uint16_le(s, 6); /* cache size */
862  out_uint16(s, 0); /* pad */
863 }
864 
865 /* Output brush cache capability set */
866 static void
868 {
871  out_uint32_le(s, 1); /* cache type */
872 }
873 
874 static uint8 caps_0x0d[] = {
875  0x01, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00,
876  0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
877  0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
878  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
879  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
880  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
881  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
882  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
883  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
884  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
885  0x00, 0x00, 0x00, 0x00
886 };
887 
888 static uint8 caps_0x0c[] = { 0x01, 0x00, 0x00, 0x00 };
889 
890 static uint8 caps_0x0e[] = { 0x01, 0x00, 0x00, 0x00 };
891 
892 static uint8 caps_0x10[] = {
893  0xFE, 0x00, 0x04, 0x00, 0xFE, 0x00, 0x04, 0x00,
894  0xFE, 0x00, 0x08, 0x00, 0xFE, 0x00, 0x08, 0x00,
895  0xFE, 0x00, 0x10, 0x00, 0xFE, 0x00, 0x20, 0x00,
896  0xFE, 0x00, 0x40, 0x00, 0xFE, 0x00, 0x80, 0x00,
897  0xFE, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x08,
898  0x00, 0x01, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00
899 };
900 
901 /* Output unknown capability sets */
902 static void
904 {
905  out_uint16_le(s, id);
906  out_uint16_le(s, length);
907 
908  out_uint8p(s, caps, length - 4);
909 }
910 
911 #define RDP5_FLAG 0x0030
912 /* Send a confirm active PDU */
913 static void
915 {
916  STREAM s;
917  uint32 sec_flags = g_encryption ? (RDP5_FLAG | SEC_ENCRYPT) : RDP5_FLAG;
918  uint16 caplen =
923  RDP_CAPLEN_BRUSHCACHE + 0x58 + 0x08 + 0x08 + 0x34 /* unknown caps */ +
924  4 /* w2k fix, sessionid */ ;
925 
926  if (g_rdp_version >= RDP_V5)
927  {
928  caplen += RDP_CAPLEN_BMPCACHE2;
929  caplen += RDP_CAPLEN_NEWPOINTER;
930  }
931  else
932  {
933  caplen += RDP_CAPLEN_BMPCACHE;
934  caplen += RDP_CAPLEN_POINTER;
935  }
936 
937  s = sec_init(sec_flags, 6 + 14 + caplen + sizeof(RDP_SOURCE));
938 
939  out_uint16_le(s, 2 + 14 + caplen + sizeof(RDP_SOURCE));
940  out_uint16_le(s, (RDP_PDU_CONFIRM_ACTIVE | 0x10)); /* Version 1 */
941  out_uint16_le(s, (g_mcs_userid + 1001));
942 
944  out_uint16_le(s, 0x3ea); /* userid */
945  out_uint16_le(s, sizeof(RDP_SOURCE));
946  out_uint16_le(s, caplen);
947 
948  out_uint8p(s, RDP_SOURCE, sizeof(RDP_SOURCE));
949  out_uint16_le(s, 0xe); /* num_caps */
950  out_uint8s(s, 2); /* pad */
951 
955  if (g_rdp_version >= RDP_V5)
956  {
959  }
960  else
961  {
964  }
970 
971  rdp_out_unknown_caps(s, 0x0d, 0x58, caps_0x0d); /* CAPSTYPE_INPUT */
972  rdp_out_unknown_caps(s, 0x0c, 0x08, caps_0x0c); /* CAPSTYPE_SOUND */
973  rdp_out_unknown_caps(s, 0x0e, 0x08, caps_0x0e); /* CAPSTYPE_FONT */
974  rdp_out_unknown_caps(s, 0x10, 0x34, caps_0x10); /* CAPSTYPE_GLYPHCACHE */
975 
976  s_mark_end(s);
977  sec_send(s, sec_flags);
978 }
979 
980 /* Process a general capability set */
981 static void
983 {
984  uint16 pad2octetsB; /* rdp5 flags? */
985 
986  in_uint8s(s, 10);
987  in_uint16_le(s, pad2octetsB);
988 
989  if (!pad2octetsB)
991 }
992 
993 /* Process a bitmap capability set */
994 static void
996 {
998 
999  in_uint16_le(s, depth);
1000  in_uint8s(s, 6);
1001 
1002  in_uint16_le(s, width);
1003  in_uint16_le(s, height);
1004 
1005  DEBUG(("setting desktop size and depth to: %dx%dx%d\n", width, height, depth));
1006 
1007  /*
1008  * The server may limit depth and change the size of the desktop (for
1009  * example when shadowing another session).
1010  */
1011  if (g_server_depth != depth)
1012  {
1013  warning("Remote desktop does not support colour depth %d; falling back to %d\n",
1014  g_server_depth, depth);
1016  }
1017  if (g_width != width || g_height != height)
1018  {
1019  warning("Remote desktop changed from %dx%d to %dx%d.\n", g_width, g_height,
1020  width, height);
1021  g_width = width;
1022  g_height = height;
1023  ui_resize_window();
1024  }
1025 }
1026 
1027 /* Process server capabilities */
1028 static void
1030 {
1031  int n;
1032  uint8 *next, *start;
1033  uint16 ncapsets, capset_type, capset_length;
1034 
1035  start = s->p;
1036 
1037  in_uint16_le(s, ncapsets);
1038  in_uint8s(s, 2); /* pad */
1039 
1040  for (n = 0; n < ncapsets; n++)
1041  {
1042  if (s->p > start + length)
1043  return;
1044 
1045  in_uint16_le(s, capset_type);
1046  in_uint16_le(s, capset_length);
1047 
1048  next = s->p + capset_length - 4;
1049 
1050  switch (capset_type)
1051  {
1052  case RDP_CAPSET_GENERAL:
1054  break;
1055 
1056  case RDP_CAPSET_BITMAP:
1058  break;
1059  }
1060 
1061  s->p = next;
1062  }
1063 }
1064 
1065 /* Respond to a demand active PDU */
1066 static void
1068 {
1069  uint8 type;
1070  uint16 len_src_descriptor, len_combined_caps;
1071 
1073  in_uint16_le(s, len_src_descriptor);
1074  in_uint16_le(s, len_combined_caps);
1075  in_uint8s(s, len_src_descriptor);
1076 
1077  DEBUG(("DEMAND_ACTIVE(id=0x%x)\n", g_rdp_shareid));
1078  rdp_process_server_caps(s, len_combined_caps);
1079 
1084  rdp_recv(&type); /* RDP_PDU_SYNCHRONIZE */
1085  rdp_recv(&type); /* RDP_CTL_COOPERATE */
1086  rdp_recv(&type); /* RDP_CTL_GRANT_CONTROL */
1089 
1090  if (g_rdp_version >= RDP_V5)
1091  {
1093  rdp_send_fonts(3);
1094  }
1095  else
1096  {
1097  rdp_send_fonts(1);
1098  rdp_send_fonts(2);
1099  }
1100 
1101  rdp_recv(&type); /* RDP_PDU_UNKNOWN 0x28 (Fonts?) */
1103 }
1104 
1105 /* Process a colour pointer PDU */
1106 static void
1108 {
1109  uint16 width, height, cache_idx, masklen, datalen;
1110  uint16 x, y;
1111  uint8 *mask;
1112  uint8 *data;
1114 
1115  in_uint16_le(s, cache_idx);
1116  in_uint16_le(s, x);
1117  in_uint16_le(s, y);
1118  in_uint16_le(s, width);
1119  in_uint16_le(s, height);
1120  in_uint16_le(s, masklen);
1121  in_uint16_le(s, datalen);
1122  in_uint8p(s, data, datalen);
1123  in_uint8p(s, mask, masklen);
1124  if ((width != 32) || (height != 32))
1125  {
1126  warning("process_colour_pointer_common: " "width %d height %d\n", width, height);
1127  }
1128 
1129  /* keep hotspot within cursor bounding box */
1130  x = MIN(x, width - 1);
1131  y = MIN(y, height - 1);
1132  cursor = ui_create_cursor(x, y, width, height, mask, data, bpp);
1133  ui_set_cursor(cursor);
1134  cache_put_cursor(cache_idx, cursor);
1135 }
1136 
1137 /* Process a colour pointer PDU */
1138 void
1140 {
1142 }
1143 
1144 /* Process a New Pointer PDU - these pointers have variable bit depth */
1145 void
1147 {
1148  int xor_bpp;
1149 
1150  in_uint16_le(s, xor_bpp);
1151  process_colour_pointer_common(s, xor_bpp);
1152 }
1153 
1154 /* Process a cached pointer PDU */
1155 void
1157 {
1158  uint16 cache_idx;
1159 
1160  in_uint16_le(s, cache_idx);
1161  ui_set_cursor(cache_get_cursor(cache_idx));
1162 }
1163 
1164 /* Process a system pointer PDU */
1165 void
1167 {
1168  uint16 system_pointer_type;
1169 
1170  in_uint16_le(s, system_pointer_type);
1171  switch (system_pointer_type)
1172  {
1173  case RDP_NULL_POINTER:
1175  break;
1176 
1177  default:
1178  unimpl("System pointer message 0x%x\n", system_pointer_type);
1179  }
1180 }
1181 
1182 /* Process a pointer PDU */
1183 static void
1185 {
1186  uint16 message_type;
1187  uint16 x, y;
1188 
1189  in_uint16_le(s, message_type);
1190  in_uint8s(s, 2); /* pad */
1191 
1192  switch (message_type)
1193  {
1194  case RDP_POINTER_MOVE:
1195  in_uint16_le(s, x);
1196  in_uint16_le(s, y);
1197  if (s_check(s))
1198  ui_move_pointer(x, y);
1199  break;
1200 
1201  case RDP_POINTER_COLOR:
1203  break;
1204 
1205  case RDP_POINTER_CACHED:
1207  break;
1208 
1209  case RDP_POINTER_SYSTEM:
1211  break;
1212 
1213  case RDP_POINTER_NEW:
1215  break;
1216 
1217  default:
1218  unimpl("Pointer message 0x%x\n", message_type);
1219  }
1220 }
1221 
1222 /* Process bitmap updates */
1223 void
1225 {
1226  uint16 num_updates;
1228  uint16 cx, cy, bpp, Bpp, compress, bufsize, size;
1229  uint8 *data, *bmpdata;
1230  int i;
1231 
1232  in_uint16_le(s, num_updates);
1233 
1234  for (i = 0; i < num_updates; i++)
1235  {
1236  in_uint16_le(s, left);
1237  in_uint16_le(s, top);
1238  in_uint16_le(s, right);
1239  in_uint16_le(s, bottom);
1240  in_uint16_le(s, width);
1241  in_uint16_le(s, height);
1242  in_uint16_le(s, bpp);
1243  Bpp = (bpp + 7) / 8;
1244  in_uint16_le(s, compress);
1245  in_uint16_le(s, bufsize);
1246 
1247  cx = right - left + 1;
1248  cy = bottom - top + 1;
1249 
1250  DEBUG(("BITMAP_UPDATE(l=%d,t=%d,r=%d,b=%d,w=%d,h=%d,Bpp=%d,cmp=%d)\n",
1251  left, top, right, bottom, width, height, Bpp, compress));
1252 
1253  if (!compress)
1254  {
1255  int y;
1256  bmpdata = (uint8 *) xmalloc(width * height * Bpp);
1257  for (y = 0; y < height; y++)
1258  {
1259  in_uint8a(s, &bmpdata[(height - y - 1) * (width * Bpp)],
1260  width * Bpp);
1261  }
1262  ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata);
1263  xfree(bmpdata);
1264  continue;
1265  }
1266 
1267 
1268  if (compress & 0x400)
1269  {
1270  size = bufsize;
1271  }
1272  else
1273  {
1274  in_uint8s(s, 2); /* pad */
1275  in_uint16_le(s, size);
1276  in_uint8s(s, 4); /* line_size, final_size */
1277  }
1278  in_uint8p(s, data, size);
1279  bmpdata = (uint8 *) xmalloc(width * height * Bpp);
1280  if (bitmap_decompress(bmpdata, width, height, data, size, Bpp))
1281  {
1282  ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata);
1283  }
1284  else
1285  {
1286  DEBUG_RDP5(("Failed to decompress data\n"));
1287  }
1288 
1289  xfree(bmpdata);
1290  }
1291 }
1292 
1293 /* Process a palette update */
1294 void
1296 {
1297  COLOURENTRY *entry;
1298  COLOURMAP map;
1299  RD_HCOLOURMAP hmap;
1300  int i;
1301 
1302  in_uint8s(s, 2); /* pad */
1303  in_uint16_le(s, map.ncolours);
1304  in_uint8s(s, 2); /* pad */
1305 
1306  map.colours = (COLOURENTRY *) xmalloc(sizeof(COLOURENTRY) * map.ncolours);
1307 
1308  DEBUG(("PALETTE(c=%d)\n", map.ncolours));
1309 
1310  for (i = 0; i < map.ncolours; i++)
1311  {
1312  entry = &map.colours[i];
1313  in_uint8(s, entry->red);
1314  in_uint8(s, entry->green);
1315  in_uint8(s, entry->blue);
1316  }
1317 
1318  hmap = ui_create_colourmap(&map);
1319  ui_set_colourmap(hmap);
1320 
1321  xfree(map.colours);
1322 }
1323 
1324 /* Process an update PDU */
1325 static void
1327 {
1328  uint16 update_type, count;
1329 
1330  in_uint16_le(s, update_type);
1331 
1332  ui_begin_update();
1333  switch (update_type)
1334  {
1335  case RDP_UPDATE_ORDERS:
1336  in_uint8s(s, 2); /* pad */
1337  in_uint16_le(s, count);
1338  in_uint8s(s, 2); /* pad */
1339  process_orders(s, count);
1340  break;
1341 
1342  case RDP_UPDATE_BITMAP:
1344  break;
1345 
1346  case RDP_UPDATE_PALETTE:
1347  process_palette(s);
1348  break;
1349 
1351  break;
1352 
1353  default:
1354  unimpl("update %d\n", update_type);
1355  }
1356  ui_end_update();
1357 }
1358 
1359 
1360 /* Process a Save Session Info PDU */
1361 void
1363 {
1364  uint32 infotype;
1365  in_uint32_le(s, infotype);
1366  if (infotype == INFOTYPE_LOGON_EXTENDED_INF)
1367  {
1368  uint32 fieldspresent;
1369 
1370  in_uint8s(s, 2); /* Length */
1371  in_uint32_le(s, fieldspresent);
1372  if (fieldspresent & LOGON_EX_AUTORECONNECTCOOKIE)
1373  {
1374  uint32 len;
1375  uint32 version;
1376 
1377  /* TS_LOGON_INFO_FIELD */
1378  in_uint8s(s, 4); /* cbFieldData */
1379 
1380  /* ARC_SC_PRIVATE_PACKET */
1381  in_uint32_le(s, len);
1382  if (len != 28)
1383  {
1384  warning("Invalid length in Auto-Reconnect packet\n");
1385  return;
1386  }
1387 
1388  in_uint32_le(s, version);
1389  if (version != 1)
1390  {
1391  warning("Unsupported version of Auto-Reconnect packet\n");
1392  return;
1393  }
1394 
1396  in_uint8a(s, g_reconnect_random, 16);
1399  DEBUG(("Saving auto-reconnect cookie, id=%u\n", g_reconnect_logonid));
1400  }
1401  }
1402 }
1403 
1404 
1405 /* Process a disconnect PDU */
1406 void
1408 {
1409  in_uint32_le(s, *ext_disc_reason);
1410 
1411  DEBUG(("Received disconnect PDU\n"));
1412 }
1413 
1414 /* Process data PDU */
1415 static RD_BOOL
1417 {
1418  uint8 data_pdu_type;
1419  uint8 ctype;
1420  uint16 clen;
1421  uint32 len;
1422 
1423  uint32 roff, rlen;
1424 
1425  struct stream *ns = &(g_mppc_dict.ns);
1426 
1427  in_uint8s(s, 6); /* shareid, pad, streamid */
1428  in_uint16_le(s, len);
1429  in_uint8(s, data_pdu_type);
1430  in_uint8(s, ctype);
1431  in_uint16_le(s, clen);
1432  clen -= 18;
1433 
1434  if (ctype & RDP_MPPC_COMPRESSED)
1435  {
1436  if (len > RDP_MPPC_DICT_SIZE)
1437  error("error decompressed packet size exceeds max\n");
1438  if (mppc_expand(s->p, clen, ctype, &roff, &rlen) == -1)
1439  error("error while decompressing packet\n");
1440 
1441  /* len -= 18; */
1442 
1443  /* allocate memory and copy the uncompressed data into the temporary stream */
1444  ns->data = (uint8 *) xrealloc(ns->data, rlen);
1445 
1446  memcpy((ns->data), (unsigned char *) (g_mppc_dict.hist + roff), rlen);
1447 
1448  ns->size = rlen;
1449  ns->end = (ns->data + ns->size);
1450  ns->p = ns->data;
1451  ns->rdp_hdr = ns->p;
1452 
1453  s = ns;
1454  }
1455 
1456  switch (data_pdu_type)
1457  {
1458  case RDP_DATA_PDU_UPDATE:
1459  process_update_pdu(s);
1460  break;
1461 
1462  case RDP_DATA_PDU_CONTROL:
1463  DEBUG(("Received Control PDU\n"));
1464  break;
1465 
1467  DEBUG(("Received Sync PDU\n"));
1468  break;
1469 
1470  case RDP_DATA_PDU_POINTER:
1472  break;
1473 
1474  case RDP_DATA_PDU_BELL:
1475  ui_bell();
1476  break;
1477 
1478  case RDP_DATA_PDU_LOGON:
1479  DEBUG(("Received Logon PDU\n"));
1480  /* User logged on */
1481  process_pdu_logon(s);
1482  break;
1483 
1485  process_disconnect_pdu(s, ext_disc_reason);
1486 
1487  /* We used to return true and disconnect immediately here, but
1488  * Windows Vista sends a disconnect PDU with reason 0 when
1489  * reconnecting to a disconnected session, and MSTSC doesn't
1490  * drop the connection. I think we should just save the status.
1491  */
1492  break;
1493 
1495  warning("Automatic reconnect using cookie, failed.\n");
1496  break;
1497 
1498  default:
1499  unimpl("data PDU %d\n", data_pdu_type);
1500  }
1501  return False;
1502 }
1503 
1504 /* Process redirect PDU from Session Directory */
1505 static RD_BOOL
1506 process_redirect_pdu(STREAM s, RD_BOOL enhanced_redirect /*, uint32 * ext_disc_reason */ )
1507 {
1508  uint32 len;
1509  uint16 redirect_identifier;
1510 
1511  /* reset any previous redirection information */
1512  g_redirect = True;
1518 
1524 
1525  /* these 2 bytes are unknown, seem to be zeros */
1526  in_uint8s(s, 2);
1527 
1528  /* FIXME: Previous implementation only reads 4 bytes which has been working
1529  but todays spec says something different. Investigate and retest
1530  server redirection using WTS 2003 cluster.
1531  */
1532 
1533  if (enhanced_redirect)
1534  {
1535  /* read identifier */
1536  in_uint16_le(s, redirect_identifier);
1537  if (redirect_identifier != 0x0400)
1538  error("Protocol error in server redirection, unexpected data.");
1539 
1540  /* FIXME: skip total length */
1541  in_uint8s(s, 2);
1542 
1543  /* read session_id */
1545  }
1546 
1547  /* read connection flags */
1549 
1551  {
1552  /* read length of ip string */
1553  in_uint32_le(s, len);
1554 
1555  /* read ip string */
1557  }
1558 
1560  {
1561  /* read length of load balance info blob */
1563 
1564  /* reallocate a loadbalance info blob */
1565  if (g_redirect_lb_info != NULL)
1567 
1569 
1570  /* read load balance info blob */
1572  }
1573 
1575  {
1576  /* read length of username string */
1577  in_uint32_le(s, len);
1578 
1579  /* read username string */
1581  }
1582 
1584  {
1585  /* read length of domain string */
1586  in_uint32_le(s, len);
1587 
1588  /* read domain string */
1590  }
1591 
1593  {
1594  /* the information in this blob is either a password or a cookie that
1595  should be passed though as blob and not parsed as a unicode string */
1596 
1597  /* read blob length */
1599 
1600  /* reallocate cookie blob */
1601  if (g_redirect_cookie != NULL)
1603 
1605 
1606  /* read cookie as is */
1608  }
1609 
1611  {
1612  warning("LB_DONTSTOREUSERNAME set\n");
1613  }
1614 
1616  {
1617  warning("LB_SMARTCARD_LOGON set\n");
1618  }
1619 
1621  {
1622  /* By spec this is only for information and doesn't mean that an actual
1623  redirect should be performed. How it should be used is not mentioned. */
1624  g_redirect = False;
1625  }
1626 
1628  {
1629  in_uint32_le(s, len);
1630 
1631  /* Let target fqdn replace target ip address */
1632  if (g_redirect_server)
1633  {
1636  }
1637 
1638  /* read fqdn string */
1640  }
1641 
1643  {
1644  warning("LB_TARGET_NETBIOS set\n");
1645  }
1646 
1648  {
1649  warning("LB_TARGET_NET_ADDRESSES set\n");
1650  }
1651 
1653  {
1654  warning("LB_CLIENT_TSV_URL set\n");
1655  }
1656 
1658  {
1659  warning("LB_SERVER_TSV_CAPABLE set\n");
1660  }
1661 
1663  {
1664  warning("LB_PASSWORD_IS_PK_ENCRYPTED set\n");
1665  }
1666 
1668  {
1669  warning("LB_REDIRECTION_GUID set\n");
1670  }
1671 
1673  {
1674  warning("LB_TARGET_CERTIFICATE set\n");
1675  }
1676 
1677  return True;
1678 }
1679 
1680 /* Process incoming packets */
1681 void
1683 {
1684  while (rdp_loop(deactivated, ext_disc_reason))
1685  {
1687  {
1688  return;
1689  }
1690  }
1691 }
1692 
1693 /* used in uiports and rdp_main_loop, processes the rdp packets waiting */
1694 RD_BOOL
1696 {
1697  uint8 type;
1698  RD_BOOL cont = True;
1699  STREAM s;
1700 
1701  while (cont)
1702  {
1703  s = rdp_recv(&type);
1704  if (s == NULL)
1705  return False;
1706  switch (type)
1707  {
1708  case RDP_PDU_DEMAND_ACTIVE:
1710  *deactivated = False;
1711  break;
1712  case RDP_PDU_DEACTIVATE:
1713  DEBUG(("RDP_PDU_DEACTIVATE\n"));
1714  *deactivated = True;
1715  break;
1716  case RDP_PDU_REDIRECT:
1717  return process_redirect_pdu(s, False);
1718  break;
1720  return process_redirect_pdu(s, True);
1721  break;
1722  case RDP_PDU_DATA:
1723  /* If we got a data PDU, we don't need to keep the password in memory
1724  anymore and therefor we should clear it for security reasons. */
1725  if (g_password[0] != '\0')
1726  memset(g_password, 0, sizeof(g_password));
1727 
1728  process_data_pdu(s, ext_disc_reason);
1729  break;
1730  case 0:
1731  break;
1732  default:
1733  unimpl("PDU %d\n", type);
1734  }
1735  cont = g_next_packet < s->end;
1736  }
1737  return True;
1738 }
1739 
1740 /* Establish a connection up to the RDP layer */
1741 RD_BOOL
1742 rdp_connect(char *server, uint32 flags, char *domain, char *password,
1743  char *command, char *directory, RD_BOOL reconnect)
1744 {
1746  uint32 ext_disc_reason = 0;
1747 
1748  if (!sec_connect(server, g_username, domain, password, reconnect))
1749  return False;
1750 
1751  rdp_send_logon_info(flags, domain, g_username, password, command, directory);
1752 
1753  /* run RDP loop until first licence demand active PDU */
1754  while (!g_rdp_shareid)
1755  {
1756  if (g_network_error)
1757  return False;
1758 
1759  if (!rdp_loop(&deactivated, &ext_disc_reason))
1760  return False;
1761 
1762  if (g_redirect)
1763  return True;
1764  }
1765  return True;
1766 }
1767 
1768 /* Called during redirection to reset the state to support redirection */
1769 void
1771 {
1772  g_next_packet = NULL; /* reset the packet information */
1773  g_rdp_shareid = 0;
1774  sec_reset_state();
1775 }
1776 
1777 /* Disconnect from the RDP layer */
1778 void
1780 {
1781  sec_disconnect();
1782 }
static void rdp_process_bitmap_caps(STREAM s)
Definition: rdp.c:995
unsigned int read_keyboard_state(void)
Definition: uimain.c:632
RD_HCURSOR ui_create_cursor(unsigned int x, unsigned int y, int width, int height, uint8 *andmask, uint8 *xormask, int bpp)
Definition: uimain.c:175
#define out_uint16_le(s, v)
Definition: parse.h:58
#define RDP_SOURCE
Definition: constants.h:330
#define out_uint8p(s, v, n)
Definition: parse.h:93
GLint GLint GLsizei width
Definition: gl.h:1546
RD_BOOL g_network_error
Definition: uimain.c:77
void ui_set_colourmap(RD_HCOLOURMAP map)
Definition: qtewin.cpp:1527
Definition: arc.h:33
GLenum GLclampf GLint GLenum GLuint GLenum GLenum GLsizei GLenum const GLvoid GLfloat GLfloat GLfloat GLfloat GLclampd GLint GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean GLboolean GLboolean GLboolean GLint GLenum GLsizei const GLvoid GLenum GLint GLenum GLint GLint GLsizei GLint GLenum GLint GLint GLint GLint GLsizei GLenum GLsizei const GLuint GLboolean GLenum GLenum GLint GLsizei GLenum GLsizei GLenum const GLvoid GLboolean const GLboolean GLenum const GLdouble const GLfloat const GLdouble const GLfloat GLenum GLint GLint GLint GLint GLint GLint j
Definition: glfuncs.h:98
void process_palette(STREAM s)
Definition: rdp.c:1295
void ui_begin_update(void)
Definition: uimain.c:657
#define RDP_CAPSET_GENERAL
Definition: constants.h:291
static UCHAR ULONG UCHAR ULONG UCHAR * output
Definition: bcrypt.c:29
uint16 ui_get_numlock_state(unsigned int state)
Definition: svgawin.c:1620
RD_BOOL g_desktop_save
Definition: uimain.c:32
unsigned char * rdp_hdr
Definition: parse.h:33
uint16 ncolours
Definition: types.h:66
#define BMPCACHE2_C2_CELLS
Definition: constants.h:284
void rdp_out_unistr(STREAM s, char *string, int len)
Definition: rdp.c:188
void ui_resize_window(void)
Definition: uimain.c:651
#define RDP_MPPC_COMPRESSED
Definition: constants.h:355
RD_BOOL pstcache_init(uint8 cache_id)
Definition: pstcache.c:163
static rfbScreenInfoPtr server
Definition: vnc.c:74
int deactivated
Definition: svgawin.c:63
#define RDP_CAPSET_BMPCACHE
Definition: constants.h:304
RD_BOOL g_encryption
Definition: uimain.c:40
RD_BOOL g_bitmap_cache_persist_enable
Definition: uimain.c:37
#define RDP_CAPLEN_SHARE
Definition: constants.h:318
#define error(str)
Definition: mkdosfs.c:1605
void rdp_disconnect(void)
Definition: rdp.c:1779
void process_orders(STREAM s, uint16 num_orders)
Definition: orders.c:1311
int g_width
Definition: uimain.c:42
time_t g_reconnect_random_ts
Definition: uimain.c:84
char g_reconnect_random[16]
Definition: uimain.c:83
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
int g_height
Definition: uimain.c:43
static void rdp_enum_bmpcache2(void)
Definition: rdp.c:603
#define out_uint8a(s, v, n)
Definition: parse.h:94
RD_BOOL g_bitmap_cache
Definition: uimain.c:39
RD_HCOLOURMAP ui_create_colourmap(COLOURMAP *colours)
Definition: uimain.c:336
char g_codepage[16]
Definition: rdp.c:27
#define RDP_CAPLEN_BMPCACHE2
Definition: constants.h:327
static void rdp_out_control_caps(STREAM s)
Definition: rdp.c:796
GLuint GLuint GLsizei count
Definition: gl.h:1545
unsigned int uint32
Definition: types.h:32
static void rdp_send_control(uint16 action)
Definition: rdp.c:520
char * g_redirect_domain
Definition: uimain.c:58
static void rdp_out_order_caps(STREAM s)
Definition: rdp.c:711
#define free
Definition: debug_ros.c:5
uint8_t entry
Definition: isohybrid.c:63
uint32 ext_disc_reason
Definition: svgawin.c:64
STREAM sec_init(uint32 flags, int maxlen)
Definition: secure.c:419
GLenum GLclampf GLint GLenum GLuint GLenum GLenum GLsizei GLenum const GLvoid GLfloat GLfloat GLfloat GLfloat GLclampd GLint GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean GLboolean GLboolean GLboolean GLint GLenum GLsizei const GLvoid GLenum GLint GLenum GLint GLint GLsizei GLint GLenum GLint GLint GLint GLint GLsizei GLenum GLsizei const GLuint GLboolean GLenum GLenum GLint GLsizei GLenum GLsizei GLenum const GLvoid GLboolean const GLboolean GLenum const GLdouble const GLfloat const GLdouble const GLfloat GLenum GLint GLint GLint GLint GLint GLint GLenum GLfloat GLenum GLint GLenum GLsizei GLenum GLboolean GLenum GLdouble GLenum GLfloat GLenum GLenum GLfloat GLenum GLenum GLdouble GLenum GLenum GLint GLenum GLenum GLint GLenum map
Definition: glfuncs.h:124
GLintptr offset
Definition: glext.h:5920
#define RDP_CAPSET_ACTIVATE
Definition: constants.h:310
RD_BOOL g_polygon_ellipse_orders
Definition: uimain.c:33
#define out_uint32_le(s, v)
Definition: parse.h:59
uint32 g_rdp_shareid
Definition: rdp.c:46
RD_BOOL g_pending_resize
Definition: uimain.c:79
#define RDP_CAPLEN_BRUSHCACHE
Definition: constants.h:324
GLdouble GLdouble t
Definition: gl.h:2047
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define o(x)
Definition: extensions.c:56
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
RD_BOOL g_orders
uint8 g_client_random[SEC_RANDOM_SIZE]
Definition: uimain.c:78
#define out_uint16(s, v)
Definition: parse.h:84
static void rdp_out_bmpcache2_caps(STREAM s)
Definition: rdp.c:771
int errno
__u16 time
Definition: mkdosfs.c:366
static void rdp_process_server_caps(STREAM s, uint16 length)
Definition: rdp.c:1029
GLenum GLuint GLsizei bufsize
Definition: glext.h:7473
unsigned char * data
Definition: parse.h:26
int const JOCTET unsigned int datalen
Definition: jpeglib.h:1027
static void rdp_out_share_caps(STREAM s)
Definition: rdp.c:845
static void process_pointer_pdu(STREAM s)
Definition: rdp.c:1184
#define RDP_CAPLEN_CONTROL
Definition: constants.h:308
#define in_uint8p(s, v, n)
Definition: parse.h:89
#define BMPCACHE2_C1_CELLS
Definition: constants.h:283
GLuint const GLubyte mask[]
Definition: s_context.h:57
DWORD WINAPI GetModuleFileNameA(HINSTANCE hModule, LPSTR lpFilename, DWORD nSize)
Definition: loader.c:546
static void rdp_send_data(STREAM s, uint8 data_pdu_type)
Definition: rdp.c:152
void process_disconnect_pdu(STREAM s, uint32 *ext_disc_reason)
Definition: rdp.c:1407
static void rdp_out_general_caps(STREAM s)
Definition: rdp.c:664
#define SEC_INFO_PKT
Definition: constants.h:104
RD_BOOL sec_connect(char *server, char *username, char *domain, char *password, RD_BOOL reconnect)
Definition: secure.c:1005
#define s_check(s)
Definition: parse.h:42
T MIN(T a, T b)
Definition: polytest.cpp:79
Definition: regsvr.c:103
#define RDP_CAPSET_BITMAP
Definition: constants.h:296
INT INT y
Definition: msvc.h:62
GLuint n
Definition: s_context.h:57
size_t iconv(iconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft)
Definition: win_iconv.c:771
#define out_uint8(s, v)
Definition: parse.h:92
void ui_move_pointer(int x, int y)
Definition: uimain.c:616
GLenum GLclampf GLint i
Definition: glfuncs.h:14
void * xrealloc(void *oldmem, size_t size)
Definition: uimain.c:736
static void rdp_out_brushcache_caps(STREAM s)
Definition: rdp.c:867
static uint8 caps_0x0c[]
Definition: rdp.c:888
void * xmalloc(int size)
Definition: uimain.c:747
#define RDP_MPPC_DICT_SIZE
Definition: constants.h:358
#define RDP_CAPLEN_ACTIVATE
Definition: constants.h:311
void ui_set_null_cursor(void)
Definition: uimain.c:227
#define RDP_CAPSET_CONTROL
Definition: constants.h:307
char * tcp_get_address(void)
Definition: tcp.c:866
#define BMPCACHE2_C0_CELLS
Definition: constants.h:282
#define RDP5_FLAG
Definition: rdp.c:911
RD_BOOL bitmap_decompress(uint8 *output, int width, int height, uint8 *input, int size, int Bpp)
Definition: bitmap.c:884
void process_pdu_logon(STREAM s)
Definition: rdp.c:1362
#define s_pop_layer(s, h)
Definition: parse.h:40
_Out_opt_ int _Out_opt_ int * cy
Definition: commctrl.h:570
uint8 HASH_KEY[8]
Definition: types.h:161
smooth NULL
Definition: ftsmooth.c:416
static const WCHAR version[]
Definition: asmname.c:64
void process_bitmap_updates(STREAM s)
Definition: rdp.c:1224
static void rdp_out_unknown_caps(STREAM s, uint16 id, uint16 length, uint8 *caps)
Definition: rdp.c:903
static STREAM rdp_recv(uint8 *type)
Definition: rdp.c:85
GLint GLint bottom
Definition: glext.h:7726
#define RDP_CAPLEN_ORDER
Definition: constants.h:300
#define RDP_CAPLEN_BMPCACHE
Definition: constants.h:305
#define in_uint8s(s, n)
Definition: parse.h:91
int mppc_expand(uint8 *data, uint32 clen, uint8 ctype, uint32 *roff, uint32 *rlen)
Definition: mppc.c:58
void process_system_pointer_pdu(STREAM s)
Definition: rdp.c:1166
#define RDP_CAPLEN_POINTER
Definition: constants.h:314
#define SEC_ENCRYPT
Definition: constants.h:101
int RD_BOOL
Definition: types.h:21
#define out_uint8s(s, n)
Definition: parse.h:95
static uint8 caps_0x0e[]
Definition: rdp.c:890
uint8 blue
Definition: types.h:59
static void rdp_process_general_caps(STREAM s)
Definition: rdp.c:982
COLOURENTRY * colours
Definition: types.h:67
RD_HCURSOR cache_get_cursor(uint16 cache_idx)
Definition: cache.c:400
void process_new_pointer_pdu(STREAM s)
Definition: rdp.c:1146
static uint8 caps_0x0d[]
Definition: rdp.c:874
#define RDP_CAPSET_SHARE
Definition: constants.h:317
RD_BOOL g_redirect
Definition: uimain.c:55
__kernel_size_t size_t
Definition: linux.h:237
#define True
Definition: types.h:24
uint8 * g_redirect_cookie
Definition: uimain.c:64
static void process_colour_pointer_common(STREAM s, int bpp)
Definition: rdp.c:1107
static void process_demand_active(STREAM s)
Definition: rdp.c:1067
void rdp_main_loop(RD_BOOL *deactivated, uint32 *ext_disc_reason)
Definition: rdp.c:1682
#define False
Definition: types.h:25
Definition: _ctype.h:58
uint32 g_rdp5_performanceflags
Definition: uimain.c:35
GLsizeiptr size
Definition: glext.h:5919
void xfree(void *mem)
Definition: uimain.c:758
uint32 g_redirect_domain_len
Definition: uimain.c:59
Definition: types.h:44
#define WINDOWS_CODEPAGE
Definition: constants.h:24
void sec_reset_state(void)
Definition: secure.c:1039
#define ICONV_CONST
Definition: win32config.h:28
char * g_redirect_server
Definition: uimain.c:56
int ZEXPORT compress(Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen)
Definition: compress.c:68
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
static void rdp_send_logon_info(uint32 flags, char *domain, char *user, char *password, char *program, char *directory)
Definition: rdp.c:343
RD_BOOL g_has_reconnect_random
Definition: uimain.c:85
void rdp_out_unistr_mandatory_null(STREAM s, char *string, int len)
Definition: rdp.c:178
#define RDP_CAPLEN_GENERAL
Definition: constants.h:292
#define SEC_RANDOM_SIZE
Definition: constants.h:91
uint32 g_redirect_server_len
Definition: uimain.c:57
#define MAX_PATH
Definition: compat.h:26
void cache_put_cursor(uint16 cache_idx, RD_HCURSOR cursor)
Definition: cache.c:417
RDPCOMP g_mppc_dict
Definition: mppc.c:55
unsigned char * end
Definition: parse.h:25
GLint left
Definition: glext.h:7726
unsigned char uint8
Definition: types.h:28
GLdouble GLdouble right
Definition: glext.h:10859
void sec_disconnect(void)
Definition: secure.c:1032
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
#define PDU_FLAG_LAST
Definition: constants.h:288
void reset_order_state(void)
Definition: orders.c:1454
GLbitfield flags
Definition: glext.h:7161
#define BMPCACHE2_FLAG_PERSIST
Definition: constants.h:328
uint32 g_reconnect_logonid
Definition: uimain.c:82
GLint GLint GLsizei GLsizei GLsizei depth
Definition: gl.h:1546
void rdp_send_input(uint32 time, uint16 message_type, uint16 device_flags, uint16 param1, uint16 param2)
Definition: rdp.c:551
uint32 g_redirect_session_id
Definition: uimain.c:67
Definition: mxnamespace.c:44
uint32 g_redirect_lb_info_len
Definition: uimain.c:63
unsigned int size
Definition: parse.h:27
Definition: parse.h:22
T1_FIELD_DICT_PRIVATE password
Definition: t1tokens.h:64
enum _RDP_VERSION RDP_VERSION
void rdp_reset_state(void)
Definition: rdp.c:1770
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
RDP_VERSION g_rdp_version
Definition: uimain.c:74
GLdouble s
Definition: gl.h:2039
iconv_t iconv_open(const char *tocode, const char *fromcode)
Definition: win_iconv.c:730
#define PDU_FLAG_FIRST
Definition: constants.h:287
void ui_paint_bitmap(int x, int y, int cx, int cy, int width, int height, uint8 *data)
Definition: uimain.c:307
static void rdp_out_colcache_caps(STREAM s)
Definition: rdp.c:856
char g_password[256]
Definition: uimain.c:28
#define RDP_CAPSET_BMPCACHE2
Definition: constants.h:326
_CRTIMP struct tm *__cdecl localtime(const time_t *_Time)
Definition: time.h:426
uint16 g_mcs_userid
Definition: mcs.c:23
void ui_end_update(void)
Definition: uimain.c:664
#define RDP_CAPLEN_BITMAP
Definition: constants.h:297
Definition: types.h:43
static void rdp_send_fonts(uint16 seq)
Definition: rdp.c:647
RD_BOOL g_numlock_sync
Definition: uimain.c:80
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
void sec_send(STREAM s, uint32 flags)
Definition: secure.c:472
char string[160]
Definition: util.h:11
uint8 green
Definition: types.h:58
void ui_set_cursor(HCURSOR)
Definition: qtewin.cpp:1446
#define in_uint8a(s, v, n)
Definition: parse.h:90
#define RDP_CAPSET_BRUSHCACHE
Definition: constants.h:323
#define s_push_layer(s, h, n)
Definition: parse.h:39
void hexdump(unsigned char *p, unsigned int len)
Definition: shimdbg.c:234
#define DEBUG_RDP5(args)
Definition: rdesktop.h:141
static void rdp_out_activate_caps(STREAM s)
Definition: rdp.c:809
static unsigned __int64 next
Definition: rand_nt.c:6
uint8 * g_redirect_lb_info
Definition: uimain.c:62
const WCHAR * action
Definition: action.c:7779
static void rdp_out_bitmap_caps(STREAM s)
Definition: rdp.c:690
const char cursor[]
Definition: icontest.c:13
static uint8 caps_0x10[]
Definition: rdp.c:892
GLuint program
Definition: glext.h:6723
#define RDP_CAPLEN_COLCACHE
Definition: constants.h:321
static void process_update_pdu(STREAM s)
Definition: rdp.c:1326
__kernel_time_t time_t
Definition: linux.h:252
INT x
Definition: msvc.h:62
GLuint start
Definition: gl.h:1545
#define iconv_t
Definition: iconv.h:68
unsigned short uint16
Definition: types.h:30
uint32 g_redirect_username_len
Definition: uimain.c:61
#define BMPCACHE2_NUM_PSTCELLS
Definition: constants.h:285
char * g_redirect_username
Definition: uimain.c:60
#define in_uint8(s, v)
Definition: parse.h:88
STREAM sec_recv(uint8 *rdpver)
Definition: secure.c:903
void rdp5_process(STREAM s)
Definition: rdp5.c:28
_CRTIMP time_t __cdecl mktime(struct tm *_Tm)
Definition: time.h:428
static RD_BOOL process_redirect_pdu(STREAM s, RD_BOOL enhanced_redirect)
Definition: rdp.c:1506
static void rdp_out_newpointer_caps(STREAM s)
Definition: rdp.c:833
void process_cached_pointer_pdu(STREAM s)
Definition: rdp.c:1156
RD_BOOL rdp_loop(RD_BOOL *deactivated, uint32 *ext_disc_reason)
Definition: rdp.c:1695
static RD_BOOL process_data_pdu(STREAM s, uint32 *ext_disc_reason)
Definition: rdp.c:1416
#define RDP_INFO_AUTOLOGON
Definition: constants.h:335
static void rdp_out_pointer_caps(STREAM s)
Definition: rdp.c:822
#define RDP_CAPSET_POINTER
Definition: constants.h:313
unsigned char * p
Definition: parse.h:24
#define out_uint16_be(s, v)
Definition: parse.h:77
int pstcache_enumerate(uint8 id, HASH_KEY *keylist)
Definition: pstcache.c:107
static STREAM rdp_init_data(int maxlen)
Definition: rdp.c:140
static void rdp_out_bmpcache_caps(STREAM s)
Definition: rdp.c:753
_Out_opt_ int * cx
Definition: commctrl.h:570
int g_server_depth
Definition: uimain.c:41
#define RDP_CAPSET_COLCACHE
Definition: constants.h:320
uint16 g_server_rdp_version
Definition: secure.c:105
uint32 g_redirect_cookie_len
Definition: uimain.c:65
uint8 red
Definition: types.h:57
RD_BOOL g_bitmap_compression
Definition: uimain.c:34
#define out_uint32(s, v)
Definition: parse.h:85
void unimpl(char *format,...)
Definition: uimain.c:801
_CRTIMP struct tm *__cdecl gmtime(const time_t *_Time)
Definition: time.h:425
DWORD bpp
Definition: surface.c:181
#define DEBUG(args)
Definition: rdesktop.h:129
int iconv_close(iconv_t cd)
Definition: win_iconv.c:756
RD_BOOL rdp_connect(char *server, uint32 flags, char *domain, char *password, char *command, char *directory, RD_BOOL reconnect)
Definition: rdp.c:1742
GLdouble GLdouble GLdouble GLdouble top
Definition: glext.h:10859
#define s_mark_end(s)
Definition: parse.h:41
void rdssl_hmac_md5(char *key, int keylen, char *data, int len, char *output)
Definition: ssl_calls.c:449
void rdp_in_unistr(STREAM s, int in_len, char **string, uint32 *str_size)
Definition: rdp.c:265
#define RDP_CAPSET_ORDER
Definition: constants.h:299
uint8 hist[RDP_MPPC_DICT_SIZE]
Definition: types.h:191
static void rdp_send_synchronise(void)
Definition: rdp.c:536
#define in_uint32_le(s, v)
Definition: parse.h:56
void ui_bell(void)
Definition: uimain.c:158
uint32 g_redirect_flags
Definition: uimain.c:66
#define memset(x, y, z)
Definition: compat.h:39
static SERVICE_STATUS status
Definition: service.c:31
#define RDP_CAPLEN_NEWPOINTER
Definition: constants.h:315
struct stream ns
Definition: types.h:192
void rdp_send_client_window_status(int status)
Definition: rdp.c:572
uint8 * g_next_packet
Definition: rdp.c:45
void process_colour_pointer_pdu(STREAM s)
Definition: rdp.c:1139
void user(int argc, const char *argv[])
Definition: cmds.c:1350
Definition: path.c:35
char g_username[256]
Definition: uimain.c:25
#define warning(s)
Definition: debug.h:71
#define in_uint16_le(s, v)
Definition: parse.h:55
Definition: path.c:42
static void rdp_send_confirm_active(void)
Definition: rdp.c:914
Definition: ps.c:97