00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "rdesktop.h"
00022
00023 extern uint16 mcs_userid;
00024 extern char username[16];
00025 extern BOOL bitmap_compression;
00026 extern BOOL orders;
00027 extern BOOL encryption;
00028 extern BOOL desktop_save;
00029
00030 uint8 *next_packet;
00031 uint32 rdp_shareid;
00032
00033
00034 static STREAM
00035 rdp_init(int maxlen)
00036 {
00037 STREAM s;
00038
00039 s = sec_init(encryption ? SEC_ENCRYPT : 0, maxlen + 6);
00040 s_push_layer(s, rdp_hdr, 6);
00041
00042 return s;
00043 }
00044
00045
00046 static void
00047 rdp_send(STREAM s, uint8 pdu_type)
00048 {
00049 uint16 length;
00050
00051 s_pop_layer(s, rdp_hdr);
00052 length = s->end - s->p;
00053
00054 out_uint16_le(s, length);
00055 out_uint16_le(s, (pdu_type | 0x10));
00056 out_uint16_le(s, (mcs_userid + 1001));
00057
00058 sec_send(s, encryption ? SEC_ENCRYPT : 0);
00059 }
00060
00061
00062 STREAM
00063 rdp_recv(uint8 * type)
00064 {
00065 static STREAM rdp_s;
00066 uint16 length, pdu_type;
00067
00068 if ((rdp_s == NULL) || (next_packet >= rdp_s->end))
00069 {
00070 rdp_s = sec_recv();
00071 if (rdp_s == NULL)
00072 return NULL;
00073
00074 next_packet = rdp_s->p;
00075 }
00076 else
00077 {
00078 rdp_s->p = next_packet;
00079 }
00080
00081 in_uint16_le(rdp_s, length);
00082
00083 if (length == 0x8000)
00084 {
00085 next_packet += 8;
00086 *type = 0;
00087 return rdp_s;
00088 }
00089 in_uint16_le(rdp_s, pdu_type);
00090 in_uint8s(rdp_s, 2);
00091 *type = pdu_type & 0xf;
00092
00093 #if WITH_DEBUG
00094 DEBUG(("RDP packet (type %x):\n", *type));
00095 hexdump(next_packet, length);
00096 #endif
00097
00098 next_packet += length;
00099 return rdp_s;
00100 }
00101
00102
00103 static STREAM
00104 rdp_init_data(int maxlen)
00105 {
00106 STREAM s;
00107
00108 s = sec_init(encryption ? SEC_ENCRYPT : 0, maxlen + 18);
00109 s_push_layer(s, rdp_hdr, 18);
00110
00111 return s;
00112 }
00113
00114
00115 static void
00116 rdp_send_data(STREAM s, uint8 data_pdu_type)
00117 {
00118 uint16 length;
00119
00120 s_pop_layer(s, rdp_hdr);
00121 length = s->end - s->p;
00122
00123 out_uint16_le(s, length);
00124 out_uint16_le(s, (RDP_PDU_DATA | 0x10));
00125 out_uint16_le(s, (mcs_userid + 1001));
00126
00127 out_uint32_le(s, rdp_shareid);
00128 out_uint8(s, 0);
00129 out_uint8(s, 1);
00130 out_uint16_le(s, (length - 14));
00131 out_uint8(s, data_pdu_type);
00132 out_uint8(s, 0);
00133 out_uint16(s, 0);
00134
00135 sec_send(s, encryption ? SEC_ENCRYPT : 0);
00136 }
00137
00138
00139 void
00140 rdp_out_unistr(STREAM s, char *string, int len)
00141 {
00142 int i = 0, j = 0;
00143
00144 len += 2;
00145
00146 while (i < len)
00147 {
00148 s->p[i++] = string[j++];
00149 s->p[i++] = 0;
00150 }
00151
00152 s->p += len;
00153 }
00154
00155
00156 static void
00157 rdp_send_logon_info(uint32 flags, char *domain, char *user,
00158 char *password, char *program, char *directory)
00159 {
00160 int len_domain = 2 * strlen(domain);
00161 int len_user = 2 * strlen(user);
00162 int len_password = 2 * strlen(password);
00163 int len_program = 2 * strlen(program);
00164 int len_directory = 2 * strlen(directory);
00165 uint32 sec_flags = encryption ? (SEC_LOGON_INFO | SEC_ENCRYPT) : SEC_LOGON_INFO;
00166 STREAM s;
00167
00168 s = sec_init(sec_flags, 18 + len_domain + len_user + len_password
00169 + len_program + len_directory + 10);
00170
00171 out_uint32(s, 0);
00172 out_uint32_le(s, flags);
00173 out_uint16_le(s, len_domain);
00174 out_uint16_le(s, len_user);
00175 out_uint16_le(s, len_password);
00176 out_uint16_le(s, len_program);
00177 out_uint16_le(s, len_directory);
00178 rdp_out_unistr(s, domain, len_domain);
00179 rdp_out_unistr(s, user, len_user);
00180 rdp_out_unistr(s, password, len_password);
00181 rdp_out_unistr(s, program, len_program);
00182 rdp_out_unistr(s, directory, len_directory);
00183
00184 s_mark_end(s);
00185 sec_send(s, sec_flags);
00186 }
00187
00188
00189 static void
00190 rdp_send_control(uint16 action)
00191 {
00192 STREAM s;
00193
00194 s = rdp_init_data(8);
00195
00196 out_uint16_le(s, action);
00197 out_uint16(s, 0);
00198 out_uint32(s, 0);
00199
00200 s_mark_end(s);
00201 rdp_send_data(s, RDP_DATA_PDU_CONTROL);
00202 }
00203
00204
00205 static void
00206 rdp_send_synchronise(void)
00207 {
00208 STREAM s;
00209
00210 s = rdp_init_data(4);
00211
00212 out_uint16_le(s, 1);
00213 out_uint16_le(s, 1002);
00214
00215 s_mark_end(s);
00216 rdp_send_data(s, RDP_DATA_PDU_SYNCHRONISE);
00217 }
00218
00219
00220 void
00221 rdp_send_input(uint32 time, uint16 message_type, uint16 device_flags, uint16 param1, uint16 param2)
00222 {
00223 STREAM s;
00224
00225 s = rdp_init_data(16);
00226
00227 out_uint16_le(s, 1);
00228 out_uint16(s, 0);
00229
00230 out_uint32_le(s, time);
00231 out_uint16_le(s, message_type);
00232 out_uint16_le(s, device_flags);
00233 out_uint16_le(s, param1);
00234 out_uint16_le(s, param2);
00235
00236 s_mark_end(s);
00237 rdp_send_data(s, RDP_DATA_PDU_INPUT);
00238 }
00239
00240
00241 static void
00242 rdp_send_fonts(uint16 seq)
00243 {
00244 STREAM s;
00245
00246 s = rdp_init_data(8);
00247
00248 out_uint16(s, 0);
00249 out_uint16_le(s, 0x3e);
00250 out_uint16_le(s, seq);
00251 out_uint16_le(s, 0x32);
00252
00253 s_mark_end(s);
00254 rdp_send_data(s, RDP_DATA_PDU_FONT2);
00255 }
00256
00257
00258 static void
00259 rdp_out_general_caps(STREAM s)
00260 {
00261 out_uint16_le(s, RDP_CAPSET_GENERAL);
00262 out_uint16_le(s, RDP_CAPLEN_GENERAL);
00263
00264 out_uint16_le(s, 1);
00265 out_uint16_le(s, 3);
00266 out_uint16_le(s, 0x200);
00267 out_uint16(s, 0);
00268 out_uint16(s, 0);
00269 out_uint16(s, 0);
00270 out_uint16(s, 0);
00271 out_uint16(s, 0);
00272 out_uint16(s, 0);
00273 out_uint16(s, 0);
00274 }
00275
00276
00277 static void
00278 rdp_out_bitmap_caps(STREAM s)
00279 {
00280 out_uint16_le(s, RDP_CAPSET_BITMAP);
00281 out_uint16_le(s, RDP_CAPLEN_BITMAP);
00282
00283 out_uint16_le(s, 8);
00284 out_uint16_le(s, 1);
00285 out_uint16_le(s, 1);
00286 out_uint16_le(s, 1);
00287 out_uint16_le(s, 800);
00288 out_uint16_le(s, 600);
00289 out_uint16(s, 0);
00290 out_uint16(s, 0);
00291 out_uint16_le(s, bitmap_compression ? 1 : 0);
00292 out_uint16(s, 0);
00293 out_uint16_le(s, 1);
00294 out_uint16(s, 0);
00295 }
00296
00297
00298 static void
00299 rdp_out_order_caps(STREAM s)
00300 {
00301 uint8 order_caps[32];
00302
00303
00304 memset(order_caps, 0, 32);
00305 order_caps[0] = 1;
00306 order_caps[1] = 1;
00307 order_caps[2] = 1;
00308
00309 order_caps[8] = 1;
00310 order_caps[9] = 1;
00311 order_caps[10] = 1;
00312 order_caps[11] = (desktop_save == False ? 0 : 1);
00313 order_caps[13] = 1;
00314 order_caps[14] = 1;
00315 order_caps[22] = 1;
00316 order_caps[27] = 1;
00317 out_uint16_le(s, RDP_CAPSET_ORDER);
00318 out_uint16_le(s, RDP_CAPLEN_ORDER);
00319
00320 out_uint8s(s, 20);
00321 out_uint16_le(s, 1);
00322 out_uint16_le(s, 20);
00323 out_uint16(s, 0);
00324 out_uint16_le(s, 1);
00325 out_uint16_le(s, 0x147);
00326 out_uint16_le(s, 0x2a);
00327 out_uint8p(s, order_caps, 32);
00328 out_uint16_le(s, 0x6a1);
00329 out_uint8s(s, 6);
00330 out_uint32_le(s, desktop_save == False ? 0 : 0x38400);
00331
00332 out_uint32(s, 0);
00333 out_uint32_le(s, 0x4e4);
00334 }
00335
00336
00337 static void
00338 rdp_out_bmpcache_caps(STREAM s)
00339 {
00340 out_uint16_le(s, RDP_CAPSET_BMPCACHE);
00341 out_uint16_le(s, RDP_CAPLEN_BMPCACHE);
00342
00343 out_uint8s(s, 24);
00344 out_uint16_le(s, 0x258);
00345 out_uint16_le(s, 0x100);
00346 out_uint16_le(s, 0x12c);
00347 out_uint16_le(s, 0x400);
00348 out_uint16_le(s, 0x106);
00349 out_uint16_le(s, 0x1000);
00350 }
00351
00352
00353 static void
00354 rdp_out_control_caps(STREAM s)
00355 {
00356 out_uint16_le(s, RDP_CAPSET_CONTROL);
00357 out_uint16_le(s, RDP_CAPLEN_CONTROL);
00358
00359 out_uint16(s, 0);
00360 out_uint16(s, 0);
00361 out_uint16_le(s, 2);
00362 out_uint16_le(s, 2);
00363 }
00364
00365
00366 static void
00367 rdp_out_activate_caps(STREAM s)
00368 {
00369 out_uint16_le(s, RDP_CAPSET_ACTIVATE);
00370 out_uint16_le(s, RDP_CAPLEN_ACTIVATE);
00371
00372 out_uint16(s, 0);
00373 out_uint16(s, 0);
00374 out_uint16(s, 0);
00375 out_uint16(s, 0);
00376 }
00377
00378
00379 static void
00380 rdp_out_pointer_caps(STREAM s)
00381 {
00382 out_uint16_le(s, RDP_CAPSET_POINTER);
00383 out_uint16_le(s, RDP_CAPLEN_POINTER);
00384
00385 out_uint16(s, 0);
00386 out_uint16_le(s, 20);
00387 }
00388
00389
00390 static void
00391 rdp_out_share_caps(STREAM s)
00392 {
00393 out_uint16_le(s, RDP_CAPSET_SHARE);
00394 out_uint16_le(s, RDP_CAPLEN_SHARE);
00395
00396 out_uint16(s, 0);
00397 out_uint16(s, 0);
00398 }
00399
00400
00401 static void
00402 rdp_out_colcache_caps(STREAM s)
00403 {
00404 out_uint16_le(s, RDP_CAPSET_COLCACHE);
00405 out_uint16_le(s, RDP_CAPLEN_COLCACHE);
00406
00407 out_uint16_le(s, 6);
00408 out_uint16(s, 0);
00409 }
00410
00411 static uint8 canned_caps[] = {
00412 0x01, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00, 0x04,
00413 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,
00414 0x00, 0x00, 0x00, 0x00, 0x00,
00415 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00416 0x00, 0x00, 0x00, 0x00, 0x00,
00417 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00418 0x00, 0x00, 0x00, 0x00, 0x00,
00419 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00420 0x00, 0x00, 0x00, 0x00, 0x00,
00421 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
00422 0x0C, 0x00, 0x08, 0x00, 0x01,
00423 0x00, 0x00, 0x00, 0x0E, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00,
00424 0x10, 0x00, 0x34, 0x00, 0xFE,
00425 0x00, 0x04, 0x00, 0xFE, 0x00, 0x04, 0x00, 0xFE, 0x00, 0x08, 0x00,
00426 0xFE, 0x00, 0x08, 0x00, 0xFE,
00427 0x00, 0x10, 0x00, 0xFE, 0x00, 0x20, 0x00, 0xFE, 0x00, 0x40, 0x00,
00428 0xFE, 0x00, 0x80, 0x00, 0xFE,
00429 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01,
00430 0x02, 0x00, 0x00, 0x00
00431 };
00432
00433
00434 static void
00435 rdp_out_unknown_caps(STREAM s)
00436 {
00437 out_uint16_le(s, RDP_CAPSET_UNKNOWN);
00438 out_uint16_le(s, 0x58);
00439
00440 out_uint8p(s, canned_caps, RDP_CAPLEN_UNKNOWN - 4);
00441 }
00442
00443
00444 static void
00445 rdp_send_confirm_active(void)
00446 {
00447 STREAM s;
00448 uint16 caplen =
00449 RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER +
00450 RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE +
00451 RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL +
00452 RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE + RDP_CAPLEN_UNKNOWN + 4 ;
00453
00454 s = rdp_init(14 + caplen + sizeof(RDP_SOURCE));
00455
00456 out_uint32_le(s, rdp_shareid);
00457 out_uint16_le(s, 0x3ea);
00458 out_uint16_le(s, sizeof(RDP_SOURCE));
00459 out_uint16_le(s, caplen);
00460
00461 out_uint8p(s, RDP_SOURCE, sizeof(RDP_SOURCE));
00462 out_uint16_le(s, 0xd);
00463 out_uint8s(s, 2);
00464
00465 rdp_out_general_caps(s);
00466 rdp_out_bitmap_caps(s);
00467 rdp_out_order_caps(s);
00468 rdp_out_bmpcache_caps(s);
00469 rdp_out_colcache_caps(s);
00470 rdp_out_activate_caps(s);
00471 rdp_out_control_caps(s);
00472 rdp_out_pointer_caps(s);
00473 rdp_out_share_caps(s);
00474 rdp_out_unknown_caps(s);
00475
00476 s_mark_end(s);
00477 rdp_send(s, RDP_PDU_CONFIRM_ACTIVE);
00478 }
00479
00480
00481 void
00482 process_demand_active(STREAM s)
00483 {
00484 uint8 type;
00485
00486 in_uint32_le(s, rdp_shareid);
00487
00488 DEBUG(("DEMAND_ACTIVE(id=0x%x)\n", rdp_shareid));
00489
00490 rdp_send_confirm_active();
00491 rdp_send_synchronise();
00492 rdp_send_control(RDP_CTL_COOPERATE);
00493 rdp_send_control(RDP_CTL_REQUEST_CONTROL);
00494 rdp_recv(&type);
00495 rdp_recv(&type);
00496 rdp_recv(&type);
00497 rdp_send_input(0, RDP_INPUT_SYNCHRONIZE, 0, 0, 0);
00498 rdp_send_fonts(1);
00499 rdp_send_fonts(2);
00500 rdp_recv(&type);
00501 reset_order_state();
00502 }
00503
00504
00505 static void
00506 process_pointer_pdu(STREAM s)
00507 {
00508 uint16 message_type;
00509 uint16 x, y, width, height, cache_idx, masklen, datalen;
00510 uint8 *mask, *data;
00511 HCURSOR cursor;
00512
00513 in_uint16_le(s, message_type);
00514 in_uint8s(s, 2);
00515
00516 switch (message_type)
00517 {
00518 case RDP_POINTER_MOVE:
00519 in_uint16_le(s, x);
00520 in_uint16_le(s, y);
00521 if (s_check(s))
00522 ui_move_pointer(x, y);
00523 break;
00524
00525 case RDP_POINTER_COLOR:
00526 in_uint16_le(s, cache_idx);
00527 in_uint16_le(s, x);
00528 in_uint16_le(s, y);
00529 in_uint16_le(s, width);
00530 in_uint16_le(s, height);
00531 in_uint16_le(s, masklen);
00532 in_uint16_le(s, datalen);
00533 in_uint8p(s, data, datalen);
00534 in_uint8p(s, mask, masklen);
00535 cursor = ui_create_cursor(x, y, width, height, mask, data);
00536 ui_set_cursor(cursor);
00537 cache_put_cursor(cache_idx, cursor);
00538 break;
00539
00540 case RDP_POINTER_CACHED:
00541 in_uint16_le(s, cache_idx);
00542 ui_set_cursor(cache_get_cursor(cache_idx));
00543 break;
00544
00545 default:
00546 DEBUG(("Pointer message 0x%x\n", message_type));
00547 }
00548 }
00549
00550
00551 static void
00552 process_bitmap_updates(STREAM s)
00553 {
00554 uint16 num_updates;
00555 uint16 left, top, right, bottom, width, height;
00556 uint16 cx, cy, bpp, Bpp, compress, bufsize, size;
00557 uint8 *data, *bmpdata;
00558 int i;
00559
00560 in_uint16_le(s, num_updates);
00561
00562 for (i = 0; i < num_updates; i++)
00563 {
00564 in_uint16_le(s, left);
00565 in_uint16_le(s, top);
00566 in_uint16_le(s, right);
00567 in_uint16_le(s, bottom);
00568 in_uint16_le(s, width);
00569 in_uint16_le(s, height);
00570 in_uint16_le(s, bpp);
00571 Bpp = (bpp + 7) / 8;
00572 in_uint16_le(s, compress);
00573 in_uint16_le(s, bufsize);
00574
00575 cx = right - left + 1;
00576 cy = bottom - top + 1;
00577
00578 DEBUG(("UPDATE(l=%d,t=%d,r=%d,b=%d,w=%d,h=%d,cmp=%d)\n",
00579 left, top, right, bottom, width, height, compress));
00580
00581 if (!compress)
00582 {
00583 int y;
00584 bmpdata = (uint8*)xmalloc(width * height * Bpp);
00585 for (y = 0; y < height; y++)
00586 {
00587 in_uint8a(s, &bmpdata[(height - y - 1) * (width * Bpp)],
00588 width * Bpp);
00589 }
00590 ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata);
00591 xfree(bmpdata);
00592 continue;
00593 }
00594
00595 in_uint8s(s, 2);
00596 in_uint16_le(s, size);
00597 in_uint8s(s, 4);
00598 in_uint8p(s, data, size);
00599 bmpdata = (uint8*)xmalloc(width * height * Bpp);
00600 if (bitmap_decompress(bmpdata, width, height, data, size, Bpp))
00601 {
00602 ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata);
00603 }
00604 xfree(bmpdata);
00605 }
00606 }
00607
00608
00609 static void
00610 process_palette(STREAM s)
00611 {
00612 COLOURENTRY *entry;
00613 COLOURMAP map;
00614 HCOLOURMAP hmap;
00615 int i;
00616 uint8 data[1536];
00617
00618 in_uint8s(s, 2);
00619 in_uint16_le(s, map.ncolours);
00620 in_uint8s(s, 2);
00621
00622 map.colours = (COLOURENTRY*)data;
00623
00624 for (i = 0; i < map.ncolours; i++)
00625 {
00626 entry = &map.colours[i];
00627 in_uint8(s, entry->red);
00628 in_uint8(s, entry->green);
00629 in_uint8(s, entry->blue);
00630 }
00631 hmap = ui_create_colourmap(&map);
00632 ui_set_colourmap(hmap);
00633 }
00634
00635
00636 static void
00637 process_update_pdu(STREAM s)
00638 {
00639 uint16 update_type;
00640
00641 in_uint16_le(s, update_type);
00642 ui_begin_update();
00643 switch (update_type)
00644 {
00645 case RDP_UPDATE_ORDERS:
00646 process_orders(s);
00647 break;
00648
00649 case RDP_UPDATE_BITMAP:
00650 process_bitmap_updates(s);
00651 break;
00652
00653 case RDP_UPDATE_PALETTE:
00654 process_palette(s);
00655 break;
00656
00657 case RDP_UPDATE_SYNCHRONIZE:
00658 break;
00659
00660 default:
00661 unimpl("update %d\n", update_type);
00662 }
00663 ui_end_update();
00664 }
00665
00666
00667 void
00668 process_data_pdu(STREAM s)
00669 {
00670 uint8 data_pdu_type;
00671
00672 in_uint8s(s, 8);
00673 in_uint8(s, data_pdu_type);
00674 in_uint8s(s, 3);
00675
00676 switch (data_pdu_type)
00677 {
00678 case RDP_DATA_PDU_UPDATE:
00679 process_update_pdu(s);
00680 break;
00681
00682 case RDP_DATA_PDU_POINTER:
00683 process_pointer_pdu(s);
00684 break;
00685
00686 case RDP_DATA_PDU_BELL:
00687 ui_bell();
00688 break;
00689
00690 case RDP_DATA_PDU_LOGON:
00691
00692 break;
00693
00694 default:
00695 unimpl("data PDU %d\n", data_pdu_type);
00696 }
00697 }
00698
00699
00700 BOOL
00701 rdp_main_loop(void)
00702 {
00703 uint8 type;
00704 STREAM s;
00705 BOOL cont = True;
00706 while (cont)
00707 {
00708 s = rdp_recv(&type);
00709 if (s == NULL)
00710 return False;
00711 switch (type)
00712 {
00713 case RDP_PDU_DEMAND_ACTIVE:
00714 process_demand_active(s);
00715 break;
00716 case RDP_PDU_DEACTIVATE:
00717 break;
00718 case RDP_PDU_DATA:
00719 process_data_pdu(s);
00720 break;
00721 case 0:
00722 break;
00723 default:
00724 unimpl("PDU %d\n", type);
00725 }
00726 cont = next_packet < s->end;
00727 }
00728 return True;
00729 }
00730
00731
00732 BOOL
00733 rdp_connect(char *server, uint32 flags, char *domain, char *password,
00734 char *command, char *directory)
00735 {
00736 if (!sec_connect(server))
00737 return False;
00738
00739 rdp_send_logon_info(flags, domain, username, password, command, directory);
00740 return True;
00741 }
00742
00743
00744 void
00745 rdp_disconnect(void)
00746 {
00747 sec_disconnect();
00748 }