/[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 658 - (hide annotations)
Fri Apr 16 11:36:29 2004 UTC (20 years, 1 month ago) by astrand
File MIME type: text/plain
File size: 23942 byte(s)
Small indent fix

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

  ViewVC Help
Powered by ViewVC 1.1.26