/[rdesktop]/jpeg/rdesktop/trunk/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 /jpeg/rdesktop/trunk/rdp.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 604 - (hide annotations)
Sat Feb 14 19:30:01 2004 UTC (20 years, 3 months ago) by stargo
Original Path: sourceforge.net/trunk/rdesktop/rdp.c
File MIME type: text/plain
File size: 22847 byte(s)
Timezone patch from Mark Roach/Stephen Sprunk

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

  ViewVC Help
Powered by ViewVC 1.1.26