/[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 562 - (hide annotations)
Thu Dec 11 17:20:01 2003 UTC (20 years, 5 months ago) by stargo
File MIME type: text/plain
File size: 22637 byte(s)
Hopefully portable timezone implementation by Johan Larsson

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

  ViewVC Help
Powered by ViewVC 1.1.26