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,
53 rdpMcsChannel* mcsChannel = NULL;
54 rdpPeerChannel* peerChannel = NULL;
58 WINPR_ASSERT(client->context);
59 WINPR_ASSERT(client->context->rdp);
61 mcs = client->context->rdp->mcs;
64 if (flags & WTS_CHANNEL_OPTION_DYNAMIC)
67 const size_t length = strnlen(name, 9);
72 for (; index < mcs->channelCount; index++)
74 mcsChannel = &(mcs->channels[index]);
76 if (!mcsChannel->joined)
79 if (_strnicmp(name, mcsChannel->Name, length) == 0)
89 peerChannel = (rdpPeerChannel*)mcsChannel->handle;
94 return (HANDLE)peerChannel;
97 WINPR_ASSERT(index <= UINT16_MAX);
99 server_channel_common_new(client, (UINT16)index, mcsChannel->ChannelId, 128, NULL, name);
103 peerChannel->channelFlags = flags;
104 peerChannel->mcsChannel = mcsChannel;
105 mcsChannel->handle = (
void*)peerChannel;
108 return (HANDLE)peerChannel;
111static BOOL freerdp_peer_virtual_channel_close(WINPR_ATTR_UNUSED freerdp_peer* client,
114 rdpMcsChannel* mcsChannel = NULL;
115 rdpPeerChannel* peerChannel = NULL;
117 WINPR_ASSERT(client);
122 peerChannel = (rdpPeerChannel*)hChannel;
123 mcsChannel = peerChannel->mcsChannel;
124 WINPR_ASSERT(mcsChannel);
125 mcsChannel->handle = NULL;
126 server_channel_common_free(peerChannel);
130static int freerdp_peer_virtual_channel_write(freerdp_peer* client, HANDLE hChannel,
131 const BYTE* buffer, UINT32 length)
135 UINT32 chunkSize = 0;
136 UINT32 maxChunkSize = 0;
137 UINT32 totalLength = 0;
138 rdpPeerChannel* peerChannel = NULL;
139 rdpMcsChannel* mcsChannel = NULL;
142 WINPR_ASSERT(client);
143 WINPR_ASSERT(client->context);
145 rdp = client->context->rdp;
147 WINPR_ASSERT(rdp->settings);
152 peerChannel = (rdpPeerChannel*)hChannel;
153 mcsChannel = peerChannel->mcsChannel;
154 WINPR_ASSERT(peerChannel);
155 WINPR_ASSERT(mcsChannel);
156 if (peerChannel->channelFlags & WTS_CHANNEL_OPTION_DYNAMIC)
159 maxChunkSize = rdp->settings->VCChunkSize;
160 totalLength = length;
161 flags = CHANNEL_FLAG_FIRST;
165 UINT16 sec_flags = 0;
166 s = rdp_send_stream_init(rdp, &sec_flags);
171 if (length > maxChunkSize)
173 chunkSize = rdp->settings->VCChunkSize;
178 flags |= CHANNEL_FLAG_LAST;
181 if (mcsChannel->options & CHANNEL_OPTION_SHOW_PROTOCOL)
182 flags |= CHANNEL_FLAG_SHOW_PROTOCOL;
184 Stream_Write_UINT32(s, totalLength);
185 Stream_Write_UINT32(s, flags);
187 if (!Stream_EnsureRemainingCapacity(s, chunkSize))
193 Stream_Write(s, buffer, chunkSize);
195 WINPR_ASSERT(peerChannel->channelId <= UINT16_MAX);
196 if (!rdp_send(rdp, s, (UINT16)peerChannel->channelId, sec_flags))
207static void* freerdp_peer_virtual_channel_get_data(WINPR_ATTR_UNUSED freerdp_peer* client,
210 rdpPeerChannel* peerChannel = (rdpPeerChannel*)hChannel;
212 WINPR_ASSERT(client);
216 return peerChannel->extra;
219static int freerdp_peer_virtual_channel_set_data(WINPR_ATTR_UNUSED freerdp_peer* client,
220 HANDLE hChannel,
void* data)
222 rdpPeerChannel* peerChannel = (rdpPeerChannel*)hChannel;
224 WINPR_ASSERT(client);
228 peerChannel->extra = data;
232static BOOL freerdp_peer_set_state(freerdp_peer* client, CONNECTION_STATE state)
234 WINPR_ASSERT(client);
235 WINPR_ASSERT(client->context);
236 return rdp_server_transition_to_state(client->context->rdp, state);
239static BOOL freerdp_peer_initialize(freerdp_peer* client)
242 rdpSettings* settings = NULL;
244 WINPR_ASSERT(client);
245 WINPR_ASSERT(client->context);
247 rdp = client->context->rdp;
250 settings = rdp->settings;
251 WINPR_ASSERT(settings);
253 settings->ServerMode = TRUE;
254 settings->FrameAcknowledge = 0;
255 settings->LocalConnection = client->local;
257 const rdpCertificate* cert =
261 WLog_ERR(TAG,
"Missing server certificate, can not continue.");
268 if (!freerdp_certificate_is_rdp_security_compatible(cert))
277 nego_set_RCG_supported(rdp->nego, settings->RemoteCredentialGuard);
278 nego_set_restricted_admin_mode_supported(rdp->nego, settings->RestrictedAdminModeSupported);
280 if (!rdp_server_transition_to_state(rdp, CONNECTION_STATE_INITIAL))
286#if defined(WITH_FREERDP_DEPRECATED)
287static BOOL freerdp_peer_get_fds(freerdp_peer* client,
void** rfds,
int* rcount)
289 rdpTransport* transport = NULL;
290 WINPR_ASSERT(client);
291 WINPR_ASSERT(client->context);
292 WINPR_ASSERT(client->context->rdp);
294 transport = client->context->rdp->transport;
295 WINPR_ASSERT(transport);
296 transport_get_fds(transport, rfds, rcount);
301static HANDLE freerdp_peer_get_event_handle(freerdp_peer* client)
303 HANDLE hEvent = NULL;
304 rdpTransport* transport = NULL;
305 WINPR_ASSERT(client);
306 WINPR_ASSERT(client->context);
307 WINPR_ASSERT(client->context->rdp);
309 transport = client->context->rdp->transport;
310 hEvent = transport_get_front_bio(transport);
314static DWORD freerdp_peer_get_event_handles(freerdp_peer* client, HANDLE* events, DWORD count)
316 WINPR_ASSERT(client);
317 WINPR_ASSERT(client->context);
318 WINPR_ASSERT(client->context->rdp);
319 return transport_get_event_handles(client->context->rdp->transport, events, count);
322static BOOL freerdp_peer_check_fds(freerdp_peer* peer)
328 WINPR_ASSERT(peer->context);
330 rdp = peer->context->rdp;
331 status = rdp_check_fds(rdp);
339static state_run_t peer_recv_data_pdu(freerdp_peer* client,
wStream* s,
340 WINPR_ATTR_UNUSED UINT16 totalLength)
345 BYTE compressed_type = 0;
346 UINT16 compressed_len = 0;
347 rdpUpdate* update = NULL;
350 WINPR_ASSERT(client);
351 WINPR_ASSERT(client->context);
352 rdpRdp* rdp = client->context->rdp;
354 WINPR_ASSERT(rdp->mcs);
356 update = client->context->update;
357 WINPR_ASSERT(update);
359 if (!rdp_read_share_data_header(rdp, s, &length, &type, &share_id, &compressed_type,
361 return STATE_RUN_FAILED;
364 WLog_Print(rdp->log, WLOG_DEBUG,
"recv %s Data PDU (0x%02" PRIX8
"), length: %" PRIu16
"",
365 data_pdu_type_to_string(type), type, length);
370 case DATA_PDU_TYPE_SYNCHRONIZE:
371 if (!rdp_recv_client_synchronize_pdu(rdp, s))
372 return STATE_RUN_FAILED;
376 case DATA_PDU_TYPE_CONTROL:
377 if (!rdp_server_accept_client_control_pdu(rdp, s))
378 return STATE_RUN_FAILED;
382 case DATA_PDU_TYPE_INPUT:
383 if (!input_recv(rdp->input, s))
384 return STATE_RUN_FAILED;
388 case DATA_PDU_TYPE_BITMAP_CACHE_PERSISTENT_LIST:
389 if (!rdp_server_accept_client_persistent_key_list_pdu(rdp, s))
390 return STATE_RUN_FAILED;
393 case DATA_PDU_TYPE_FONT_LIST:
394 if (!rdp_server_accept_client_font_list_pdu(rdp, s))
395 return STATE_RUN_FAILED;
397 return STATE_RUN_CONTINUE;
399 case DATA_PDU_TYPE_SHUTDOWN_REQUEST:
400 mcs_send_disconnect_provider_ultimatum(rdp->mcs,
401 Disconnect_Ultimatum_provider_initiated);
402 WLog_WARN(TAG,
"disconnect provider ultimatum sent to peer, closing connection");
403 return STATE_RUN_QUIT_SESSION;
405 case DATA_PDU_TYPE_FRAME_ACKNOWLEDGE:
406 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
407 return STATE_RUN_FAILED;
409 Stream_Read_UINT32(s, client->ack_frame_id);
410 IFCALL(update->SurfaceFrameAcknowledge, update->context, client->ack_frame_id);
413 case DATA_PDU_TYPE_REFRESH_RECT:
414 if (!update_read_refresh_rect(update, s))
415 return STATE_RUN_FAILED;
419 case DATA_PDU_TYPE_SUPPRESS_OUTPUT:
420 if (!update_read_suppress_output(update, s))
421 return STATE_RUN_FAILED;
426 WLog_ERR(TAG,
"Data PDU type %" PRIu8
"", type);
430 return STATE_RUN_SUCCESS;
433static state_run_t peer_recv_tpkt_pdu(freerdp_peer* client,
wStream* s)
435 state_run_t rc = STATE_RUN_SUCCESS;
438 UINT16 pduSource = 0;
439 UINT16 channelId = 0;
440 UINT16 securityFlags = 0;
443 WINPR_ASSERT(client);
444 WINPR_ASSERT(client->context);
446 rdpRdp* rdp = client->context->rdp;
448 WINPR_ASSERT(rdp->mcs);
450 rdpSettings* settings = client->context->settings;
451 WINPR_ASSERT(settings);
453 if (!rdp_read_header(rdp, s, &length, &channelId))
454 return STATE_RUN_FAILED;
457 if (freerdp_shall_disconnect_context(rdp->context))
458 return STATE_RUN_SUCCESS;
460 if (rdp_get_state(rdp) <= CONNECTION_STATE_LICENSING)
462 return rdp_handle_message_channel(rdp, s, channelId, length);
465 if (!rdp_handle_optional_rdp_decryption(rdp, s, &length, &securityFlags))
466 return STATE_RUN_FAILED;
468 if (channelId == MCS_GLOBAL_CHANNEL_ID)
470 char buffer[256] = { 0 };
471 UINT16 pduLength = 0;
473 if (!rdp_read_share_control_header(rdp, s, &pduLength, &remain, &pduType, &pduSource))
474 return STATE_RUN_FAILED;
476 settings->PduSource = pduSource;
478 WLog_DBG(TAG,
"Received %s", pdu_type_to_str(pduType, buffer,
sizeof(buffer)));
482 rc = peer_recv_data_pdu(client, s, pduLength);
485 case PDU_TYPE_CONFIRM_ACTIVE:
486 if (!rdp_server_accept_confirm_active(rdp, s, pduLength))
487 return STATE_RUN_FAILED;
491 case PDU_TYPE_FLOW_RESPONSE:
492 case PDU_TYPE_FLOW_STOP:
493 case PDU_TYPE_FLOW_TEST:
494 if (!Stream_SafeSeek(s, remain))
496 WLog_WARN(TAG,
"Short PDU, need %" PRIuz
" bytes, got %" PRIuz, remain,
497 Stream_GetRemainingLength(s));
498 return STATE_RUN_FAILED;
503 WLog_ERR(TAG,
"Client sent unknown pduType %" PRIu16
"", pduType);
504 return STATE_RUN_FAILED;
507 else if ((rdp->mcs->messageChannelId > 0) && (channelId == rdp->mcs->messageChannelId))
509 if (!settings->UseRdpSecurityLayer)
511 if (!rdp_read_security_header(rdp, s, &securityFlags, NULL))
512 return STATE_RUN_FAILED;
515 return rdp_recv_message_channel_pdu(rdp, s, securityFlags);
519 if (!freerdp_channel_peer_process(client, s, channelId))
520 return STATE_RUN_FAILED;
522 if (!tpkt_ensure_stream_consumed(rdp->log, s, length))
523 return STATE_RUN_FAILED;
528static state_run_t peer_recv_handle_auto_detect(freerdp_peer* client,
wStream* s)
530 state_run_t ret = STATE_RUN_FAILED;
533 WINPR_ASSERT(client);
535 WINPR_ASSERT(client->context);
537 rdp = client->context->rdp;
540 const rdpSettings* settings = client->context->settings;
541 WINPR_ASSERT(settings);
545 switch (rdp_get_state(rdp))
547 case CONNECTION_STATE_CONNECT_TIME_AUTO_DETECT_REQUEST:
548 autodetect_on_connect_time_auto_detect_begin(rdp->autodetect);
549 switch (autodetect_get_state(rdp->autodetect))
551 case FREERDP_AUTODETECT_STATE_REQUEST:
552 ret = STATE_RUN_SUCCESS;
553 if (!rdp_server_transition_to_state(
554 rdp, CONNECTION_STATE_CONNECT_TIME_AUTO_DETECT_RESPONSE))
555 return STATE_RUN_FAILED;
557 case FREERDP_AUTODETECT_STATE_COMPLETE:
558 ret = STATE_RUN_CONTINUE;
559 if (!rdp_server_transition_to_state(rdp, CONNECTION_STATE_LICENSING))
560 return STATE_RUN_FAILED;
566 case CONNECTION_STATE_CONNECT_TIME_AUTO_DETECT_RESPONSE:
567 ret = peer_recv_pdu(client, s);
568 if (state_run_success(ret))
570 autodetect_on_connect_time_auto_detect_progress(rdp->autodetect);
571 switch (autodetect_get_state(rdp->autodetect))
573 case FREERDP_AUTODETECT_STATE_REQUEST:
574 ret = STATE_RUN_SUCCESS;
576 case FREERDP_AUTODETECT_STATE_COMPLETE:
577 ret = STATE_RUN_CONTINUE;
578 if (!rdp_server_transition_to_state(rdp, CONNECTION_STATE_LICENSING))
579 return STATE_RUN_FAILED;
593 if (!rdp_server_transition_to_state(rdp, CONNECTION_STATE_LICENSING))
594 return STATE_RUN_FAILED;
596 ret = STATE_RUN_CONTINUE;
602static state_run_t peer_recv_handle_licensing(freerdp_peer* client,
wStream* s)
604 state_run_t ret = STATE_RUN_FAILED;
606 rdpSettings* settings = NULL;
608 WINPR_ASSERT(client);
610 WINPR_ASSERT(client->context);
612 rdp = client->context->rdp;
615 settings = rdp->settings;
616 WINPR_ASSERT(settings);
618 switch (license_get_state(rdp->license))
620 case LICENSE_STATE_INITIAL:
622 const BOOL required =
627 if (!license_server_configure(rdp->license))
628 ret = STATE_RUN_FAILED;
629 else if (!license_server_send_request(rdp->license))
630 ret = STATE_RUN_FAILED;
632 ret = STATE_RUN_SUCCESS;
636 if (license_send_valid_client_error_packet(rdp))
637 ret = STATE_RUN_CONTINUE;
641 case LICENSE_STATE_COMPLETED:
642 ret = STATE_RUN_CONTINUE;
644 case LICENSE_STATE_ABORTED:
645 ret = STATE_RUN_FAILED;
648 ret = peer_recv_pdu(client, s);
655static state_run_t peer_recv_fastpath_pdu(freerdp_peer* client,
wStream* s)
660 rdpFastPath* fastpath = NULL;
663 WINPR_ASSERT(client);
664 WINPR_ASSERT(client->context);
666 rdp = client->context->rdp;
669 fastpath = rdp->fastpath;
670 WINPR_ASSERT(fastpath);
672 rc = fastpath_read_header_rdp(fastpath, s, &length);
674 if (!rc || (length == 0))
676 WLog_ERR(TAG,
"incorrect FastPath PDU header length %" PRIu16
"", length);
677 return STATE_RUN_FAILED;
679 if (!Stream_CheckAndLogRequiredLength(TAG, s, length))
680 return STATE_RUN_FAILED;
682 if (!fastpath_decrypt(fastpath, s, &length))
683 return STATE_RUN_FAILED;
687 return fastpath_recv_inputs(fastpath, s);
690state_run_t peer_recv_pdu(freerdp_peer* client,
wStream* s)
692 int rc = tpkt_verify_header(s);
695 return peer_recv_tpkt_pdu(client, s);
697 return peer_recv_fastpath_pdu(client, s);
699 return STATE_RUN_FAILED;
702static state_run_t peer_unexpected_client_message(rdpRdp* rdp, UINT32 flag)
704 char buffer[1024] = { 0 };
705 WLog_WARN(TAG,
"Unexpected client message in state %s, missing flag %s",
706 rdp_get_state_string(rdp), rdp_finalize_flags_to_str(flag, buffer,
sizeof(buffer)));
707 return STATE_RUN_SUCCESS;
710state_run_t rdp_peer_handle_state_demand_active(freerdp_peer* client)
712 state_run_t ret = STATE_RUN_FAILED;
714 WINPR_ASSERT(client);
715 WINPR_ASSERT(client->context);
717 rdpRdp* rdp = client->context->rdp;
720 if (client->Capabilities && !client->Capabilities(client))
722 WLog_ERR(TAG,
"[%s] freerdp_peer::Capabilities() callback failed",
723 rdp_get_state_string(rdp));
725 else if (!rdp_send_demand_active(rdp))
727 WLog_ERR(TAG,
"[%s] rdp_send_demand_active() fail", rdp_get_state_string(rdp));
731 if (!rdp_server_transition_to_state(rdp,
732 CONNECTION_STATE_CAPABILITIES_EXCHANGE_MONITOR_LAYOUT))
733 return STATE_RUN_FAILED;
734 ret = STATE_RUN_CONTINUE;
745static state_run_t rdp_peer_handle_state_active(freerdp_peer* client)
747 state_run_t ret = STATE_RUN_FAILED;
749 WINPR_ASSERT(client);
750 WINPR_ASSERT(client->context);
752 if (!client->connected)
758 IFCALLRET(client->PostConnect, client->connected, client);
760 if (!client->connected)
762 WLog_ERR(TAG,
"PostConnect for peer %p failed", client);
763 ret = STATE_RUN_FAILED;
765 else if (!client->activated)
767 BOOL activated = TRUE;
772 client->activated = TRUE;
773 IFCALLRET(client->Activate, activated, client);
777 WLog_ERR(TAG,
"Activate for peer %p failed", client);
778 ret = STATE_RUN_FAILED;
781 ret = STATE_RUN_SUCCESS;
784 ret = STATE_RUN_ACTIVE;
788static state_run_t peer_recv_callback_internal(WINPR_ATTR_UNUSED rdpTransport* transport,
791 UINT32 SelectedProtocol = 0;
792 freerdp_peer* client = (freerdp_peer*)extra;
794 state_run_t ret = STATE_RUN_FAILED;
795 rdpSettings* settings = NULL;
797 WINPR_ASSERT(transport);
798 WINPR_ASSERT(client);
799 WINPR_ASSERT(client->context);
801 rdp = client->context->rdp;
804 settings = client->context->settings;
805 WINPR_ASSERT(settings);
807 IFCALL(client->ReachedState, client, rdp_get_state(rdp));
808 switch (rdp_get_state(rdp))
810 case CONNECTION_STATE_INITIAL:
811 if (!freerdp_settings_enforce_consistency(settings))
812 ret = STATE_RUN_FAILED;
813 else if (rdp_server_transition_to_state(rdp, CONNECTION_STATE_NEGO))
814 ret = STATE_RUN_CONTINUE;
817 case CONNECTION_STATE_NEGO:
818 if (!rdp_server_accept_nego(rdp, s))
820 WLog_ERR(TAG,
"%s - rdp_server_accept_nego() fail", rdp_get_state_string(rdp));
824 SelectedProtocol = nego_get_selected_protocol(rdp->nego);
825 settings->RdstlsSecurity = (SelectedProtocol & PROTOCOL_RDSTLS) ? TRUE : FALSE;
826 settings->NlaSecurity = (SelectedProtocol & PROTOCOL_HYBRID) ? TRUE : FALSE;
827 settings->TlsSecurity = (SelectedProtocol & PROTOCOL_SSL) ? TRUE : FALSE;
828 settings->RdpSecurity = (SelectedProtocol == PROTOCOL_RDP) ? TRUE : FALSE;
830 if (SelectedProtocol & PROTOCOL_HYBRID)
834 sspi_CopyAuthIdentity(&client->identity, identity);
835 IFCALLRET(client->Logon, client->authenticated, client, &client->identity,
837 nego_free_nla(rdp->nego);
841 IFCALLRET(client->Logon, client->authenticated, client, &client->identity,
844 if (rdp_server_transition_to_state(rdp, CONNECTION_STATE_MCS_CREATE_REQUEST))
845 ret = STATE_RUN_SUCCESS;
849 case CONNECTION_STATE_NLA:
853 case CONNECTION_STATE_MCS_CREATE_REQUEST:
854 if (!rdp_server_accept_mcs_connect_initial(rdp, s))
858 "rdp_server_accept_mcs_connect_initial() fail",
859 rdp_get_state_string(rdp));
862 ret = STATE_RUN_SUCCESS;
866 case CONNECTION_STATE_MCS_ERECT_DOMAIN:
867 if (!rdp_server_accept_mcs_erect_domain_request(rdp, s))
871 "rdp_server_accept_mcs_erect_domain_request() fail",
872 rdp_get_state_string(rdp));
875 ret = STATE_RUN_SUCCESS;
879 case CONNECTION_STATE_MCS_ATTACH_USER:
880 if (!rdp_server_accept_mcs_attach_user_request(rdp, s))
884 "rdp_server_accept_mcs_attach_user_request() fail",
885 rdp_get_state_string(rdp));
888 ret = STATE_RUN_SUCCESS;
892 case CONNECTION_STATE_MCS_CHANNEL_JOIN_REQUEST:
893 if (!rdp_server_accept_mcs_channel_join_request(rdp, s))
897 "rdp_server_accept_mcs_channel_join_request() fail",
898 rdp_get_state_string(rdp));
901 ret = STATE_RUN_SUCCESS;
904 case CONNECTION_STATE_RDP_SECURITY_COMMENCEMENT:
905 ret = STATE_RUN_SUCCESS;
907 if (!rdp_server_establish_keys(rdp, s))
911 "rdp_server_establish_keys() fail",
912 rdp_get_state_string(rdp));
913 ret = STATE_RUN_FAILED;
916 if (state_run_success(ret))
918 if (!rdp_server_transition_to_state(rdp, CONNECTION_STATE_SECURE_SETTINGS_EXCHANGE))
919 ret = STATE_RUN_FAILED;
920 else if (Stream_GetRemainingLength(s) > 0)
921 ret = STATE_RUN_CONTINUE;
925 case CONNECTION_STATE_SECURE_SETTINGS_EXCHANGE:
926 if (rdp_recv_client_info(rdp, s))
928 if (rdp_server_transition_to_state(
929 rdp, CONNECTION_STATE_CONNECT_TIME_AUTO_DETECT_REQUEST))
930 ret = STATE_RUN_CONTINUE;
934 case CONNECTION_STATE_CONNECT_TIME_AUTO_DETECT_REQUEST:
935 case CONNECTION_STATE_CONNECT_TIME_AUTO_DETECT_RESPONSE:
936 ret = peer_recv_handle_auto_detect(client, s);
939 case CONNECTION_STATE_LICENSING:
940 ret = peer_recv_handle_licensing(client, s);
941 if (ret == STATE_RUN_CONTINUE)
943 if (!rdp_server_transition_to_state(
944 rdp, CONNECTION_STATE_MULTITRANSPORT_BOOTSTRAPPING_REQUEST))
945 ret = STATE_RUN_FAILED;
949 case CONNECTION_STATE_MULTITRANSPORT_BOOTSTRAPPING_REQUEST:
950 if (settings->SupportMultitransport &&
951 ((settings->MultitransportFlags & INITIATE_REQUEST_PROTOCOL_UDPFECR) != 0))
954 ret = multitransport_server_request(rdp->multitransport,
955 INITIATE_REQUEST_PROTOCOL_UDPFECR);
958 case STATE_RUN_SUCCESS:
959 rdp_server_transition_to_state(
960 rdp, CONNECTION_STATE_MULTITRANSPORT_BOOTSTRAPPING_RESPONSE);
962 case STATE_RUN_CONTINUE:
964 rdp_server_transition_to_state(
965 rdp, CONNECTION_STATE_CAPABILITIES_EXCHANGE_DEMAND_ACTIVE);
973 if (rdp_server_transition_to_state(
974 rdp, CONNECTION_STATE_CAPABILITIES_EXCHANGE_DEMAND_ACTIVE))
975 ret = STATE_RUN_CONTINUE;
978 case CONNECTION_STATE_MULTITRANSPORT_BOOTSTRAPPING_RESPONSE:
979 ret = peer_recv_pdu(client, s);
982 case CONNECTION_STATE_CAPABILITIES_EXCHANGE_DEMAND_ACTIVE:
983 ret = rdp_peer_handle_state_demand_active(client);
986 case CONNECTION_STATE_CAPABILITIES_EXCHANGE_MONITOR_LAYOUT:
991 IFCALL(client->AdjustMonitorsLayout, client);
994 ret = STATE_RUN_SUCCESS;
1001 .width = WINPR_ASSERTING_INT_CAST(int32_t, w),
1002 .height = WINPR_ASSERTING_INT_CAST(int32_t, h),
1005 .attributes = { .physicalWidth = w,
1006 .physicalHeight = h,
1008 ORIENTATION_LANDSCAPE,
1009 .desktopScaleFactor = 100,
1010 .deviceScaleFactor = 100 } };
1011 if (!freerdp_settings_set_pointer_array(settings, FreeRDP_MonitorDefArray, 0,
1013 ret = STATE_RUN_FAILED;
1015 ret = STATE_RUN_FAILED;
1017 if (state_run_failed(ret))
1020 else if (!display_convert_rdp_monitor_to_monitor_def(
1021 settings->MonitorCount, settings->MonitorDefArray, &monitors))
1023 ret = STATE_RUN_FAILED;
1025 else if (!freerdp_display_send_monitor_layout(rdp->context, settings->MonitorCount,
1028 ret = STATE_RUN_FAILED;
1031 ret = STATE_RUN_SUCCESS;
1034 const size_t len = Stream_GetRemainingLength(s);
1035 if (!state_run_failed(ret) && (len > 0))
1036 ret = STATE_RUN_CONTINUE;
1040 const size_t len = Stream_GetRemainingLength(s);
1042 ret = STATE_RUN_CONTINUE;
1044 ret = STATE_RUN_SUCCESS;
1046 if (state_run_success(ret))
1048 if (!rdp_server_transition_to_state(
1049 rdp, CONNECTION_STATE_CAPABILITIES_EXCHANGE_CONFIRM_ACTIVE))
1050 ret = STATE_RUN_FAILED;
1054 case CONNECTION_STATE_CAPABILITIES_EXCHANGE_CONFIRM_ACTIVE:
1059 ret = peer_recv_pdu(client, s);
1062 case CONNECTION_STATE_FINALIZATION_SYNC:
1063 ret = peer_recv_pdu(client, s);
1064 if (rdp_finalize_is_flag_set(rdp, FINALIZE_CS_SYNCHRONIZE_PDU))
1066 if (!rdp_server_transition_to_state(rdp, CONNECTION_STATE_FINALIZATION_COOPERATE))
1067 ret = STATE_RUN_FAILED;
1070 ret = peer_unexpected_client_message(rdp, FINALIZE_CS_SYNCHRONIZE_PDU);
1072 case CONNECTION_STATE_FINALIZATION_COOPERATE:
1073 ret = peer_recv_pdu(client, s);
1074 if (rdp_finalize_is_flag_set(rdp, FINALIZE_CS_CONTROL_COOPERATE_PDU))
1076 if (!rdp_server_transition_to_state(rdp,
1077 CONNECTION_STATE_FINALIZATION_REQUEST_CONTROL))
1078 ret = STATE_RUN_FAILED;
1081 ret = peer_unexpected_client_message(rdp, FINALIZE_CS_CONTROL_COOPERATE_PDU);
1083 case CONNECTION_STATE_FINALIZATION_REQUEST_CONTROL:
1084 ret = peer_recv_pdu(client, s);
1085 if (rdp_finalize_is_flag_set(rdp, FINALIZE_CS_CONTROL_REQUEST_PDU))
1087 if (!rdp_send_server_control_granted_pdu(rdp))
1088 ret = STATE_RUN_FAILED;
1089 else if (!rdp_server_transition_to_state(
1090 rdp, CONNECTION_STATE_FINALIZATION_PERSISTENT_KEY_LIST))
1091 ret = STATE_RUN_FAILED;
1094 ret = peer_unexpected_client_message(rdp, FINALIZE_CS_CONTROL_REQUEST_PDU);
1096 case CONNECTION_STATE_FINALIZATION_PERSISTENT_KEY_LIST:
1098 !rdp_finalize_is_flag_set(rdp, FINALIZE_DEACTIVATE_REACTIVATE))
1100 ret = peer_recv_pdu(client, s);
1102 if (rdp_finalize_is_flag_set(rdp, FINALIZE_CS_PERSISTENT_KEY_LIST_PDU))
1104 if (!rdp_server_transition_to_state(rdp,
1105 CONNECTION_STATE_FINALIZATION_FONT_LIST))
1106 ret = STATE_RUN_FAILED;
1109 ret = peer_unexpected_client_message(rdp,
1110 CONNECTION_STATE_FINALIZATION_FONT_LIST);
1114 if (!rdp_server_transition_to_state(rdp, CONNECTION_STATE_FINALIZATION_FONT_LIST))
1115 ret = STATE_RUN_FAILED;
1117 ret = STATE_RUN_CONTINUE;
1120 case CONNECTION_STATE_FINALIZATION_FONT_LIST:
1121 ret = peer_recv_pdu(client, s);
1122 if (state_run_success(ret))
1124 if (rdp_finalize_is_flag_set(rdp, FINALIZE_CS_FONT_LIST_PDU))
1126 if (!rdp_server_transition_to_state(rdp, CONNECTION_STATE_ACTIVE))
1127 ret = STATE_RUN_FAILED;
1130 update_reset_state(rdp->update);
1131 ret = STATE_RUN_CONTINUE;
1135 ret = peer_unexpected_client_message(rdp, FINALIZE_CS_FONT_LIST_PDU);
1139 case CONNECTION_STATE_ACTIVE:
1140 ret = rdp_peer_handle_state_active(client);
1141 if (ret >= STATE_RUN_ACTIVE)
1142 ret = peer_recv_pdu(client, s);
1146 case CONNECTION_STATE_FINALIZATION_CLIENT_SYNC:
1147 case CONNECTION_STATE_FINALIZATION_CLIENT_COOPERATE:
1148 case CONNECTION_STATE_FINALIZATION_CLIENT_GRANTED_CONTROL:
1149 case CONNECTION_STATE_FINALIZATION_CLIENT_FONT_MAP:
1151 WLog_ERR(TAG,
"%s state %d", rdp_get_state_string(rdp), rdp_get_state(rdp));
1158static state_run_t peer_recv_callback(rdpTransport* transport,
wStream* s,
void* extra)
1160 char buffer[64] = { 0 };
1161 state_run_t rc = STATE_RUN_FAILED;
1162 const size_t start = Stream_GetPosition(s);
1163 const rdpContext* context = transport_get_context(transport);
1164 DWORD level = WLOG_TRACE;
1165 static wLog* log = NULL;
1167 log = WLog_Get(TAG);
1169 WINPR_ASSERT(context);
1172 const rdpRdp* rdp = context->rdp;
1173 const char* old = rdp_get_state_string(rdp);
1175 if (rc == STATE_RUN_TRY_AGAIN)
1176 Stream_SetPosition(s, start);
1177 rc = peer_recv_callback_internal(transport, s, extra);
1179 const size_t len = Stream_GetRemainingLength(s);
1180 if ((len > 0) && !state_run_continue(rc))
1182 WLog_Print(log, level,
1183 "(server)[%s -> %s] current return %s [%" PRIuz
" bytes not processed]", old,
1184 rdp_get_state_string(rdp), state_run_result_string(rc, buffer,
sizeof(buffer)),
1186 }
while (state_run_continue(rc));
1191static BOOL freerdp_peer_close(freerdp_peer* client)
1193 UINT32 SelectedProtocol = 0;
1194 rdpContext* context = NULL;
1196 WINPR_ASSERT(client);
1198 context = client->context;
1199 WINPR_ASSERT(context);
1200 WINPR_ASSERT(context->settings);
1201 WINPR_ASSERT(context->rdp);
1206 SelectedProtocol = nego_get_selected_protocol(context->rdp->nego);
1208 if (SelectedProtocol & PROTOCOL_FAILED_NEGO)
1216 if (!rdp_send_deactivate_all(context->rdp))
1221 rdp_send_error_info(context->rdp);
1224 return mcs_send_disconnect_provider_ultimatum(context->rdp->mcs,
1225 Disconnect_Ultimatum_provider_initiated);
1228static void freerdp_peer_disconnect(freerdp_peer* client)
1230 rdpTransport* transport = NULL;
1231 WINPR_ASSERT(client);
1233 transport = freerdp_get_transport(client->context);
1234 transport_disconnect(transport);
1237static BOOL freerdp_peer_send_channel_data(freerdp_peer* client, UINT16 channelId,
const BYTE* data,
1240 WINPR_ASSERT(client);
1241 WINPR_ASSERT(client->context);
1242 WINPR_ASSERT(client->context->rdp);
1243 return rdp_send_channel_data(client->context->rdp, channelId, data, size);
1246static BOOL freerdp_peer_send_server_redirection_pdu(freerdp_peer* peer,
1247 const rdpRedirection* redirection)
1251 WINPR_ASSERT(peer->context);
1253 UINT16 sec_flags = 0;
1254 wStream* s = rdp_send_stream_pdu_init(peer->context->rdp, &sec_flags);
1257 if (!rdp_write_enhanced_security_redirection_packet(s, redirection))
1259 if (!rdp_send_pdu(peer->context->rdp, s, PDU_TYPE_SERVER_REDIRECTION, 0, sec_flags))
1261 rc = rdp_reset_runtime_settings(peer->context->rdp);
1267static BOOL freerdp_peer_send_channel_packet(freerdp_peer* client, UINT16 channelId,
1268 size_t totalSize, UINT32 flags,
const BYTE* data,
1271 WINPR_ASSERT(client);
1272 WINPR_ASSERT(client->context);
1273 WINPR_ASSERT(client->context->rdp);
1274 return rdp_channel_send_packet(client->context->rdp, channelId, totalSize, flags, data,
1278static BOOL freerdp_peer_is_write_blocked(freerdp_peer* peer)
1280 rdpTransport* transport = NULL;
1282 WINPR_ASSERT(peer->context);
1283 WINPR_ASSERT(peer->context->rdp);
1284 WINPR_ASSERT(peer->context->rdp->transport);
1285 transport = peer->context->rdp->transport;
1286 return transport_is_write_blocked(transport);
1289static int freerdp_peer_drain_output_buffer(freerdp_peer* peer)
1291 rdpTransport* transport = NULL;
1293 WINPR_ASSERT(peer->context);
1294 WINPR_ASSERT(peer->context->rdp);
1295 WINPR_ASSERT(peer->context->rdp->transport);
1296 transport = peer->context->rdp->transport;
1297 return transport_drain_output_buffer(transport);
1300static BOOL freerdp_peer_has_more_to_read(freerdp_peer* peer)
1303 WINPR_ASSERT(peer->context);
1304 WINPR_ASSERT(peer->context->rdp);
1305 return transport_have_more_bytes_to_read(peer->context->rdp->transport);
1308static LicenseCallbackResult freerdp_peer_nolicense(freerdp_peer* peer,
1314 WINPR_ASSERT(peer->context);
1316 rdp = peer->context->rdp;
1318 if (!license_send_valid_client_error_packet(rdp))
1320 WLog_ERR(TAG,
"freerdp_peer_nolicense: license_send_valid_client_error_packet() failed");
1321 return LICENSE_CB_ABORT;
1324 return LICENSE_CB_COMPLETED;
1327BOOL freerdp_peer_context_new(freerdp_peer* client)
1329 return freerdp_peer_context_new_ex(client, NULL);
1332void freerdp_peer_context_free(freerdp_peer* client)
1337 IFCALL(client->ContextFree, client, client->context);
1339 if (client->context)
1341 rdpContext* ctx = client->context;
1343 (void)CloseHandle(ctx->channelErrorEvent);
1344 ctx->channelErrorEvent = NULL;
1345 free(ctx->errorDescription);
1346 ctx->errorDescription = NULL;
1349 metrics_free(ctx->metrics);
1350 ctx->metrics = NULL;
1351 stream_dump_free(ctx->dump);
1355 client->context = NULL;
1358static const char* os_major_type_to_string(UINT16 osMajorType)
1360 switch (osMajorType)
1362 case OSMAJORTYPE_UNSPECIFIED:
1363 return "Unspecified platform";
1364 case OSMAJORTYPE_WINDOWS:
1365 return "Windows platform";
1366 case OSMAJORTYPE_OS2:
1367 return "OS/2 platform";
1368 case OSMAJORTYPE_MACINTOSH:
1369 return "Macintosh platform";
1370 case OSMAJORTYPE_UNIX:
1371 return "UNIX platform";
1372 case OSMAJORTYPE_IOS:
1373 return "iOS platform";
1374 case OSMAJORTYPE_OSX:
1375 return "OS X platform";
1376 case OSMAJORTYPE_ANDROID:
1377 return "Android platform";
1378 case OSMAJORTYPE_CHROME_OS:
1379 return "Chrome OS platform";
1384 return "Unknown platform";
1387const char* freerdp_peer_os_major_type_string(freerdp_peer* client)
1389 WINPR_ASSERT(client);
1391 rdpContext* context = client->context;
1392 WINPR_ASSERT(context);
1393 WINPR_ASSERT(context->settings);
1396 WINPR_ASSERT(osMajorType <= UINT16_MAX);
1397 return os_major_type_to_string((UINT16)osMajorType);
1400static const char* os_minor_type_to_string(UINT16 osMinorType)
1402 switch (osMinorType)
1404 case OSMINORTYPE_UNSPECIFIED:
1405 return "Unspecified version";
1406 case OSMINORTYPE_WINDOWS_31X:
1407 return "Windows 3.1x";
1408 case OSMINORTYPE_WINDOWS_95:
1409 return "Windows 95";
1410 case OSMINORTYPE_WINDOWS_NT:
1411 return "Windows NT";
1412 case OSMINORTYPE_OS2_V21:
1414 case OSMINORTYPE_POWER_PC:
1416 case OSMINORTYPE_MACINTOSH:
1418 case OSMINORTYPE_NATIVE_XSERVER:
1419 return "Native X Server";
1420 case OSMINORTYPE_PSEUDO_XSERVER:
1421 return "Pseudo X Server";
1422 case OSMINORTYPE_WINDOWS_RT:
1423 return "Windows RT";
1428 return "Unknown version";
1431const char* freerdp_peer_os_minor_type_string(freerdp_peer* client)
1433 WINPR_ASSERT(client);
1435 rdpContext* context = client->context;
1436 WINPR_ASSERT(context);
1437 WINPR_ASSERT(context->settings);
1440 WINPR_ASSERT(osMinorType <= UINT16_MAX);
1441 return os_minor_type_to_string((UINT16)osMinorType);
1444freerdp_peer* freerdp_peer_new(
int sockfd)
1446 UINT32 option_value = 0;
1447 socklen_t option_len = 0;
1448 freerdp_peer* client = (freerdp_peer*)calloc(1,
sizeof(freerdp_peer));
1453 option_value = TRUE;
1454 option_len =
sizeof(option_value);
1458 if (setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, (
void*)&option_value, option_len) < 0)
1462 WLog_DBG(TAG,
"can't set TCP_NODELAY, continuing anyway");
1468 client->sockfd = sockfd;
1469 client->ContextSize =
sizeof(rdpContext);
1470 client->Initialize = freerdp_peer_initialize;
1471#if defined(WITH_FREERDP_DEPRECATED)
1472 client->GetFileDescriptor = freerdp_peer_get_fds;
1474 client->GetEventHandle = freerdp_peer_get_event_handle;
1475 client->GetEventHandles = freerdp_peer_get_event_handles;
1476 client->CheckFileDescriptor = freerdp_peer_check_fds;
1477 client->Close = freerdp_peer_close;
1478 client->Disconnect = freerdp_peer_disconnect;
1479 client->SendChannelData = freerdp_peer_send_channel_data;
1480 client->SendChannelPacket = freerdp_peer_send_channel_packet;
1481 client->SendServerRedirection = freerdp_peer_send_server_redirection_pdu;
1482 client->IsWriteBlocked = freerdp_peer_is_write_blocked;
1483 client->DrainOutputBuffer = freerdp_peer_drain_output_buffer;
1484 client->HasMoreToRead = freerdp_peer_has_more_to_read;
1485 client->VirtualChannelOpen = freerdp_peer_virtual_channel_open;
1486 client->VirtualChannelClose = freerdp_peer_virtual_channel_close;
1487 client->VirtualChannelWrite = freerdp_peer_virtual_channel_write;
1488 client->VirtualChannelRead = NULL;
1489 client->VirtualChannelGetData = freerdp_peer_virtual_channel_get_data;
1490 client->VirtualChannelSetData = freerdp_peer_virtual_channel_set_data;
1491 client->SetState = freerdp_peer_set_state;
1497void freerdp_peer_free(freerdp_peer* client)
1502 sspi_FreeAuthIdentity(&client->identity);
1503 if (client->sockfd >= 0)
1504 closesocket((SOCKET)client->sockfd);
1508static BOOL freerdp_peer_transport_setup(freerdp_peer* client)
1512 WINPR_ASSERT(client);
1513 WINPR_ASSERT(client->context);
1515 rdp = client->context->rdp;
1518 if (!transport_attach(rdp->transport, client->sockfd))
1520 client->sockfd = -1;
1522 if (!transport_set_recv_callbacks(rdp->transport, peer_recv_callback, client))
1525 if (!transport_set_blocking_mode(rdp->transport, FALSE))
1531BOOL freerdp_peer_context_new_ex(freerdp_peer* client,
const rdpSettings* settings)
1534 rdpContext* context = NULL;
1540 WINPR_ASSERT(client->ContextSize >=
sizeof(rdpContext));
1541 if (!(context = (rdpContext*)calloc(1, client->ContextSize)))
1544 client->context = context;
1545 context->peer = client;
1546 context->ServerMode = TRUE;
1547 context->log = WLog_Get(TAG);
1554 if (!context->settings)
1558 context->dump = stream_dump_new();
1561 if (!(context->metrics = metrics_new(context)))
1564 if (!(rdp = rdp_new(context)))
1567 rdp_log_build_warnings(rdp);
1569#if defined(WITH_FREERDP_DEPRECATED)
1570 client->update = rdp->update;
1571 client->settings = rdp->settings;
1572 client->autodetect = rdp->autodetect;
1575 context->input = rdp->input;
1576 context->update = rdp->update;
1577 context->settings = rdp->settings;
1578 context->autodetect = rdp->autodetect;
1579 update_register_server_callbacks(rdp->update);
1580 autodetect_register_server_callbacks(rdp->autodetect);
1582 if (!(context->channelErrorEvent = CreateEvent(NULL, TRUE, FALSE, NULL)))
1584 WLog_ERR(TAG,
"CreateEvent failed!");
1588 if (!(context->errorDescription = calloc(1, 500)))
1590 WLog_ERR(TAG,
"calloc failed!");
1594 if (!freerdp_peer_transport_setup(client))
1597 client->IsWriteBlocked = freerdp_peer_is_write_blocked;
1598 client->DrainOutputBuffer = freerdp_peer_drain_output_buffer;
1599 client->HasMoreToRead = freerdp_peer_has_more_to_read;
1600 client->LicenseCallback = freerdp_peer_nolicense;
1601 IFCALLRET(client->ContextNew, ret, client, client->context);
1608 WLog_ERR(TAG,
"ContextNew callback failed");
1609 freerdp_peer_context_free(client);
FREERDP_API UINT32 freerdp_settings_get_uint32(const rdpSettings *settings, FreeRDP_Settings_Keys_UInt32 id)
Returns a UINT32 settings value.
FREERDP_API BOOL freerdp_settings_get_bool(const rdpSettings *settings, FreeRDP_Settings_Keys_Bool id)
Returns a boolean settings value.
FREERDP_API rdpSettings * freerdp_settings_clone(const rdpSettings *settings)
Creates a deep copy of settings.
FREERDP_API const void * freerdp_settings_get_pointer(const rdpSettings *settings, FreeRDP_Settings_Keys_Pointer id)
Returns a immutable pointer settings value.
FREERDP_API BOOL freerdp_settings_set_uint32(rdpSettings *settings, FreeRDP_Settings_Keys_UInt32 id, UINT32 param)
Sets a UINT32 settings value.
FREERDP_API BOOL freerdp_settings_set_bool(rdpSettings *settings, FreeRDP_Settings_Keys_Bool id, BOOL param)
Sets a BOOL settings value.