/[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 678 - (hide annotations)
Mon Apr 26 22:31:22 2004 UTC (20 years ago) by jsorg71
File MIME type: text/plain
File size: 25116 byte(s)
fix the -b switch

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

  ViewVC Help
Powered by ViewVC 1.1.26