23#include <freerdp/config.h>
27#include <winpr/assert.h>
28#include <winpr/cast.h>
30#include <winpr/winsock.h>
35#include <freerdp/log.h>
36#include <freerdp/streamdump.h>
37#include <freerdp/redirection.h>
38#include <freerdp/crypto/certificate.h>
42#include "multitransport.h"
44#define TAG FREERDP_TAG("core.peer")
46static state_run_t peer_recv_pdu(freerdp_peer* client,
wStream* s);
48static HANDLE freerdp_peer_virtual_channel_open(freerdp_peer* client,
const char* name,
52 WINPR_ASSERT(client->context);
53 WINPR_ASSERT(client->context->rdp);
55 rdpMcs* mcs = client->context->rdp->mcs;
58 if (flags & WTS_CHANNEL_OPTION_DYNAMIC)
61 const size_t length = strnlen(name, 9);
68 rdpMcsChannel* mcsChannel =
nullptr;
69 for (; index < mcs->channelCount; index++)
71 mcsChannel = &(mcs->channels[index]);
73 if (!mcsChannel->joined)
76 if (_strnicmp(name, mcsChannel->Name, length) == 0)
86 rdpPeerChannel* peerChannel = (rdpPeerChannel*)mcsChannel->handle;
91 return (HANDLE)peerChannel;
94 WINPR_ASSERT(index <= UINT16_MAX);
96 server_channel_common_new(client, (UINT16)index, mcsChannel->ChannelId, 128,
nullptr, name);
100 peerChannel->channelFlags = flags;
101 peerChannel->mcsChannel = mcsChannel;
102 mcsChannel->handle = (
void*)peerChannel;
105 return (HANDLE)peerChannel;
108static BOOL freerdp_peer_virtual_channel_close(WINPR_ATTR_UNUSED freerdp_peer* client,
111 rdpMcsChannel* mcsChannel =
nullptr;
112 rdpPeerChannel* peerChannel =
nullptr;
114 WINPR_ASSERT(client);
119 peerChannel = (rdpPeerChannel*)hChannel;
120 mcsChannel = peerChannel->mcsChannel;
121 WINPR_ASSERT(mcsChannel);
122 mcsChannel->handle =
nullptr;
123 server_channel_common_free(peerChannel);
127static int freerdp_peer_virtual_channel_write(freerdp_peer* client, HANDLE hChannel,
128 const BYTE* buffer, UINT32 length)
132 UINT32 chunkSize = 0;
133 UINT32 maxChunkSize = 0;
134 UINT32 totalLength = 0;
135 rdpPeerChannel* peerChannel =
nullptr;
136 rdpMcsChannel* mcsChannel =
nullptr;
137 rdpRdp* rdp =
nullptr;
139 WINPR_ASSERT(client);
140 WINPR_ASSERT(client->context);
142 rdp = client->context->rdp;
144 WINPR_ASSERT(rdp->settings);
149 peerChannel = (rdpPeerChannel*)hChannel;
150 mcsChannel = peerChannel->mcsChannel;
151 WINPR_ASSERT(peerChannel);
152 WINPR_ASSERT(mcsChannel);
153 if (peerChannel->channelFlags & WTS_CHANNEL_OPTION_DYNAMIC)
156 maxChunkSize = rdp->settings->VCChunkSize;
157 totalLength = length;
158 flags = CHANNEL_FLAG_FIRST;
162 UINT16 sec_flags = 0;
163 s = rdp_send_stream_init(rdp, &sec_flags);
168 if (length > maxChunkSize)
170 chunkSize = rdp->settings->VCChunkSize;
175 flags |= CHANNEL_FLAG_LAST;
178 if (mcsChannel->options & CHANNEL_OPTION_SHOW_PROTOCOL)
179 flags |= CHANNEL_FLAG_SHOW_PROTOCOL;
181 Stream_Write_UINT32(s, totalLength);
182 Stream_Write_UINT32(s, flags);
184 if (!Stream_EnsureRemainingCapacity(s, chunkSize))
190 Stream_Write(s, buffer, chunkSize);
192 WINPR_ASSERT(peerChannel->channelId <= UINT16_MAX);
193 if (!rdp_send(rdp, s, (UINT16)peerChannel->channelId, sec_flags))
204static void* freerdp_peer_virtual_channel_get_data(WINPR_ATTR_UNUSED freerdp_peer* client,
207 rdpPeerChannel* peerChannel = (rdpPeerChannel*)hChannel;
209 WINPR_ASSERT(client);
213 return peerChannel->extra;
216static int freerdp_peer_virtual_channel_set_data(WINPR_ATTR_UNUSED freerdp_peer* client,
217 HANDLE hChannel,
void* data)
219 rdpPeerChannel* peerChannel = (rdpPeerChannel*)hChannel;
221 WINPR_ASSERT(client);
225 peerChannel->extra = data;
229static BOOL freerdp_peer_set_state(freerdp_peer* client, CONNECTION_STATE state)
231 WINPR_ASSERT(client);
232 WINPR_ASSERT(client->context);
233 return rdp_server_transition_to_state(client->context->rdp, state);
236static BOOL freerdp_peer_initialize(freerdp_peer* client)
238 rdpRdp* rdp =
nullptr;
239 rdpSettings* settings =
nullptr;
241 WINPR_ASSERT(client);
242 WINPR_ASSERT(client->context);
244 rdp = client->context->rdp;
247 settings = rdp->settings;
248 WINPR_ASSERT(settings);
250 settings->ServerMode = TRUE;
251 settings->FrameAcknowledge = 0;
252 settings->LocalConnection = client->local;
254 const rdpCertificate* cert =
258 WLog_ERR(TAG,
"Missing server certificate, can not continue.");
265 if (!freerdp_certificate_is_rdp_security_compatible(cert))
274 nego_set_RCG_supported(rdp->nego, settings->RemoteCredentialGuard);
275 nego_set_restricted_admin_mode_supported(rdp->nego, settings->RestrictedAdminModeSupported);
277 return (rdp_server_transition_to_state(rdp, CONNECTION_STATE_INITIAL));
280#if defined(WITH_FREERDP_DEPRECATED)
281static BOOL freerdp_peer_get_fds(freerdp_peer* client,
void** rfds,
int* rcount)
283 rdpTransport* transport =
nullptr;
284 WINPR_ASSERT(client);
285 WINPR_ASSERT(client->context);
286 WINPR_ASSERT(client->context->rdp);
288 transport = client->context->rdp->transport;
289 WINPR_ASSERT(transport);
290 transport_get_fds(transport, rfds, rcount);
295static HANDLE freerdp_peer_get_event_handle(freerdp_peer* client)
297 HANDLE hEvent =
nullptr;
298 rdpTransport* transport =
nullptr;
299 WINPR_ASSERT(client);
300 WINPR_ASSERT(client->context);
301 WINPR_ASSERT(client->context->rdp);
303 transport = client->context->rdp->transport;
304 hEvent = transport_get_front_bio(transport);
308static DWORD freerdp_peer_get_event_handles(freerdp_peer* client, HANDLE* events, DWORD count)
310 WINPR_ASSERT(client);
311 WINPR_ASSERT(client->context);
312 WINPR_ASSERT(client->context->rdp);
313 return transport_get_event_handles(client->context->rdp->transport, events, count);
316static BOOL freerdp_peer_check_fds(freerdp_peer* peer)
319 rdpRdp* rdp =
nullptr;
322 WINPR_ASSERT(peer->context);
324 rdp = peer->context->rdp;
325 status = rdp_check_fds(rdp);
327 return (status >= 0);
330static state_run_t peer_recv_data_pdu(freerdp_peer* client,
wStream* s,
331 WINPR_ATTR_UNUSED UINT16 totalLength)
336 BYTE compressed_type = 0;
337 UINT16 compressed_len = 0;
338 rdpUpdate* update =
nullptr;
341 WINPR_ASSERT(client);
342 WINPR_ASSERT(client->context);
343 rdpRdp* rdp = client->context->rdp;
345 WINPR_ASSERT(rdp->mcs);
347 update = client->context->update;
348 WINPR_ASSERT(update);
350 if (!rdp_read_share_data_header(rdp, s, &length, &type, &share_id, &compressed_type,
352 return STATE_RUN_FAILED;
355 WLog_Print(rdp->log, WLOG_DEBUG,
"recv %s Data PDU (0x%02" PRIX8
"), length: %" PRIu16
"",
356 data_pdu_type_to_string(type), type, length);
361 case DATA_PDU_TYPE_SYNCHRONIZE:
362 if (!rdp_recv_client_synchronize_pdu(rdp, s))
363 return STATE_RUN_FAILED;
367 case DATA_PDU_TYPE_CONTROL:
368 if (!rdp_server_accept_client_control_pdu(rdp, s))
369 return STATE_RUN_FAILED;
373 case DATA_PDU_TYPE_INPUT:
374 if (!input_recv(rdp->input, s))
375 return STATE_RUN_FAILED;
379 case DATA_PDU_TYPE_BITMAP_CACHE_PERSISTENT_LIST:
380 if (!rdp_server_accept_client_persistent_key_list_pdu(rdp, s))
381 return STATE_RUN_FAILED;
384 case DATA_PDU_TYPE_FONT_LIST:
385 if (!rdp_server_accept_client_font_list_pdu(rdp, s))
386 return STATE_RUN_FAILED;
388 return STATE_RUN_CONTINUE;
390 case DATA_PDU_TYPE_SHUTDOWN_REQUEST:
391 mcs_send_disconnect_provider_ultimatum(rdp->mcs,
392 Disconnect_Ultimatum_provider_initiated);
393 WLog_WARN(TAG,
"disconnect provider ultimatum sent to peer, closing connection");
394 return STATE_RUN_QUIT_SESSION;
396 case DATA_PDU_TYPE_FRAME_ACKNOWLEDGE:
397 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
398 return STATE_RUN_FAILED;
400 Stream_Read_UINT32(s, client->ack_frame_id);
401 if (update->SurfaceFrameAcknowledge)
403 if (!update->SurfaceFrameAcknowledge(update->context, client->ack_frame_id))
404 return STATE_RUN_FAILED;
408 case DATA_PDU_TYPE_REFRESH_RECT:
409 if (!update_read_refresh_rect(update, s))
410 return STATE_RUN_FAILED;
414 case DATA_PDU_TYPE_SUPPRESS_OUTPUT:
415 if (!update_read_suppress_output(update, s))
416 return STATE_RUN_FAILED;
421 WLog_ERR(TAG,
"Data PDU type %" PRIu8
"", type);
425 return STATE_RUN_SUCCESS;
428static state_run_t peer_recv_tpkt_pdu(freerdp_peer* client,
wStream* s)
430 state_run_t rc = STATE_RUN_SUCCESS;
433 UINT16 pduSource = 0;
434 UINT16 channelId = 0;
435 UINT16 securityFlags = 0;
438 WINPR_ASSERT(client);
439 WINPR_ASSERT(client->context);
441 rdpRdp* rdp = client->context->rdp;
443 WINPR_ASSERT(rdp->mcs);
445 rdpSettings* settings = client->context->settings;
446 WINPR_ASSERT(settings);
448 if (!rdp_read_header(rdp, s, &length, &channelId))
449 return STATE_RUN_FAILED;
452 if (freerdp_shall_disconnect_context(rdp->context))
453 return STATE_RUN_SUCCESS;
455 if (rdp_get_state(rdp) <= CONNECTION_STATE_LICENSING)
457 return rdp_handle_message_channel(rdp, s, channelId, length);
460 if (!rdp_handle_optional_rdp_decryption(rdp, s, &length, &securityFlags))
461 return STATE_RUN_FAILED;
463 if (channelId == MCS_GLOBAL_CHANNEL_ID)
465 char buffer[256] = WINPR_C_ARRAY_INIT;
466 UINT16 pduLength = 0;
468 if (!rdp_read_share_control_header(rdp, s, &pduLength, &remain, &pduType, &pduSource))
469 return STATE_RUN_FAILED;
471 settings->PduSource = pduSource;
473 WLog_DBG(TAG,
"Received %s", pdu_type_to_str(pduType, buffer,
sizeof(buffer)));
477 rc = peer_recv_data_pdu(client, s, pduLength);
480 case PDU_TYPE_CONFIRM_ACTIVE:
481 if (!rdp_server_accept_confirm_active(rdp, s, pduLength))
482 return STATE_RUN_FAILED;
486 case PDU_TYPE_FLOW_RESPONSE:
487 case PDU_TYPE_FLOW_STOP:
488 case PDU_TYPE_FLOW_TEST:
489 if (!Stream_SafeSeek(s, remain))
491 WLog_WARN(TAG,
"Short PDU, need %" PRIu16
" bytes, got %" PRIuz, remain,
492 Stream_GetRemainingLength(s));
493 return STATE_RUN_FAILED;
498 WLog_ERR(TAG,
"Client sent unknown pduType %" PRIu16
"", pduType);
499 return STATE_RUN_FAILED;
502 else if ((rdp->mcs->messageChannelId > 0) && (channelId == rdp->mcs->messageChannelId))
504 if (!settings->UseRdpSecurityLayer)
506 if (!rdp_read_security_header(rdp, s, &securityFlags,
nullptr))
507 return STATE_RUN_FAILED;
510 return rdp_recv_message_channel_pdu(rdp, s, securityFlags);
514 if (!freerdp_channel_peer_process(client, s, channelId))
515 return STATE_RUN_FAILED;
517 if (!tpkt_ensure_stream_consumed(rdp->log, s, length))
518 return STATE_RUN_FAILED;
523static state_run_t peer_recv_handle_auto_detect(freerdp_peer* client,
wStream* s)
525 state_run_t ret = STATE_RUN_FAILED;
526 rdpRdp* rdp =
nullptr;
528 WINPR_ASSERT(client);
530 WINPR_ASSERT(client->context);
532 rdp = client->context->rdp;
535 const rdpSettings* settings = client->context->settings;
536 WINPR_ASSERT(settings);
540 switch (rdp_get_state(rdp))
542 case CONNECTION_STATE_CONNECT_TIME_AUTO_DETECT_REQUEST:
543 autodetect_on_connect_time_auto_detect_begin(rdp->autodetect);
544 switch (autodetect_get_state(rdp->autodetect))
546 case FREERDP_AUTODETECT_STATE_REQUEST:
547 ret = STATE_RUN_SUCCESS;
548 if (!rdp_server_transition_to_state(
549 rdp, CONNECTION_STATE_CONNECT_TIME_AUTO_DETECT_RESPONSE))
550 return STATE_RUN_FAILED;
552 case FREERDP_AUTODETECT_STATE_COMPLETE:
553 ret = STATE_RUN_CONTINUE;
554 if (!rdp_server_transition_to_state(rdp, CONNECTION_STATE_LICENSING))
555 return STATE_RUN_FAILED;
561 case CONNECTION_STATE_CONNECT_TIME_AUTO_DETECT_RESPONSE:
562 ret = peer_recv_pdu(client, s);
563 if (state_run_success(ret))
565 autodetect_on_connect_time_auto_detect_progress(rdp->autodetect);
566 switch (autodetect_get_state(rdp->autodetect))
568 case FREERDP_AUTODETECT_STATE_REQUEST:
569 ret = STATE_RUN_SUCCESS;
571 case FREERDP_AUTODETECT_STATE_COMPLETE:
572 ret = STATE_RUN_CONTINUE;
573 if (!rdp_server_transition_to_state(rdp, CONNECTION_STATE_LICENSING))
574 return STATE_RUN_FAILED;
588 if (!rdp_server_transition_to_state(rdp, CONNECTION_STATE_LICENSING))
589 return STATE_RUN_FAILED;
591 ret = STATE_RUN_CONTINUE;
597static state_run_t peer_recv_handle_licensing(freerdp_peer* client,
wStream* s)
599 state_run_t ret = STATE_RUN_FAILED;
600 rdpRdp* rdp =
nullptr;
601 rdpSettings* settings =
nullptr;
603 WINPR_ASSERT(client);
605 WINPR_ASSERT(client->context);
607 rdp = client->context->rdp;
610 settings = rdp->settings;
611 WINPR_ASSERT(settings);
613 switch (license_get_state(rdp->license))
615 case LICENSE_STATE_INITIAL:
617 const BOOL required =
622 if (!license_server_configure(rdp->license))
623 ret = STATE_RUN_FAILED;
624 else if (!license_server_send_request(rdp->license))
625 ret = STATE_RUN_FAILED;
627 ret = STATE_RUN_SUCCESS;
631 if (license_send_valid_client_error_packet(rdp))
632 ret = STATE_RUN_CONTINUE;
636 case LICENSE_STATE_COMPLETED:
637 ret = STATE_RUN_CONTINUE;
639 case LICENSE_STATE_ABORTED:
640 ret = STATE_RUN_FAILED;
643 ret = peer_recv_pdu(client, s);
650static state_run_t peer_recv_fastpath_pdu(freerdp_peer* client,
wStream* s)
652 rdpRdp* rdp =
nullptr;
655 rdpFastPath* fastpath =
nullptr;
658 WINPR_ASSERT(client);
659 WINPR_ASSERT(client->context);
661 rdp = client->context->rdp;
664 fastpath = rdp->fastpath;
665 WINPR_ASSERT(fastpath);
667 rc = fastpath_read_header_rdp(fastpath, s, &length);
669 if (!rc || (length == 0))
671 WLog_ERR(TAG,
"incorrect FastPath PDU header length %" PRIu16
"", length);
672 return STATE_RUN_FAILED;
674 if (!Stream_CheckAndLogRequiredLength(TAG, s, length))
675 return STATE_RUN_FAILED;
677 if (!fastpath_decrypt(fastpath, s, &length))
678 return STATE_RUN_FAILED;
682 return fastpath_recv_inputs(fastpath, s);
685state_run_t peer_recv_pdu(freerdp_peer* client,
wStream* s)
687 int rc = tpkt_verify_header(s);
690 return peer_recv_tpkt_pdu(client, s);
692 return peer_recv_fastpath_pdu(client, s);
694 return STATE_RUN_FAILED;
697static state_run_t peer_unexpected_client_message(rdpRdp* rdp, UINT32 flag)
699 char buffer[1024] = WINPR_C_ARRAY_INIT;
700 WLog_WARN(TAG,
"Unexpected client message in state %s, missing flag %s",
701 rdp_get_state_string(rdp), rdp_finalize_flags_to_str(flag, buffer,
sizeof(buffer)));
702 return STATE_RUN_SUCCESS;
705state_run_t rdp_peer_handle_state_demand_active(freerdp_peer* client)
707 state_run_t ret = STATE_RUN_FAILED;
709 WINPR_ASSERT(client);
710 WINPR_ASSERT(client->context);
712 rdpRdp* rdp = client->context->rdp;
715 if (client->Capabilities && !client->Capabilities(client))
717 WLog_ERR(TAG,
"[%s] freerdp_peer::Capabilities() callback failed",
718 rdp_get_state_string(rdp));
720 else if (!rdp_send_demand_active(rdp))
722 WLog_ERR(TAG,
"[%s] rdp_send_demand_active() fail", rdp_get_state_string(rdp));
726 if (!rdp_server_transition_to_state(rdp,
727 CONNECTION_STATE_CAPABILITIES_EXCHANGE_MONITOR_LAYOUT))
728 return STATE_RUN_FAILED;
729 ret = STATE_RUN_CONTINUE;
740static state_run_t rdp_peer_handle_state_active(freerdp_peer* client)
742 state_run_t ret = STATE_RUN_FAILED;
744 WINPR_ASSERT(client);
745 WINPR_ASSERT(client->context);
747 if (!client->connected)
753 IFCALLRET(client->PostConnect, client->connected, client);
755 if (!client->connected)
757 WLog_ERR(TAG,
"PostConnect for peer %p failed", WINPR_CXX_COMPAT_CAST(
const void*, client));
758 ret = STATE_RUN_FAILED;
760 else if (!client->activated)
762 BOOL activated = TRUE;
767 client->activated = TRUE;
768 IFCALLRET(client->Activate, activated, client);
772 WLog_ERR(TAG,
"Activate for peer %p failed",
773 WINPR_CXX_COMPAT_CAST(
const void*, client));
774 ret = STATE_RUN_FAILED;
777 ret = STATE_RUN_SUCCESS;
780 ret = STATE_RUN_ACTIVE;
784static state_run_t peer_recv_callback_internal(WINPR_ATTR_UNUSED rdpTransport* transport,
787 freerdp_peer* client = (freerdp_peer*)extra;
788 state_run_t ret = STATE_RUN_FAILED;
790 WINPR_ASSERT(transport);
791 WINPR_ASSERT(client);
792 WINPR_ASSERT(client->context);
794 rdpRdp* rdp = client->context->rdp;
797 rdpSettings* settings = client->context->settings;
798 WINPR_ASSERT(settings);
800 if (client->ReachedState)
802 if (!client->ReachedState(client, rdp_get_state(rdp)))
803 return STATE_RUN_FAILED;
805 switch (rdp_get_state(rdp))
807 case CONNECTION_STATE_INITIAL:
808 if (!freerdp_settings_enforce_consistency(settings))
809 ret = STATE_RUN_FAILED;
810 else if (rdp_server_transition_to_state(rdp, CONNECTION_STATE_NEGO))
811 ret = STATE_RUN_CONTINUE;
814 case CONNECTION_STATE_NEGO:
815 if (!rdp_server_accept_nego(rdp, s))
817 WLog_ERR(TAG,
"%s - rdp_server_accept_nego() fail", rdp_get_state_string(rdp));
821 const UINT32 SelectedProtocol = nego_get_selected_protocol(rdp->nego);
823 settings->RdstlsSecurity = (SelectedProtocol & PROTOCOL_RDSTLS) != 0;
824 settings->NlaSecurity = (SelectedProtocol & PROTOCOL_HYBRID) != 0;
825 settings->TlsSecurity = (SelectedProtocol & PROTOCOL_SSL) != 0;
826 settings->RdpSecurity = (SelectedProtocol == PROTOCOL_RDP) != 0;
828 client->authenticated = FALSE;
829 if (SelectedProtocol & PROTOCOL_HYBRID)
833 if (sspi_CopyAuthIdentity(&client->identity, identity) >= 0)
835 client->authenticated =
836 IFCALLRESULT(TRUE, client->Logon, client, &client->identity, TRUE);
838 nego_free_nla(rdp->nego);
842 client->authenticated =
843 IFCALLRESULT(TRUE, client->Logon, client, &client->identity, FALSE);
845 if (!client->authenticated)
846 ret = STATE_RUN_FAILED;
849 if (rdp_server_transition_to_state(rdp, CONNECTION_STATE_MCS_CREATE_REQUEST))
850 ret = STATE_RUN_SUCCESS;
855 case CONNECTION_STATE_NLA:
859 case CONNECTION_STATE_MCS_CREATE_REQUEST:
860 if (!rdp_server_accept_mcs_connect_initial(rdp, s))
864 "rdp_server_accept_mcs_connect_initial() fail",
865 rdp_get_state_string(rdp));
868 ret = STATE_RUN_SUCCESS;
872 case CONNECTION_STATE_MCS_ERECT_DOMAIN:
873 if (!rdp_server_accept_mcs_erect_domain_request(rdp, s))
877 "rdp_server_accept_mcs_erect_domain_request() fail",
878 rdp_get_state_string(rdp));
881 ret = STATE_RUN_SUCCESS;
885 case CONNECTION_STATE_MCS_ATTACH_USER:
886 if (!rdp_server_accept_mcs_attach_user_request(rdp, s))
890 "rdp_server_accept_mcs_attach_user_request() fail",
891 rdp_get_state_string(rdp));
894 ret = STATE_RUN_SUCCESS;
898 case CONNECTION_STATE_MCS_CHANNEL_JOIN_REQUEST:
899 if (!rdp_server_accept_mcs_channel_join_request(rdp, s))
903 "rdp_server_accept_mcs_channel_join_request() fail",
904 rdp_get_state_string(rdp));
907 ret = STATE_RUN_SUCCESS;
910 case CONNECTION_STATE_RDP_SECURITY_COMMENCEMENT:
911 ret = STATE_RUN_SUCCESS;
913 if (!rdp_server_establish_keys(rdp, s))
917 "rdp_server_establish_keys() fail",
918 rdp_get_state_string(rdp));
919 ret = STATE_RUN_FAILED;
922 if (state_run_success(ret))
924 if (!rdp_server_transition_to_state(rdp, CONNECTION_STATE_SECURE_SETTINGS_EXCHANGE))
925 ret = STATE_RUN_FAILED;
926 else if (Stream_GetRemainingLength(s) > 0)
927 ret = STATE_RUN_CONTINUE;
931 case CONNECTION_STATE_SECURE_SETTINGS_EXCHANGE:
932 if (rdp_recv_client_info(rdp, s))
934 if (rdp_server_transition_to_state(
935 rdp, CONNECTION_STATE_CONNECT_TIME_AUTO_DETECT_REQUEST))
936 ret = STATE_RUN_CONTINUE;
940 case CONNECTION_STATE_CONNECT_TIME_AUTO_DETECT_REQUEST:
941 case CONNECTION_STATE_CONNECT_TIME_AUTO_DETECT_RESPONSE:
942 ret = peer_recv_handle_auto_detect(client, s);
945 case CONNECTION_STATE_LICENSING:
946 ret = peer_recv_handle_licensing(client, s);
947 if (ret == STATE_RUN_CONTINUE)
949 if (!rdp_server_transition_to_state(
950 rdp, CONNECTION_STATE_MULTITRANSPORT_BOOTSTRAPPING_REQUEST))
951 ret = STATE_RUN_FAILED;
955 case CONNECTION_STATE_MULTITRANSPORT_BOOTSTRAPPING_REQUEST:
956 if (settings->SupportMultitransport &&
957 ((settings->MultitransportFlags & INITIATE_REQUEST_PROTOCOL_UDPFECR) != 0))
960 ret = multitransport_server_request(rdp->multitransport,
961 INITIATE_REQUEST_PROTOCOL_UDPFECR);
964 case STATE_RUN_SUCCESS:
965 if (!rdp_server_transition_to_state(
966 rdp, CONNECTION_STATE_MULTITRANSPORT_BOOTSTRAPPING_RESPONSE))
967 ret = STATE_RUN_FAILED;
969 case STATE_RUN_CONTINUE:
971 if (!rdp_server_transition_to_state(
972 rdp, CONNECTION_STATE_CAPABILITIES_EXCHANGE_DEMAND_ACTIVE))
973 ret = STATE_RUN_FAILED;
981 if (rdp_server_transition_to_state(
982 rdp, CONNECTION_STATE_CAPABILITIES_EXCHANGE_DEMAND_ACTIVE))
983 ret = STATE_RUN_CONTINUE;
986 case CONNECTION_STATE_MULTITRANSPORT_BOOTSTRAPPING_RESPONSE:
987 ret = peer_recv_pdu(client, s);
990 case CONNECTION_STATE_CAPABILITIES_EXCHANGE_DEMAND_ACTIVE:
991 ret = rdp_peer_handle_state_demand_active(client);
994 case CONNECTION_STATE_CAPABILITIES_EXCHANGE_MONITOR_LAYOUT:
999 if (client->AdjustMonitorsLayout)
1001 if (!client->AdjustMonitorsLayout(client))
1002 return STATE_RUN_FAILED;
1006 ret = STATE_RUN_SUCCESS;
1013 .width = WINPR_ASSERTING_INT_CAST(int32_t, w),
1014 .height = WINPR_ASSERTING_INT_CAST(int32_t, h),
1017 .attributes = { .physicalWidth = w,
1018 .physicalHeight = h,
1020 ORIENTATION_LANDSCAPE,
1021 .desktopScaleFactor = 100,
1022 .deviceScaleFactor = 100 } };
1023 if (!freerdp_settings_set_pointer_array(settings, FreeRDP_MonitorDefArray, 0,
1025 ret = STATE_RUN_FAILED;
1027 ret = STATE_RUN_FAILED;
1029 if (state_run_failed(ret))
1032 else if (!display_convert_rdp_monitor_to_monitor_def(
1033 settings->MonitorCount, settings->MonitorDefArray, &monitors))
1035 ret = STATE_RUN_FAILED;
1037 else if (!freerdp_display_send_monitor_layout(rdp->context, settings->MonitorCount,
1040 ret = STATE_RUN_FAILED;
1043 ret = STATE_RUN_SUCCESS;
1046 const size_t len = Stream_GetRemainingLength(s);
1047 if (!state_run_failed(ret) && (len > 0))
1048 ret = STATE_RUN_CONTINUE;
1052 const size_t len = Stream_GetRemainingLength(s);
1054 ret = STATE_RUN_CONTINUE;
1056 ret = STATE_RUN_SUCCESS;
1058 if (state_run_success(ret))
1060 if (!rdp_server_transition_to_state(
1061 rdp, CONNECTION_STATE_CAPABILITIES_EXCHANGE_CONFIRM_ACTIVE))
1062 ret = STATE_RUN_FAILED;
1066 case CONNECTION_STATE_CAPABILITIES_EXCHANGE_CONFIRM_ACTIVE:
1071 ret = peer_recv_pdu(client, s);
1074 case CONNECTION_STATE_FINALIZATION_SYNC:
1075 ret = peer_recv_pdu(client, s);
1076 if (rdp_finalize_is_flag_set(rdp, FINALIZE_CS_SYNCHRONIZE_PDU))
1078 if (!rdp_server_transition_to_state(rdp, CONNECTION_STATE_FINALIZATION_COOPERATE))
1079 ret = STATE_RUN_FAILED;
1082 ret = peer_unexpected_client_message(rdp, FINALIZE_CS_SYNCHRONIZE_PDU);
1084 case CONNECTION_STATE_FINALIZATION_COOPERATE:
1085 ret = peer_recv_pdu(client, s);
1086 if (rdp_finalize_is_flag_set(rdp, FINALIZE_CS_CONTROL_COOPERATE_PDU))
1088 if (!rdp_server_transition_to_state(rdp,
1089 CONNECTION_STATE_FINALIZATION_REQUEST_CONTROL))
1090 ret = STATE_RUN_FAILED;
1093 ret = peer_unexpected_client_message(rdp, FINALIZE_CS_CONTROL_COOPERATE_PDU);
1095 case CONNECTION_STATE_FINALIZATION_REQUEST_CONTROL:
1096 ret = peer_recv_pdu(client, s);
1097 if (rdp_finalize_is_flag_set(rdp, FINALIZE_CS_CONTROL_REQUEST_PDU))
1099 if (!rdp_send_server_control_granted_pdu(rdp))
1100 ret = STATE_RUN_FAILED;
1101 else if (!rdp_server_transition_to_state(
1102 rdp, CONNECTION_STATE_FINALIZATION_PERSISTENT_KEY_LIST))
1103 ret = STATE_RUN_FAILED;
1106 ret = peer_unexpected_client_message(rdp, FINALIZE_CS_CONTROL_REQUEST_PDU);
1108 case CONNECTION_STATE_FINALIZATION_PERSISTENT_KEY_LIST:
1110 !rdp_finalize_is_flag_set(rdp, FINALIZE_DEACTIVATE_REACTIVATE))
1112 ret = peer_recv_pdu(client, s);
1114 if (rdp_finalize_is_flag_set(rdp, FINALIZE_CS_PERSISTENT_KEY_LIST_PDU))
1116 if (!rdp_server_transition_to_state(rdp,
1117 CONNECTION_STATE_FINALIZATION_FONT_LIST))
1118 ret = STATE_RUN_FAILED;
1121 ret = peer_unexpected_client_message(rdp,
1122 CONNECTION_STATE_FINALIZATION_FONT_LIST);
1126 if (!rdp_server_transition_to_state(rdp, CONNECTION_STATE_FINALIZATION_FONT_LIST))
1127 ret = STATE_RUN_FAILED;
1129 ret = STATE_RUN_CONTINUE;
1132 case CONNECTION_STATE_FINALIZATION_FONT_LIST:
1133 ret = peer_recv_pdu(client, s);
1134 if (state_run_success(ret))
1136 if (rdp_finalize_is_flag_set(rdp, FINALIZE_CS_FONT_LIST_PDU))
1138 if (!rdp_server_transition_to_state(rdp, CONNECTION_STATE_ACTIVE))
1139 ret = STATE_RUN_FAILED;
1142 update_reset_state(rdp->update);
1143 ret = STATE_RUN_CONTINUE;
1147 ret = peer_unexpected_client_message(rdp, FINALIZE_CS_FONT_LIST_PDU);
1151 case CONNECTION_STATE_ACTIVE:
1152 ret = rdp_peer_handle_state_active(client);
1153 if (ret >= STATE_RUN_ACTIVE)
1154 ret = peer_recv_pdu(client, s);
1158 case CONNECTION_STATE_FINALIZATION_CLIENT_SYNC:
1159 case CONNECTION_STATE_FINALIZATION_CLIENT_COOPERATE:
1160 case CONNECTION_STATE_FINALIZATION_CLIENT_GRANTED_CONTROL:
1161 case CONNECTION_STATE_FINALIZATION_CLIENT_FONT_MAP:
1163 WLog_ERR(TAG,
"%s state %" PRId32, rdp_get_state_string(rdp),
1164 WINPR_CXX_COMPAT_CAST(int32_t, rdp_get_state(rdp)));
1171static state_run_t peer_recv_callback(rdpTransport* transport,
wStream* s,
void* extra)
1173 char buffer[64] = WINPR_C_ARRAY_INIT;
1174 state_run_t rc = STATE_RUN_FAILED;
1175 const size_t start = Stream_GetPosition(s);
1176 const rdpContext* context = transport_get_context(transport);
1177 DWORD level = WLOG_TRACE;
1178 static wLog* log =
nullptr;
1180 log = WLog_Get(TAG);
1182 WINPR_ASSERT(context);
1185 const rdpRdp* rdp = context->rdp;
1186 const char* old = rdp_get_state_string(rdp);
1188 if (rc == STATE_RUN_TRY_AGAIN)
1190 if (!Stream_SetPosition(s, start))
1191 return STATE_RUN_FAILED;
1193 rc = peer_recv_callback_internal(transport, s, extra);
1195 const size_t len = Stream_GetRemainingLength(s);
1196 if ((len > 0) && !state_run_continue(rc))
1198 WLog_Print(log, level,
1199 "(server)[%s -> %s] current return %s [%" PRIuz
" bytes not processed]", old,
1200 rdp_get_state_string(rdp), state_run_result_string(rc, buffer,
sizeof(buffer)),
1202 }
while (state_run_continue(rc));
1207static BOOL freerdp_peer_close(freerdp_peer* client)
1209 UINT32 SelectedProtocol = 0;
1210 rdpContext* context =
nullptr;
1212 WINPR_ASSERT(client);
1214 context = client->context;
1215 WINPR_ASSERT(context);
1216 WINPR_ASSERT(context->settings);
1217 WINPR_ASSERT(context->rdp);
1222 SelectedProtocol = nego_get_selected_protocol(context->rdp->nego);
1224 if (SelectedProtocol & PROTOCOL_FAILED_NEGO)
1232 if (!rdp_send_deactivate_all(context->rdp))
1237 if (!rdp_send_error_info(context->rdp))
1241 return mcs_send_disconnect_provider_ultimatum(context->rdp->mcs,
1242 Disconnect_Ultimatum_provider_initiated);
1245static void freerdp_peer_disconnect(freerdp_peer* client)
1247 rdpTransport* transport =
nullptr;
1248 WINPR_ASSERT(client);
1250 transport = freerdp_get_transport(client->context);
1251 transport_disconnect(transport);
1254static BOOL freerdp_peer_send_channel_data(freerdp_peer* client, UINT16 channelId,
const BYTE* data,
1257 WINPR_ASSERT(client);
1258 WINPR_ASSERT(client->context);
1259 WINPR_ASSERT(client->context->rdp);
1260 return rdp_send_channel_data(client->context->rdp, channelId, data, size);
1263static BOOL freerdp_peer_send_server_redirection_pdu(freerdp_peer* peer,
1264 const rdpRedirection* redirection)
1268 WINPR_ASSERT(peer->context);
1270 UINT16 sec_flags = 0;
1271 wStream* s = rdp_send_stream_pdu_init(peer->context->rdp, &sec_flags);
1274 if (!rdp_write_enhanced_security_redirection_packet(s, redirection))
1276 if (!rdp_send_pdu(peer->context->rdp, s, PDU_TYPE_SERVER_REDIRECTION, 0, sec_flags))
1278 rc = rdp_reset_runtime_settings(peer->context->rdp);
1284static BOOL freerdp_peer_send_channel_packet(freerdp_peer* client, UINT16 channelId,
1285 size_t totalSize, UINT32 flags,
const BYTE* data,
1288 WINPR_ASSERT(client);
1289 WINPR_ASSERT(client->context);
1290 WINPR_ASSERT(client->context->rdp);
1291 return rdp_channel_send_packet(client->context->rdp, channelId, totalSize, flags, data,
1295static BOOL freerdp_peer_is_write_blocked(freerdp_peer* peer)
1297 rdpTransport* transport =
nullptr;
1299 WINPR_ASSERT(peer->context);
1300 WINPR_ASSERT(peer->context->rdp);
1301 WINPR_ASSERT(peer->context->rdp->transport);
1302 transport = peer->context->rdp->transport;
1303 return transport_is_write_blocked(transport);
1306static int freerdp_peer_drain_output_buffer(freerdp_peer* peer)
1308 rdpTransport* transport =
nullptr;
1310 WINPR_ASSERT(peer->context);
1311 WINPR_ASSERT(peer->context->rdp);
1312 WINPR_ASSERT(peer->context->rdp->transport);
1313 transport = peer->context->rdp->transport;
1314 return transport_drain_output_buffer(transport);
1317static BOOL freerdp_peer_has_more_to_read(freerdp_peer* peer)
1320 WINPR_ASSERT(peer->context);
1321 WINPR_ASSERT(peer->context->rdp);
1322 return transport_have_more_bytes_to_read(peer->context->rdp->transport);
1325static LicenseCallbackResult freerdp_peer_nolicense(freerdp_peer* peer,
1328 rdpRdp* rdp =
nullptr;
1331 WINPR_ASSERT(peer->context);
1333 rdp = peer->context->rdp;
1335 if (!license_send_valid_client_error_packet(rdp))
1337 WLog_ERR(TAG,
"freerdp_peer_nolicense: license_send_valid_client_error_packet() failed");
1338 return LICENSE_CB_ABORT;
1341 return LICENSE_CB_COMPLETED;
1344BOOL freerdp_peer_context_new(freerdp_peer* client)
1346 return freerdp_peer_context_new_ex(client,
nullptr);
1349void freerdp_peer_context_free(freerdp_peer* client)
1354 IFCALL(client->ContextFree, client, client->context);
1356 if (client->context)
1358 rdpContext* ctx = client->context;
1360 (void)CloseHandle(ctx->channelErrorEvent);
1361 ctx->channelErrorEvent =
nullptr;
1362 free(ctx->errorDescription);
1363 ctx->errorDescription =
nullptr;
1366 metrics_free(ctx->metrics);
1367 ctx->metrics =
nullptr;
1368 stream_dump_free(ctx->dump);
1369 ctx->dump =
nullptr;
1372 client->context =
nullptr;
1375static const char* os_major_type_to_string(UINT16 osMajorType)
1377 switch (osMajorType)
1379 case OSMAJORTYPE_UNSPECIFIED:
1380 return "Unspecified platform";
1381 case OSMAJORTYPE_WINDOWS:
1382 return "Windows platform";
1383 case OSMAJORTYPE_OS2:
1384 return "OS/2 platform";
1385 case OSMAJORTYPE_MACINTOSH:
1386 return "Macintosh platform";
1387 case OSMAJORTYPE_UNIX:
1388 return "UNIX platform";
1389 case OSMAJORTYPE_IOS:
1390 return "iOS platform";
1391 case OSMAJORTYPE_OSX:
1392 return "OS X platform";
1393 case OSMAJORTYPE_ANDROID:
1394 return "Android platform";
1395 case OSMAJORTYPE_CHROME_OS:
1396 return "Chrome OS platform";
1401 return "Unknown platform";
1404const char* freerdp_peer_os_major_type_string(freerdp_peer* client)
1406 WINPR_ASSERT(client);
1408 rdpContext* context = client->context;
1409 WINPR_ASSERT(context);
1410 WINPR_ASSERT(context->settings);
1413 WINPR_ASSERT(osMajorType <= UINT16_MAX);
1414 return os_major_type_to_string((UINT16)osMajorType);
1417static const char* os_minor_type_to_string(UINT16 osMinorType)
1419 switch (osMinorType)
1421 case OSMINORTYPE_UNSPECIFIED:
1422 return "Unspecified version";
1423 case OSMINORTYPE_WINDOWS_31X:
1424 return "Windows 3.1x";
1425 case OSMINORTYPE_WINDOWS_95:
1426 return "Windows 95";
1427 case OSMINORTYPE_WINDOWS_NT:
1428 return "Windows NT";
1429 case OSMINORTYPE_OS2_V21:
1431 case OSMINORTYPE_POWER_PC:
1433 case OSMINORTYPE_MACINTOSH:
1435 case OSMINORTYPE_NATIVE_XSERVER:
1436 return "Native X Server";
1437 case OSMINORTYPE_PSEUDO_XSERVER:
1438 return "Pseudo X Server";
1439 case OSMINORTYPE_WINDOWS_RT:
1440 return "Windows RT";
1445 return "Unknown version";
1448const char* freerdp_peer_os_minor_type_string(freerdp_peer* client)
1450 WINPR_ASSERT(client);
1452 rdpContext* context = client->context;
1453 WINPR_ASSERT(context);
1454 WINPR_ASSERT(context->settings);
1457 WINPR_ASSERT(osMinorType <= UINT16_MAX);
1458 return os_minor_type_to_string((UINT16)osMinorType);
1461freerdp_peer* freerdp_peer_new(
int sockfd)
1463 freerdp_peer* client = (freerdp_peer*)calloc(1,
sizeof(freerdp_peer));
1470 (void)freerdp_tcp_set_nodelay(WLog_Get(TAG), WLOG_DEBUG, sockfd);
1473 client->sockfd = sockfd;
1474 client->ContextSize =
sizeof(rdpContext);
1475 client->Initialize = freerdp_peer_initialize;
1476#if defined(WITH_FREERDP_DEPRECATED)
1477 client->GetFileDescriptor = freerdp_peer_get_fds;
1479 client->GetEventHandle = freerdp_peer_get_event_handle;
1480 client->GetEventHandles = freerdp_peer_get_event_handles;
1481 client->CheckFileDescriptor = freerdp_peer_check_fds;
1482 client->Close = freerdp_peer_close;
1483 client->Disconnect = freerdp_peer_disconnect;
1484 client->SendChannelData = freerdp_peer_send_channel_data;
1485 client->SendChannelPacket = freerdp_peer_send_channel_packet;
1486 client->SendServerRedirection = freerdp_peer_send_server_redirection_pdu;
1487 client->IsWriteBlocked = freerdp_peer_is_write_blocked;
1488 client->DrainOutputBuffer = freerdp_peer_drain_output_buffer;
1489 client->HasMoreToRead = freerdp_peer_has_more_to_read;
1490 client->VirtualChannelOpen = freerdp_peer_virtual_channel_open;
1491 client->VirtualChannelClose = freerdp_peer_virtual_channel_close;
1492 client->VirtualChannelWrite = freerdp_peer_virtual_channel_write;
1493 client->VirtualChannelRead =
nullptr;
1494 client->VirtualChannelGetData = freerdp_peer_virtual_channel_get_data;
1495 client->VirtualChannelSetData = freerdp_peer_virtual_channel_set_data;
1496 client->SetState = freerdp_peer_set_state;
1501void freerdp_peer_free(freerdp_peer* client)
1506 sspi_FreeAuthIdentity(&client->identity);
1507 if (client->sockfd >= 0)
1508 closesocket((SOCKET)client->sockfd);
1512static BOOL freerdp_peer_transport_setup(freerdp_peer* client)
1514 rdpRdp* rdp =
nullptr;
1516 WINPR_ASSERT(client);
1517 WINPR_ASSERT(client->context);
1519 rdp = client->context->rdp;
1522 if (!transport_attach(rdp->transport, client->sockfd))
1524 client->sockfd = -1;
1526 if (!transport_set_recv_callbacks(rdp->transport, peer_recv_callback, client))
1529 if (!transport_set_blocking_mode(rdp->transport, FALSE))
1535BOOL freerdp_peer_context_new_ex(freerdp_peer* client,
const rdpSettings* settings)
1537 rdpRdp* rdp =
nullptr;
1538 rdpContext* context =
nullptr;
1544 WINPR_ASSERT(client->ContextSize >=
sizeof(rdpContext));
1545 if (!(context = (rdpContext*)calloc(1, client->ContextSize)))
1548 client->context = context;
1549 context->peer = client;
1550 context->ServerMode = TRUE;
1551 context->log = WLog_Get(TAG);
1558 if (!context->settings)
1562 context->dump = stream_dump_new();
1565 if (!(context->metrics = metrics_new(context)))
1568 if (!(rdp = rdp_new(context)))
1571 rdp_log_build_warnings(rdp);
1573#if defined(WITH_FREERDP_DEPRECATED)
1574 client->update = rdp->update;
1575 client->settings = rdp->settings;
1576 client->autodetect = rdp->autodetect;
1579 context->input = rdp->input;
1580 context->update = rdp->update;
1581 context->settings = rdp->settings;
1582 context->autodetect = rdp->autodetect;
1583 update_register_server_callbacks(rdp->update);
1584 autodetect_register_server_callbacks(rdp->autodetect);
1586 if (!(context->channelErrorEvent = CreateEvent(
nullptr, TRUE, FALSE,
nullptr)))
1588 WLog_ERR(TAG,
"CreateEvent failed!");
1592 if (!(context->errorDescription = calloc(1, 500)))
1594 WLog_ERR(TAG,
"calloc failed!");
1598 if (!freerdp_peer_transport_setup(client))
1601 client->IsWriteBlocked = freerdp_peer_is_write_blocked;
1602 client->DrainOutputBuffer = freerdp_peer_drain_output_buffer;
1603 client->HasMoreToRead = freerdp_peer_has_more_to_read;
1604 client->LicenseCallback = freerdp_peer_nolicense;
1605 IFCALLRET(client->ContextNew, ret, client, client->context);
1612 WLog_ERR(TAG,
"ContextNew callback failed");
1613 freerdp_peer_context_free(client);
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.
FREERDP_API rdpSettings * freerdp_settings_clone(const rdpSettings *settings)
Creates a deep copy of settings.
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 BOOL freerdp_settings_set_uint32(rdpSettings *settings, FreeRDP_Settings_Keys_UInt32 id, UINT32 val)
Sets a UINT32 settings value.
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_get_bool(const rdpSettings *settings, FreeRDP_Settings_Keys_Bool id)
Returns a boolean settings value.