FreeRDP
Loading...
Searching...
No Matches
connection.c
1/*
2 * FreeRDP: A Remote Desktop Protocol Implementation
3 * Connection Sequence
4 *
5 * Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
6 * Copyright 2015 Thincast Technologies GmbH
7 * Copyright 2015 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
8 * Copyright 2023 Armin Novak <anovak@thincast.com>
9 * Copyright 2023 Thincast Technologies GmbH
10 *
11 * Licensed under the Apache License, Version 2.0 (the "License");
12 * you may not use this file except in compliance with the License.
13 * You may obtain a copy of the License at
14 *
15 * http://www.apache.org/licenses/LICENSE-2.0
16 *
17 * Unless required by applicable law or agreed to in writing, software
18 * distributed under the License is distributed on an "AS IS" BASIS,
19 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 * See the License for the specific language governing permissions and
21 * limitations under the License.
22 */
23
24#include <freerdp/config.h>
25
26#include "settings.h"
27
28#include "info.h"
29#include "input.h"
30#include "rdp.h"
31#include "peer.h"
32
33#include "connection.h"
34#include "transport.h"
35
36#include <winpr/crt.h>
37#include <winpr/crypto.h>
38#include <winpr/ssl.h>
39
40#include <freerdp/log.h>
41#include <freerdp/error.h>
42#include <freerdp/listener.h>
43
44#include "../cache/pointer.h"
45#include "../crypto/crypto.h"
46#include "../crypto/privatekey.h"
47#include "../crypto/certificate.h"
48#include "gateway/arm.h"
49
50#include "utils.h"
51
52#define TAG FREERDP_TAG("core.connection")
53
197static BOOL rdp_set_state(rdpRdp* rdp, CONNECTION_STATE state);
198
199static BOOL rdp_client_reset_codecs(rdpContext* context)
200{
201 rdpSettings* settings = nullptr;
202
203 if (!context || !context->settings)
204 return FALSE;
205
206 settings = context->settings;
207
208 if (!freerdp_settings_get_bool(settings, FreeRDP_DeactivateClientDecoding))
209 {
210 const UINT32 flags = freerdp_settings_get_uint32(settings, FreeRDP_ThreadingFlags);
211 freerdp_client_codecs_free(context->codecs);
212 context->codecs = freerdp_client_codecs_new(flags);
213
214 if (!context->codecs)
215 return FALSE;
216
217 if (!freerdp_client_codecs_prepare(context->codecs,
219 settings->DesktopWidth, settings->DesktopHeight))
220 return FALSE;
221
222/* Runtime H264 detection. (only available if dynamic backend loading is defined)
223 * If no backend is available disable it before the channel is loaded.
224 */
225#if defined(WITH_GFX_H264) && defined(WITH_OPENH264_LOADING)
226 if (!context->codecs->h264)
227 {
228 settings->GfxH264 = FALSE;
229 settings->GfxAVC444 = FALSE;
230 settings->GfxAVC444v2 = FALSE;
231 }
232#endif
233 }
234
235 return TRUE;
236}
237
238static BOOL rdp_client_wait_for_activation(rdpRdp* rdp)
239{
240 BOOL timedout = FALSE;
241 WINPR_ASSERT(rdp);
242
243 const rdpSettings* settings = rdp->settings;
244 WINPR_ASSERT(settings);
245
246 UINT64 now = GetTickCount64();
247 UINT64 dueDate = now + freerdp_settings_get_uint32(settings, FreeRDP_TcpAckTimeout);
248
249 for (; (now < dueDate) && !timedout; now = GetTickCount64())
250 {
251 HANDLE events[MAXIMUM_WAIT_OBJECTS] = WINPR_C_ARRAY_INIT;
252 DWORD wstatus = 0;
253 DWORD nevents = freerdp_get_event_handles(rdp->context, events, ARRAYSIZE(events));
254 if (!nevents)
255 {
256 WLog_ERR(TAG, "error retrieving connection events");
257 return FALSE;
258 }
259
260 const UINT64 timeout = (dueDate - now);
261 WINPR_ASSERT(timeout <= UINT32_MAX);
262 wstatus = WaitForMultipleObjectsEx(nevents, events, FALSE, (UINT32)timeout, TRUE);
263 switch (wstatus)
264 {
265 case WAIT_TIMEOUT:
266 /* will make us quit with a timeout */
267 timedout = TRUE;
268 break;
269 case WAIT_ABANDONED:
270 case WAIT_FAILED:
271 return FALSE;
272 case WAIT_IO_COMPLETION:
273 break;
274 case WAIT_OBJECT_0:
275 default:
276 /* handles all WAIT_OBJECT_0 + [0 .. MAXIMUM_WAIT_OBJECTS-1] cases */
277 if (rdp_check_fds(rdp) < 0)
278 {
279 freerdp_set_last_error_if_not(rdp->context,
280 FREERDP_ERROR_CONNECT_TRANSPORT_FAILED);
281 return FALSE;
282 }
283 break;
284 }
285
286 if (rdp_is_active_state(rdp))
287 return TRUE;
288 }
289
290 WLog_ERR(TAG, "Timeout waiting for activation");
291 freerdp_set_last_error_if_not(rdp->context, FREERDP_ERROR_CONNECT_ACTIVATION_TIMEOUT);
292 return FALSE;
293}
301BOOL rdp_client_connect(rdpRdp* rdp)
302{
303 UINT32 SelectedProtocol = 0;
304 BOOL status = 0;
305 /* make sure SSL is initialize for earlier enough for crypto, by taking advantage of winpr SSL
306 * FIPS flag for openssl initialization */
307 DWORD flags = WINPR_SSL_INIT_DEFAULT;
308
309 WINPR_ASSERT(rdp);
310
311 rdpSettings* settings = rdp->settings;
312 WINPR_ASSERT(settings);
313
314 if (!rdp_client_reset_codecs(rdp->context))
315 return FALSE;
316
317 if (settings->FIPSMode)
318 flags |= WINPR_SSL_INIT_ENABLE_FIPS;
319
320 if (!winpr_InitializeSSL(flags))
321 return FALSE;
322
323 rdp_log_build_warnings(rdp);
324
325 /* FIPS Mode forces the following and overrides the following(by happening later
326 * in the command line processing):
327 * 1. Forces the only supported RDP encryption method to be FIPS.
328 * 2. Disables NTLM authentication (not FIPS compliant due to MD4/RC4).
329 * 3. Disables RDP Security if 3DES is not available in the crypto provider. */
330 if (settings->FIPSMode || winpr_FIPSMode())
331 {
332
333 settings->EncryptionMethods = ENCRYPTION_METHOD_FIPS;
334
335 if (!settings->AuthenticationPackageList)
336 {
337 if (!freerdp_settings_set_string(settings, FreeRDP_AuthenticationPackageList, "!ntlm"))
338 return FALSE;
339 }
340
341 const BYTE key[WINPR_CIPHER_MAX_KEY_LENGTH] = WINPR_C_ARRAY_INIT;
342 const BYTE iv[WINPR_CIPHER_MAX_IV_LENGTH] = WINPR_C_ARRAY_INIT;
343 WINPR_CIPHER_CTX* ctx = winpr_Cipher_NewEx(WINPR_CIPHER_DES_EDE3_CBC, WINPR_ENCRYPT, key,
344 sizeof(key), iv, sizeof(iv));
345 if (ctx)
346 {
347 winpr_Cipher_Free(ctx);
348 }
349 else
350 {
351 settings->RdpSecurity = FALSE;
352 }
353 }
354
355 UINT32 TcpConnectTimeout = freerdp_settings_get_uint32(settings, FreeRDP_TcpConnectTimeout);
356 if (settings->GatewayArmTransport)
357 {
358 if (!arm_resolve_endpoint(rdp->log, rdp->context, TcpConnectTimeout))
359 {
360 WLog_ERR(TAG, "error retrieving ARM configuration");
361 return FALSE;
362 }
363 }
364
365 const char* hostname = settings->ServerHostname;
366 if (!hostname)
367 {
368 WLog_ERR(TAG, "Missing hostname, can not connect to nullptr target");
369 return FALSE;
370 }
371
372 const UINT32 port = settings->ServerPort;
373 WINPR_ASSERT(port <= UINT32_MAX);
374
375 if (!rdp->nego)
376 return FALSE;
377
378 nego_init(rdp->nego);
379 nego_set_target(rdp->nego, hostname, (UINT16)port);
380
381 if (settings->GatewayEnabled)
382 {
383 char* user = nullptr;
384 char* domain = nullptr;
385 size_t user_length = 0;
386
387 if (settings->Username)
388 {
389 user = settings->Username;
390 user_length = strlen(settings->Username);
391 }
392
393 if (settings->Domain)
394 domain = settings->Domain;
395 else
396 domain = settings->ComputerName;
397
398 const size_t domain_length = strlen(domain);
399 const size_t cookie_length = domain_length + 1 + user_length;
400 char* cookie = malloc(cookie_length + 1);
401
402 if (!cookie)
403 return FALSE;
404
405 CopyMemory(cookie, domain, domain_length);
406 WINPR_ASSERT(domain_length <= UINT32_MAX);
407 CharUpperBuffA(cookie, (UINT32)domain_length);
408 cookie[domain_length] = '\\';
409
410 if (settings->Username)
411 CopyMemory(&cookie[domain_length + 1], user, user_length);
412
413 cookie[cookie_length] = '\0';
414 status = nego_set_cookie(rdp->nego, cookie);
415 free(cookie);
416 }
417 else
418 {
419 status = nego_set_cookie(rdp->nego, settings->Username);
420 }
421
422 if (!status)
423 return FALSE;
424
425 nego_set_childsession_enabled(rdp->nego, settings->ConnectChildSession);
426 nego_set_send_preconnection_pdu(rdp->nego, settings->SendPreconnectionPdu);
427 nego_set_preconnection_id(rdp->nego, settings->PreconnectionId);
428 nego_set_preconnection_blob(rdp->nego, settings->PreconnectionBlob);
429 nego_set_negotiation_enabled(rdp->nego, settings->NegotiateSecurityLayer);
430 nego_set_restricted_admin_mode_required(rdp->nego, settings->RestrictedAdminModeRequired);
431 nego_set_RCG_required(rdp->nego, settings->RemoteCredentialGuard);
432 nego_set_gateway_enabled(rdp->nego, settings->GatewayEnabled);
433 nego_set_gateway_bypass_local(rdp->nego, settings->GatewayBypassLocal);
434 nego_enable_rdp(rdp->nego, settings->RdpSecurity);
435 nego_enable_tls(rdp->nego, settings->TlsSecurity);
436 nego_enable_nla(rdp->nego, settings->NlaSecurity);
437 nego_enable_ext(rdp->nego, settings->ExtSecurity);
438 nego_enable_rdstls(rdp->nego, settings->RdstlsSecurity);
439 nego_enable_aad(rdp->nego, settings->AadSecurity);
440
441 if (settings->MstscCookieMode)
442 settings->CookieMaxLength = MSTSC_COOKIE_MAX_LENGTH;
443
444 nego_set_cookie_max_length(rdp->nego, settings->CookieMaxLength);
445
446 if (settings->LoadBalanceInfo && (settings->LoadBalanceInfoLength > 0))
447 {
448 if (!nego_set_routing_token(rdp->nego, settings->LoadBalanceInfo,
449 settings->LoadBalanceInfoLength))
450 return FALSE;
451 }
452
453 if (!freerdp_settings_get_bool(settings, FreeRDP_TransportDumpReplay))
454 {
455 if (!rdp_client_transition_to_state(rdp, CONNECTION_STATE_NEGO))
456 return FALSE;
457
458 if (!nego_connect(rdp->nego))
459 {
460 if (!freerdp_get_last_error(rdp->context))
461 {
462 freerdp_set_last_error_log(rdp->context,
463 FREERDP_ERROR_SECURITY_NEGO_CONNECT_FAILED);
464 WLog_ERR(TAG, "Error: protocol security negotiation or connection failure");
465 }
466
467 return FALSE;
468 }
469
470 SelectedProtocol = nego_get_selected_protocol(rdp->nego);
471
472 if ((SelectedProtocol & PROTOCOL_SSL) || (SelectedProtocol == PROTOCOL_RDP) ||
473 (SelectedProtocol == PROTOCOL_RDSTLS))
474 {
475 wStream s = WINPR_C_ARRAY_INIT;
476
477 if ((settings->Username != nullptr) &&
478 ((freerdp_settings_get_string(settings, FreeRDP_Password) != nullptr) ||
479 (settings->RedirectionPassword != nullptr &&
480 settings->RedirectionPasswordLength > 0)))
481 settings->AutoLogonEnabled = TRUE;
482
483 if (rdp_recv_callback(rdp->transport, &s, rdp) < 0)
484 return FALSE;
485 }
486
487 if (!transport_set_blocking_mode(rdp->transport, FALSE))
488 return FALSE;
489 }
490 else
491 {
492 if (!rdp_client_transition_to_state(rdp, CONNECTION_STATE_MCS_CREATE_REQUEST))
493 return FALSE;
494 }
495
496 /* everything beyond this point is event-driven and non blocking */
497 if (!transport_set_recv_callbacks(rdp->transport, rdp_recv_callback, rdp))
498 return FALSE;
499
500 return rdp_client_wait_for_activation(rdp);
501}
502
503BOOL rdp_client_disconnect(rdpRdp* rdp)
504{
505 rdpContext* context = nullptr;
506
507 if (!rdp || !rdp->settings || !rdp->context)
508 return FALSE;
509
510 context = rdp->context;
511
512 if (rdp->nego)
513 {
514 if (!nego_disconnect(rdp->nego))
515 return FALSE;
516 }
517
518 if (!transport_disconnect(rdp->transport))
519 return FALSE;
520
521 if (!rdp_reset(rdp))
522 return FALSE;
523
524 if (!rdp_client_transition_to_state(rdp, CONNECTION_STATE_INITIAL))
525 return FALSE;
526
527 if (context->channels)
528 {
529 if (freerdp_channels_disconnect(context->channels, context->instance) != CHANNEL_RC_OK)
530 return FALSE;
531 }
532
533 freerdp_client_codecs_free(context->codecs);
534 context->codecs = nullptr;
535 return TRUE;
536}
537
538BOOL rdp_client_disconnect_and_clear(rdpRdp* rdp)
539{
540 rdpContext* context = nullptr;
541
542 if (!rdp_client_disconnect(rdp))
543 return FALSE;
544
545 WINPR_ASSERT(rdp);
546
547 context = rdp->context;
548 WINPR_ASSERT(context);
549
550 if (freerdp_get_last_error(context) == FREERDP_ERROR_CONNECT_CANCELLED)
551 return FALSE;
552
553 context->LastError = FREERDP_ERROR_SUCCESS;
554 clearChannelError(context);
555 return utils_reset_abort(rdp);
556}
557
558static BOOL rdp_client_reconnect_channels(rdpRdp* rdp, BOOL redirect)
559{
560 BOOL status = FALSE;
561 rdpContext* context = nullptr;
562
563 if (!rdp || !rdp->context || !rdp->context->channels)
564 return FALSE;
565
566 context = rdp->context;
567
568 if (context->instance->ConnectionCallbackState == CLIENT_STATE_INITIAL)
569 return FALSE;
570
571 if (context->instance->ConnectionCallbackState == CLIENT_STATE_PRECONNECT_PASSED)
572 {
573 if (redirect)
574 return TRUE;
575
576 pointer_cache_register_callbacks(context->update);
577
578 if (!IFCALLRESULT(FALSE, context->instance->PostConnect, context->instance))
579 return FALSE;
580
581 context->instance->ConnectionCallbackState = CLIENT_STATE_POSTCONNECT_PASSED;
582 }
583
584 if (context->instance->ConnectionCallbackState == CLIENT_STATE_POSTCONNECT_PASSED)
585 status =
586 (freerdp_channels_post_connect(context->channels, context->instance) == CHANNEL_RC_OK);
587
588 return status;
589}
590
591static BOOL rdp_client_redirect_resolvable(const char* host)
592{
593 struct addrinfo* result = freerdp_tcp_resolve_host(host, -1, 0);
594
595 if (!result)
596 return FALSE;
597
598 freeaddrinfo(result);
599 return TRUE;
600}
601
602static BOOL rdp_client_redirect_try_fqdn(rdpSettings* settings)
603{
604 if (settings->RedirectionFlags & LB_TARGET_FQDN)
605 {
606 if (settings->GatewayEnabled ||
607 rdp_client_redirect_resolvable(settings->RedirectionTargetFQDN))
608 {
609 return (freerdp_settings_set_string(settings, FreeRDP_ServerHostname,
610 settings->RedirectionTargetFQDN));
611 }
612 }
613
614 return FALSE;
615}
616
617static BOOL rdp_client_redirect_try_ip(rdpSettings* settings)
618{
619 if (settings->RedirectionFlags & LB_TARGET_NET_ADDRESS)
620 {
621 return (freerdp_settings_set_string(settings, FreeRDP_ServerHostname,
622 settings->TargetNetAddress));
623 }
624
625 return FALSE;
626}
627
628static BOOL rdp_client_redirect_try_netbios(rdpSettings* settings)
629{
630 if (settings->RedirectionFlags & LB_TARGET_NETBIOS_NAME)
631 {
632 if (settings->GatewayEnabled ||
633 rdp_client_redirect_resolvable(settings->RedirectionTargetNetBiosName))
634 {
635 return (freerdp_settings_set_string(settings, FreeRDP_ServerHostname,
636 settings->RedirectionTargetNetBiosName));
637 }
638 }
639
640 return FALSE;
641}
642
643BOOL rdp_client_redirect(rdpRdp* rdp)
644{
645 BOOL status = 0;
646 rdpSettings* settings = nullptr;
647
648 if (!rdp_client_disconnect_and_clear(rdp))
649 return FALSE;
650
651 /* Only disconnect & close the channels here.
652 * they will be discarded and recreated after the new settings have been applied. */
653 freerdp_channels_disconnect(rdp->context->channels, rdp->context->instance);
654 freerdp_channels_close(rdp->context->channels, rdp->context->instance);
655
656 if (rdp_redirection_apply_settings(rdp) != 0)
657 return FALSE;
658
659 WINPR_ASSERT(rdp);
660
661 settings = rdp->settings;
662 WINPR_ASSERT(settings);
663
664 if ((settings->RedirectionFlags & LB_LOAD_BALANCE_INFO) == 0)
665 {
666 BOOL haveRedirectAddress = FALSE;
667 UINT32 redirectionMask = settings->RedirectionPreferType;
668
669 do
670 {
671 const BOOL tryFQDN = (redirectionMask & 0x01) == 0;
672 const BOOL tryNetAddress = (redirectionMask & 0x02) == 0;
673 const BOOL tryNetbios = (redirectionMask & 0x04) == 0;
674
675 if (tryFQDN && !haveRedirectAddress)
676 haveRedirectAddress = rdp_client_redirect_try_fqdn(settings);
677
678 if (tryNetAddress && !haveRedirectAddress)
679 haveRedirectAddress = rdp_client_redirect_try_ip(settings);
680
681 if (tryNetbios && !haveRedirectAddress)
682 haveRedirectAddress = rdp_client_redirect_try_netbios(settings);
683
684 redirectionMask >>= 3;
685 } while (!haveRedirectAddress && (redirectionMask != 0));
686 }
687
688 if (settings->RedirectionFlags & LB_USERNAME)
689 {
691 settings, FreeRDP_Username,
692 freerdp_settings_get_string(settings, FreeRDP_RedirectionUsername)))
693 return FALSE;
694 }
695
696 if (settings->RedirectionFlags & LB_DOMAIN)
697 {
699 settings, FreeRDP_Domain,
700 freerdp_settings_get_string(settings, FreeRDP_RedirectionDomain)))
701 return FALSE;
702 }
703
704 settings->RdstlsSecurity = ((settings->RedirectionFlags & LB_PASSWORD_IS_PK_ENCRYPTED) != 0);
705
706 WINPR_ASSERT(rdp->context);
707 WINPR_ASSERT(rdp->context->instance);
708 if (!IFCALLRESULT(TRUE, rdp->context->instance->Redirect, rdp->context->instance))
709 return FALSE;
710
711 BOOL ok = utils_reload_channels(rdp->context);
712 if (!ok)
713 return FALSE;
714
715 status = rdp_client_connect(rdp);
716
717 if (status)
718 status = rdp_client_reconnect_channels(rdp, TRUE);
719
720 return status;
721}
722
723BOOL rdp_client_reconnect(rdpRdp* rdp)
724{
725 if (!rdp_client_disconnect_and_clear(rdp))
726 return FALSE;
727
728 if (!freerdp_settings_set_bool(rdp->settings, FreeRDP_SessionHasBeenReconnected, TRUE))
729 return FALSE;
730
731 BOOL status = rdp_client_connect(rdp);
732
733 if (status)
734 status = rdp_client_reconnect_channels(rdp, FALSE);
735
736 return status;
737}
738
739static const BYTE fips_ivec[8] = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };
740
741static BOOL rdp_client_establish_keys(rdpRdp* rdp)
742{
743 wStream* s = nullptr;
744 BOOL ret = FALSE;
745
746 WINPR_ASSERT(rdp);
747 rdpSettings* settings = rdp->settings;
748 BYTE* crypt_client_random = nullptr;
749
750 WINPR_ASSERT(settings);
751 if (!settings->UseRdpSecurityLayer)
752 {
753 /* no RDP encryption */
754 return TRUE;
755 }
756
757 if (!rdp_client_transition_to_state(rdp, CONNECTION_STATE_RDP_SECURITY_COMMENCEMENT))
758 return FALSE;
759
760 /* encrypt client random */
761 if (!freerdp_settings_set_pointer_len(settings, FreeRDP_ClientRandom, nullptr,
762 CLIENT_RANDOM_LENGTH))
763 return FALSE;
764 if (winpr_RAND(settings->ClientRandom, settings->ClientRandomLength) < 0)
765 return FALSE;
766
767 const rdpCertInfo* info = freerdp_certificate_get_info(settings->RdpServerCertificate);
768 if (!info)
769 {
770 WLog_ERR(TAG, "Failed to get rdpCertInfo from RdpServerCertificate");
771 return FALSE;
772 }
773
774 /*
775 * client random must be (bitlen / 8) + 8 - see [MS-RDPBCGR] 5.3.4.1
776 * for details
777 */
778 crypt_client_random = calloc(info->ModulusLength, 1);
779
780 if (!crypt_client_random)
781 return FALSE;
782
783 if (crypto_rsa_public_encrypt(settings->ClientRandom, settings->ClientRandomLength, info,
784 crypt_client_random, info->ModulusLength) < 0)
785 goto end;
786 /* send crypt client random to server */
787 const size_t length = RDP_PACKET_HEADER_MAX_LENGTH + RDP_SECURITY_HEADER_LENGTH + 4ULL +
788 info->ModulusLength + 8ULL;
789 if (length > UINT16_MAX)
790 goto end;
791
792 s = Stream_New(nullptr, length);
793
794 if (!s)
795 {
796 WLog_ERR(TAG, "Stream_New failed!");
797 goto end;
798 }
799
800 {
801 const UINT16 sec_flags = SEC_EXCHANGE_PKT | SEC_LICENSE_ENCRYPT_SC;
802 if (!rdp_write_header(rdp, s, length, MCS_GLOBAL_CHANNEL_ID, sec_flags))
803 goto end;
804 if (!rdp_write_security_header(rdp, s, sec_flags))
805 goto end;
806 }
807
808 Stream_Write_UINT32(s, info->ModulusLength + 8);
809 Stream_Write(s, crypt_client_random, info->ModulusLength);
810 Stream_Zero(s, 8);
811 Stream_SealLength(s);
812
813 {
814 rdpTransport* transport = freerdp_get_transport(rdp->context);
815 const int status = transport_write(transport, s);
816
817 if (status < 0)
818 goto end;
819 }
820
821 rdp->do_crypt_license = TRUE;
822
823 /* now calculate encrypt / decrypt and update keys */
824 if (!security_establish_keys(rdp))
825 goto end;
826
827 rdp->do_crypt = TRUE;
828
829 if (settings->SaltedChecksum)
830 rdp->do_secure_checksum = TRUE;
831
832 if (settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS)
833 {
834 rdp->fips_encrypt =
835 winpr_Cipher_NewEx(WINPR_CIPHER_DES_EDE3_CBC, WINPR_ENCRYPT, rdp->fips_encrypt_key,
836 sizeof(rdp->fips_encrypt_key), fips_ivec, sizeof(fips_ivec));
837
838 if (!rdp->fips_encrypt)
839 {
840 WLog_ERR(TAG, "unable to allocate des3 encrypt key");
841 goto end;
842 }
843
844 rdp->fips_decrypt =
845 winpr_Cipher_NewEx(WINPR_CIPHER_DES_EDE3_CBC, WINPR_DECRYPT, rdp->fips_decrypt_key,
846 sizeof(rdp->fips_decrypt_key), fips_ivec, sizeof(fips_ivec));
847
848 if (!rdp->fips_decrypt)
849 {
850 WLog_ERR(TAG, "unable to allocate des3 decrypt key");
851 goto end;
852 }
853
854 ret = TRUE;
855 goto end;
856 }
857
858 if (!rdp_reset_rc4_encrypt_keys(rdp))
859 goto end;
860 if (!rdp_reset_rc4_decrypt_keys(rdp))
861 goto end;
862
863 ret = TRUE;
864end:
865 Stream_Free(s, TRUE);
866 free(crypt_client_random);
867
868 if (!ret)
869 {
870 winpr_Cipher_Free(rdp->fips_decrypt);
871 winpr_Cipher_Free(rdp->fips_encrypt);
872 rdp->fips_decrypt = nullptr;
873 rdp->fips_encrypt = nullptr;
874
875 rdp_free_rc4_decrypt_keys(rdp);
876 rdp_free_rc4_encrypt_keys(rdp);
877 }
878
879 return ret;
880}
881
882static BOOL rdp_update_client_random(rdpSettings* settings, const BYTE* crypt_random,
883 size_t crypt_random_len)
884{
885 const size_t length = 32;
886 WINPR_ASSERT(settings);
887
888 const rdpPrivateKey* rsa = freerdp_settings_get_pointer(settings, FreeRDP_RdpServerRsaKey);
889 WINPR_ASSERT(rsa);
890
891 const rdpCertInfo* cinfo = freerdp_key_get_info(rsa);
892 WINPR_ASSERT(cinfo);
893
894 if (crypt_random_len != cinfo->ModulusLength + 8)
895 {
896 WLog_ERR(TAG, "invalid encrypted client random length");
897 return FALSE;
898 }
899 if (!freerdp_settings_set_pointer_len(settings, FreeRDP_ClientRandom, nullptr, length))
900 return FALSE;
901
902 BYTE* client_random = freerdp_settings_get_pointer_writable(settings, FreeRDP_ClientRandom);
903 WINPR_ASSERT(client_random);
904 return crypto_rsa_private_decrypt(crypt_random, crypt_random_len - 8, rsa, client_random,
905 length) > 0;
906}
907
908BOOL rdp_server_establish_keys(rdpRdp* rdp, wStream* s)
909{
910 UINT32 rand_len = 0;
911 UINT16 channel_id = 0;
912 UINT16 length = 0;
913 UINT16 sec_flags = 0;
914 BOOL ret = FALSE;
915
916 WINPR_ASSERT(rdp);
917
918 if (!rdp->settings->UseRdpSecurityLayer)
919 {
920 /* No RDP Security. */
921 return TRUE;
922 }
923
924 if (!rdp_read_header(rdp, s, &length, &channel_id))
925 return FALSE;
926
927 if (!rdp_read_security_header(rdp, s, &sec_flags, nullptr))
928 {
929 WLog_Print(rdp->log, WLOG_ERROR, "invalid security header");
930 return FALSE;
931 }
932
933 if ((sec_flags & SEC_EXCHANGE_PKT) == 0)
934 {
935 WLog_Print(rdp->log, WLOG_ERROR, "missing SEC_EXCHANGE_PKT in security header");
936 return FALSE;
937 }
938
939 rdp->do_crypt_license = ((sec_flags & SEC_LICENSE_ENCRYPT_SC) != 0);
940
941 if (!Stream_CheckAndLogRequiredLengthWLog(rdp->log, s, 4))
942 return FALSE;
943
944 Stream_Read_UINT32(s, rand_len);
945
946 /* rand_len already includes 8 bytes of padding */
947 if (!Stream_CheckAndLogRequiredLengthWLog(rdp->log, s, rand_len))
948 return FALSE;
949
950 const BYTE* crypt_random = Stream_ConstPointer(s);
951 if (!Stream_SafeSeek(s, rand_len))
952 goto end;
953 if (!rdp_update_client_random(rdp->settings, crypt_random, rand_len))
954 goto end;
955
956 /* now calculate encrypt / decrypt and update keys */
957 if (!security_establish_keys(rdp))
958 goto end;
959
960 rdp->do_crypt = TRUE;
961
962 if (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS)
963 {
964 rdp->fips_encrypt =
965 winpr_Cipher_NewEx(WINPR_CIPHER_DES_EDE3_CBC, WINPR_ENCRYPT, rdp->fips_encrypt_key,
966 sizeof(rdp->fips_encrypt_key), fips_ivec, sizeof(fips_ivec));
967
968 if (!rdp->fips_encrypt)
969 {
970 WLog_Print(rdp->log, WLOG_ERROR, "unable to allocate des3 encrypt key");
971 goto end;
972 }
973
974 rdp->fips_decrypt =
975 winpr_Cipher_NewEx(WINPR_CIPHER_DES_EDE3_CBC, WINPR_DECRYPT, rdp->fips_decrypt_key,
976 sizeof(rdp->fips_decrypt_key), fips_ivec, sizeof(fips_ivec));
977
978 if (!rdp->fips_decrypt)
979 {
980 WLog_Print(rdp->log, WLOG_ERROR, "unable to allocate des3 decrypt key");
981 goto end;
982 }
983
984 ret = TRUE;
985 goto end;
986 }
987
988 if (!rdp_reset_rc4_encrypt_keys(rdp))
989 goto end;
990
991 if (!rdp_reset_rc4_decrypt_keys(rdp))
992 goto end;
993
994 ret = tpkt_ensure_stream_consumed(rdp->log, s, length);
995end:
996
997 if (!ret)
998 {
999 winpr_Cipher_Free(rdp->fips_encrypt);
1000 winpr_Cipher_Free(rdp->fips_decrypt);
1001 rdp->fips_encrypt = nullptr;
1002 rdp->fips_decrypt = nullptr;
1003
1004 rdp_free_rc4_encrypt_keys(rdp);
1005 rdp_free_rc4_decrypt_keys(rdp);
1006 }
1007
1008 return ret;
1009}
1010
1011static BOOL rdp_client_send_client_info_and_change_state(rdpRdp* rdp)
1012{
1013 WINPR_ASSERT(rdp);
1014 if (!rdp_client_establish_keys(rdp))
1015 return FALSE;
1016 if (!rdp_client_transition_to_state(rdp, CONNECTION_STATE_SECURE_SETTINGS_EXCHANGE))
1017 return FALSE;
1018 if (!rdp_send_client_info(rdp))
1019 return FALSE;
1020 if (!rdp_client_transition_to_state(rdp, CONNECTION_STATE_CONNECT_TIME_AUTO_DETECT_REQUEST))
1021 return FALSE;
1022 return TRUE;
1023}
1024
1025BOOL rdp_client_skip_mcs_channel_join(rdpRdp* rdp)
1026{
1027 WINPR_ASSERT(rdp);
1028
1029 rdpMcs* mcs = rdp->mcs;
1030 WINPR_ASSERT(mcs);
1031
1032 mcs->userChannelJoined = TRUE;
1033 mcs->globalChannelJoined = TRUE;
1034 mcs->messageChannelJoined = TRUE;
1035
1036 for (UINT32 i = 0; i < mcs->channelCount; i++)
1037 {
1038 rdpMcsChannel* cur = &mcs->channels[i];
1039 WLog_DBG(TAG, " %s [%" PRIu16 "]", cur->Name, cur->ChannelId);
1040 cur->joined = TRUE;
1041 }
1042
1043 return rdp_client_send_client_info_and_change_state(rdp);
1044}
1045
1046static BOOL rdp_client_join_channel(rdpRdp* rdp, UINT16 ChannelId)
1047{
1048 WINPR_ASSERT(rdp);
1049
1050 rdpMcs* mcs = rdp->mcs;
1051 if (!rdp_client_transition_to_state(rdp, CONNECTION_STATE_MCS_CHANNEL_JOIN_REQUEST))
1052 return FALSE;
1053 if (!mcs_send_channel_join_request(mcs, ChannelId))
1054 return FALSE;
1055 if (!rdp_client_transition_to_state(rdp, CONNECTION_STATE_MCS_CHANNEL_JOIN_RESPONSE))
1056 return FALSE;
1057 return TRUE;
1058}
1059
1060BOOL rdp_client_connect_mcs_channel_join_confirm(rdpRdp* rdp, wStream* s)
1061{
1062 UINT16 channelId = 0;
1063 BOOL allJoined = TRUE;
1064
1065 WINPR_ASSERT(rdp);
1066 rdpMcs* mcs = rdp->mcs;
1067
1068 if (!mcs_recv_channel_join_confirm(mcs, s, &channelId))
1069 return FALSE;
1070
1071 if (!mcs->userChannelJoined)
1072 {
1073 if (channelId != mcs->userId)
1074 {
1075 WLog_ERR(TAG, "expected user channel id %" PRIu16 ", but received %" PRIu16,
1076 mcs->userId, channelId);
1077 return FALSE;
1078 }
1079
1080 mcs->userChannelJoined = TRUE;
1081 if (!rdp_client_join_channel(rdp, MCS_GLOBAL_CHANNEL_ID))
1082 return FALSE;
1083 }
1084 else if (!mcs->globalChannelJoined)
1085 {
1086 if (channelId != MCS_GLOBAL_CHANNEL_ID)
1087 {
1088 WLog_ERR(TAG, "expected uglobalser channel id %d, but received %" PRIu16,
1089 MCS_GLOBAL_CHANNEL_ID, channelId);
1090 return FALSE;
1091 }
1092 mcs->globalChannelJoined = TRUE;
1093
1094 if (mcs->messageChannelId != 0)
1095 {
1096 if (!rdp_client_join_channel(rdp, mcs->messageChannelId))
1097 return FALSE;
1098 allJoined = FALSE;
1099 }
1100 else
1101 {
1102 if (mcs->channelCount > 0)
1103 {
1104 const rdpMcsChannel* cur = &mcs->channels[0];
1105 if (!rdp_client_join_channel(rdp, cur->ChannelId))
1106 return FALSE;
1107 allJoined = FALSE;
1108 }
1109 }
1110 }
1111 else if ((mcs->messageChannelId != 0) && !mcs->messageChannelJoined)
1112 {
1113 if (channelId != mcs->messageChannelId)
1114 {
1115 WLog_ERR(TAG, "expected messageChannelId=%" PRIu16 ", got %" PRIu16,
1116 mcs->messageChannelId, channelId);
1117 return FALSE;
1118 }
1119
1120 mcs->messageChannelJoined = TRUE;
1121
1122 if (mcs->channelCount > 0)
1123 {
1124 const rdpMcsChannel* cur = &mcs->channels[0];
1125 if (!rdp_client_join_channel(rdp, cur->ChannelId))
1126 return FALSE;
1127 allJoined = FALSE;
1128 }
1129 }
1130 else
1131 {
1132 UINT32 i = 0;
1133 for (; i < mcs->channelCount; i++)
1134 {
1135 rdpMcsChannel* cur = &mcs->channels[i];
1136 if (cur->joined)
1137 continue;
1138
1139 if (cur->ChannelId != channelId)
1140 {
1141 WLog_ERR(TAG, "expected channel id %d, but received %" PRIu16,
1142 MCS_GLOBAL_CHANNEL_ID, channelId);
1143 return FALSE;
1144 }
1145 cur->joined = TRUE;
1146 break;
1147 }
1148
1149 if (i + 1 < mcs->channelCount)
1150 {
1151 const rdpMcsChannel* cur = &mcs->channels[i + 1];
1152 if (!rdp_client_join_channel(rdp, cur->ChannelId))
1153 return FALSE;
1154 allJoined = FALSE;
1155 }
1156 }
1157
1158 if (mcs->userChannelJoined && mcs->globalChannelJoined && allJoined)
1159 {
1160 if (!rdp_client_send_client_info_and_change_state(rdp))
1161 return FALSE;
1162 }
1163
1164 return TRUE;
1165}
1166
1167state_run_t rdp_handle_message_channel(rdpRdp* rdp, wStream* s, UINT16 channelId, UINT16 length)
1168{
1169 WINPR_ASSERT(rdp);
1170 WINPR_ASSERT(rdp->mcs);
1171
1172 if (!rdp->mcs->messageChannelJoined)
1173 {
1174 WLog_Print(rdp->log, WLOG_WARN, "MCS message channel not joined!");
1175 return STATE_RUN_FAILED;
1176 }
1177 const UINT16 messageChannelId = rdp->mcs->messageChannelId;
1178 if (messageChannelId == 0)
1179 {
1180 WLog_Print(rdp->log, WLOG_WARN, "MCS message channel id == 0");
1181 return STATE_RUN_FAILED;
1182 }
1183
1184 if ((channelId != messageChannelId) && (channelId != MCS_GLOBAL_CHANNEL_ID))
1185 {
1186 WLog_Print(rdp->log, WLOG_WARN,
1187 "MCS message channel expected id=[%" PRIu16 "|%d], got %" PRIu16,
1188 messageChannelId, MCS_GLOBAL_CHANNEL_ID, channelId);
1189 return STATE_RUN_FAILED;
1190 }
1191
1192 UINT16 securityFlags = 0;
1193 if (!rdp_read_security_header(rdp, s, &securityFlags, &length))
1194 return STATE_RUN_FAILED;
1195
1196 if (securityFlags & SEC_ENCRYPT)
1197 {
1198 if (!rdp_decrypt(rdp, s, &length, securityFlags))
1199 return STATE_RUN_FAILED;
1200 }
1201
1202 const state_run_t rc = rdp_recv_message_channel_pdu(rdp, s, securityFlags);
1203 if (state_run_success(rc))
1204 {
1205 if (!tpkt_ensure_stream_consumed(rdp->log, s, length))
1206 return STATE_RUN_FAILED;
1207 }
1208 return rc;
1209}
1210
1211BOOL rdp_client_connect_auto_detect(rdpRdp* rdp, wStream* s, DWORD logLevel)
1212{
1213 BOOL res = TRUE;
1214 WINPR_ASSERT(rdp);
1215 WINPR_ASSERT(rdp->mcs);
1216
1217 size_t pos = Stream_GetPosition(s);
1218 UINT16 length = 0;
1219 UINT16 channelId = 0;
1220
1221 if (!rdp_read_header(rdp, s, &length, &channelId))
1222 res = FALSE;
1223 else
1224 {
1225 const UINT16 messageChannelId = rdp->mcs->messageChannelId;
1226 /* If the MCS message channel has been joined... */
1227
1228 /* Process any MCS message channel PDUs. */
1229 if (rdp->mcs->messageChannelJoined && (channelId == messageChannelId))
1230 {
1231 const state_run_t rc = rdp_handle_message_channel(rdp, s, channelId, length);
1232 res = state_run_success(rc);
1233 pos = Stream_GetPosition(s);
1234 }
1235 else
1236 {
1237 wLog* log = WLog_Get(TAG);
1238 WLog_Print(log, logLevel, "expected messageChannelId=%" PRIu16 ", got %" PRIu16,
1239 messageChannelId, channelId);
1240 res = FALSE;
1241 }
1242 }
1243
1244 if (!Stream_SetPosition(s, pos))
1245 res = FALSE;
1246 return res;
1247}
1248
1249state_run_t rdp_client_connect_license(rdpRdp* rdp, wStream* s)
1250{
1251 state_run_t status = STATE_RUN_FAILED;
1252 LICENSE_STATE state = LICENSE_STATE_ABORTED;
1253 UINT16 length = 0;
1254 UINT16 channelId = 0;
1255 UINT16 securityFlags = 0;
1256
1257 WINPR_ASSERT(rdp);
1258 if (!rdp_read_header(rdp, s, &length, &channelId))
1259 return STATE_RUN_FAILED;
1260
1261 /* there might be autodetect messages mixed in between licensing messages.
1262 * that has been observed with 2k12 R2 and 2k19
1263 */
1264 const UINT16 messageChannelId = rdp->mcs->messageChannelId;
1265 if (rdp->mcs->messageChannelJoined && (channelId == messageChannelId))
1266 {
1267 return rdp_handle_message_channel(rdp, s, channelId, length);
1268 }
1269
1270 if (!rdp_read_security_header(rdp, s, &securityFlags, &length))
1271 return STATE_RUN_FAILED;
1272
1273 if (securityFlags & SEC_ENCRYPT)
1274 {
1275 if (!rdp_decrypt(rdp, s, &length, securityFlags))
1276 return STATE_RUN_FAILED;
1277 }
1278
1279 if (channelId != MCS_GLOBAL_CHANNEL_ID)
1280 WLog_WARN(TAG, "unexpected message for channel %u, expected %d", channelId,
1281 MCS_GLOBAL_CHANNEL_ID);
1282
1283 if ((securityFlags & SEC_LICENSE_PKT) == 0)
1284 {
1285 char buffer[512] = WINPR_C_ARRAY_INIT;
1286 char lbuffer[32] = WINPR_C_ARRAY_INIT;
1287 WLog_ERR(TAG, "securityFlags=%s, missing required flag %s",
1288 rdp_security_flag_string(securityFlags, buffer, sizeof(buffer)),
1289 rdp_security_flag_string(SEC_LICENSE_PKT, lbuffer, sizeof(lbuffer)));
1290 return STATE_RUN_FAILED;
1291 }
1292
1293 status = license_recv(rdp->license, s);
1294
1295 if (state_run_failed(status))
1296 return status;
1297
1298 state = license_get_state(rdp->license);
1299 switch (state)
1300 {
1301 case LICENSE_STATE_ABORTED:
1302 WLog_ERR(TAG, "license connection sequence aborted.");
1303 return STATE_RUN_FAILED;
1304 case LICENSE_STATE_COMPLETED:
1305 if (rdp->settings->MultitransportFlags)
1306 {
1307 if (!rdp_client_transition_to_state(
1308 rdp, CONNECTION_STATE_MULTITRANSPORT_BOOTSTRAPPING_REQUEST))
1309 return STATE_RUN_FAILED;
1310 }
1311 else
1312 {
1313 if (!rdp_client_transition_to_state(
1314 rdp, CONNECTION_STATE_CAPABILITIES_EXCHANGE_DEMAND_ACTIVE))
1315 return STATE_RUN_FAILED;
1316 }
1317 return STATE_RUN_SUCCESS;
1318 default:
1319 return STATE_RUN_SUCCESS;
1320 }
1321}
1322
1323state_run_t rdp_client_connect_demand_active(rdpRdp* rdp, wStream* s)
1324{
1325 UINT16 length = 0;
1326 UINT16 channelId = 0;
1327 UINT16 pduType = 0;
1328 UINT16 pduSource = 0;
1329
1330 WINPR_ASSERT(rdp);
1331 WINPR_ASSERT(s);
1332 WINPR_ASSERT(rdp->settings);
1333
1334 if (!rdp_recv_get_active_header(rdp, s, &channelId, &length))
1335 return STATE_RUN_FAILED;
1336
1337 if (freerdp_shall_disconnect_context(rdp->context))
1338 return STATE_RUN_QUIT_SESSION;
1339
1340 if (rdp->mcs->messageChannelId && (channelId == rdp->mcs->messageChannelId))
1341 {
1342 rdp->inPackets++;
1343 return rdp_handle_message_channel(rdp, s, channelId, length);
1344 }
1345
1346 if (!rdp_handle_optional_rdp_decryption(rdp, s, &length, nullptr))
1347 return STATE_RUN_FAILED;
1348
1349 if (!rdp_read_share_control_header(rdp, s, nullptr, nullptr, &pduType, &pduSource))
1350 return STATE_RUN_FAILED;
1351
1352 switch (pduType)
1353 {
1354 case PDU_TYPE_DEMAND_ACTIVE:
1355 if (!rdp_recv_demand_active(rdp, s, pduSource, length))
1356 return STATE_RUN_FAILED;
1357 return STATE_RUN_ACTIVE;
1358 default:
1359 return rdp_recv_out_of_sequence_pdu(rdp, s, pduType, length);
1360 }
1361}
1362
1363state_run_t rdp_client_connect_finalize(rdpRdp* rdp)
1364{
1365 WINPR_ASSERT(rdp);
1372 if (!rdp_client_transition_to_state(rdp, CONNECTION_STATE_FINALIZATION_SYNC))
1373 return STATE_RUN_FAILED;
1374
1375 if (!rdp_send_client_synchronize_pdu(rdp))
1376 return STATE_RUN_FAILED;
1377
1378 if (!rdp_client_transition_to_state(rdp, CONNECTION_STATE_FINALIZATION_COOPERATE))
1379 return STATE_RUN_FAILED;
1380 if (!rdp_send_client_control_pdu(rdp, CTRLACTION_COOPERATE))
1381 return STATE_RUN_FAILED;
1382
1383 if (!rdp_client_transition_to_state(rdp, CONNECTION_STATE_FINALIZATION_REQUEST_CONTROL))
1384 return STATE_RUN_FAILED;
1385 if (!rdp_send_client_control_pdu(rdp, CTRLACTION_REQUEST_CONTROL))
1386 return STATE_RUN_FAILED;
1387
1395 if (!rdp_finalize_is_flag_set(rdp, FINALIZE_DEACTIVATE_REACTIVATE) &&
1396 freerdp_settings_get_bool(rdp->settings, FreeRDP_BitmapCachePersistEnabled))
1397 {
1398 if (!rdp_client_transition_to_state(rdp, CONNECTION_STATE_FINALIZATION_PERSISTENT_KEY_LIST))
1399 return STATE_RUN_FAILED;
1400 if (!rdp_send_client_persistent_key_list_pdu(rdp))
1401 return STATE_RUN_FAILED;
1402 }
1403
1404 if (!rdp_client_transition_to_state(rdp, CONNECTION_STATE_FINALIZATION_FONT_LIST))
1405 return STATE_RUN_FAILED;
1406 if (!rdp_send_client_font_list_pdu(rdp, FONTLIST_FIRST | FONTLIST_LAST))
1407 return STATE_RUN_FAILED;
1408
1409 if (!rdp_client_transition_to_state(rdp, CONNECTION_STATE_FINALIZATION_CLIENT_SYNC))
1410 return STATE_RUN_FAILED;
1411 return STATE_RUN_SUCCESS;
1412}
1413
1414BOOL rdp_client_transition_to_state(rdpRdp* rdp, CONNECTION_STATE state)
1415{
1416 const char* name = rdp_state_string(state);
1417
1418 WINPR_ASSERT(rdp);
1419 WLog_Print(rdp->log, WLOG_DEBUG, "%s --> %s", rdp_get_state_string(rdp), name);
1420
1421 if (!rdp_set_state(rdp, state))
1422 return FALSE;
1423
1424 switch (state)
1425 {
1426 case CONNECTION_STATE_FINALIZATION_SYNC:
1427 case CONNECTION_STATE_FINALIZATION_COOPERATE:
1428 case CONNECTION_STATE_FINALIZATION_REQUEST_CONTROL:
1429 case CONNECTION_STATE_FINALIZATION_PERSISTENT_KEY_LIST:
1430 case CONNECTION_STATE_FINALIZATION_FONT_LIST:
1431 update_reset_state(rdp->update);
1432 break;
1433
1434 case CONNECTION_STATE_CAPABILITIES_EXCHANGE_CONFIRM_ACTIVE:
1435 {
1436 ActivatedEventArgs activatedEvent = WINPR_C_ARRAY_INIT;
1437 rdpContext* context = rdp->context;
1438 EventArgsInit(&activatedEvent, "libfreerdp");
1439 activatedEvent.firstActivation =
1440 !rdp_finalize_is_flag_set(rdp, FINALIZE_DEACTIVATE_REACTIVATE);
1441 if (PubSub_OnActivated(rdp->pubSub, context, &activatedEvent) < 0)
1442 return FALSE;
1443 }
1444
1445 break;
1446
1447 default:
1448 break;
1449 }
1450
1451 {
1452 ConnectionStateChangeEventArgs stateEvent = WINPR_C_ARRAY_INIT;
1453 rdpContext* context = rdp->context;
1454 EventArgsInit(&stateEvent, "libfreerdp");
1455 stateEvent.state = WINPR_ASSERTING_INT_CAST(int32_t, rdp_get_state(rdp));
1456 stateEvent.active = rdp_is_active_state(rdp);
1457 if (PubSub_OnConnectionStateChange(rdp->pubSub, context, &stateEvent) < 0)
1458 return FALSE;
1459 }
1460
1461 return TRUE;
1462}
1463
1464BOOL rdp_server_accept_nego(rdpRdp* rdp, wStream* s)
1465{
1466 UINT32 SelectedProtocol = 0;
1467 UINT32 RequestedProtocols = 0;
1468 BOOL status = 0;
1469 rdpSettings* settings = nullptr;
1470 rdpNego* nego = nullptr;
1471
1472 WINPR_ASSERT(rdp);
1473 WINPR_ASSERT(s);
1474
1475 settings = rdp->settings;
1476 WINPR_ASSERT(settings);
1477
1478 nego = rdp->nego;
1479 WINPR_ASSERT(nego);
1480
1481 if (!transport_set_blocking_mode(rdp->transport, TRUE))
1482 return FALSE;
1483
1484 if (!nego_read_request(nego, s))
1485 return FALSE;
1486
1487 RequestedProtocols = nego_get_requested_protocols(nego);
1488 WLog_DBG(TAG, "Client Security: RDSTLS:%d NLA:%d TLS:%d RDP:%d",
1489 (RequestedProtocols & PROTOCOL_RDSTLS) ? 1 : 0,
1490 (RequestedProtocols & PROTOCOL_HYBRID) ? 1 : 0,
1491 (RequestedProtocols & PROTOCOL_SSL) ? 1 : 0,
1492 (RequestedProtocols == PROTOCOL_RDP) ? 1 : 0);
1493 WLog_DBG(TAG,
1494 "Server Security: RDSTLS:%" PRId32 " NLA:%" PRId32 " TLS:%" PRId32 " RDP:%" PRId32 "",
1495 settings->RdstlsSecurity, settings->NlaSecurity, settings->TlsSecurity,
1496 settings->RdpSecurity);
1497
1498 if ((settings->RdstlsSecurity) && (RequestedProtocols & PROTOCOL_RDSTLS))
1499 {
1500 SelectedProtocol = PROTOCOL_RDSTLS;
1501 }
1502 else if ((settings->NlaSecurity) && (RequestedProtocols & PROTOCOL_HYBRID))
1503 {
1504 SelectedProtocol = PROTOCOL_HYBRID;
1505 }
1506 else if ((settings->TlsSecurity) && (RequestedProtocols & PROTOCOL_SSL))
1507 {
1508 SelectedProtocol = PROTOCOL_SSL;
1509 }
1510 else if ((settings->RdpSecurity) && (RequestedProtocols == PROTOCOL_RDP))
1511 {
1512 SelectedProtocol = PROTOCOL_RDP;
1513 }
1514 else
1515 {
1516 /*
1517 * when here client and server aren't compatible, we select the right
1518 * error message to return to the client in the nego failure packet
1519 */
1520 SelectedProtocol = PROTOCOL_FAILED_NEGO;
1521
1522 if (settings->RdpSecurity)
1523 {
1524 WLog_ERR(TAG, "server supports only Standard RDP Security");
1525 SelectedProtocol |= SSL_NOT_ALLOWED_BY_SERVER;
1526 }
1527 else
1528 {
1529 if (settings->NlaSecurity && !settings->TlsSecurity)
1530 {
1531 WLog_WARN(TAG, "server supports only NLA Security");
1532 SelectedProtocol |= HYBRID_REQUIRED_BY_SERVER;
1533 }
1534 else
1535 {
1536 WLog_WARN(TAG, "server supports only a SSL based Security (TLS or NLA)");
1537 SelectedProtocol |= SSL_REQUIRED_BY_SERVER;
1538 }
1539 }
1540
1541 WLog_ERR(TAG, "Protocol security negotiation failure");
1542 }
1543
1544 if (!(SelectedProtocol & PROTOCOL_FAILED_NEGO))
1545 {
1546 WLog_DBG(TAG, "Negotiated Security: RDSTLS:%d NLA:%d TLS:%d RDP:%d",
1547 (SelectedProtocol & PROTOCOL_RDSTLS) ? 1 : 0,
1548 (SelectedProtocol & PROTOCOL_HYBRID) ? 1 : 0,
1549 (SelectedProtocol & PROTOCOL_SSL) ? 1 : 0,
1550 (SelectedProtocol == PROTOCOL_RDP) ? 1 : 0);
1551 }
1552
1553 if (!nego_set_selected_protocol(nego, SelectedProtocol))
1554 return FALSE;
1555
1556 if (!nego_send_negotiation_response(nego))
1557 return FALSE;
1558
1559 SelectedProtocol = nego_get_selected_protocol(nego);
1560 status = FALSE;
1561
1562 if (freerdp_settings_get_bool(rdp->settings, FreeRDP_VmConnectMode) &&
1563 SelectedProtocol != PROTOCOL_RDP)
1564 /* When behind a Hyper-V proxy, security != RDP is handled by the host. */
1565 status = TRUE;
1566 else if (SelectedProtocol & PROTOCOL_RDSTLS)
1567 status = transport_accept_rdstls(rdp->transport);
1568 else if (SelectedProtocol & PROTOCOL_HYBRID)
1569 status = transport_accept_nla(rdp->transport);
1570 else if (SelectedProtocol & PROTOCOL_SSL)
1571 status = transport_accept_tls(rdp->transport);
1572 else if (SelectedProtocol == PROTOCOL_RDP) /* 0 */
1573 status = transport_accept_rdp(rdp->transport);
1574
1575 if (!status)
1576 return FALSE;
1577
1578 return transport_set_blocking_mode(rdp->transport, FALSE);
1579}
1580
1581static BOOL rdp_update_encryption_level(rdpSettings* settings)
1582{
1583 WINPR_ASSERT(settings);
1584
1585 UINT32 EncryptionLevel = freerdp_settings_get_uint32(settings, FreeRDP_EncryptionLevel);
1586 UINT32 EncryptionMethods = freerdp_settings_get_uint32(settings, FreeRDP_EncryptionMethods);
1587
1598 if (!settings->UseRdpSecurityLayer)
1599 {
1600 /* TLS/NLA is used: disable rdp style encryption */
1601 EncryptionLevel = ENCRYPTION_LEVEL_NONE;
1602 }
1603 else
1604 {
1605 /* verify server encryption level value */
1606 switch (EncryptionLevel)
1607 {
1608 case ENCRYPTION_LEVEL_NONE:
1609 WLog_INFO(TAG, "Active rdp encryption level: NONE");
1610 break;
1611
1612 case ENCRYPTION_LEVEL_FIPS:
1613 WLog_INFO(TAG, "Active rdp encryption level: FIPS Compliant");
1614 break;
1615
1616 case ENCRYPTION_LEVEL_HIGH:
1617 WLog_INFO(TAG, "Active rdp encryption level: HIGH");
1618 break;
1619
1620 case ENCRYPTION_LEVEL_LOW:
1621 WLog_INFO(TAG, "Active rdp encryption level: LOW");
1622 break;
1623
1624 case ENCRYPTION_LEVEL_CLIENT_COMPATIBLE:
1625 WLog_INFO(TAG, "Active rdp encryption level: CLIENT-COMPATIBLE");
1626 break;
1627
1628 default:
1629 WLog_ERR(TAG, "Invalid server encryption level 0x%08" PRIX32 "", EncryptionLevel);
1630 WLog_ERR(TAG, "Switching to encryption level CLIENT-COMPATIBLE");
1631 EncryptionLevel = ENCRYPTION_LEVEL_CLIENT_COMPATIBLE;
1632 }
1633 }
1634
1635 /* choose rdp encryption method based on server level and client methods */
1636 switch (EncryptionLevel)
1637 {
1638 case ENCRYPTION_LEVEL_NONE:
1639 /* The only valid method is NONE in this case */
1640 EncryptionMethods = ENCRYPTION_METHOD_NONE;
1641 break;
1642
1643 case ENCRYPTION_LEVEL_FIPS:
1644
1645 /* The only valid method is FIPS in this case */
1646 if (!(EncryptionMethods & ENCRYPTION_METHOD_FIPS))
1647 {
1648 WLog_WARN(TAG, "client does not support FIPS as required by server configuration");
1649 }
1650
1651 EncryptionMethods = ENCRYPTION_METHOD_FIPS;
1652 break;
1653
1654 case ENCRYPTION_LEVEL_HIGH:
1655
1656 /* Maximum key strength supported by the server must be used (128 bit)*/
1657 if (!(EncryptionMethods & ENCRYPTION_METHOD_128BIT))
1658 {
1659 WLog_WARN(TAG, "client does not support 128 bit encryption method as required by "
1660 "server configuration");
1661 }
1662
1663 EncryptionMethods = ENCRYPTION_METHOD_128BIT;
1664 break;
1665
1666 case ENCRYPTION_LEVEL_LOW:
1667 case ENCRYPTION_LEVEL_CLIENT_COMPATIBLE:
1668
1669 /* Maximum key strength supported by the client must be used */
1670 if (EncryptionMethods & ENCRYPTION_METHOD_128BIT)
1671 EncryptionMethods = ENCRYPTION_METHOD_128BIT;
1672 else if (EncryptionMethods & ENCRYPTION_METHOD_56BIT)
1673 EncryptionMethods = ENCRYPTION_METHOD_56BIT;
1674 else if (EncryptionMethods & ENCRYPTION_METHOD_40BIT)
1675 EncryptionMethods = ENCRYPTION_METHOD_40BIT;
1676 else if (EncryptionMethods & ENCRYPTION_METHOD_FIPS)
1677 EncryptionMethods = ENCRYPTION_METHOD_FIPS;
1678 else
1679 {
1680 WLog_WARN(TAG, "client has not announced any supported encryption methods");
1681 EncryptionMethods = ENCRYPTION_METHOD_128BIT;
1682 }
1683
1684 break;
1685
1686 default:
1687 WLog_ERR(TAG, "internal error: unknown encryption level");
1688 return FALSE;
1689 }
1690
1691 /* log selected encryption method */
1692 if (settings->UseRdpSecurityLayer)
1693 {
1694 switch (EncryptionMethods)
1695 {
1696 case ENCRYPTION_METHOD_NONE:
1697 WLog_INFO(TAG, "Selected rdp encryption method: NONE");
1698 break;
1699
1700 case ENCRYPTION_METHOD_40BIT:
1701 WLog_INFO(TAG, "Selected rdp encryption method: 40BIT");
1702 break;
1703
1704 case ENCRYPTION_METHOD_56BIT:
1705 WLog_INFO(TAG, "Selected rdp encryption method: 56BIT");
1706 break;
1707
1708 case ENCRYPTION_METHOD_128BIT:
1709 WLog_INFO(TAG, "Selected rdp encryption method: 128BIT");
1710 break;
1711
1712 case ENCRYPTION_METHOD_FIPS:
1713 WLog_INFO(TAG, "Selected rdp encryption method: FIPS");
1714 break;
1715
1716 default:
1717 WLog_ERR(TAG, "internal error: unknown encryption method");
1718 return FALSE;
1719 }
1720 }
1721
1722 if (!freerdp_settings_set_uint32(settings, FreeRDP_EncryptionLevel, EncryptionLevel))
1723 return FALSE;
1724 if (!freerdp_settings_set_uint32(settings, FreeRDP_EncryptionMethods, EncryptionMethods))
1725 return FALSE;
1726 return TRUE;
1727}
1728
1729BOOL rdp_server_accept_mcs_connect_initial(rdpRdp* rdp, wStream* s)
1730{
1731 WINPR_ASSERT(rdp);
1732 WINPR_ASSERT(s);
1733
1734 rdpMcs* mcs = rdp->mcs;
1735 WINPR_ASSERT(mcs);
1736
1737 WINPR_ASSERT(rdp_get_state(rdp) == CONNECTION_STATE_MCS_CREATE_REQUEST);
1738 if (!mcs_recv_connect_initial(mcs, s))
1739 return FALSE;
1740 WINPR_ASSERT(rdp->settings);
1741
1742 if (!mcs_server_apply_to_settings(mcs, rdp->settings))
1743 return FALSE;
1744
1745 WLog_DBG(TAG, "Accepted client: %s", rdp->settings->ClientHostname);
1746 WLog_DBG(TAG, "Accepted channels:");
1747
1748 WINPR_ASSERT(mcs->channels || (mcs->channelCount == 0));
1749 for (UINT32 i = 0; i < mcs->channelCount; i++)
1750 {
1751 ADDIN_ARGV* arg = nullptr;
1752 rdpMcsChannel* cur = &mcs->channels[i];
1753 const char* params[1] = { cur->Name };
1754 WLog_DBG(TAG, " %s [%" PRIu16 "]", cur->Name, cur->ChannelId);
1755 arg = freerdp_addin_argv_new(ARRAYSIZE(params), params);
1756 if (!arg)
1757 return FALSE;
1758
1759 if (!freerdp_static_channel_collection_add(rdp->settings, arg))
1760 {
1761 freerdp_addin_argv_free(arg);
1762 return FALSE;
1763 }
1764 }
1765
1766 if (!rdp_server_transition_to_state(rdp, CONNECTION_STATE_MCS_CREATE_RESPONSE))
1767 return FALSE;
1768 if (!rdp_update_encryption_level(rdp->settings))
1769 return FALSE;
1770 if (!mcs_send_connect_response(mcs))
1771 return FALSE;
1772 if (!rdp_server_transition_to_state(rdp, CONNECTION_STATE_MCS_ERECT_DOMAIN))
1773 return FALSE;
1774
1775 return TRUE;
1776}
1777
1778BOOL rdp_server_accept_mcs_erect_domain_request(rdpRdp* rdp, wStream* s)
1779{
1780 WINPR_ASSERT(rdp);
1781 WINPR_ASSERT(s);
1782 WINPR_ASSERT(rdp_get_state(rdp) == CONNECTION_STATE_MCS_ERECT_DOMAIN);
1783
1784 if (!mcs_recv_erect_domain_request(rdp->mcs, s))
1785 return FALSE;
1786
1787 return rdp_server_transition_to_state(rdp, CONNECTION_STATE_MCS_ATTACH_USER);
1788}
1789
1790static BOOL rdp_server_skip_mcs_channel_join(rdpRdp* rdp)
1791{
1792 WINPR_ASSERT(rdp);
1793
1794 rdpMcs* mcs = rdp->mcs;
1795 WINPR_ASSERT(mcs);
1796
1797 mcs->userChannelJoined = TRUE;
1798 mcs->globalChannelJoined = TRUE;
1799 mcs->messageChannelJoined = TRUE;
1800
1801 for (UINT32 i = 0; i < mcs->channelCount; i++)
1802 {
1803 rdpMcsChannel* cur = &mcs->channels[i];
1804 WLog_DBG(TAG, " %s [%" PRIu16 "]", cur->Name, cur->ChannelId);
1805 cur->joined = TRUE;
1806 }
1807 return rdp_server_transition_to_state(rdp, CONNECTION_STATE_RDP_SECURITY_COMMENCEMENT);
1808}
1809
1810BOOL rdp_server_accept_mcs_attach_user_request(rdpRdp* rdp, wStream* s)
1811{
1812 if (!mcs_recv_attach_user_request(rdp->mcs, s))
1813 return FALSE;
1814
1815 if (!rdp_server_transition_to_state(rdp, CONNECTION_STATE_MCS_ATTACH_USER_CONFIRM))
1816 return FALSE;
1817
1818 if (!mcs_send_attach_user_confirm(rdp->mcs))
1819 return FALSE;
1820
1821 if (freerdp_settings_get_bool(rdp->settings, FreeRDP_SupportSkipChannelJoin))
1822 return rdp_server_skip_mcs_channel_join(rdp);
1823 return rdp_server_transition_to_state(rdp, CONNECTION_STATE_MCS_CHANNEL_JOIN_REQUEST);
1824}
1825
1826BOOL rdp_server_accept_mcs_channel_join_request(rdpRdp* rdp, wStream* s)
1827{
1828 UINT16 channelId = 0;
1829 BOOL allJoined = TRUE;
1830 rdpMcs* mcs = nullptr;
1831
1832 WINPR_ASSERT(rdp);
1833 WINPR_ASSERT(rdp->context);
1834
1835 mcs = rdp->mcs;
1836 WINPR_ASSERT(mcs);
1837
1838 WINPR_ASSERT(rdp_get_state(rdp) == CONNECTION_STATE_MCS_CHANNEL_JOIN_REQUEST);
1839
1840 if (!mcs_recv_channel_join_request(mcs, rdp->settings, s, &channelId))
1841 return FALSE;
1842
1843 if (!rdp_server_transition_to_state(rdp, CONNECTION_STATE_MCS_CHANNEL_JOIN_RESPONSE))
1844 return FALSE;
1845
1846 if (!mcs_send_channel_join_confirm(mcs, channelId))
1847 return FALSE;
1848
1849 if (channelId == mcs->userId)
1850 mcs->userChannelJoined = TRUE;
1851 if (channelId == MCS_GLOBAL_CHANNEL_ID)
1852 mcs->globalChannelJoined = TRUE;
1853 if (channelId == mcs->messageChannelId)
1854 mcs->messageChannelJoined = TRUE;
1855
1856 for (UINT32 i = 0; i < mcs->channelCount; i++)
1857 {
1858 rdpMcsChannel* cur = &mcs->channels[i];
1859 WLog_DBG(TAG, " %s [%" PRIu16 "]", cur->Name, cur->ChannelId);
1860 if (cur->ChannelId == channelId)
1861 cur->joined = TRUE;
1862
1863 if (!cur->joined)
1864 allJoined = FALSE;
1865 }
1866
1867 CONNECTION_STATE rc = CONNECTION_STATE_INITIAL;
1868 if ((mcs->userChannelJoined) && (mcs->globalChannelJoined) &&
1869 (mcs->messageChannelId == 0 || mcs->messageChannelJoined) && allJoined)
1870 rc = CONNECTION_STATE_RDP_SECURITY_COMMENCEMENT;
1871 else
1872 rc = CONNECTION_STATE_MCS_CHANNEL_JOIN_REQUEST;
1873
1874 return rdp_server_transition_to_state(rdp, rc);
1875}
1876
1877static BOOL rdp_server_send_sync(rdpRdp* rdp)
1878{
1879 WINPR_ASSERT(rdp);
1880
1881 if (!rdp_server_transition_to_state(rdp, CONNECTION_STATE_FINALIZATION_CLIENT_SYNC))
1882 return FALSE;
1883 if (!rdp_send_server_synchronize_pdu(rdp))
1884 return FALSE;
1885 if (!rdp_server_transition_to_state(rdp, CONNECTION_STATE_FINALIZATION_CLIENT_COOPERATE))
1886 return FALSE;
1887 if (!rdp_send_server_control_cooperate_pdu(rdp))
1888 return FALSE;
1889 if (!rdp_finalize_reset_flags(rdp, FALSE))
1890 return FALSE;
1891 return rdp_server_transition_to_state(rdp, CONNECTION_STATE_FINALIZATION_SYNC);
1892}
1893
1894BOOL rdp_server_accept_confirm_active(rdpRdp* rdp, wStream* s, UINT16 pduLength)
1895{
1896 WINPR_ASSERT(rdp);
1897 WINPR_ASSERT(rdp->context);
1898 WINPR_ASSERT(rdp->settings);
1899 WINPR_ASSERT(s);
1900
1901 freerdp_peer* peer = rdp->context->peer;
1902 WINPR_ASSERT(peer);
1903
1904 if (rdp_get_state(rdp) != CONNECTION_STATE_CAPABILITIES_EXCHANGE_CONFIRM_ACTIVE)
1905 {
1906 if (freerdp_settings_get_bool(rdp->settings, FreeRDP_TransportDumpReplay))
1907 rdp_finalize_set_flag(rdp, FINALIZE_DEACTIVATE_REACTIVATE);
1908 else
1909 {
1910 WLog_WARN(TAG, "Invalid state, got %s, expected %s", rdp_get_state_string(rdp),
1911 rdp_state_string(CONNECTION_STATE_CAPABILITIES_EXCHANGE_CONFIRM_ACTIVE));
1912 return FALSE;
1913 }
1914 }
1915
1916 if (!rdp_recv_confirm_active(rdp, s, pduLength))
1917 return FALSE;
1918
1919 if (peer->ClientCapabilities && !peer->ClientCapabilities(peer))
1920 {
1921 WLog_WARN(TAG, "peer->ClientCapabilities failed");
1922 return FALSE;
1923 }
1924
1925 if (rdp->settings->SaltedChecksum)
1926 rdp->do_secure_checksum = TRUE;
1927
1928 return rdp_server_send_sync(rdp);
1929}
1930
1931BOOL rdp_server_reactivate(rdpRdp* rdp)
1932{
1933 freerdp_peer* client = nullptr;
1934
1935 if (rdp->context && rdp->context->peer)
1936 client = rdp->context->peer;
1937
1938 if (client)
1939 client->activated = FALSE;
1940
1941 if (!rdp_send_deactivate_all(rdp))
1942 return FALSE;
1943
1944 rdp_finalize_set_flag(rdp, FINALIZE_DEACTIVATE_REACTIVATE);
1945 if (!rdp_server_transition_to_state(rdp, CONNECTION_STATE_CAPABILITIES_EXCHANGE_DEMAND_ACTIVE))
1946 return FALSE;
1947
1948 state_run_t rc = rdp_peer_handle_state_demand_active(client);
1949 return state_run_success(rc);
1950}
1951
1952static BOOL rdp_is_active_peer_state(CONNECTION_STATE state)
1953{
1954 /* [MS-RDPBCGR] 1.3.1.1 Connection Sequence states:
1955 * 'upon receipt of the Font List PDU the server can start sending graphics
1956 * output to the client'
1957 */
1958 switch (state)
1959 {
1960 case CONNECTION_STATE_FINALIZATION_CLIENT_SYNC:
1961 case CONNECTION_STATE_FINALIZATION_CLIENT_COOPERATE:
1962 case CONNECTION_STATE_FINALIZATION_CLIENT_GRANTED_CONTROL:
1963 case CONNECTION_STATE_FINALIZATION_CLIENT_FONT_MAP:
1964 case CONNECTION_STATE_ACTIVE:
1965 return TRUE;
1966 default:
1967 return FALSE;
1968 }
1969}
1970
1971static BOOL rdp_is_active_client_state(CONNECTION_STATE state)
1972{
1973 /* [MS-RDPBCGR] 1.3.1.1 Connection Sequence states:
1974 * 'Once the client has sent the Confirm Active PDU, it can start sending
1975 * mouse and keyboard input to the server'
1976 */
1977 switch (state)
1978 {
1979 case CONNECTION_STATE_FINALIZATION_SYNC:
1980 case CONNECTION_STATE_FINALIZATION_COOPERATE:
1981 case CONNECTION_STATE_FINALIZATION_REQUEST_CONTROL:
1982 case CONNECTION_STATE_FINALIZATION_PERSISTENT_KEY_LIST:
1983 case CONNECTION_STATE_FINALIZATION_FONT_LIST:
1984 case CONNECTION_STATE_FINALIZATION_CLIENT_SYNC:
1985 case CONNECTION_STATE_FINALIZATION_CLIENT_COOPERATE:
1986 case CONNECTION_STATE_FINALIZATION_CLIENT_GRANTED_CONTROL:
1987 case CONNECTION_STATE_FINALIZATION_CLIENT_FONT_MAP:
1988 case CONNECTION_STATE_ACTIVE:
1989 return TRUE;
1990 default:
1991 return FALSE;
1992 }
1993}
1994
1995BOOL rdp_is_active_state(const rdpRdp* rdp)
1996{
1997 WINPR_ASSERT(rdp);
1998 WINPR_ASSERT(rdp->context);
1999
2000 const CONNECTION_STATE state = rdp_get_state(rdp);
2001 if (freerdp_settings_get_bool(rdp->context->settings, FreeRDP_ServerMode))
2002 return rdp_is_active_peer_state(state);
2003 else
2004 return rdp_is_active_client_state(state);
2005}
2006
2007BOOL rdp_server_transition_to_state(rdpRdp* rdp, CONNECTION_STATE state)
2008{
2009 BOOL status = FALSE;
2010 freerdp_peer* client = nullptr;
2011 const CONNECTION_STATE cstate = rdp_get_state(rdp);
2012
2013 if (cstate >= CONNECTION_STATE_RDP_SECURITY_COMMENCEMENT)
2014 {
2015 WINPR_ASSERT(rdp->context);
2016 client = rdp->context->peer;
2017 }
2018
2019 if (!rdp_is_active_peer_state(cstate))
2020 {
2021 if (client)
2022 client->activated = FALSE;
2023 }
2024
2025 WLog_Print(rdp->log, WLOG_DEBUG, "%s --> %s", rdp_get_state_string(rdp),
2026 rdp_state_string(state));
2027 if (!rdp_set_state(rdp, state))
2028 goto fail;
2029
2030 status = TRUE;
2031fail:
2032 return status;
2033}
2034
2035const char* rdp_client_connection_state_string(UINT state)
2036{
2037 switch (state)
2038 {
2039 case CLIENT_STATE_INITIAL:
2040 return "CLIENT_STATE_INITIAL";
2041 case CLIENT_STATE_PRECONNECT_PASSED:
2042 return "CLIENT_STATE_PRECONNECT_PASSED";
2043 case CLIENT_STATE_POSTCONNECT_PASSED:
2044 return "CLIENT_STATE_POSTCONNECT_PASSED";
2045 default:
2046 return "UNKNOWN";
2047 }
2048}
2049
2050const char* rdp_state_string(CONNECTION_STATE state)
2051{
2052 switch (state)
2053 {
2054 case CONNECTION_STATE_INITIAL:
2055 return "CONNECTION_STATE_INITIAL";
2056 case CONNECTION_STATE_NEGO:
2057 return "CONNECTION_STATE_NEGO";
2058 case CONNECTION_STATE_NLA:
2059 return "CONNECTION_STATE_NLA";
2060 case CONNECTION_STATE_AAD:
2061 return "CONNECTION_STATE_AAD";
2062 case CONNECTION_STATE_MCS_CREATE_REQUEST:
2063 return "CONNECTION_STATE_MCS_CREATE_REQUEST";
2064 case CONNECTION_STATE_MCS_CREATE_RESPONSE:
2065 return "CONNECTION_STATE_MCS_CREATE_RESPONSE";
2066 case CONNECTION_STATE_MCS_ERECT_DOMAIN:
2067 return "CONNECTION_STATE_MCS_ERECT_DOMAIN";
2068 case CONNECTION_STATE_MCS_ATTACH_USER:
2069 return "CONNECTION_STATE_MCS_ATTACH_USER";
2070 case CONNECTION_STATE_MCS_ATTACH_USER_CONFIRM:
2071 return "CONNECTION_STATE_MCS_ATTACH_USER_CONFIRM";
2072 case CONNECTION_STATE_MCS_CHANNEL_JOIN_REQUEST:
2073 return "CONNECTION_STATE_MCS_CHANNEL_JOIN_REQUEST";
2074 case CONNECTION_STATE_MCS_CHANNEL_JOIN_RESPONSE:
2075 return "CONNECTION_STATE_MCS_CHANNEL_JOIN_RESPONSE";
2076 case CONNECTION_STATE_RDP_SECURITY_COMMENCEMENT:
2077 return "CONNECTION_STATE_RDP_SECURITY_COMMENCEMENT";
2078 case CONNECTION_STATE_SECURE_SETTINGS_EXCHANGE:
2079 return "CONNECTION_STATE_SECURE_SETTINGS_EXCHANGE";
2080 case CONNECTION_STATE_CONNECT_TIME_AUTO_DETECT_REQUEST:
2081 return "CONNECTION_STATE_CONNECT_TIME_AUTO_DETECT_REQUEST";
2082 case CONNECTION_STATE_CONNECT_TIME_AUTO_DETECT_RESPONSE:
2083 return "CONNECTION_STATE_CONNECT_TIME_AUTO_DETECT_RESPONSE";
2084 case CONNECTION_STATE_LICENSING:
2085 return "CONNECTION_STATE_LICENSING";
2086 case CONNECTION_STATE_MULTITRANSPORT_BOOTSTRAPPING_REQUEST:
2087 return "CONNECTION_STATE_MULTITRANSPORT_BOOTSTRAPPING_REQUEST";
2088 case CONNECTION_STATE_MULTITRANSPORT_BOOTSTRAPPING_RESPONSE:
2089 return "CONNECTION_STATE_MULTITRANSPORT_BOOTSTRAPPING_RESPONSE";
2090 case CONNECTION_STATE_CAPABILITIES_EXCHANGE_DEMAND_ACTIVE:
2091 return "CONNECTION_STATE_CAPABILITIES_EXCHANGE_DEMAND_ACTIVE";
2092 case CONNECTION_STATE_CAPABILITIES_EXCHANGE_MONITOR_LAYOUT:
2093 return "CONNECTION_STATE_CAPABILITIES_EXCHANGE_MONITOR_LAYOUT";
2094 case CONNECTION_STATE_CAPABILITIES_EXCHANGE_CONFIRM_ACTIVE:
2095 return "CONNECTION_STATE_CAPABILITIES_EXCHANGE_CONFIRM_ACTIVE";
2096 case CONNECTION_STATE_FINALIZATION_SYNC:
2097 return "CONNECTION_STATE_FINALIZATION_SYNC";
2098 case CONNECTION_STATE_FINALIZATION_COOPERATE:
2099 return "CONNECTION_STATE_FINALIZATION_COOPERATE";
2100 case CONNECTION_STATE_FINALIZATION_REQUEST_CONTROL:
2101 return "CONNECTION_STATE_FINALIZATION_REQUEST_CONTROL";
2102 case CONNECTION_STATE_FINALIZATION_PERSISTENT_KEY_LIST:
2103 return "CONNECTION_STATE_FINALIZATION_PERSISTENT_KEY_LIST";
2104 case CONNECTION_STATE_FINALIZATION_FONT_LIST:
2105 return "CONNECTION_STATE_FINALIZATION_FONT_LIST";
2106 case CONNECTION_STATE_FINALIZATION_CLIENT_SYNC:
2107 return "CONNECTION_STATE_FINALIZATION_CLIENT_SYNC";
2108 case CONNECTION_STATE_FINALIZATION_CLIENT_COOPERATE:
2109 return "CONNECTION_STATE_FINALIZATION_CLIENT_COOPERATE";
2110 case CONNECTION_STATE_FINALIZATION_CLIENT_GRANTED_CONTROL:
2111 return "CONNECTION_STATE_FINALIZATION_CLIENT_GRANTED_CONTROL";
2112 case CONNECTION_STATE_FINALIZATION_CLIENT_FONT_MAP:
2113 return "CONNECTION_STATE_FINALIZATION_CLIENT_FONT_MAP";
2114 case CONNECTION_STATE_ACTIVE:
2115 return "CONNECTION_STATE_ACTIVE";
2116 default:
2117 return "UNKNOWN";
2118 }
2119}
2120
2121CONNECTION_STATE rdp_get_state(const rdpRdp* rdp)
2122{
2123 WINPR_ASSERT(rdp);
2124 return rdp->state;
2125}
2126
2127BOOL rdp_set_state(rdpRdp* rdp, CONNECTION_STATE state)
2128{
2129 WINPR_ASSERT(rdp);
2130 rdp->state = state;
2131 return TRUE;
2132}
2133
2134const char* rdp_get_state_string(const rdpRdp* rdp)
2135{
2136 CONNECTION_STATE state = rdp_get_state(rdp);
2137 return rdp_state_string(state);
2138}
2139
2140BOOL rdp_channels_from_mcs(rdpSettings* settings, const rdpRdp* rdp)
2141{
2142 const rdpMcs* mcs = nullptr;
2143
2144 WINPR_ASSERT(rdp);
2145
2146 mcs = rdp->mcs;
2147 WINPR_ASSERT(mcs);
2148
2149 if (!freerdp_settings_set_pointer_len(settings, FreeRDP_ChannelDefArray, nullptr,
2150 CHANNEL_MAX_COUNT))
2151 return FALSE;
2152
2153 for (UINT32 x = 0; x < mcs->channelCount; x++)
2154 {
2155 const rdpMcsChannel* mchannel = &mcs->channels[x];
2156 CHANNEL_DEF cur = WINPR_C_ARRAY_INIT;
2157
2158 memcpy(cur.name, mchannel->Name, sizeof(cur.name));
2159 cur.options = mchannel->options;
2160 if (!freerdp_settings_set_pointer_array(settings, FreeRDP_ChannelDefArray, x, &cur))
2161 return FALSE;
2162 }
2163
2164 return freerdp_settings_set_uint32(settings, FreeRDP_ChannelCount, mcs->channelCount);
2165}
2166
2167/* Here we are in client state CONFIRM_ACTIVE.
2168 *
2169 * This means:
2170 * 1. send the CONFIRM_ACTIVE PDU to the server
2171 * 2. register callbacks, the server can now start sending stuff
2172 */
2173state_run_t rdp_client_connect_confirm_active(rdpRdp* rdp, WINPR_ATTR_UNUSED wStream* s)
2174{
2175 WINPR_ASSERT(rdp);
2176 WINPR_ASSERT(rdp->settings);
2177 WINPR_ASSERT(s);
2178
2179 const UINT32 width = rdp->settings->DesktopWidth;
2180 const UINT32 height = rdp->settings->DesktopHeight;
2181
2182 if (!rdp_send_confirm_active(rdp))
2183 return STATE_RUN_FAILED;
2184
2185 if (!input_register_client_callbacks(rdp->input))
2186 {
2187 WLog_ERR(TAG, "error registering client callbacks");
2188 return STATE_RUN_FAILED;
2189 }
2190
2195 const BOOL deactivate_reactivate =
2196 rdp->was_deactivated && ((rdp->deactivated_width != rdp->settings->DesktopWidth) ||
2197 (rdp->deactivated_height != rdp->settings->DesktopHeight));
2198 const BOOL resolution_change =
2199 ((width != rdp->settings->DesktopWidth) || (height != rdp->settings->DesktopHeight));
2200 if (deactivate_reactivate || resolution_change)
2201 {
2202 BOOL status = TRUE;
2203 WLog_DBG(TAG, "new size %" PRIu32 "x%" PRIu32, rdp->settings->DesktopWidth,
2204 rdp->settings->DesktopHeight);
2205
2206 IFCALLRET(rdp->update->DesktopResize, status, rdp->update->context);
2207
2208 if (!status)
2209 {
2210 WLog_ERR(TAG, "client desktop resize callback failed");
2211 return STATE_RUN_FAILED;
2212 }
2213 }
2214
2215 WINPR_ASSERT(rdp->context);
2216 if (freerdp_shall_disconnect_context(rdp->context))
2217 return STATE_RUN_SUCCESS;
2218
2219 state_run_t status = STATE_RUN_SUCCESS;
2220 if (!rdp->settings->SupportMonitorLayoutPdu)
2221 status = rdp_client_connect_finalize(rdp);
2222 else
2223 {
2224 if (!rdp_client_transition_to_state(rdp,
2225 CONNECTION_STATE_CAPABILITIES_EXCHANGE_MONITOR_LAYOUT))
2226 status = STATE_RUN_FAILED;
2227 }
2228 if (!rdp_finalize_reset_flags(rdp, FALSE))
2229 status = STATE_RUN_FAILED;
2230 return status;
2231}
2232
2233BOOL rdp_handle_optional_rdp_decryption(rdpRdp* rdp, wStream* s, UINT16* length,
2234 UINT16* pSecurityFlags)
2235{
2236 BOOL rc = FALSE;
2237 WINPR_ASSERT(rdp);
2238 WINPR_ASSERT(rdp->settings);
2239
2240 UINT16 securityFlags = 0;
2241 if (rdp->settings->UseRdpSecurityLayer)
2242 {
2243 if (!rdp_read_security_header(rdp, s, &securityFlags, length))
2244 goto fail;
2245
2246 if (securityFlags & SEC_ENCRYPT)
2247 {
2248 if (!rdp_decrypt(rdp, s, length, securityFlags))
2249 goto fail;
2250 }
2251 }
2252
2253 rc = TRUE;
2254
2255fail:
2256 if (pSecurityFlags)
2257 *pSecurityFlags = securityFlags;
2258 return rc;
2259}
WINPR_ATTR_NODISCARD FREERDP_API const void * freerdp_settings_get_pointer(const rdpSettings *settings, FreeRDP_Settings_Keys_Pointer id)
Returns a immutable pointer settings value.
WINPR_ATTR_NODISCARD FREERDP_API const char * freerdp_settings_get_string(const rdpSettings *settings, FreeRDP_Settings_Keys_String id)
Returns a immutable string settings value.
WINPR_ATTR_NODISCARD FREERDP_API BOOL freerdp_settings_set_bool(rdpSettings *settings, FreeRDP_Settings_Keys_Bool id, BOOL val)
Sets a BOOL settings value.
WINPR_ATTR_NODISCARD FREERDP_API void * freerdp_settings_get_pointer_writable(rdpSettings *settings, FreeRDP_Settings_Keys_Pointer id)
Returns a mutable pointer settings value.
WINPR_ATTR_NODISCARD FREERDP_API UINT32 freerdp_settings_get_codecs_flags(const rdpSettings *settings)
helper function to get a mask of supported codec flags.
WINPR_ATTR_NODISCARD FREERDP_API BOOL freerdp_settings_set_uint32(rdpSettings *settings, FreeRDP_Settings_Keys_UInt32 id, UINT32 val)
Sets a UINT32 settings value.
WINPR_ATTR_NODISCARD FREERDP_API BOOL freerdp_settings_set_pointer_len(rdpSettings *settings, FreeRDP_Settings_Keys_Pointer id, const void *data, size_t len)
Set a pointer to value data.
WINPR_ATTR_NODISCARD FREERDP_API UINT32 freerdp_settings_get_uint32(const rdpSettings *settings, FreeRDP_Settings_Keys_UInt32 id)
Returns a UINT32 settings value.
WINPR_ATTR_NODISCARD FREERDP_API BOOL freerdp_settings_set_string(rdpSettings *settings, FreeRDP_Settings_Keys_String id, const char *val)
Sets a string settings value. The param is copied.
WINPR_ATTR_NODISCARD FREERDP_API BOOL freerdp_settings_get_bool(const rdpSettings *settings, FreeRDP_Settings_Keys_Bool id)
Returns a boolean settings value.