/[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 540 - (hide annotations)
Fri Oct 31 20:34:26 2003 UTC (20 years, 6 months ago) by astrand
File MIME type: text/plain
File size: 22476 byte(s)
Replaced C++ comments with C-style

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

  ViewVC Help
Powered by ViewVC 1.1.26