1
1
/* -*- c-basic-offset: 8 -*-
2
2
rdesktop: A Remote Desktop Protocol client.
3
3
Protocol services - RDP layer
4
Copyright (C) Matthew Chapman 1999-2007
4
Copyright (C) Matthew Chapman <matthewc.unsw.edu.au> 1999-2008
5
Copyright 2003-2011 Peter Astrand <astrand@cendio.se> for Cendio AB
6
This program is free software; you can redistribute it and/or modify
7
This program is free software: you can redistribute it and/or modify
7
8
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
the Free Software Foundation, either version 3 of the License, or
9
10
(at your option) any later version.
11
12
This program is distributed in the hope that it will be useful,
72
74
extern char g_redirect_server[64];
73
75
extern char g_redirect_domain[16];
74
76
extern char g_redirect_password[64];
75
extern char g_redirect_username[64];
77
extern char *g_redirect_username;
76
78
extern char g_redirect_cookie[128];
77
79
extern uint32 g_redirect_flags;
78
80
/* END Session Directory support */
82
extern uint32 g_reconnect_logonid;
83
extern char g_reconnect_random[16];
84
extern RD_BOOL g_has_reconnect_random;
85
extern uint8 g_client_random[SEC_RANDOM_SIZE];
81
88
static uint32 g_packetno;
439
447
out_uint16_le(s, 0);
442
out_uint16_le(s, len_ip + 2); /* Length of client ip */
443
rdp_out_unistr(s, ipaddr, len_ip);
444
out_uint16_le(s, len_dll + 2);
445
rdp_out_unistr(s, "C:\\WINNT\\System32\\mstscax.dll", len_dll);
449
/* TS_EXTENDED_INFO_PACKET */
450
out_uint16_le(s, 2); /* clientAddressFamily = AF_INET */
451
out_uint16_le(s, len_ip + 2); /* cbClientAddress, Length of client ip */
452
rdp_out_unistr(s, ipaddr, len_ip); /* clientAddress */
453
out_uint16_le(s, len_dll + 2); /* cbClientDir */
454
rdp_out_unistr(s, "C:\\WINNT\\System32\\mstscax.dll", len_dll); /* clientDir */
456
/* TS_TIME_ZONE_INFORMATION */
447
457
tzone = (mktime(gmtime(&t)) - mktime(localtime(&t))) / 60;
448
458
out_uint32_le(s, tzone);
450
459
rdp_out_unistr(s, "GTB, normaltid", 2 * strlen("GTB, normaltid"));
451
460
out_uint8s(s, 62 - 2 * strlen("GTB, normaltid"));
453
461
out_uint32_le(s, 0x0a0000);
454
462
out_uint32_le(s, 0x050000);
455
463
out_uint32_le(s, 3);
456
464
out_uint32_le(s, 0);
457
465
out_uint32_le(s, 0);
459
466
rdp_out_unistr(s, "GTB, sommartid", 2 * strlen("GTB, sommartid"));
460
467
out_uint8s(s, 62 - 2 * strlen("GTB, sommartid"));
462
468
out_uint32_le(s, 0x30000);
463
469
out_uint32_le(s, 0x050000);
464
470
out_uint32_le(s, 2);
465
471
out_uint32(s, 0);
466
out_uint32_le(s, 0xffffffc4);
467
out_uint32_le(s, 0xfffffffe);
472
out_uint32_le(s, 0xffffffc4); /* DaylightBias */
474
/* Rest of TS_EXTENDED_INFO_PACKET */
475
out_uint32_le(s, 0xfffffffe); /* clientSessionId, consider changing to 0 */
468
476
out_uint32_le(s, g_rdp5_performanceflags);
478
/* Client Auto-Reconnect */
479
if (g_has_reconnect_random)
481
out_uint16_le(s, 28); /* cbAutoReconnectLen */
482
/* ARC_CS_PRIVATE_PACKET */
483
out_uint32_le(s, 28); /* cbLen */
484
out_uint32_le(s, 1); /* Version */
485
out_uint32_le(s, g_reconnect_logonid); /* LogonId */
486
ssl_hmac_md5(g_reconnect_random, sizeof(g_reconnect_random),
487
g_client_random, SEC_RANDOM_SIZE, security_verifier);
488
out_uint8a(s, security_verifier, sizeof(security_verifier));
492
out_uint16_le(s, 0); /* cbAutoReconnectLen */
787
810
out_uint16_le(s, 20); /* Cache size */
813
/* Output new pointer capability set */
815
rdp_out_newpointer_caps(STREAM s)
817
out_uint16_le(s, RDP_CAPSET_POINTER);
818
out_uint16_le(s, RDP_CAPLEN_NEWPOINTER);
820
out_uint16_le(s, 1); /* Colour pointer */
821
out_uint16_le(s, 20); /* Cache size */
822
out_uint16_le(s, 20); /* Cache size for new pointers */
790
825
/* Output share capability set */
792
827
rdp_out_share_caps(STREAM s)
809
844
out_uint16(s, 0); /* pad */
847
/* Output brush cache capability set */
849
rdp_out_brushcache_caps(STREAM s)
851
out_uint16_le(s, RDP_CAPSET_BRUSHCACHE);
852
out_uint16_le(s, RDP_CAPLEN_BRUSHCACHE);
853
out_uint32_le(s, 1); /* cache type */
812
856
static uint8 caps_0x0d[] = {
813
857
0x01, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00,
814
858
0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
855
899
uint32 sec_flags = g_encryption ? (RDP5_FLAG | SEC_ENCRYPT) : RDP5_FLAG;
857
901
RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER +
858
RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE +
902
RDP_CAPLEN_COLCACHE +
859
903
RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL +
860
RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE +
861
0x58 + 0x08 + 0x08 + 0x34 /* unknown caps */ +
862
4 /* w2k fix, why? */ ;
905
RDP_CAPLEN_BRUSHCACHE + 0x58 + 0x08 + 0x08 + 0x34 /* unknown caps */ +
906
4 /* w2k fix, sessionid */ ;
910
caplen += RDP_CAPLEN_BMPCACHE2;
911
caplen += RDP_CAPLEN_NEWPOINTER;
915
caplen += RDP_CAPLEN_BMPCACHE;
916
caplen += RDP_CAPLEN_POINTER;
864
919
s = sec_init(sec_flags, 6 + 14 + caplen + sizeof(RDP_SOURCE));
873
928
out_uint16_le(s, caplen);
875
930
out_uint8p(s, RDP_SOURCE, sizeof(RDP_SOURCE));
876
out_uint16_le(s, 0xd); /* num_caps */
931
out_uint16_le(s, 0xe); /* num_caps */
877
932
out_uint8s(s, 2); /* pad */
879
934
rdp_out_general_caps(s);
880
935
rdp_out_bitmap_caps(s);
881
936
rdp_out_order_caps(s);
882
g_use_rdp5 ? rdp_out_bmpcache2_caps(s) : rdp_out_bmpcache_caps(s);
939
rdp_out_bmpcache2_caps(s);
940
rdp_out_newpointer_caps(s);
944
rdp_out_bmpcache_caps(s);
945
rdp_out_pointer_caps(s);
883
947
rdp_out_colcache_caps(s);
884
948
rdp_out_activate_caps(s);
885
949
rdp_out_control_caps(s);
886
rdp_out_pointer_caps(s);
887
950
rdp_out_share_caps(s);
951
rdp_out_brushcache_caps(s);
889
rdp_out_unknown_caps(s, 0x0d, 0x58, caps_0x0d); /* international? */
890
rdp_out_unknown_caps(s, 0x0c, 0x08, caps_0x0c);
891
rdp_out_unknown_caps(s, 0x0e, 0x08, caps_0x0e);
892
rdp_out_unknown_caps(s, 0x10, 0x34, caps_0x10); /* glyph cache? */
953
rdp_out_unknown_caps(s, 0x0d, 0x58, caps_0x0d); /* CAPSTYPE_INPUT */
954
rdp_out_unknown_caps(s, 0x0c, 0x08, caps_0x0c); /* CAPSTYPE_SOUND */
955
rdp_out_unknown_caps(s, 0x0e, 0x08, caps_0x0e); /* CAPSTYPE_FONT */
956
rdp_out_unknown_caps(s, 0x10, 0x34, caps_0x10); /* CAPSTYPE_GLYPHCACHE */
895
959
sec_send(s, sec_flags);
1037
1103
in_uint16_le(s, datalen);
1038
1104
in_uint8p(s, data, datalen);
1039
1105
in_uint8p(s, mask, masklen);
1040
cursor = ui_create_cursor(x, y, width, height, mask, data);
1106
if ((width != 32) || (height != 32))
1108
warning("process_colour_pointer_common: " "width %d height %d\n", width, height);
1110
/* sometimes x or y is out of bounds */
1112
x = MIN(x, width - 1);
1114
y = MIN(y, height - 1);
1115
cursor = ui_create_cursor(x, y, width, height, mask, data, bpp);
1041
1116
ui_set_cursor(cursor);
1042
1117
cache_put_cursor(cache_idx, cursor);
1120
/* Process a colour pointer PDU */
1122
process_colour_pointer_pdu(STREAM s)
1124
process_colour_pointer_common(s, 24);
1127
/* Process a New Pointer PDU - these pointers have variable bit depth */
1129
process_new_pointer_pdu(STREAM s)
1133
in_uint16_le(s, xor_bpp);
1134
process_colour_pointer_common(s, xor_bpp);
1045
1137
/* Process a cached pointer PDU */
1047
1139
process_cached_pointer_pdu(STREAM s)
1243
1339
ui_end_update();
1343
/* Process a Save Session Info PDU */
1345
process_pdu_logon(STREAM s)
1348
in_uint32_le(s, infotype);
1349
if (infotype == INFOTYPE_LOGON_EXTENDED_INF)
1351
uint32 fieldspresent;
1353
in_uint8s(s, 2); /* Length */
1354
in_uint32_le(s, fieldspresent);
1355
if (fieldspresent & LOGON_EX_AUTORECONNECTCOOKIE)
1360
/* TS_LOGON_INFO_FIELD */
1361
in_uint8s(s, 4); /* cbFieldData */
1363
/* ARC_SC_PRIVATE_PACKET */
1364
in_uint32_le(s, len);
1367
warning("Invalid length in Auto-Reconnect packet\n");
1371
in_uint32_le(s, version);
1374
warning("Unsupported version of Auto-Reconnect packet\n");
1378
in_uint32_le(s, g_reconnect_logonid);
1379
in_uint8a(s, g_reconnect_random, 16);
1380
g_has_reconnect_random = True;
1381
DEBUG(("Saving auto-reconnect cookie, id=%u\n", g_reconnect_logonid));
1246
1387
/* Process a disconnect PDU */
1248
1389
process_disconnect_pdu(STREAM s, uint32 * ext_disc_reason)
1349
1491
/* read connection flags */
1350
1492
in_uint32_le(s, g_redirect_flags);
1352
/* read length of ip string */
1353
in_uint32_le(s, len);
1355
/* read ip string */
1356
rdp_in_unistr(s, g_redirect_server, sizeof(g_redirect_server), len);
1358
/* read length of cookie string */
1359
in_uint32_le(s, len);
1361
/* read cookie string (plain ASCII) */
1362
if (len > sizeof(g_redirect_cookie) - 1)
1364
uint32 rem = len - (sizeof(g_redirect_cookie) - 1);
1365
len = sizeof(g_redirect_cookie) - 1;
1367
warning("Unexpectedly large redirection cookie\n");
1368
in_uint8a(s, g_redirect_cookie, len);
1373
in_uint8a(s, g_redirect_cookie, len);
1375
g_redirect_cookie[len] = 0;
1377
/* read length of username string */
1378
in_uint32_le(s, len);
1380
/* read username string */
1381
rdp_in_unistr(s, g_redirect_username, sizeof(g_redirect_username), len);
1383
/* read length of domain string */
1384
in_uint32_le(s, len);
1386
/* read domain string */
1387
rdp_in_unistr(s, g_redirect_domain, sizeof(g_redirect_domain), len);
1389
/* read length of password string */
1390
in_uint32_le(s, len);
1392
/* read password string */
1393
rdp_in_unistr(s, g_redirect_password, sizeof(g_redirect_password), len);
1494
if (g_redirect_flags & PDU_REDIRECT_HAS_IP)
1496
/* read length of ip string */
1497
in_uint32_le(s, len);
1499
/* read ip string */
1500
rdp_in_unistr(s, g_redirect_server, sizeof(g_redirect_server), len);
1503
if (g_redirect_flags & PDU_REDIRECT_HAS_COOKIE)
1505
/* read length of cookie string */
1506
in_uint32_le(s, len);
1508
/* read cookie string (plain ASCII) */
1509
if (len > sizeof(g_redirect_cookie) - 1)
1511
uint32 rem = len - (sizeof(g_redirect_cookie) - 1);
1512
len = sizeof(g_redirect_cookie) - 1;
1514
warning("Unexpectedly large redirection cookie\n");
1515
in_uint8a(s, g_redirect_cookie, len);
1520
in_uint8a(s, g_redirect_cookie, len);
1522
g_redirect_cookie[len] = 0;
1525
if (g_redirect_flags & PDU_REDIRECT_HAS_USERNAME)
1527
/* read length of username string */
1528
in_uint32_le(s, len);
1530
/* read username string */
1531
g_redirect_username = (char *) xmalloc(len + 1);
1532
rdp_in_unistr(s, g_redirect_username, strlen(g_redirect_username), len);
1535
if (g_redirect_flags & PDU_REDIRECT_HAS_DOMAIN)
1537
/* read length of domain string */
1538
in_uint32_le(s, len);
1540
/* read domain string */
1541
rdp_in_unistr(s, g_redirect_domain, sizeof(g_redirect_domain), len);
1544
if (g_redirect_flags & PDU_REDIRECT_HAS_PASSWORD)
1546
/* read length of password string */
1547
in_uint32_le(s, len);
1549
/* read password string */
1550
rdp_in_unistr(s, g_redirect_password, sizeof(g_redirect_password), len);
1553
if (g_redirect_flags & PDU_REDIRECT_DONT_STORE_USERNAME)
1555
warning("PDU_REDIRECT_DONT_STORE_USERNAME set\n");
1558
if (g_redirect_flags & PDU_REDIRECT_USE_SMARTCARD)
1560
warning("PDU_REDIRECT_USE_SMARTCARD set\n");
1563
if (g_redirect_flags & PDU_REDIRECT_INFORMATIONAL)
1565
warning("PDU_REDIRECT_INFORMATIONAL set\n");
1568
if (g_redirect_flags & PDU_REDIRECT_HAS_TARGET_FQDN)
1570
warning("PDU_REDIRECT_HAS_TARGET_FQDN set\n");
1573
if (g_redirect_flags & PDU_REDIRECT_HAS_TARGET_NETBIOS)
1575
warning("PDU_REDIRECT_HAS_TARGET_NETBIOS set\n");
1578
if (g_redirect_flags & PDU_REDIRECT_HAS_TARGET_IP_ARRAY)
1580
warning("PDU_REDIRECT_HAS_TARGET_IP_ARRAY set\n");
1395
1583
g_redirect = True;
1451
1640
/* Establish a connection up to the RDP layer */
1453
1642
rdp_connect(char *server, uint32 flags, char *domain, char *password,
1454
char *command, char *directory)
1456
if (!sec_connect(server, g_username))
1459
rdp_send_logon_info(flags, domain, g_username, password, command, directory);
1463
/* Establish a reconnection up to the RDP layer */
1465
rdp_reconnect(char *server, uint32 flags, char *domain, char *password,
1466
char *command, char *directory, char *cookie)
1468
if (!sec_reconnect(server))
1643
char *command, char *directory, RD_BOOL reconnect)
1645
if (!sec_connect(server, g_username, reconnect))
1471
1648
rdp_send_logon_info(flags, domain, g_username, password, command, directory);