2
* FreeRDP: A Remote Desktop Protocol Client
5
* Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
7
* Licensed under the Apache License, Version 2.0 (the "License");
8
* you may not use this file except in compliance with the License.
9
* You may obtain a copy of the License at
11
* http://www.apache.org/licenses/LICENSE-2.0
13
* Unless required by applicable law or agreed to in writing, software
14
* distributed under the License is distributed on an "AS IS" BASIS,
15
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
* See the License for the specific language governing permissions and
17
* limitations under the License.
24
#include "connection.h"
30
* |-----------------------X.224 Connection Request PDU--------------------->|
31
* |<----------------------X.224 Connection Confirm PDU----------------------|
32
* |-------MCS Connect-Initial PDU with GCC Conference Create Request------->|
33
* |<-----MCS Connect-Response PDU with GCC Conference Create Response-------|
34
* |------------------------MCS Erect Domain Request PDU-------------------->|
35
* |------------------------MCS Attach User Request PDU--------------------->|
36
* |<-----------------------MCS Attach User Confirm PDU----------------------|
37
* |------------------------MCS Channel Join Request PDU-------------------->|
38
* |<-----------------------MCS Channel Join Confirm PDU---------------------|
39
* |----------------------------Security Exchange PDU----------------------->|
40
* |-------------------------------Client Info PDU-------------------------->|
41
* |<---------------------License Error PDU - Valid Client-------------------|
42
* |<-----------------------------Demand Active PDU--------------------------|
43
* |------------------------------Confirm Active PDU------------------------>|
44
* |-------------------------------Synchronize PDU-------------------------->|
45
* |---------------------------Control PDU - Cooperate---------------------->|
46
* |------------------------Control PDU - Request Control------------------->|
47
* |--------------------------Persistent Key List PDU(s)-------------------->|
48
* |--------------------------------Font List PDU--------------------------->|
49
* |<------------------------------Synchronize PDU---------------------------|
50
* |<--------------------------Control PDU - Cooperate-----------------------|
51
* |<-----------------------Control PDU - Granted Control--------------------|
52
* |<-------------------------------Font Map PDU-----------------------------|
57
* Establish RDP Connection.\n
59
* @param rdp RDP module
62
boolean rdp_client_connect(rdpRdp* rdp)
65
uint32 selectedProtocol;
66
rdpSettings* settings = rdp->settings;
69
nego_set_target(rdp->nego, settings->hostname, settings->port);
70
nego_set_cookie(rdp->nego, settings->username);
71
nego_enable_rdp(rdp->nego, settings->rdp_security);
72
nego_enable_nla(rdp->nego, settings->nla_security);
73
nego_enable_tls(rdp->nego, settings->tls_security);
75
if (nego_connect(rdp->nego) != true)
77
printf("Error: protocol security negotiation failure\n");
81
selectedProtocol = rdp->nego->selected_protocol;
83
if ((selectedProtocol & PROTOCOL_TLS) || (selectedProtocol == PROTOCOL_RDP))
85
if ((settings->username != NULL) && (settings->password != NULL))
86
settings->autologon = true;
90
if (selectedProtocol & PROTOCOL_NLA)
91
status = transport_connect_nla(rdp->transport);
92
else if (selectedProtocol & PROTOCOL_TLS)
93
status = transport_connect_tls(rdp->transport);
94
else if (selectedProtocol == PROTOCOL_RDP) /* 0 */
95
status = transport_connect_rdp(rdp->transport);
100
rdp_set_blocking_mode(rdp, false);
101
rdp->state = CONNECTION_STATE_NEGO;
102
rdp->finalize_sc_pdus = 0;
104
if (mcs_send_connect_initial(rdp->mcs) != true)
106
printf("Error: unable to send MCS Connect Initial\n");
110
while (rdp->state != CONNECTION_STATE_ACTIVE)
112
if (rdp_check_fds(rdp) < 0)
119
boolean rdp_client_disconnect(rdpRdp* rdp)
121
return transport_disconnect(rdp->transport);
124
boolean rdp_client_redirect(rdpRdp* rdp)
126
rdpSettings* settings = rdp->settings;
127
rdpRedirection* redirection = rdp->redirection;
129
rdp_client_disconnect(rdp);
132
nego_free(rdp->nego);
133
license_free(rdp->license);
134
transport_free(rdp->transport);
135
rdp->transport = transport_new(settings);
136
rdp->license = license_new(rdp);
137
rdp->nego = nego_new(rdp->transport);
138
rdp->mcs = mcs_new(rdp->transport);
140
rdp->transport->layer = TRANSPORT_LAYER_TCP;
141
settings->redirected_session_id = redirection->sessionID;
143
if (redirection->flags & LB_LOAD_BALANCE_INFO)
144
nego_set_routing_token(rdp->nego, &redirection->loadBalanceInfo);
146
if (redirection->flags & LB_TARGET_NET_ADDRESS)
148
xfree(settings->hostname);
149
settings->hostname = redirection->targetNetAddress.ascii;
151
else if (redirection->flags & LB_TARGET_FQDN)
153
xfree(settings->hostname);
154
settings->hostname = redirection->targetFQDN.ascii;
156
else if (redirection->flags & LB_TARGET_NETBIOS_NAME)
158
xfree(settings->hostname);
159
settings->hostname = redirection->targetNetBiosName.ascii;
162
if (redirection->flags & LB_USERNAME)
164
xfree(settings->username);
165
settings->username = redirection->username.ascii;
168
if (redirection->flags & LB_DOMAIN)
170
xfree(settings->domain);
171
settings->domain = redirection->domain.ascii;
174
if (redirection->flags & LB_PASSWORD)
176
xfree(settings->password);
177
settings->password = redirection->password.ascii;
180
return rdp_client_connect(rdp);
183
static boolean rdp_establish_keys(rdpRdp* rdp)
185
uint8 client_random[32];
186
uint8 crypt_client_random[256 + 8];
193
if (rdp->settings->encryption == false)
195
/* no RDP encryption */
199
/* encrypt client random */
200
memset(crypt_client_random, 0, sizeof(crypt_client_random));
201
memset(client_random, 0x5e, 32);
202
crypto_nonce(client_random, 32);
203
key_len = rdp->settings->server_cert->cert_info.modulus.length;
204
mod = rdp->settings->server_cert->cert_info.modulus.data;
205
exp = rdp->settings->server_cert->cert_info.exponent;
206
crypto_rsa_encrypt(client_random, 32, key_len, mod, exp, crypt_client_random);
208
/* send crypt client random to server */
209
length = 7 + 8 + 4 + 4 + key_len + 8;
210
s = transport_send_stream_init(rdp->mcs->transport, length);
211
tpkt_write_header(s, length);
212
tpdu_write_header(s, 2, 0xf0);
213
per_write_choice(s, DomainMCSPDU_SendDataRequest << 2);
214
per_write_integer16(s, rdp->mcs->user_id, MCS_BASE_CHANNEL_ID);
215
per_write_integer16(s, MCS_GLOBAL_CHANNEL_ID, 0);
216
stream_write_uint8(s, 0x70);
217
length = (4 + 4 + key_len + 8) | 0x8000;
218
stream_write_uint16_be(s, length);
219
stream_write_uint32(s, 1); /* SEC_CLIENT_RANDOM */
220
length = key_len + 8;
221
stream_write_uint32(s, length);
222
stream_write(s, crypt_client_random, length);
223
if (transport_write(rdp->mcs->transport, s) < 0)
228
/* now calculate encrypt / decrypt and update keys */
229
if (!security_establish_keys(client_random, rdp))
234
rdp->do_crypt = true;
236
if (rdp->settings->encryption_method == ENCRYPTION_METHOD_FIPS)
238
uint8 fips_ivec[8] = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };
239
rdp->fips_encrypt = crypto_des3_encrypt_init(rdp->fips_encrypt_key, fips_ivec);
240
rdp->fips_decrypt = crypto_des3_decrypt_init(rdp->fips_decrypt_key, fips_ivec);
242
rdp->fips_hmac = crypto_hmac_new();
246
rdp->rc4_decrypt_key = crypto_rc4_init(rdp->decrypt_key, rdp->rc4_key_len);
247
rdp->rc4_encrypt_key = crypto_rc4_init(rdp->encrypt_key, rdp->rc4_key_len);
252
boolean rdp_client_connect_mcs_connect_response(rdpRdp* rdp, STREAM* s)
254
if (!mcs_recv_connect_response(rdp->mcs, s))
256
printf("rdp_client_connect_mcs_connect_response: mcs_recv_connect_response failed\n");
259
if (!mcs_send_erect_domain_request(rdp->mcs))
261
if (!mcs_send_attach_user_request(rdp->mcs))
264
rdp->state = CONNECTION_STATE_MCS_ATTACH_USER;
269
boolean rdp_client_connect_mcs_attach_user_confirm(rdpRdp* rdp, STREAM* s)
271
if (!mcs_recv_attach_user_confirm(rdp->mcs, s))
274
if (!mcs_send_channel_join_request(rdp->mcs, rdp->mcs->user_id))
277
rdp->state = CONNECTION_STATE_MCS_CHANNEL_JOIN;
282
boolean rdp_client_connect_mcs_channel_join_confirm(rdpRdp* rdp, STREAM* s)
286
boolean all_joined = true;
288
if (!mcs_recv_channel_join_confirm(rdp->mcs, s, &channel_id))
291
if (!rdp->mcs->user_channel_joined)
293
if (channel_id != rdp->mcs->user_id)
295
rdp->mcs->user_channel_joined = true;
297
if (!mcs_send_channel_join_request(rdp->mcs, MCS_GLOBAL_CHANNEL_ID))
300
else if (!rdp->mcs->global_channel_joined)
302
if (channel_id != MCS_GLOBAL_CHANNEL_ID)
304
rdp->mcs->global_channel_joined = true;
306
if (rdp->settings->num_channels > 0)
308
if (!mcs_send_channel_join_request(rdp->mcs, rdp->settings->channels[0].channel_id))
316
for (i = 0; i < rdp->settings->num_channels; i++)
318
if (rdp->settings->channels[i].joined)
321
if (rdp->settings->channels[i].channel_id != channel_id)
324
rdp->settings->channels[i].joined = true;
327
if (i + 1 < rdp->settings->num_channels)
329
if (!mcs_send_channel_join_request(rdp->mcs, rdp->settings->channels[i + 1].channel_id))
336
if (rdp->mcs->user_channel_joined && rdp->mcs->global_channel_joined && all_joined)
338
if (!rdp_establish_keys(rdp))
340
if (!rdp_send_client_info(rdp))
342
rdp->state = CONNECTION_STATE_LICENSE;
348
boolean rdp_client_connect_license(rdpRdp* rdp, STREAM* s)
350
if (!license_recv(rdp->license, s))
353
if (rdp->license->state == LICENSE_STATE_ABORTED)
355
printf("license connection sequence aborted.\n");
359
if (rdp->license->state == LICENSE_STATE_COMPLETED)
361
rdp->state = CONNECTION_STATE_CAPABILITY;
367
boolean rdp_client_connect_demand_active(rdpRdp* rdp, STREAM* s)
373
width = rdp->settings->width;
374
height = rdp->settings->height;
376
stream_get_mark(s, mark);
378
if (!rdp_recv_demand_active(rdp, s))
380
stream_set_mark(s, mark);
381
stream_seek(s, RDP_PACKET_HEADER_LENGTH);
383
if (rdp_recv_out_of_sequence_pdu(rdp, s) != true)
389
if (!rdp_send_confirm_active(rdp))
392
input_register_client_callbacks(rdp->input);
395
* The server may request a different desktop size during Deactivation-Reactivation sequence.
396
* In this case, the UI should be informed and do actual window resizing at this point.
398
if (width != rdp->settings->width || height != rdp->settings->height)
400
IFCALL(rdp->update->DesktopResize, rdp->update->context);
403
rdp->state = CONNECTION_STATE_FINALIZATION;
404
update_reset_state(rdp->update);
406
rdp_client_connect_finalize(rdp);
411
boolean rdp_client_connect_finalize(rdpRdp* rdp)
414
* [MS-RDPBCGR] 1.3.1.1 - 8.
415
* The client-to-server PDUs sent during this phase have no dependencies on any of the server-to-
416
* client PDUs; they may be sent as a single batch, provided that sequencing is maintained.
419
if (!rdp_send_client_synchronize_pdu(rdp))
421
if (!rdp_send_client_control_pdu(rdp, CTRLACTION_COOPERATE))
423
if (!rdp_send_client_control_pdu(rdp, CTRLACTION_REQUEST_CONTROL))
426
rdp->input->SynchronizeEvent(rdp->input, 0);
428
if (!rdp_send_client_persistent_key_list_pdu(rdp))
430
if (!rdp_send_client_font_list_pdu(rdp, FONTLIST_FIRST | FONTLIST_LAST))
436
boolean rdp_server_accept_nego(rdpRdp* rdp, STREAM* s)
440
transport_set_blocking_mode(rdp->transport, true);
442
if (!nego_read_request(rdp->nego, s))
444
if (rdp->nego->requested_protocols == PROTOCOL_RDP)
446
printf("Standard RDP encryption is not supported.\n");
450
printf("Requested protocols:");
451
if ((rdp->nego->requested_protocols | PROTOCOL_TLS))
454
if (rdp->settings->tls_security)
457
rdp->nego->selected_protocol |= PROTOCOL_TLS;
462
if ((rdp->nego->requested_protocols | PROTOCOL_NLA))
465
if (rdp->settings->nla_security)
468
rdp->nego->selected_protocol |= PROTOCOL_NLA;
475
if (!nego_send_negotiation_response(rdp->nego))
479
if (rdp->nego->selected_protocol & PROTOCOL_NLA)
480
ret = transport_accept_nla(rdp->transport);
481
else if (rdp->nego->selected_protocol & PROTOCOL_TLS)
482
ret = transport_accept_tls(rdp->transport);
483
else if (rdp->nego->selected_protocol & PROTOCOL_RDP)
484
ret = transport_accept_rdp(rdp->transport);
489
transport_set_blocking_mode(rdp->transport, false);
491
rdp->state = CONNECTION_STATE_NEGO;
496
boolean rdp_server_accept_mcs_connect_initial(rdpRdp* rdp, STREAM* s)
500
if (!mcs_recv_connect_initial(rdp->mcs, s))
503
printf("Accepted client: %s\n", rdp->settings->client_hostname);
504
printf("Accepted channels:");
505
for (i = 0; i < rdp->settings->num_channels; i++)
507
printf(" %s", rdp->settings->channels[i].name);
511
if (!mcs_send_connect_response(rdp->mcs))
514
rdp->state = CONNECTION_STATE_MCS_CONNECT;
519
boolean rdp_server_accept_mcs_erect_domain_request(rdpRdp* rdp, STREAM* s)
521
if (!mcs_recv_erect_domain_request(rdp->mcs, s))
524
rdp->state = CONNECTION_STATE_MCS_ERECT_DOMAIN;
529
boolean rdp_server_accept_mcs_attach_user_request(rdpRdp* rdp, STREAM* s)
531
if (!mcs_recv_attach_user_request(rdp->mcs, s))
534
if (!mcs_send_attach_user_confirm(rdp->mcs))
537
rdp->state = CONNECTION_STATE_MCS_ATTACH_USER;
542
boolean rdp_server_accept_mcs_channel_join_request(rdpRdp* rdp, STREAM* s)
546
boolean all_joined = true;
548
if (!mcs_recv_channel_join_request(rdp->mcs, s, &channel_id))
551
if (!mcs_send_channel_join_confirm(rdp->mcs, channel_id))
554
if (channel_id == rdp->mcs->user_id)
555
rdp->mcs->user_channel_joined = true;
556
else if (channel_id == MCS_GLOBAL_CHANNEL_ID)
557
rdp->mcs->global_channel_joined = true;
559
for (i = 0; i < rdp->settings->num_channels; i++)
561
if (rdp->settings->channels[i].channel_id == channel_id)
562
rdp->settings->channels[i].joined = true;
564
if (!rdp->settings->channels[i].joined)
568
if (rdp->mcs->user_channel_joined && rdp->mcs->global_channel_joined && all_joined)
569
rdp->state = CONNECTION_STATE_MCS_CHANNEL_JOIN;
574
boolean rdp_server_accept_client_info(rdpRdp* rdp, STREAM* s)
576
if (!rdp_recv_client_info(rdp, s))
579
if (!license_send_valid_client_error_packet(rdp->license))
582
rdp->state = CONNECTION_STATE_LICENSE;
587
boolean rdp_server_accept_confirm_active(rdpRdp* rdp, STREAM* s)
589
if (!rdp_recv_confirm_active(rdp, s))
592
rdp->state = CONNECTION_STATE_ACTIVE;
593
update_reset_state(rdp->update);
595
if (!rdp_send_server_synchronize_pdu(rdp))
598
if (!rdp_send_server_control_cooperate_pdu(rdp))
604
boolean rdp_server_reactivate(rdpRdp* rdp)
606
if (!rdp_send_deactivate_all(rdp))
609
rdp->state = CONNECTION_STATE_LICENSE;
611
if (!rdp_send_demand_active(rdp))