/[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 624 - (hide annotations)
Thu Mar 4 08:11:40 2004 UTC (20 years, 2 months ago) by n-ki
File MIME type: text/plain
File size: 23571 byte(s)
get real ip address, or lp if not avail - volker milde, also part of rdp compression within ifdef 0 from uni patches

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

  ViewVC Help
Powered by ViewVC 1.1.26