/[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 559 - (hide annotations)
Thu Dec 11 12:25:38 2003 UTC (20 years, 5 months ago) by stargo
File MIME type: text/plain
File size: 22591 byte(s)
Removed timezone stuff, due to too much portability problems...
Will solve this later
Portability "fix" for rdpsnd_sun.c on openbsd

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

  ViewVC Help
Powered by ViewVC 1.1.26