/[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 676 - (hide annotations)
Tue Apr 20 07:01:21 2004 UTC (20 years, 1 month ago) by astrand
File MIME type: text/plain
File size: 24065 byte(s)
Applied disconnect handling patch from Jeroen Meijer

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 astrand 676 /* Process a disconnect PDU */
890     void
891     process_disconnect_pdu(STREAM s, uint32 * ext_disc_reason)
892     {
893     in_uint32_le(s, *ext_disc_reason);
894    
895     DEBUG(("Received disconnect PDU\n"));
896     }
897    
898 matty 10 /* Process data PDU */
899 astrand 676 static BOOL
900     process_data_pdu(STREAM s, uint32 * ext_disc_reason)
901 matty 9 {
902 matty 10 uint8 data_pdu_type;
903 n-ki 624 uint8 ctype;
904     uint16 clen;
905 astrand 668 int len;
906     #if 0
907     int roff, rlen, ret;
908 n-ki 624 static struct stream ns;
909     static signed char *dict = 0;
910 astrand 668 #endif
911 matty 9
912 n-ki 624 in_uint8s(s, 6); /* shareid, pad, streamid */
913     in_uint16(s, len);
914 matty 10 in_uint8(s, data_pdu_type);
915 n-ki 624 in_uint8(s, ctype);
916     in_uint16(s, clen);
917     clen -= 18;
918 matty 3
919 n-ki 624 #if 0
920     if (ctype & 0x20)
921     {
922     if (!dict)
923     {
924     dict = (signed char *) malloc(8200 * sizeof(signed char));
925     dict = (signed char *) memset(dict, 0, 8200 * sizeof(signed char));
926     }
927    
928     ret = decompress(s->p, clen, ctype, (signed char *) dict, &roff, &rlen);
929    
930     len -= 18;
931    
932     ns.data = xrealloc(ns.data, len);
933    
934     ns.data = (unsigned char *) memcpy(ns.data, (unsigned char *) (dict + roff), len);
935    
936     ns.size = len;
937     ns.end = ns.data + ns.size;
938     ns.p = ns.data;
939     ns.rdp_hdr = ns.p;
940    
941     s = &ns;
942     }
943     #endif
944    
945 matty 10 switch (data_pdu_type)
946 matty 3 {
947 matty 10 case RDP_DATA_PDU_UPDATE:
948     process_update_pdu(s);
949     break;
950 matty 3
951 astrand 676 case RDP_DATA_PDU_CONTROL:
952     DEBUG(("Received Control PDU\n"));
953     break;
954    
955     case RDP_DATA_PDU_SYNCHRONISE:
956     DEBUG(("Received Sync PDU\n"));
957     break;
958    
959 matty 10 case RDP_DATA_PDU_POINTER:
960     process_pointer_pdu(s);
961     break;
962 matty 3
963 matty 10 case RDP_DATA_PDU_BELL:
964     ui_bell();
965     break;
966 matty 3
967 matty 10 case RDP_DATA_PDU_LOGON:
968 forsberg 351 DEBUG(("Received Logon PDU\n"));
969 matty 10 /* User logged on */
970     break;
971 matty 3
972 matthewc 522 case RDP_DATA_PDU_DISCONNECT:
973 astrand 676 process_disconnect_pdu(s, ext_disc_reason);
974     return True;
975 matthewc 522
976 matty 10 default:
977 matty 30 unimpl("data PDU %d\n", data_pdu_type);
978 matty 3 }
979 astrand 676 return False;
980 matty 3 }
981    
982 matty 10 /* Process incoming packets */
983 astrand 676 void
984     rdp_main_loop(BOOL * deactivated, uint32 * ext_disc_reason)
985 matty 9 {
986 matty 10 uint8 type;
987 astrand 676 BOOL disc = False; /* True when a disconnect PDU was received */
988 matty 10 STREAM s;
989 matty 9
990 matty 10 while ((s = rdp_recv(&type)) != NULL)
991 matty 3 {
992 matty 10 switch (type)
993     {
994     case RDP_PDU_DEMAND_ACTIVE:
995     process_demand_active(s);
996 astrand 676 *deactivated = False;
997 matty 10 break;
998 matty 3
999 matty 10 case RDP_PDU_DEACTIVATE:
1000 astrand 676 *deactivated = True;
1001 matty 10 break;
1002 matty 3
1003 matty 10 case RDP_PDU_DATA:
1004 astrand 676 disc = process_data_pdu(s, ext_disc_reason);
1005 matty 10 break;
1006 matty 3
1007 jsorg71 283 case 0:
1008     break;
1009    
1010 matty 10 default:
1011 matty 30 unimpl("PDU %d\n", type);
1012 matty 10 }
1013 astrand 676
1014     if (disc)
1015     {
1016     return;
1017     }
1018 matty 3 }
1019 astrand 676 return;
1020 matty 3 }
1021    
1022 matty 10 /* Establish a connection up to the RDP layer */
1023 matty 25 BOOL
1024     rdp_connect(char *server, uint32 flags, char *domain, char *password,
1025     char *command, char *directory)
1026 matty 9 {
1027 jsorg71 437 if (!sec_connect(server, g_username))
1028 matty 3 return False;
1029    
1030 jsorg71 437 rdp_send_logon_info(flags, domain, g_username, password, command, directory);
1031 matty 10 return True;
1032 matty 3 }
1033    
1034 matty 10 /* Disconnect from the RDP layer */
1035 matty 25 void
1036 matthewc 192 rdp_disconnect(void)
1037 matty 9 {
1038 matty 10 sec_disconnect();
1039 matty 9 }

  ViewVC Help
Powered by ViewVC 1.1.26