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"
25 #include "transport.h"
31 * |-----------------------X.224 Connection Request PDU--------------------->|
32 * |<----------------------X.224 Connection Confirm PDU----------------------|
33 * |-------MCS Connect-Initial PDU with GCC Conference Create Request------->|
34 * |<-----MCS Connect-Response PDU with GCC Conference Create Response-------|
35 * |------------------------MCS Erect Domain Request PDU-------------------->|
36 * |------------------------MCS Attach User Request PDU--------------------->|
37 * |<-----------------------MCS Attach User Confirm PDU----------------------|
38 * |------------------------MCS Channel Join Request PDU-------------------->|
39 * |<-----------------------MCS Channel Join Confirm PDU---------------------|
40 * |----------------------------Security Exchange PDU----------------------->|
41 * |-------------------------------Client Info PDU-------------------------->|
42 * |<---------------------License Error PDU - Valid Client-------------------|
43 * |<-----------------------------Demand Active PDU--------------------------|
44 * |------------------------------Confirm Active PDU------------------------>|
45 * |-------------------------------Synchronize PDU-------------------------->|
46 * |---------------------------Control PDU - Cooperate---------------------->|
47 * |------------------------Control PDU - Request Control------------------->|
48 * |--------------------------Persistent Key List PDU(s)-------------------->|
49 * |--------------------------------Font List PDU--------------------------->|
50 * |<------------------------------Synchronize PDU---------------------------|
51 * |<--------------------------Control PDU - Cooperate-----------------------|
52 * |<-----------------------Control PDU - Granted Control--------------------|
53 * |<-------------------------------Font Map PDU-----------------------------|
58 * Establish RDP Connection.\n
60 * @param rdp RDP module
63 boolean rdp_client_connect(rdpRdp* rdp)
65 rdpSettings* settings = rdp->settings;
68 nego_set_target(rdp->nego, settings->hostname, settings->port);
69 nego_set_cookie(rdp->nego, settings->username);
70 nego_set_send_preconnection_pdu(rdp->nego, settings->send_preconnection_pdu);
71 nego_set_preconnection_id(rdp->nego, settings->preconnection_id);
72 nego_set_preconnection_blob(rdp->nego, settings->preconnection_blob);
74 nego_set_negotiation_enabled(rdp->nego, settings->security_layer_negotiation);
75 nego_enable_rdp(rdp->nego, settings->rdp_security);
76 nego_enable_nla(rdp->nego, settings->nla_security);
77 nego_enable_tls(rdp->nego, settings->tls_security);
79 if (!nego_connect(rdp->nego))
81 printf("Error: protocol security negotiation or connection failure\n");
85 if ((rdp->nego->selected_protocol & PROTOCOL_TLS) || (rdp->nego->selected_protocol == PROTOCOL_RDP))
87 if ((settings->username != NULL) && ((settings->password != NULL) || (settings->password_cookie != NULL && settings->password_cookie->length > 0)))
88 settings->autologon = true;
91 rdp_set_blocking_mode(rdp, false);
92 rdp->state = CONNECTION_STATE_NEGO;
93 rdp->finalize_sc_pdus = 0;
95 if (!mcs_send_connect_initial(rdp->mcs))
97 printf("Error: unable to send MCS Connect Initial\n");
101 while (rdp->state != CONNECTION_STATE_ACTIVE)
103 if (rdp_check_fds(rdp) < 0)
110 boolean rdp_client_disconnect(rdpRdp* rdp)
112 return transport_disconnect(rdp->transport);
115 boolean rdp_client_redirect(rdpRdp* rdp)
117 rdpSettings* settings = rdp->settings;
118 rdpRedirection* redirection = rdp->redirection;
120 rdp_client_disconnect(rdp);
123 nego_free(rdp->nego);
124 license_free(rdp->license);
125 transport_free(rdp->transport);
126 rdp->transport = transport_new(settings);
127 rdp->license = license_new(rdp);
128 rdp->nego = nego_new(rdp->transport);
129 rdp->mcs = mcs_new(rdp->transport);
131 rdp->transport->layer = TRANSPORT_LAYER_TCP;
132 settings->redirected_session_id = redirection->sessionID;
134 if (redirection->flags & LB_LOAD_BALANCE_INFO)
136 nego_set_routing_token(rdp->nego, &redirection->loadBalanceInfo);
140 if (redirection->flags & LB_TARGET_NET_ADDRESS)
142 xfree(settings->hostname);
143 settings->hostname = xstrdup(redirection->targetNetAddress.ascii);
145 else if (redirection->flags & LB_TARGET_FQDN)
147 xfree(settings->hostname);
148 settings->hostname = xstrdup(redirection->targetFQDN.ascii);
150 else if (redirection->flags & LB_TARGET_NETBIOS_NAME)
152 xfree(settings->hostname);
153 settings->hostname = xstrdup(redirection->targetNetBiosName.ascii);
157 if (redirection->flags & LB_USERNAME)
159 xfree(settings->username);
160 settings->username = xstrdup(redirection->username.ascii);
163 if (redirection->flags & LB_DOMAIN)
165 xfree(settings->domain);
166 settings->domain = xstrdup(redirection->domain.ascii);
169 if (redirection->flags & LB_PASSWORD)
171 settings->password_cookie = &redirection->password_cookie;
174 return rdp_client_connect(rdp);
177 static boolean rdp_client_establish_keys(rdpRdp* rdp)
179 uint8 client_random[CLIENT_RANDOM_LENGTH];
180 uint8 crypt_client_random[256 + 8];
187 if (rdp->settings->encryption == false)
189 /* no RDP encryption */
193 /* encrypt client random */
194 memset(crypt_client_random, 0, sizeof(crypt_client_random));
195 crypto_nonce(client_random, sizeof(client_random));
196 key_len = rdp->settings->server_cert->cert_info.modulus.length;
197 mod = rdp->settings->server_cert->cert_info.modulus.data;
198 exp = rdp->settings->server_cert->cert_info.exponent;
199 crypto_rsa_public_encrypt(client_random, sizeof(client_random), key_len, mod, exp, crypt_client_random);
201 /* send crypt client random to server */
202 length = RDP_PACKET_HEADER_MAX_LENGTH + RDP_SECURITY_HEADER_LENGTH + 4 + key_len + 8;
203 s = transport_send_stream_init(rdp->mcs->transport, length);
204 rdp_write_header(rdp, s, length, MCS_GLOBAL_CHANNEL_ID);
205 rdp_write_security_header(s, SEC_EXCHANGE_PKT);
206 length = key_len + 8;
207 stream_write_uint32(s, length);
208 stream_write(s, crypt_client_random, length);
209 if (transport_write(rdp->mcs->transport, s) < 0)
214 /* now calculate encrypt / decrypt and update keys */
215 if (!security_establish_keys(client_random, rdp))
220 rdp->do_crypt = true;
221 if (rdp->settings->secure_checksum)
222 rdp->do_secure_checksum = true;
224 if (rdp->settings->encryption_method == ENCRYPTION_METHOD_FIPS)
226 uint8 fips_ivec[8] = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };
227 rdp->fips_encrypt = crypto_des3_encrypt_init(rdp->fips_encrypt_key, fips_ivec);
228 rdp->fips_decrypt = crypto_des3_decrypt_init(rdp->fips_decrypt_key, fips_ivec);
230 rdp->fips_hmac = crypto_hmac_new();
234 rdp->rc4_decrypt_key = crypto_rc4_init(rdp->decrypt_key, rdp->rc4_key_len);
235 rdp->rc4_encrypt_key = crypto_rc4_init(rdp->encrypt_key, rdp->rc4_key_len);
240 static boolean rdp_server_establish_keys(rdpRdp* rdp, STREAM* s)
242 uint8 client_random[64]; /* Should be only 32 after successfull decryption, but on failure might take up to 64 bytes. */
243 uint8 crypt_client_random[256 + 8];
244 uint32 rand_len, key_len;
245 uint16 channel_id, length, sec_flags;
249 if (rdp->settings->encryption == false)
251 /* No RDP Security. */
255 if (!rdp_read_header(rdp, s, &length, &channel_id))
257 printf("rdp_server_establish_keys: invalid RDP header\n");
260 rdp_read_security_header(s, &sec_flags);
261 if ((sec_flags & SEC_EXCHANGE_PKT) == 0)
263 printf("rdp_server_establish_keys: missing SEC_EXCHANGE_PKT in security header\n");
266 stream_read_uint32(s, rand_len);
267 key_len = rdp->settings->server_key->modulus.length;
268 if (rand_len != key_len + 8)
270 printf("rdp_server_establish_keys: invalid encrypted client random length\n");
273 memset(crypt_client_random, 0, sizeof(crypt_client_random));
274 stream_read(s, crypt_client_random, rand_len);
275 /* 8 zero bytes of padding */
277 mod = rdp->settings->server_key->modulus.data;
278 priv_exp = rdp->settings->server_key->private_exponent.data;
279 crypto_rsa_private_decrypt(crypt_client_random, rand_len - 8, key_len, mod, priv_exp, client_random);
281 /* now calculate encrypt / decrypt and update keys */
282 if (!security_establish_keys(client_random, rdp))
287 rdp->do_crypt = true;
288 if (rdp->settings->secure_checksum)
289 rdp->do_secure_checksum = true;
291 if (rdp->settings->encryption_method == ENCRYPTION_METHOD_FIPS)
293 uint8 fips_ivec[8] = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };
294 rdp->fips_encrypt = crypto_des3_encrypt_init(rdp->fips_encrypt_key, fips_ivec);
295 rdp->fips_decrypt = crypto_des3_decrypt_init(rdp->fips_decrypt_key, fips_ivec);
297 rdp->fips_hmac = crypto_hmac_new();
301 rdp->rc4_decrypt_key = crypto_rc4_init(rdp->decrypt_key, rdp->rc4_key_len);
302 rdp->rc4_encrypt_key = crypto_rc4_init(rdp->encrypt_key, rdp->rc4_key_len);
307 boolean rdp_client_connect_mcs_connect_response(rdpRdp* rdp, STREAM* s)
309 if (!mcs_recv_connect_response(rdp->mcs, s))
311 printf("rdp_client_connect_mcs_connect_response: mcs_recv_connect_response failed\n");
314 if (!mcs_send_erect_domain_request(rdp->mcs))
316 if (!mcs_send_attach_user_request(rdp->mcs))
319 rdp->state = CONNECTION_STATE_MCS_ATTACH_USER;
324 boolean rdp_client_connect_mcs_attach_user_confirm(rdpRdp* rdp, STREAM* s)
326 if (!mcs_recv_attach_user_confirm(rdp->mcs, s))
329 if (!mcs_send_channel_join_request(rdp->mcs, rdp->mcs->user_id))
332 rdp->state = CONNECTION_STATE_MCS_CHANNEL_JOIN;
337 boolean rdp_client_connect_mcs_channel_join_confirm(rdpRdp* rdp, STREAM* s)
341 boolean all_joined = true;
343 if (!mcs_recv_channel_join_confirm(rdp->mcs, s, &channel_id))
346 if (!rdp->mcs->user_channel_joined)
348 if (channel_id != rdp->mcs->user_id)
350 rdp->mcs->user_channel_joined = true;
352 if (!mcs_send_channel_join_request(rdp->mcs, MCS_GLOBAL_CHANNEL_ID))
355 else if (!rdp->mcs->global_channel_joined)
357 if (channel_id != MCS_GLOBAL_CHANNEL_ID)
359 rdp->mcs->global_channel_joined = true;
361 if (rdp->settings->num_channels > 0)
363 if (!mcs_send_channel_join_request(rdp->mcs, rdp->settings->channels[0].channel_id))
371 for (i = 0; i < rdp->settings->num_channels; i++)
373 if (rdp->settings->channels[i].joined)
376 if (rdp->settings->channels[i].channel_id != channel_id)
379 rdp->settings->channels[i].joined = true;
382 if (i + 1 < rdp->settings->num_channels)
384 if (!mcs_send_channel_join_request(rdp->mcs, rdp->settings->channels[i + 1].channel_id))
391 if (rdp->mcs->user_channel_joined && rdp->mcs->global_channel_joined && all_joined)
393 if (!rdp_client_establish_keys(rdp))
395 if (!rdp_send_client_info(rdp))
397 rdp->state = CONNECTION_STATE_LICENSE;
403 boolean rdp_client_connect_license(rdpRdp* rdp, STREAM* s)
405 if (!license_recv(rdp->license, s))
408 if (rdp->license->state == LICENSE_STATE_ABORTED)
410 printf("license connection sequence aborted.\n");
414 if (rdp->license->state == LICENSE_STATE_COMPLETED)
416 rdp->state = CONNECTION_STATE_CAPABILITY;
422 boolean rdp_client_connect_demand_active(rdpRdp* rdp, STREAM* s)
428 width = rdp->settings->width;
429 height = rdp->settings->height;
431 stream_get_mark(s, mark);
433 if (!rdp_recv_demand_active(rdp, s))
435 stream_set_mark(s, mark);
436 stream_seek(s, RDP_PACKET_HEADER_MAX_LENGTH);
438 if (rdp_recv_out_of_sequence_pdu(rdp, s) != true)
447 if (!rdp_send_confirm_active(rdp))
450 input_register_client_callbacks(rdp->input);
453 * The server may request a different desktop size during Deactivation-Reactivation sequence.
454 * In this case, the UI should be informed and do actual window resizing at this point.
456 if (width != rdp->settings->width || height != rdp->settings->height)
458 IFCALL(rdp->update->DesktopResize, rdp->update->context);
461 rdp->state = CONNECTION_STATE_FINALIZATION;
462 update_reset_state(rdp->update);
464 rdp_client_connect_finalize(rdp);
469 boolean rdp_client_connect_finalize(rdpRdp* rdp)
472 * [MS-RDPBCGR] 1.3.1.1 - 8.
473 * The client-to-server PDUs sent during this phase have no dependencies on any of the server-to-
474 * client PDUs; they may be sent as a single batch, provided that sequencing is maintained.
477 if (!rdp_send_client_synchronize_pdu(rdp))
479 if (!rdp_send_client_control_pdu(rdp, CTRLACTION_COOPERATE))
481 if (!rdp_send_client_control_pdu(rdp, CTRLACTION_REQUEST_CONTROL))
484 rdp->input->SynchronizeEvent(rdp->input, 0);
486 if (!rdp_send_client_persistent_key_list_pdu(rdp))
488 if (!rdp_send_client_font_list_pdu(rdp, FONTLIST_FIRST | FONTLIST_LAST))
494 boolean rdp_server_accept_nego(rdpRdp* rdp, STREAM* s)
498 transport_set_blocking_mode(rdp->transport, true);
500 if (!nego_read_request(rdp->nego, s))
503 rdp->nego->selected_protocol = 0;
505 printf("Requested protocols:");
506 if ((rdp->nego->requested_protocols & PROTOCOL_TLS))
509 if (rdp->settings->tls_security)
512 rdp->nego->selected_protocol |= PROTOCOL_TLS;
517 if ((rdp->nego->requested_protocols & PROTOCOL_NLA))
520 if (rdp->settings->nla_security)
523 rdp->nego->selected_protocol |= PROTOCOL_NLA;
529 if (rdp->settings->rdp_security && rdp->nego->selected_protocol == 0)
532 rdp->nego->selected_protocol = PROTOCOL_RDP;
538 if (!nego_send_negotiation_response(rdp->nego))
542 if (rdp->nego->selected_protocol & PROTOCOL_NLA)
543 ret = transport_accept_nla(rdp->transport);
544 else if (rdp->nego->selected_protocol & PROTOCOL_TLS)
545 ret = transport_accept_tls(rdp->transport);
546 else if (rdp->nego->selected_protocol == PROTOCOL_RDP) /* 0 */
547 ret = transport_accept_rdp(rdp->transport);
552 transport_set_blocking_mode(rdp->transport, false);
554 rdp->state = CONNECTION_STATE_NEGO;
559 boolean rdp_server_accept_mcs_connect_initial(rdpRdp* rdp, STREAM* s)
563 if (!mcs_recv_connect_initial(rdp->mcs, s))
566 printf("Accepted client: %s\n", rdp->settings->client_hostname);
567 printf("Accepted channels:");
568 for (i = 0; i < rdp->settings->num_channels; i++)
570 printf(" %s", rdp->settings->channels[i].name);
574 if (!mcs_send_connect_response(rdp->mcs))
577 rdp->state = CONNECTION_STATE_MCS_CONNECT;
582 boolean rdp_server_accept_mcs_erect_domain_request(rdpRdp* rdp, STREAM* s)
584 if (!mcs_recv_erect_domain_request(rdp->mcs, s))
587 rdp->state = CONNECTION_STATE_MCS_ERECT_DOMAIN;
592 boolean rdp_server_accept_mcs_attach_user_request(rdpRdp* rdp, STREAM* s)
594 if (!mcs_recv_attach_user_request(rdp->mcs, s))
597 if (!mcs_send_attach_user_confirm(rdp->mcs))
600 rdp->state = CONNECTION_STATE_MCS_ATTACH_USER;
605 boolean rdp_server_accept_mcs_channel_join_request(rdpRdp* rdp, STREAM* s)
609 boolean all_joined = true;
611 if (!mcs_recv_channel_join_request(rdp->mcs, s, &channel_id))
614 if (!mcs_send_channel_join_confirm(rdp->mcs, channel_id))
617 if (channel_id == rdp->mcs->user_id)
618 rdp->mcs->user_channel_joined = true;
619 else if (channel_id == MCS_GLOBAL_CHANNEL_ID)
620 rdp->mcs->global_channel_joined = true;
622 for (i = 0; i < rdp->settings->num_channels; i++)
624 if (rdp->settings->channels[i].channel_id == channel_id)
625 rdp->settings->channels[i].joined = true;
627 if (!rdp->settings->channels[i].joined)
631 if (rdp->mcs->user_channel_joined && rdp->mcs->global_channel_joined && all_joined)
632 rdp->state = CONNECTION_STATE_MCS_CHANNEL_JOIN;
637 boolean rdp_server_accept_client_keys(rdpRdp* rdp, STREAM* s)
640 if (!rdp_server_establish_keys(rdp, s))
643 rdp->state = CONNECTION_STATE_ESTABLISH_KEYS;
648 boolean rdp_server_accept_client_info(rdpRdp* rdp, STREAM* s)
651 if (!rdp_recv_client_info(rdp, s))
654 if (!license_send_valid_client_error_packet(rdp->license))
657 rdp->state = CONNECTION_STATE_LICENSE;
662 boolean rdp_server_accept_confirm_active(rdpRdp* rdp, STREAM* s)
664 if (!rdp_recv_confirm_active(rdp, s))
667 rdp->state = CONNECTION_STATE_ACTIVE;
668 update_reset_state(rdp->update);
670 if (!rdp_send_server_synchronize_pdu(rdp))
673 if (!rdp_send_server_control_cooperate_pdu(rdp))
679 boolean rdp_server_reactivate(rdpRdp* rdp)
681 if (!rdp_send_deactivate_all(rdp))
684 rdp->state = CONNECTION_STATE_LICENSE;
686 if (!rdp_send_demand_active(rdp))