/[rdesktop]/sourceforge.net/trunk/rdesktop/rdp.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Annotation of /sourceforge.net/trunk/rdesktop/rdp.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 637 - (hide annotations)
Mon Mar 15 14:49:12 2004 UTC (20 years, 1 month ago) by stargo
File MIME type: text/plain
File size: 23629 byte(s)
RDP5 Experience patch by Jeroen Meijer <jeroen@oldambt7.com>

1 forsberg 351 /* -*- c-basic-offset: 8 -*-
2 matty 3 rdesktop: A Remote Desktop Protocol client.
3     Protocol services - RDP layer
4 matthewc 207 Copyright (C) Matthew Chapman 1999-2002
5 jsorg71 433
6 matty 3 This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10 jsorg71 433
11 matty 3 This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     GNU General Public License for more details.
15 jsorg71 433
16 matty 3 You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software
18     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19     */
20    
21 stargo 562 #include <time.h>
22 matty 10 #include "rdesktop.h"
23 matty 3
24 jsorg71 381 extern uint16 g_mcs_userid;
25 jsorg71 437 extern char g_username[16];
26     extern BOOL g_bitmap_compression;
27     extern BOOL g_orders;
28     extern BOOL g_encryption;
29 jsorg71 438 extern BOOL g_desktop_save;
30     extern BOOL g_use_rdp5;
31     extern uint16 g_server_rdp_version;
32 stargo 637 extern uint32 g_rdp5_performanceflags;
33 jsorg71 438 extern int g_server_bpp;
34 matty 3
35 jsorg71 438 uint8 *g_next_packet;
36     uint32 g_rdp_shareid;
37 matty 3
38 forsberg 340 #if WITH_DEBUG
39 jsorg71 438 static uint32 g_packetno;
40 forsberg 351 #endif
41 forsberg 340
42 matty 10 /* Receive an RDP packet */
43 matty 25 static STREAM
44 astrand 64 rdp_recv(uint8 * type)
45 matty 3 {
46 matty 10 static STREAM rdp_s;
47     uint16 length, pdu_type;
48 matty 3
49 jsorg71 438 if ((rdp_s == NULL) || (g_next_packet >= rdp_s->end))
50 matty 10 {
51     rdp_s = sec_recv();
52     if (rdp_s == NULL)
53     return NULL;
54 matty 3
55 jsorg71 438 g_next_packet = rdp_s->p;
56 matty 10 }
57     else
58 matty 7 {
59 jsorg71 438 rdp_s->p = g_next_packet;
60 matty 7 }
61    
62 matty 10 in_uint16_le(rdp_s, length);
63 jsorg71 283 /* 32k packets are really 8, keepalive fix */
64     if (length == 0x8000)
65     {
66 jsorg71 438 g_next_packet += 8;
67 jsorg71 283 *type = 0;
68     return rdp_s;
69     }
70 matty 10 in_uint16_le(rdp_s, pdu_type);
71 matty 24 in_uint8s(rdp_s, 2); /* userid */
72 matty 10 *type = pdu_type & 0xf;
73 matty 7
74 matty 30 #if WITH_DEBUG
75 jsorg71 438 DEBUG(("RDP packet #%d, (type %x)\n", ++g_packetno, *type));
76 matthewc 513 hexdump(g_next_packet, length);
77 matty 28 #endif /* */
78 matty 7
79 jsorg71 438 g_next_packet += length;
80 matty 10 return rdp_s;
81 matty 3 }
82    
83 matty 10 /* Initialise an RDP data packet */
84 matty 25 static STREAM
85     rdp_init_data(int maxlen)
86 matty 3 {
87 matty 10 STREAM s;
88 matty 3
89 jsorg71 437 s = sec_init(g_encryption ? SEC_ENCRYPT : 0, maxlen + 18);
90 matty 10 s_push_layer(s, rdp_hdr, 18);
91    
92     return s;
93 matty 3 }
94    
95 matty 10 /* Send an RDP data packet */
96 matty 25 static void
97     rdp_send_data(STREAM s, uint8 data_pdu_type)
98 matty 9 {
99 matty 10 uint16 length;
100 matty 9
101 matty 10 s_pop_layer(s, rdp_hdr);
102     length = s->end - s->p;
103 matty 9
104 matty 10 out_uint16_le(s, length);
105     out_uint16_le(s, (RDP_PDU_DATA | 0x10));
106 jsorg71 381 out_uint16_le(s, (g_mcs_userid + 1001));
107 matty 9
108 jsorg71 438 out_uint32_le(s, g_rdp_shareid);
109 matty 24 out_uint8(s, 0); /* pad */
110     out_uint8(s, 1); /* streamid */
111 n-ki 176 out_uint16_le(s, (length - 14));
112 matty 10 out_uint8(s, data_pdu_type);
113 matty 24 out_uint8(s, 0); /* compress_type */
114     out_uint16(s, 0); /* compress_len */
115 matty 3
116 jsorg71 437 sec_send(s, g_encryption ? SEC_ENCRYPT : 0);
117 matty 3 }
118    
119 matty 10 /* Output a string in Unicode */
120 matty 25 void
121     rdp_out_unistr(STREAM s, char *string, int len)
122 matty 3 {
123 matty 10 int i = 0, j = 0;
124 matty 9
125 matty 10 len += 2;
126 matty 9
127 matty 10 while (i < len)
128 matty 9 {
129 matty 10 s->p[i++] = string[j++];
130     s->p[i++] = 0;
131 matty 9 }
132    
133 matty 10 s->p += len;
134 matty 3 }
135    
136 n-ki 569 /* Input a string in Unicode
137     *
138     * Returns str_len of string
139     */
140     int
141     rdp_in_unistr(STREAM s, char *string, int uni_len)
142     {
143     int i = 0;
144    
145     while (i < uni_len / 2)
146     {
147     in_uint8a(s, &string[i++], 1);
148     in_uint8s(s, 1);
149     }
150    
151     return i - 1;
152     }
153    
154    
155 matty 10 /* Parse a logon info packet */
156 matty 25 static void
157     rdp_send_logon_info(uint32 flags, char *domain, char *user,
158     char *password, char *program, char *directory)
159 matty 3 {
160 n-ki 624 char *ipaddr = tcp_get_address();
161 matty 24 int len_domain = 2 * strlen(domain);
162     int len_user = 2 * strlen(user);
163     int len_password = 2 * strlen(password);
164     int len_program = 2 * strlen(program);
165 matty 10 int len_directory = 2 * strlen(directory);
166 n-ki 624 int len_ip = 2 * strlen(ipaddr);
167 forsberg 371 int len_dll = 2 * strlen("C:\\WINNT\\System32\\mstscax.dll");
168     int packetlen = 0;
169 jsorg71 437 uint32 sec_flags = g_encryption ? (SEC_LOGON_INFO | SEC_ENCRYPT) : SEC_LOGON_INFO;
170 matty 10 STREAM s;
171 stargo 562 time_t t = time(NULL);
172     time_t tzone;
173 matty 3
174 n-ki 624 #if 0
175     // enable rdp compression
176     flags |= RDP_COMPRESSION;
177     #endif
178    
179 jsorg71 438 if (!g_use_rdp5 || 1 == g_server_rdp_version)
180 forsberg 351 {
181     DEBUG_RDP5(("Sending RDP4-style Logon packet\n"));
182 matty 3
183 forsberg 351 s = sec_init(sec_flags, 18 + len_domain + len_user + len_password
184     + len_program + len_directory + 10);
185 matty 3
186 forsberg 351 out_uint32(s, 0);
187     out_uint32_le(s, flags);
188     out_uint16_le(s, len_domain);
189     out_uint16_le(s, len_user);
190     out_uint16_le(s, len_password);
191     out_uint16_le(s, len_program);
192     out_uint16_le(s, len_directory);
193     rdp_out_unistr(s, domain, len_domain);
194     rdp_out_unistr(s, user, len_user);
195     rdp_out_unistr(s, password, len_password);
196     rdp_out_unistr(s, program, len_program);
197     rdp_out_unistr(s, directory, len_directory);
198     }
199     else
200     {
201 forsberg 371 flags |= RDP_LOGON_BLOB;
202 forsberg 351 DEBUG_RDP5(("Sending RDP5-style Logon packet\n"));
203 astrand 540 packetlen = 4 + /* Unknown uint32 */
204     4 + /* flags */
205     2 + /* len_domain */
206     2 + /* len_user */
207     (flags & RDP_LOGON_AUTO ? 2 : 0) + /* len_password */
208     (flags & RDP_LOGON_BLOB ? 2 : 0) + /* Length of BLOB */
209     2 + /* len_program */
210     2 + /* len_directory */
211     (0 < len_domain ? len_domain : 2) + /* domain */
212     len_user + (flags & RDP_LOGON_AUTO ? len_password : 0) + 0 + /* We have no 512 byte BLOB. Perhaps we must? */
213     (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO) ? 2 : 0) + /* After the BLOB is a unknown int16. If there is a BLOB, that is. */
214     (0 < len_program ? len_program : 2) + (0 < len_directory ? len_directory : 2) + 2 + /* Unknown (2) */
215     2 + /* Client ip length */
216     len_ip + /* Client ip */
217     2 + /* DLL string length */
218     len_dll + /* DLL string */
219     2 + /* Unknown */
220     2 + /* Unknown */
221     64 + /* Time zone #0 */
222     2 + /* Unknown */
223     64 + /* Time zone #1 */
224     32; /* Unknown */
225 forsberg 410
226     s = sec_init(sec_flags, packetlen);
227 forsberg 371 DEBUG_RDP5(("Called sec_init with packetlen %d\n", packetlen));
228 forsberg 351
229 astrand 540 out_uint32(s, 0); /* Unknown */
230 forsberg 351 out_uint32_le(s, flags);
231     out_uint16_le(s, len_domain);
232     out_uint16_le(s, len_user);
233     if (flags & RDP_LOGON_AUTO)
234     {
235     out_uint16_le(s, len_password);
236 forsberg 371
237 forsberg 351 }
238 forsberg 410 if (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO))
239     {
240 forsberg 371 out_uint16_le(s, 0);
241     }
242 forsberg 351 out_uint16_le(s, len_program);
243     out_uint16_le(s, len_directory);
244 forsberg 371 if (0 < len_domain)
245     rdp_out_unistr(s, domain, len_domain);
246 forsberg 410 else
247 forsberg 371 out_uint16_le(s, 0);
248     rdp_out_unistr(s, user, len_user);
249 forsberg 351 if (flags & RDP_LOGON_AUTO)
250     {
251     rdp_out_unistr(s, password, len_password);
252     }
253 forsberg 410 if (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO))
254     {
255 forsberg 371 out_uint16_le(s, 0);
256     }
257 forsberg 410 if (0 < len_program)
258     {
259 forsberg 351 rdp_out_unistr(s, program, len_program);
260 forsberg 410
261     }
262     else
263     {
264 forsberg 371 out_uint16_le(s, 0);
265     }
266 forsberg 410 if (0 < len_directory)
267     {
268 forsberg 351 rdp_out_unistr(s, directory, len_directory);
269 forsberg 410 }
270     else
271     {
272 forsberg 371 out_uint16_le(s, 0);
273 jsorg71 376 }
274 forsberg 371 out_uint16_le(s, 2);
275 astrand 540 out_uint16_le(s, len_ip + 2); /* Length of client ip */
276 n-ki 624 rdp_out_unistr(s, ipaddr, len_ip);
277 forsberg 410 out_uint16_le(s, len_dll + 2);
278 forsberg 371 rdp_out_unistr(s, "C:\\WINNT\\System32\\mstscax.dll", len_dll);
279 stargo 562
280 stargo 604 tzone = (mktime(gmtime(&t)) - mktime(localtime(&t))) / 60;
281     out_uint32_le(s, tzone);
282 stargo 559
283 forsberg 410 rdp_out_unistr(s, "GTB, normaltid", 2 * strlen("GTB, normaltid"));
284     out_uint8s(s, 62 - 2 * strlen("GTB, normaltid"));
285 forsberg 351
286     out_uint32_le(s, 0x0a0000);
287     out_uint32_le(s, 0x050000);
288 forsberg 371 out_uint32_le(s, 3);
289     out_uint32_le(s, 0);
290     out_uint32_le(s, 0);
291 forsberg 351
292 forsberg 410 rdp_out_unistr(s, "GTB, sommartid", 2 * strlen("GTB, sommartid"));
293     out_uint8s(s, 62 - 2 * strlen("GTB, sommartid"));
294    
295 forsberg 371 out_uint32_le(s, 0x30000);
296 forsberg 351 out_uint32_le(s, 0x050000);
297     out_uint32_le(s, 2);
298 matthewc 365 out_uint32(s, 0);
299 forsberg 351 out_uint32_le(s, 0xffffffc4);
300     out_uint32_le(s, 0xfffffffe);
301 stargo 637 out_uint32_le(s, g_rdp5_performanceflags);
302 matthewc 365 out_uint32(s, 0);
303 forsberg 351
304 forsberg 371
305 forsberg 351 }
306 matty 10 s_mark_end(s);
307     sec_send(s, sec_flags);
308 matty 3 }
309    
310 matty 10 /* Send a control PDU */
311 matty 25 static void
312     rdp_send_control(uint16 action)
313 matty 3 {
314 matty 10 STREAM s;
315 matty 9
316 matty 10 s = rdp_init_data(8);
317 matty 9
318 matty 10 out_uint16_le(s, action);
319 matty 24 out_uint16(s, 0); /* userid */
320     out_uint32(s, 0); /* control id */
321 matty 9
322 matty 10 s_mark_end(s);
323     rdp_send_data(s, RDP_DATA_PDU_CONTROL);
324 matty 3 }
325    
326 matty 10 /* Send a synchronisation PDU */
327 matty 25 static void
328 matthewc 192 rdp_send_synchronise(void)
329 matty 3 {
330 matty 10 STREAM s;
331 matty 9
332 matty 10 s = rdp_init_data(4);
333 matty 9
334 matty 24 out_uint16_le(s, 1); /* type */
335 matty 10 out_uint16_le(s, 1002);
336 matty 9
337 matty 10 s_mark_end(s);
338     rdp_send_data(s, RDP_DATA_PDU_SYNCHRONISE);
339 matty 3 }
340    
341 matty 10 /* Send a single input event */
342 matty 25 void
343 astrand 82 rdp_send_input(uint32 time, uint16 message_type, uint16 device_flags, uint16 param1, uint16 param2)
344 matty 3 {
345 matty 10 STREAM s;
346 matty 9
347 matty 10 s = rdp_init_data(16);
348 matty 9
349 matty 24 out_uint16_le(s, 1); /* number of events */
350     out_uint16(s, 0); /* pad */
351 matty 9
352 matty 10 out_uint32_le(s, time);
353     out_uint16_le(s, message_type);
354     out_uint16_le(s, device_flags);
355     out_uint16_le(s, param1);
356     out_uint16_le(s, param2);
357 matty 9
358 matty 10 s_mark_end(s);
359     rdp_send_data(s, RDP_DATA_PDU_INPUT);
360 matty 3 }
361    
362 matty 10 /* Send an (empty) font information PDU */
363 matty 25 static void
364     rdp_send_fonts(uint16 seq)
365 matty 3 {
366 matty 10 STREAM s;
367 matty 3
368 matty 10 s = rdp_init_data(8);
369 matty 9
370 matty 10 out_uint16(s, 0); /* number of fonts */
371     out_uint16_le(s, 0x3e); /* unknown */
372     out_uint16_le(s, seq); /* unknown */
373     out_uint16_le(s, 0x32); /* entry size */
374 matty 9
375 matty 10 s_mark_end(s);
376     rdp_send_data(s, RDP_DATA_PDU_FONT2);
377 matty 3 }
378    
379 matty 10 /* Output general capability set */
380 matty 25 static void
381     rdp_out_general_caps(STREAM s)
382 matty 3 {
383 matty 10 out_uint16_le(s, RDP_CAPSET_GENERAL);
384     out_uint16_le(s, RDP_CAPLEN_GENERAL);
385 matty 3
386 matty 10 out_uint16_le(s, 1); /* OS major type */
387     out_uint16_le(s, 3); /* OS minor type */
388 matty 24 out_uint16_le(s, 0x200); /* Protocol version */
389 matty 10 out_uint16(s, 0); /* Pad */
390     out_uint16(s, 0); /* Compression types */
391 jsorg71 438 out_uint16_le(s, g_use_rdp5 ? 0x40d : 0);
392 forsberg 351 /* Pad, according to T.128. 0x40d seems to
393     trigger
394     the server to start sending RDP5 packets.
395     However, the value is 0x1d04 with W2KTSK and
396     NT4MS. Hmm.. Anyway, thankyou, Microsoft,
397     for sending such information in a padding
398     field.. */
399 matty 10 out_uint16(s, 0); /* Update capability */
400     out_uint16(s, 0); /* Remote unshare capability */
401     out_uint16(s, 0); /* Compression level */
402     out_uint16(s, 0); /* Pad */
403 matty 3 }
404    
405 matty 10 /* Output bitmap capability set */
406 matty 25 static void
407     rdp_out_bitmap_caps(STREAM s)
408 matty 9 {
409 matty 10 out_uint16_le(s, RDP_CAPSET_BITMAP);
410     out_uint16_le(s, RDP_CAPLEN_BITMAP);
411 matty 9
412 matty 10 out_uint16_le(s, 8); /* Preferred BPP */
413 n-ki 176 out_uint16_le(s, 1); /* Receive 1 BPP */
414     out_uint16_le(s, 1); /* Receive 4 BPP */
415 matty 10 out_uint16_le(s, 1); /* Receive 8 BPP */
416     out_uint16_le(s, 800); /* Desktop width */
417     out_uint16_le(s, 600); /* Desktop height */
418     out_uint16(s, 0); /* Pad */
419     out_uint16(s, 0); /* Allow resize */
420 jsorg71 437 out_uint16_le(s, g_bitmap_compression ? 1 : 0); /* Support compression */
421 matty 10 out_uint16(s, 0); /* Unknown */
422     out_uint16_le(s, 1); /* Unknown */
423     out_uint16(s, 0); /* Pad */
424 matty 9 }
425    
426 matty 10 /* Output order capability set */
427 matty 25 static void
428     rdp_out_order_caps(STREAM s)
429 matty 3 {
430 matty 10 uint8 order_caps[32];
431 matty 3
432 matty 9
433 matty 28 memset(order_caps, 0, 32);
434     order_caps[0] = 1; /* dest blt */
435     order_caps[1] = 1; /* pat blt */
436     order_caps[2] = 1; /* screen blt */
437 matthewc 161 order_caps[3] = 1; /* required for memblt? */
438 matty 28 order_caps[8] = 1; /* line */
439     order_caps[9] = 1; /* line */
440     order_caps[10] = 1; /* rect */
441 jsorg71 438 order_caps[11] = (g_desktop_save == False ? 0 : 1); /* desksave */
442 matty 28 order_caps[13] = 1; /* memblt */
443     order_caps[14] = 1; /* triblt */
444     order_caps[22] = 1; /* polyline */
445     order_caps[27] = 1; /* text2 */
446 matty 10 out_uint16_le(s, RDP_CAPSET_ORDER);
447     out_uint16_le(s, RDP_CAPLEN_ORDER);
448 matty 9
449 matty 10 out_uint8s(s, 20); /* Terminal desc, pad */
450     out_uint16_le(s, 1); /* Cache X granularity */
451     out_uint16_le(s, 20); /* Cache Y granularity */
452     out_uint16(s, 0); /* Pad */
453     out_uint16_le(s, 1); /* Max order level */
454     out_uint16_le(s, 0x147); /* Number of fonts */
455 matty 24 out_uint16_le(s, 0x2a); /* Capability flags */
456 matty 10 out_uint8p(s, order_caps, 32); /* Orders supported */
457     out_uint16_le(s, 0x6a1); /* Text capability flags */
458     out_uint8s(s, 6); /* Pad */
459 jsorg71 438 out_uint32_le(s, g_desktop_save == False ? 0 : 0x38400); /* Desktop cache size */
460 matty 10 out_uint32(s, 0); /* Unknown */
461 n-ki 176 out_uint32_le(s, 0x4e4); /* Unknown */
462 matty 9 }
463    
464 matty 10 /* Output bitmap cache capability set */
465 matty 25 static void
466     rdp_out_bmpcache_caps(STREAM s)
467 matty 9 {
468 jsorg71 433 int Bpp;
469 matty 10 out_uint16_le(s, RDP_CAPSET_BMPCACHE);
470     out_uint16_le(s, RDP_CAPLEN_BMPCACHE);
471 matty 3
472 jsorg71 438 Bpp = (g_server_bpp + 7) / 8;
473 matty 24 out_uint8s(s, 24); /* unused */
474     out_uint16_le(s, 0x258); /* entries */
475 jsorg71 433 out_uint16_le(s, 0x100 * Bpp); /* max cell size */
476 matty 24 out_uint16_le(s, 0x12c); /* entries */
477 jsorg71 433 out_uint16_le(s, 0x400 * Bpp); /* max cell size */
478 matty 24 out_uint16_le(s, 0x106); /* entries */
479 jsorg71 433 out_uint16_le(s, 0x1000 * Bpp); /* max cell size */
480 matty 9 }
481    
482 matty 10 /* Output control capability set */
483 matty 25 static void
484     rdp_out_control_caps(STREAM s)
485 matty 9 {
486 matty 10 out_uint16_le(s, RDP_CAPSET_CONTROL);
487     out_uint16_le(s, RDP_CAPLEN_CONTROL);
488 matty 9
489 matty 10 out_uint16(s, 0); /* Control capabilities */
490     out_uint16(s, 0); /* Remote detach */
491     out_uint16_le(s, 2); /* Control interest */
492     out_uint16_le(s, 2); /* Detach interest */
493 matty 9 }
494    
495 matty 10 /* Output activation capability set */
496 matty 25 static void
497     rdp_out_activate_caps(STREAM s)
498 matty 9 {
499 matty 10 out_uint16_le(s, RDP_CAPSET_ACTIVATE);
500     out_uint16_le(s, RDP_CAPLEN_ACTIVATE);
501 matty 9
502 matty 10 out_uint16(s, 0); /* Help key */
503     out_uint16(s, 0); /* Help index key */
504     out_uint16(s, 0); /* Extended help key */
505     out_uint16(s, 0); /* Window activate */
506 matty 9 }
507    
508 matty 10 /* Output pointer capability set */
509 matty 25 static void
510     rdp_out_pointer_caps(STREAM s)
511 matty 9 {
512 matty 10 out_uint16_le(s, RDP_CAPSET_POINTER);
513     out_uint16_le(s, RDP_CAPLEN_POINTER);
514 matty 9
515 matty 10 out_uint16(s, 0); /* Colour pointer */
516     out_uint16_le(s, 20); /* Cache size */
517 matty 9 }
518    
519 matty 10 /* Output share capability set */
520 matty 25 static void
521     rdp_out_share_caps(STREAM s)
522 matty 3 {
523 matty 10 out_uint16_le(s, RDP_CAPSET_SHARE);
524     out_uint16_le(s, RDP_CAPLEN_SHARE);
525 matty 3
526 matty 10 out_uint16(s, 0); /* userid */
527     out_uint16(s, 0); /* pad */
528 matty 9 }
529 matty 3
530 matty 10 /* Output colour cache capability set */
531 matty 25 static void
532     rdp_out_colcache_caps(STREAM s)
533 matty 9 {
534 matty 10 out_uint16_le(s, RDP_CAPSET_COLCACHE);
535     out_uint16_le(s, RDP_CAPLEN_COLCACHE);
536 matty 3
537 matty 10 out_uint16_le(s, 6); /* cache size */
538     out_uint16(s, 0); /* pad */
539 matty 3 }
540    
541 matty 10 static uint8 canned_caps[] = {
542 matty 24 0x01, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00, 0x04,
543     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,
544 matty 25 0x00, 0x00, 0x00, 0x00, 0x00,
545 matty 24 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
546 matty 25 0x00, 0x00, 0x00, 0x00, 0x00,
547 matty 24 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
548 matty 25 0x00, 0x00, 0x00, 0x00, 0x00,
549 matty 24 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
550 matty 25 0x00, 0x00, 0x00, 0x00, 0x00,
551 matty 24 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
552 matty 25 0x0C, 0x00, 0x08, 0x00, 0x01,
553 matty 24 0x00, 0x00, 0x00, 0x0E, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00,
554 matty 25 0x10, 0x00, 0x34, 0x00, 0xFE,
555 matty 24 0x00, 0x04, 0x00, 0xFE, 0x00, 0x04, 0x00, 0xFE, 0x00, 0x08, 0x00,
556 matty 25 0xFE, 0x00, 0x08, 0x00, 0xFE,
557 matty 24 0x00, 0x10, 0x00, 0xFE, 0x00, 0x20, 0x00, 0xFE, 0x00, 0x40, 0x00,
558 matty 25 0xFE, 0x00, 0x80, 0x00, 0xFE,
559 matty 24 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01,
560 matty 25 0x02, 0x00, 0x00, 0x00
561 matty 10 };
562 matty 3
563 forsberg 351 /* Output unknown capability sets (number 13, 12, 14 and 16) */
564 matty 25 static void
565     rdp_out_unknown_caps(STREAM s)
566 matty 3 {
567 matty 10 out_uint16_le(s, RDP_CAPSET_UNKNOWN);
568     out_uint16_le(s, 0x58);
569 matty 24
570     out_uint8p(s, canned_caps, RDP_CAPLEN_UNKNOWN - 4);
571 matty 3 }
572    
573 forsberg 351 #define RDP5_FLAG 0x0030
574 matty 10 /* Send a confirm active PDU */
575 matty 25 static void
576 matthewc 192 rdp_send_confirm_active(void)
577 matty 7 {
578 matty 10 STREAM s;
579 jsorg71 437 uint32 sec_flags = g_encryption ? (RDP5_FLAG | SEC_ENCRYPT) : RDP5_FLAG;
580 matty 24 uint16 caplen =
581     RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER +
582     RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE +
583     RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL +
584 astrand 82 RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE + RDP_CAPLEN_UNKNOWN + 4 /* w2k fix, why? */ ;
585 matty 7
586 forsberg 351 s = sec_init(sec_flags, 6 + 14 + caplen + sizeof(RDP_SOURCE));
587 matty 9
588 forsberg 351 out_uint16_le(s, 2 + 14 + caplen + sizeof(RDP_SOURCE));
589     out_uint16_le(s, (RDP_PDU_CONFIRM_ACTIVE | 0x10)); /* Version 1 */
590 jsorg71 381 out_uint16_le(s, (g_mcs_userid + 1001));
591 forsberg 351
592 jsorg71 438 out_uint32_le(s, g_rdp_shareid);
593 matty 24 out_uint16_le(s, 0x3ea); /* userid */
594 matty 10 out_uint16_le(s, sizeof(RDP_SOURCE));
595     out_uint16_le(s, caplen);
596 matty 9
597 matty 10 out_uint8p(s, RDP_SOURCE, sizeof(RDP_SOURCE));
598 matty 24 out_uint16_le(s, 0xd); /* num_caps */
599     out_uint8s(s, 2); /* pad */
600 matty 9
601 matty 10 rdp_out_general_caps(s);
602     rdp_out_bitmap_caps(s);
603     rdp_out_order_caps(s);
604     rdp_out_bmpcache_caps(s);
605     rdp_out_colcache_caps(s);
606     rdp_out_activate_caps(s);
607     rdp_out_control_caps(s);
608     rdp_out_pointer_caps(s);
609     rdp_out_share_caps(s);
610     rdp_out_unknown_caps(s);
611 matty 9
612 matty 10 s_mark_end(s);
613 forsberg 351 sec_send(s, sec_flags);
614 matty 9 }
615    
616 matty 10 /* Respond to a demand active PDU */
617 matty 25 static void
618     process_demand_active(STREAM s)
619 matty 9 {
620 matty 10 uint8 type;
621 matty 9
622 jsorg71 438 in_uint32_le(s, g_rdp_shareid);
623 matty 9
624 jsorg71 438 DEBUG(("DEMAND_ACTIVE(id=0x%x)\n", g_rdp_shareid));
625 matty 9
626 matty 10 rdp_send_confirm_active();
627     rdp_send_synchronise();
628     rdp_send_control(RDP_CTL_COOPERATE);
629     rdp_send_control(RDP_CTL_REQUEST_CONTROL);
630 matty 28 rdp_recv(&type); /* RDP_PDU_SYNCHRONIZE */
631     rdp_recv(&type); /* RDP_CTL_COOPERATE */
632     rdp_recv(&type); /* RDP_CTL_GRANT_CONTROL */
633 astrand 543 rdp_send_input(0, RDP_INPUT_SYNCHRONIZE, 0, ui_get_numlock_state(read_keyboard_state()), 0);
634 matty 10 rdp_send_fonts(1);
635     rdp_send_fonts(2);
636 matty 28 rdp_recv(&type); /* RDP_PDU_UNKNOWN 0x28 */
637 matty 10 reset_order_state();
638 matty 9 }
639    
640 forsberg 351 /* Process a colour pointer PDU */
641     void
642     process_colour_pointer_pdu(STREAM s)
643     {
644     uint16 x, y, width, height, cache_idx, masklen, datalen;
645     uint8 *mask, *data;
646     HCURSOR cursor;
647    
648     in_uint16_le(s, cache_idx);
649     in_uint16_le(s, x);
650     in_uint16_le(s, y);
651     in_uint16_le(s, width);
652     in_uint16_le(s, height);
653     in_uint16_le(s, masklen);
654     in_uint16_le(s, datalen);
655     in_uint8p(s, data, datalen);
656     in_uint8p(s, mask, masklen);
657     cursor = ui_create_cursor(x, y, width, height, mask, data);
658     ui_set_cursor(cursor);
659     cache_put_cursor(cache_idx, cursor);
660     }
661    
662     /* Process a cached pointer PDU */
663     void
664     process_cached_pointer_pdu(STREAM s)
665     {
666     uint16 cache_idx;
667    
668     in_uint16_le(s, cache_idx);
669     ui_set_cursor(cache_get_cursor(cache_idx));
670     }
671    
672 astrand 508 /* Process a system pointer PDU */
673     void
674     process_system_pointer_pdu(STREAM s)
675     {
676     uint16 system_pointer_type;
677 forsberg 351
678 astrand 508 in_uint16(s, system_pointer_type);
679     switch (system_pointer_type)
680     {
681     case RDP_NULL_POINTER:
682     ui_set_null_cursor();
683     break;
684    
685     default:
686     unimpl("System pointer message 0x%x\n", system_pointer_type);
687     }
688     }
689    
690 matty 10 /* Process a pointer PDU */
691 matty 25 static void
692     process_pointer_pdu(STREAM s)
693 matty 9 {
694 matty 10 uint16 message_type;
695 forsberg 351 uint16 x, y;
696 matty 9
697 matty 10 in_uint16_le(s, message_type);
698 matty 24 in_uint8s(s, 2); /* pad */
699 matty 9
700 matty 10 switch (message_type)
701 matty 7 {
702 matty 10 case RDP_POINTER_MOVE:
703     in_uint16_le(s, x);
704     in_uint16_le(s, y);
705     if (s_check(s))
706     ui_move_pointer(x, y);
707     break;
708 matty 9
709 matty 28 case RDP_POINTER_COLOR:
710 forsberg 351 process_colour_pointer_pdu(s);
711 matty 28 break;
712    
713     case RDP_POINTER_CACHED:
714 forsberg 351 process_cached_pointer_pdu(s);
715 matty 28 break;
716    
717 astrand 508 case RDP_POINTER_SYSTEM:
718     process_system_pointer_pdu(s);
719     break;
720    
721 matty 10 default:
722 astrand 508 unimpl("Pointer message 0x%x\n", message_type);
723 matty 7 }
724 matty 9 }
725    
726 matty 10 /* Process bitmap updates */
727 forsberg 351 void
728 matty 25 process_bitmap_updates(STREAM s)
729 matty 9 {
730 matty 10 uint16 num_updates;
731     uint16 left, top, right, bottom, width, height;
732 jsorg71 314 uint16 cx, cy, bpp, Bpp, compress, bufsize, size;
733 matty 28 uint8 *data, *bmpdata;
734 matty 9 int i;
735    
736 matty 10 in_uint16_le(s, num_updates);
737 matty 9
738 matty 10 for (i = 0; i < num_updates; i++)
739 matty 9 {
740 matty 10 in_uint16_le(s, left);
741     in_uint16_le(s, top);
742     in_uint16_le(s, right);
743     in_uint16_le(s, bottom);
744     in_uint16_le(s, width);
745     in_uint16_le(s, height);
746     in_uint16_le(s, bpp);
747 jsorg71 314 Bpp = (bpp + 7) / 8;
748 matty 10 in_uint16_le(s, compress);
749     in_uint16_le(s, bufsize);
750 matty 9
751 matty 10 cx = right - left + 1;
752     cy = bottom - top + 1;
753 matty 7
754 forsberg 351 DEBUG(("BITMAP_UPDATE(l=%d,t=%d,r=%d,b=%d,w=%d,h=%d,Bpp=%d,cmp=%d)\n",
755     left, top, right, bottom, width, height, Bpp, compress));
756 matty 9
757 matthewc 518 /* Server may limit bpp - this is how we find out */
758 astrand 532 if (g_server_bpp != bpp)
759     {
760 matthewc 518 warning("Server limited colour depth to %d bits\n", bpp);
761     g_server_bpp = bpp;
762     }
763    
764 matty 10 if (!compress)
765     {
766 matty 28 int y;
767 forsberg 410 bmpdata = (uint8 *) xmalloc(width * height * Bpp);
768 matty 28 for (y = 0; y < height; y++)
769     {
770 astrand 318 in_uint8a(s, &bmpdata[(height - y - 1) * (width * Bpp)],
771     width * Bpp);
772 matty 28 }
773 astrand 82 ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata);
774 matty 28 xfree(bmpdata);
775     continue;
776 matty 10 }
777 matty 9
778 forsberg 351
779     if (compress & 0x400)
780     {
781     size = bufsize;
782     }
783     else
784     {
785     in_uint8s(s, 2); /* pad */
786     in_uint16_le(s, size);
787     in_uint8s(s, 4); /* line_size, final_size */
788     }
789 matty 10 in_uint8p(s, data, size);
790 forsberg 410 bmpdata = (uint8 *) xmalloc(width * height * Bpp);
791 jsorg71 314 if (bitmap_decompress(bmpdata, width, height, data, size, Bpp))
792 matty 9 {
793 astrand 82 ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata);
794 matty 9 }
795 forsberg 351 else
796     {
797     DEBUG_RDP5(("Failed to decompress data\n"));
798     }
799    
800 matty 28 xfree(bmpdata);
801 matty 10 }
802 matty 9 }
803    
804 matty 10 /* Process a palette update */
805 forsberg 351 void
806 matty 25 process_palette(STREAM s)
807 matty 9 {
808 matthewc 254 COLOURENTRY *entry;
809     COLOURMAP map;
810 matty 10 HCOLOURMAP hmap;
811 matthewc 254 int i;
812 matty 9
813 matty 24 in_uint8s(s, 2); /* pad */
814     in_uint16_le(s, map.ncolours);
815     in_uint8s(s, 2); /* pad */
816 matty 3
817 jsorg71 436 map.colours = (COLOURENTRY *) xmalloc(sizeof(COLOURENTRY) * map.ncolours);
818 matthewc 254
819 forsberg 351 DEBUG(("PALETTE(c=%d)\n", map.ncolours));
820    
821 matthewc 254 for (i = 0; i < map.ncolours; i++)
822     {
823     entry = &map.colours[i];
824     in_uint8(s, entry->red);
825     in_uint8(s, entry->green);
826     in_uint8(s, entry->blue);
827 astrand 260 }
828 matthewc 254
829 matty 10 hmap = ui_create_colourmap(&map);
830     ui_set_colourmap(hmap);
831 matthewc 254
832     xfree(map.colours);
833 matty 3 }
834    
835 matty 10 /* Process an update PDU */
836 matty 25 static void
837     process_update_pdu(STREAM s)
838 matty 9 {
839 forsberg 351 uint16 update_type, count;
840 matty 9
841 matty 10 in_uint16_le(s, update_type);
842 matty 3
843 matty 10 switch (update_type)
844 matty 3 {
845 matty 10 case RDP_UPDATE_ORDERS:
846 forsberg 351 in_uint8s(s, 2); /* pad */
847     in_uint16_le(s, count);
848     in_uint8s(s, 2); /* pad */
849     process_orders(s, count);
850 matty 10 break;
851 matty 3
852 matty 10 case RDP_UPDATE_BITMAP:
853     process_bitmap_updates(s);
854     break;
855 matty 3
856 matty 10 case RDP_UPDATE_PALETTE:
857     process_palette(s);
858     break;
859 matty 3
860 matty 10 case RDP_UPDATE_SYNCHRONIZE:
861     break;
862 matty 9
863 matty 10 default:
864 matty 30 unimpl("update %d\n", update_type);
865 matty 3 }
866    
867     }
868    
869 matty 10 /* Process data PDU */
870 matty 25 static void
871     process_data_pdu(STREAM s)
872 matty 9 {
873 matty 10 uint8 data_pdu_type;
874 n-ki 624 uint8 ctype;
875     uint16 clen;
876     int roff, rlen, len, ret;
877     static struct stream ns;
878     static signed char *dict = 0;
879 matty 9
880 n-ki 624 in_uint8s(s, 6); /* shareid, pad, streamid */
881     in_uint16(s, len);
882 matty 10 in_uint8(s, data_pdu_type);
883 n-ki 624 in_uint8(s, ctype);
884     in_uint16(s, clen);
885     clen -= 18;
886 matty 3
887 n-ki 624 #if 0
888     if (ctype & 0x20)
889     {
890     if (!dict)
891     {
892     dict = (signed char *) malloc(8200 * sizeof(signed char));
893     dict = (signed char *) memset(dict, 0, 8200 * sizeof(signed char));
894     }
895    
896     ret = decompress(s->p, clen, ctype, (signed char *) dict, &roff, &rlen);
897    
898     len -= 18;
899    
900     ns.data = xrealloc(ns.data, len);
901    
902     ns.data = (unsigned char *) memcpy(ns.data, (unsigned char *) (dict + roff), len);
903    
904     ns.size = len;
905     ns.end = ns.data + ns.size;
906     ns.p = ns.data;
907     ns.rdp_hdr = ns.p;
908    
909     s = &ns;
910     }
911     #endif
912    
913 matty 10 switch (data_pdu_type)
914 matty 3 {
915 matty 10 case RDP_DATA_PDU_UPDATE:
916     process_update_pdu(s);
917     break;
918 matty 3
919 matty 10 case RDP_DATA_PDU_POINTER:
920     process_pointer_pdu(s);
921     break;
922 matty 3
923 matty 10 case RDP_DATA_PDU_BELL:
924     ui_bell();
925     break;
926 matty 3
927 matty 10 case RDP_DATA_PDU_LOGON:
928 forsberg 351 DEBUG(("Received Logon PDU\n"));
929 matty 10 /* User logged on */
930     break;
931 matty 3
932 matthewc 522 case RDP_DATA_PDU_DISCONNECT:
933     /* Normally received when user logs out or disconnects from a
934     console session on Windows XP and 2003 Server */
935     DEBUG(("Received disconnect PDU\n"));
936     break;
937    
938 matty 10 default:
939 matty 30 unimpl("data PDU %d\n", data_pdu_type);
940 matty 3 }
941     }
942    
943 matty 10 /* Process incoming packets */
944 forsberg 424 BOOL
945 matthewc 192 rdp_main_loop(void)
946 matty 9 {
947 matty 10 uint8 type;
948     STREAM s;
949 matty 9
950 matty 10 while ((s = rdp_recv(&type)) != NULL)
951 matty 3 {
952 matty 10 switch (type)
953     {
954     case RDP_PDU_DEMAND_ACTIVE:
955     process_demand_active(s);
956     break;
957 matty 3
958 matty 10 case RDP_PDU_DEACTIVATE:
959 forsberg 424 DEBUG(("RDP_PDU_DEACTIVATE\n"));
960 forsberg 426 /* We thought we could detect a clean
961     shutdown of the session by this
962     packet, but it seems Windows 2003
963     is sending us one of these when we
964     reconnect to a disconnected session
965     return True; */
966 matty 10 break;
967 matty 3
968 matty 10 case RDP_PDU_DATA:
969     process_data_pdu(s);
970     break;
971 matty 3
972 jsorg71 283 case 0:
973     break;
974    
975 matty 10 default:
976 matty 30 unimpl("PDU %d\n", type);
977 matty 10 }
978 matty 3 }
979 forsberg 426 return True;
980     /* We want to detect if we got a clean shutdown, but we
981 astrand 435 can't. Se above.
982     return False; */
983 matty 3 }
984    
985 matty 10 /* Establish a connection up to the RDP layer */
986 matty 25 BOOL
987     rdp_connect(char *server, uint32 flags, char *domain, char *password,
988     char *command, char *directory)
989 matty 9 {
990 jsorg71 437 if (!sec_connect(server, g_username))
991 matty 3 return False;
992    
993 jsorg71 437 rdp_send_logon_info(flags, domain, g_username, password, command, directory);
994 matty 10 return True;
995 matty 3 }
996    
997 matty 10 /* Disconnect from the RDP layer */
998 matty 25 void
999 matthewc 192 rdp_disconnect(void)
1000 matty 9 {
1001 matty 10 sec_disconnect();
1002 matty 9 }

  ViewVC Help
Powered by ViewVC 1.1.26