/[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 569 - (hide annotations)
Wed Jan 21 14:40:40 2004 UTC (20 years, 4 months ago) by n-ki
File MIME type: text/plain
File size: 22875 byte(s)
redirection of disk, lptport, printer, comport.

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

  ViewVC Help
Powered by ViewVC 1.1.26