FreeRDP
Loading...
Searching...
No Matches
peer.c
1
23#include <freerdp/config.h>
24
25#include "settings.h"
26
27#include <winpr/assert.h>
28#include <winpr/cast.h>
29#include <winpr/crt.h>
30#include <winpr/winsock.h>
31
32#include "info.h"
33#include "display.h"
34
35#include <freerdp/log.h>
36#include <freerdp/streamdump.h>
37#include <freerdp/redirection.h>
38#include <freerdp/crypto/certificate.h>
39
40#include "rdp.h"
41#include "peer.h"
42#include "multitransport.h"
43
44#define TAG FREERDP_TAG("core.peer")
45
46static state_run_t peer_recv_pdu(freerdp_peer* client, wStream* s);
47
48static HANDLE freerdp_peer_virtual_channel_open(freerdp_peer* client, const char* name,
49 UINT32 flags)
50{
51 UINT32 index = 0;
52 BOOL joined = FALSE;
53 rdpMcsChannel* mcsChannel = NULL;
54 rdpPeerChannel* peerChannel = NULL;
55 rdpMcs* mcs = NULL;
56
57 WINPR_ASSERT(client);
58 WINPR_ASSERT(client->context);
59 WINPR_ASSERT(client->context->rdp);
60 WINPR_ASSERT(name);
61 mcs = client->context->rdp->mcs;
62 WINPR_ASSERT(mcs);
63
64 if (flags & WTS_CHANNEL_OPTION_DYNAMIC)
65 return NULL; /* not yet supported */
66
67 const size_t length = strnlen(name, 9);
68
69 if (length > 8)
70 return NULL; /* SVC maximum name length is 8 */
71
72 for (; index < mcs->channelCount; index++)
73 {
74 mcsChannel = &(mcs->channels[index]);
75
76 if (!mcsChannel->joined)
77 continue;
78
79 if (_strnicmp(name, mcsChannel->Name, length) == 0)
80 {
81 joined = TRUE;
82 break;
83 }
84 }
85
86 if (!joined)
87 return NULL; /* channel is not joined */
88
89 peerChannel = (rdpPeerChannel*)mcsChannel->handle;
90
91 if (peerChannel)
92 {
93 /* channel is already open */
94 return (HANDLE)peerChannel;
95 }
96
97 WINPR_ASSERT(index <= UINT16_MAX);
98 peerChannel =
99 server_channel_common_new(client, (UINT16)index, mcsChannel->ChannelId, 128, NULL, name);
100
101 if (peerChannel)
102 {
103 peerChannel->channelFlags = flags;
104 peerChannel->mcsChannel = mcsChannel;
105 mcsChannel->handle = (void*)peerChannel;
106 }
107
108 return (HANDLE)peerChannel;
109}
110
111static BOOL freerdp_peer_virtual_channel_close(WINPR_ATTR_UNUSED freerdp_peer* client,
112 HANDLE hChannel)
113{
114 rdpMcsChannel* mcsChannel = NULL;
115 rdpPeerChannel* peerChannel = NULL;
116
117 WINPR_ASSERT(client);
118
119 if (!hChannel)
120 return FALSE;
121
122 peerChannel = (rdpPeerChannel*)hChannel;
123 mcsChannel = peerChannel->mcsChannel;
124 WINPR_ASSERT(mcsChannel);
125 mcsChannel->handle = NULL;
126 server_channel_common_free(peerChannel);
127 return TRUE;
128}
129
130static int freerdp_peer_virtual_channel_write(freerdp_peer* client, HANDLE hChannel,
131 const BYTE* buffer, UINT32 length)
132{
133 wStream* s = NULL;
134 UINT32 flags = 0;
135 UINT32 chunkSize = 0;
136 UINT32 maxChunkSize = 0;
137 UINT32 totalLength = 0;
138 rdpPeerChannel* peerChannel = NULL;
139 rdpMcsChannel* mcsChannel = NULL;
140 rdpRdp* rdp = NULL;
141
142 WINPR_ASSERT(client);
143 WINPR_ASSERT(client->context);
144
145 rdp = client->context->rdp;
146 WINPR_ASSERT(rdp);
147 WINPR_ASSERT(rdp->settings);
148
149 if (!hChannel)
150 return -1;
151
152 peerChannel = (rdpPeerChannel*)hChannel;
153 mcsChannel = peerChannel->mcsChannel;
154 WINPR_ASSERT(peerChannel);
155 WINPR_ASSERT(mcsChannel);
156 if (peerChannel->channelFlags & WTS_CHANNEL_OPTION_DYNAMIC)
157 return -1; /* not yet supported */
158
159 maxChunkSize = rdp->settings->VCChunkSize;
160 totalLength = length;
161 flags = CHANNEL_FLAG_FIRST;
162
163 while (length > 0)
164 {
165 UINT16 sec_flags = 0;
166 s = rdp_send_stream_init(rdp, &sec_flags);
167
168 if (!s)
169 return -1;
170
171 if (length > maxChunkSize)
172 {
173 chunkSize = rdp->settings->VCChunkSize;
174 }
175 else
176 {
177 chunkSize = length;
178 flags |= CHANNEL_FLAG_LAST;
179 }
180
181 if (mcsChannel->options & CHANNEL_OPTION_SHOW_PROTOCOL)
182 flags |= CHANNEL_FLAG_SHOW_PROTOCOL;
183
184 Stream_Write_UINT32(s, totalLength);
185 Stream_Write_UINT32(s, flags);
186
187 if (!Stream_EnsureRemainingCapacity(s, chunkSize))
188 {
189 Stream_Release(s);
190 return -1;
191 }
192
193 Stream_Write(s, buffer, chunkSize);
194
195 WINPR_ASSERT(peerChannel->channelId <= UINT16_MAX);
196 if (!rdp_send(rdp, s, (UINT16)peerChannel->channelId, sec_flags))
197 return -1;
198
199 buffer += chunkSize;
200 length -= chunkSize;
201 flags = 0;
202 }
203
204 return 1;
205}
206
207static void* freerdp_peer_virtual_channel_get_data(WINPR_ATTR_UNUSED freerdp_peer* client,
208 HANDLE hChannel)
209{
210 rdpPeerChannel* peerChannel = (rdpPeerChannel*)hChannel;
211
212 WINPR_ASSERT(client);
213 if (!hChannel)
214 return NULL;
215
216 return peerChannel->extra;
217}
218
219static int freerdp_peer_virtual_channel_set_data(WINPR_ATTR_UNUSED freerdp_peer* client,
220 HANDLE hChannel, void* data)
221{
222 rdpPeerChannel* peerChannel = (rdpPeerChannel*)hChannel;
223
224 WINPR_ASSERT(client);
225 if (!hChannel)
226 return -1;
227
228 peerChannel->extra = data;
229 return 1;
230}
231
232static BOOL freerdp_peer_set_state(freerdp_peer* client, CONNECTION_STATE state)
233{
234 WINPR_ASSERT(client);
235 WINPR_ASSERT(client->context);
236 return rdp_server_transition_to_state(client->context->rdp, state);
237}
238
239static BOOL freerdp_peer_initialize(freerdp_peer* client)
240{
241 rdpRdp* rdp = NULL;
242 rdpSettings* settings = NULL;
243
244 WINPR_ASSERT(client);
245 WINPR_ASSERT(client->context);
246
247 rdp = client->context->rdp;
248 WINPR_ASSERT(rdp);
249
250 settings = rdp->settings;
251 WINPR_ASSERT(settings);
252
253 settings->ServerMode = TRUE;
254 settings->FrameAcknowledge = 0;
255 settings->LocalConnection = client->local;
256
257 const rdpCertificate* cert =
258 freerdp_settings_get_pointer(settings, FreeRDP_RdpServerCertificate);
259 if (!cert)
260 {
261 WLog_ERR(TAG, "Missing server certificate, can not continue.");
262 return FALSE;
263 }
264
265 if (freerdp_settings_get_bool(settings, FreeRDP_RdpSecurity))
266 {
267
268 if (!freerdp_certificate_is_rdp_security_compatible(cert))
269 {
270 if (!freerdp_settings_set_bool(settings, FreeRDP_RdpSecurity, FALSE))
271 return FALSE;
272 if (!freerdp_settings_set_bool(settings, FreeRDP_UseRdpSecurityLayer, FALSE))
273 return FALSE;
274 }
275 }
276
277 nego_set_RCG_supported(rdp->nego, settings->RemoteCredentialGuard);
278 nego_set_restricted_admin_mode_supported(rdp->nego, settings->RestrictedAdminModeSupported);
279
280 if (!rdp_server_transition_to_state(rdp, CONNECTION_STATE_INITIAL))
281 return FALSE;
282
283 return TRUE;
284}
285
286#if defined(WITH_FREERDP_DEPRECATED)
287static BOOL freerdp_peer_get_fds(freerdp_peer* client, void** rfds, int* rcount)
288{
289 rdpTransport* transport = NULL;
290 WINPR_ASSERT(client);
291 WINPR_ASSERT(client->context);
292 WINPR_ASSERT(client->context->rdp);
293
294 transport = client->context->rdp->transport;
295 WINPR_ASSERT(transport);
296 transport_get_fds(transport, rfds, rcount);
297 return TRUE;
298}
299#endif
300
301static HANDLE freerdp_peer_get_event_handle(freerdp_peer* client)
302{
303 HANDLE hEvent = NULL;
304 rdpTransport* transport = NULL;
305 WINPR_ASSERT(client);
306 WINPR_ASSERT(client->context);
307 WINPR_ASSERT(client->context->rdp);
308
309 transport = client->context->rdp->transport;
310 hEvent = transport_get_front_bio(transport);
311 return hEvent;
312}
313
314static DWORD freerdp_peer_get_event_handles(freerdp_peer* client, HANDLE* events, DWORD count)
315{
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);
320}
321
322static BOOL freerdp_peer_check_fds(freerdp_peer* peer)
323{
324 int status = 0;
325 rdpRdp* rdp = NULL;
326
327 WINPR_ASSERT(peer);
328 WINPR_ASSERT(peer->context);
329
330 rdp = peer->context->rdp;
331 status = rdp_check_fds(rdp);
332
333 if (status < 0)
334 return FALSE;
335
336 return TRUE;
337}
338
339static state_run_t peer_recv_data_pdu(freerdp_peer* client, wStream* s,
340 WINPR_ATTR_UNUSED UINT16 totalLength)
341{
342 BYTE type = 0;
343 UINT16 length = 0;
344 UINT32 share_id = 0;
345 BYTE compressed_type = 0;
346 UINT16 compressed_len = 0;
347 rdpUpdate* update = NULL;
348
349 WINPR_ASSERT(s);
350 WINPR_ASSERT(client);
351 WINPR_ASSERT(client->context);
352 rdpRdp* rdp = client->context->rdp;
353 WINPR_ASSERT(rdp);
354 WINPR_ASSERT(rdp->mcs);
355
356 update = client->context->update;
357 WINPR_ASSERT(update);
358
359 if (!rdp_read_share_data_header(rdp, s, &length, &type, &share_id, &compressed_type,
360 &compressed_len))
361 return STATE_RUN_FAILED;
362
363#ifdef WITH_DEBUG_RDP
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);
366#endif
367
368 switch (type)
369 {
370 case DATA_PDU_TYPE_SYNCHRONIZE:
371 if (!rdp_recv_client_synchronize_pdu(rdp, s))
372 return STATE_RUN_FAILED;
373
374 break;
375
376 case DATA_PDU_TYPE_CONTROL:
377 if (!rdp_server_accept_client_control_pdu(rdp, s))
378 return STATE_RUN_FAILED;
379
380 break;
381
382 case DATA_PDU_TYPE_INPUT:
383 if (!input_recv(rdp->input, s))
384 return STATE_RUN_FAILED;
385
386 break;
387
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;
391 break;
392
393 case DATA_PDU_TYPE_FONT_LIST:
394 if (!rdp_server_accept_client_font_list_pdu(rdp, s))
395 return STATE_RUN_FAILED;
396
397 return STATE_RUN_CONTINUE; // State changed, trigger rerun
398
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;
404
405 case DATA_PDU_TYPE_FRAME_ACKNOWLEDGE:
406 if (!Stream_CheckAndLogRequiredLength(TAG, s, 4))
407 return STATE_RUN_FAILED;
408
409 Stream_Read_UINT32(s, client->ack_frame_id);
410 IFCALL(update->SurfaceFrameAcknowledge, update->context, client->ack_frame_id);
411 break;
412
413 case DATA_PDU_TYPE_REFRESH_RECT:
414 if (!update_read_refresh_rect(update, s))
415 return STATE_RUN_FAILED;
416
417 break;
418
419 case DATA_PDU_TYPE_SUPPRESS_OUTPUT:
420 if (!update_read_suppress_output(update, s))
421 return STATE_RUN_FAILED;
422
423 break;
424
425 default:
426 WLog_ERR(TAG, "Data PDU type %" PRIu8 "", type);
427 break;
428 }
429
430 return STATE_RUN_SUCCESS;
431}
432
433static state_run_t peer_recv_tpkt_pdu(freerdp_peer* client, wStream* s)
434{
435 state_run_t rc = STATE_RUN_SUCCESS;
436 UINT16 length = 0;
437 UINT16 pduType = 0;
438 UINT16 pduSource = 0;
439 UINT16 channelId = 0;
440 UINT16 securityFlags = 0;
441
442 WINPR_ASSERT(s);
443 WINPR_ASSERT(client);
444 WINPR_ASSERT(client->context);
445
446 rdpRdp* rdp = client->context->rdp;
447 WINPR_ASSERT(rdp);
448 WINPR_ASSERT(rdp->mcs);
449
450 rdpSettings* settings = client->context->settings;
451 WINPR_ASSERT(settings);
452
453 if (!rdp_read_header(rdp, s, &length, &channelId))
454 return STATE_RUN_FAILED;
455
456 rdp->inPackets++;
457 if (freerdp_shall_disconnect_context(rdp->context))
458 return STATE_RUN_SUCCESS;
459
460 if (rdp_get_state(rdp) <= CONNECTION_STATE_LICENSING)
461 {
462 return rdp_handle_message_channel(rdp, s, channelId, length);
463 }
464
465 if (!rdp_handle_optional_rdp_decryption(rdp, s, &length, &securityFlags))
466 return STATE_RUN_FAILED;
467
468 if (channelId == MCS_GLOBAL_CHANNEL_ID)
469 {
470 char buffer[256] = { 0 };
471 UINT16 pduLength = 0;
472 UINT16 remain = 0;
473 if (!rdp_read_share_control_header(rdp, s, &pduLength, &remain, &pduType, &pduSource))
474 return STATE_RUN_FAILED;
475
476 settings->PduSource = pduSource;
477
478 WLog_DBG(TAG, "Received %s", pdu_type_to_str(pduType, buffer, sizeof(buffer)));
479 switch (pduType)
480 {
481 case PDU_TYPE_DATA:
482 rc = peer_recv_data_pdu(client, s, pduLength);
483 break;
484
485 case PDU_TYPE_CONFIRM_ACTIVE:
486 if (!rdp_server_accept_confirm_active(rdp, s, pduLength))
487 return STATE_RUN_FAILED;
488
489 break;
490
491 case PDU_TYPE_FLOW_RESPONSE:
492 case PDU_TYPE_FLOW_STOP:
493 case PDU_TYPE_FLOW_TEST:
494 if (!Stream_SafeSeek(s, remain))
495 {
496 WLog_WARN(TAG, "Short PDU, need %" PRIu16 " bytes, got %" PRIuz, remain,
497 Stream_GetRemainingLength(s));
498 return STATE_RUN_FAILED;
499 }
500 break;
501
502 default:
503 WLog_ERR(TAG, "Client sent unknown pduType %" PRIu16 "", pduType);
504 return STATE_RUN_FAILED;
505 }
506 }
507 else if ((rdp->mcs->messageChannelId > 0) && (channelId == rdp->mcs->messageChannelId))
508 {
509 if (!settings->UseRdpSecurityLayer)
510 {
511 if (!rdp_read_security_header(rdp, s, &securityFlags, NULL))
512 return STATE_RUN_FAILED;
513 }
514
515 return rdp_recv_message_channel_pdu(rdp, s, securityFlags);
516 }
517 else
518 {
519 if (!freerdp_channel_peer_process(client, s, channelId))
520 return STATE_RUN_FAILED;
521 }
522 if (!tpkt_ensure_stream_consumed(rdp->log, s, length))
523 return STATE_RUN_FAILED;
524
525 return rc;
526}
527
528static state_run_t peer_recv_handle_auto_detect(freerdp_peer* client, wStream* s)
529{
530 state_run_t ret = STATE_RUN_FAILED;
531 rdpRdp* rdp = NULL;
532
533 WINPR_ASSERT(client);
534 WINPR_ASSERT(s);
535 WINPR_ASSERT(client->context);
536
537 rdp = client->context->rdp;
538 WINPR_ASSERT(rdp);
539
540 const rdpSettings* settings = client->context->settings;
541 WINPR_ASSERT(settings);
542
543 if (freerdp_settings_get_bool(settings, FreeRDP_NetworkAutoDetect))
544 {
545 switch (rdp_get_state(rdp))
546 {
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))
550 {
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;
556 break;
557 case FREERDP_AUTODETECT_STATE_COMPLETE:
558 ret = STATE_RUN_CONTINUE; /* Rerun in next state */
559 if (!rdp_server_transition_to_state(rdp, CONNECTION_STATE_LICENSING))
560 return STATE_RUN_FAILED;
561 break;
562 default:
563 break;
564 }
565 break;
566 case CONNECTION_STATE_CONNECT_TIME_AUTO_DETECT_RESPONSE:
567 ret = peer_recv_pdu(client, s);
568 if (state_run_success(ret))
569 {
570 autodetect_on_connect_time_auto_detect_progress(rdp->autodetect);
571 switch (autodetect_get_state(rdp->autodetect))
572 {
573 case FREERDP_AUTODETECT_STATE_REQUEST:
574 ret = STATE_RUN_SUCCESS;
575 break;
576 case FREERDP_AUTODETECT_STATE_COMPLETE:
577 ret = STATE_RUN_CONTINUE; /* Rerun in next state */
578 if (!rdp_server_transition_to_state(rdp, CONNECTION_STATE_LICENSING))
579 return STATE_RUN_FAILED;
580 break;
581 default:
582 break;
583 }
584 }
585 break;
586 default:
587 WINPR_ASSERT(FALSE);
588 break;
589 }
590 }
591 else
592 {
593 if (!rdp_server_transition_to_state(rdp, CONNECTION_STATE_LICENSING))
594 return STATE_RUN_FAILED;
595
596 ret = STATE_RUN_CONTINUE; /* Rerun in next state */
597 }
598
599 return ret;
600}
601
602static state_run_t peer_recv_handle_licensing(freerdp_peer* client, wStream* s)
603{
604 state_run_t ret = STATE_RUN_FAILED;
605 rdpRdp* rdp = NULL;
606 rdpSettings* settings = NULL;
607
608 WINPR_ASSERT(client);
609 WINPR_ASSERT(s);
610 WINPR_ASSERT(client->context);
611
612 rdp = client->context->rdp;
613 WINPR_ASSERT(rdp);
614
615 settings = rdp->settings;
616 WINPR_ASSERT(settings);
617
618 switch (license_get_state(rdp->license))
619 {
620 case LICENSE_STATE_INITIAL:
621 {
622 const BOOL required =
623 freerdp_settings_get_bool(settings, FreeRDP_ServerLicenseRequired);
624
625 if (required)
626 {
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;
631 else
632 ret = STATE_RUN_SUCCESS;
633 }
634 else
635 {
636 if (license_send_valid_client_error_packet(rdp))
637 ret = STATE_RUN_CONTINUE; /* Rerun in next state, might be capabilities */
638 }
639 }
640 break;
641 case LICENSE_STATE_COMPLETED:
642 ret = STATE_RUN_CONTINUE; /* Licensing completed, continue in next state */
643 break;
644 case LICENSE_STATE_ABORTED:
645 ret = STATE_RUN_FAILED;
646 break;
647 default:
648 ret = peer_recv_pdu(client, s);
649 break;
650 }
651
652 return ret;
653}
654
655static state_run_t peer_recv_fastpath_pdu(freerdp_peer* client, wStream* s)
656{
657 rdpRdp* rdp = NULL;
658 UINT16 length = 0;
659 BOOL rc = 0;
660 rdpFastPath* fastpath = NULL;
661
662 WINPR_ASSERT(s);
663 WINPR_ASSERT(client);
664 WINPR_ASSERT(client->context);
665
666 rdp = client->context->rdp;
667 WINPR_ASSERT(rdp);
668
669 fastpath = rdp->fastpath;
670 WINPR_ASSERT(fastpath);
671
672 rc = fastpath_read_header_rdp(fastpath, s, &length);
673
674 if (!rc || (length == 0))
675 {
676 WLog_ERR(TAG, "incorrect FastPath PDU header length %" PRIu16 "", length);
677 return STATE_RUN_FAILED;
678 }
679 if (!Stream_CheckAndLogRequiredLength(TAG, s, length))
680 return STATE_RUN_FAILED;
681
682 if (!fastpath_decrypt(fastpath, s, &length))
683 return STATE_RUN_FAILED;
684
685 rdp->inPackets++;
686
687 return fastpath_recv_inputs(fastpath, s);
688}
689
690state_run_t peer_recv_pdu(freerdp_peer* client, wStream* s)
691{
692 int rc = tpkt_verify_header(s);
693
694 if (rc > 0)
695 return peer_recv_tpkt_pdu(client, s);
696 else if (rc == 0)
697 return peer_recv_fastpath_pdu(client, s);
698 else
699 return STATE_RUN_FAILED;
700}
701
702static state_run_t peer_unexpected_client_message(rdpRdp* rdp, UINT32 flag)
703{
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; /* we ignore this as per spec input PDU are already allowed */
708}
709
710state_run_t rdp_peer_handle_state_demand_active(freerdp_peer* client)
711{
712 state_run_t ret = STATE_RUN_FAILED;
713
714 WINPR_ASSERT(client);
715 WINPR_ASSERT(client->context);
716
717 rdpRdp* rdp = client->context->rdp;
718 WINPR_ASSERT(rdp);
719
720 if (client->Capabilities && !client->Capabilities(client))
721 {
722 WLog_ERR(TAG, "[%s] freerdp_peer::Capabilities() callback failed",
723 rdp_get_state_string(rdp));
724 }
725 else if (!rdp_send_demand_active(rdp))
726 {
727 WLog_ERR(TAG, "[%s] rdp_send_demand_active() fail", rdp_get_state_string(rdp));
728 }
729 else
730 {
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;
735 }
736 return ret;
737}
738
745static state_run_t rdp_peer_handle_state_active(freerdp_peer* client)
746{
747 state_run_t ret = STATE_RUN_FAILED;
748
749 WINPR_ASSERT(client);
750 WINPR_ASSERT(client->context);
751
752 if (!client->connected)
753 {
758 IFCALLRET(client->PostConnect, client->connected, client);
759 }
760 if (!client->connected)
761 {
762 WLog_ERR(TAG, "PostConnect for peer %p failed", WINPR_CXX_COMPAT_CAST(const void*, client));
763 ret = STATE_RUN_FAILED;
764 }
765 else if (!client->activated)
766 {
767 BOOL activated = TRUE;
768
769 /* Set client->activated TRUE before calling the Activate callback.
770 * the Activate callback might reset the client->activated flag even if it returns success
771 * (e.g. deactivate/reactivate sequence) */
772 client->activated = TRUE;
773 IFCALLRET(client->Activate, activated, client);
774
775 if (!activated)
776 {
777 WLog_ERR(TAG, "Activate for peer %p failed",
778 WINPR_CXX_COMPAT_CAST(const void*, client));
779 ret = STATE_RUN_FAILED;
780 }
781 else
782 ret = STATE_RUN_SUCCESS;
783 }
784 else
785 ret = STATE_RUN_ACTIVE;
786 return ret;
787}
788
789static state_run_t peer_recv_callback_internal(WINPR_ATTR_UNUSED rdpTransport* transport,
790 wStream* s, void* extra)
791{
792 freerdp_peer* client = (freerdp_peer*)extra;
793 state_run_t ret = STATE_RUN_FAILED;
794
795 WINPR_ASSERT(transport);
796 WINPR_ASSERT(client);
797 WINPR_ASSERT(client->context);
798
799 rdpRdp* rdp = client->context->rdp;
800 WINPR_ASSERT(rdp);
801
802 rdpSettings* settings = client->context->settings;
803 WINPR_ASSERT(settings);
804
805 IFCALL(client->ReachedState, client, rdp_get_state(rdp));
806 switch (rdp_get_state(rdp))
807 {
808 case CONNECTION_STATE_INITIAL:
809 if (!freerdp_settings_enforce_consistency(settings))
810 ret = STATE_RUN_FAILED;
811 else if (rdp_server_transition_to_state(rdp, CONNECTION_STATE_NEGO))
812 ret = STATE_RUN_CONTINUE;
813 break;
814
815 case CONNECTION_STATE_NEGO:
816 if (!rdp_server_accept_nego(rdp, s))
817 {
818 WLog_ERR(TAG, "%s - rdp_server_accept_nego() fail", rdp_get_state_string(rdp));
819 }
820 else
821 {
822 const UINT32 SelectedProtocol = nego_get_selected_protocol(rdp->nego);
823
824 settings->RdstlsSecurity = (SelectedProtocol & PROTOCOL_RDSTLS) ? TRUE : FALSE;
825 settings->NlaSecurity = (SelectedProtocol & PROTOCOL_HYBRID) ? TRUE : FALSE;
826 settings->TlsSecurity = (SelectedProtocol & PROTOCOL_SSL) ? TRUE : FALSE;
827 settings->RdpSecurity = (SelectedProtocol == PROTOCOL_RDP) ? TRUE : FALSE;
828
829 client->authenticated = FALSE;
830 if (SelectedProtocol & PROTOCOL_HYBRID)
831 {
833 (SEC_WINNT_AUTH_IDENTITY_INFO*)nego_get_identity(rdp->nego);
834 if (sspi_CopyAuthIdentity(&client->identity, identity) >= 0)
835 {
836 client->authenticated =
837 IFCALLRESULT(TRUE, client->Logon, client, &client->identity, TRUE);
838 }
839 nego_free_nla(rdp->nego);
840 }
841 else
842 {
843 client->authenticated =
844 IFCALLRESULT(TRUE, client->Logon, client, &client->identity, FALSE);
845 }
846 if (!client->authenticated)
847 ret = STATE_RUN_FAILED;
848 else
849 {
850 if (rdp_server_transition_to_state(rdp, CONNECTION_STATE_MCS_CREATE_REQUEST))
851 ret = STATE_RUN_SUCCESS;
852 }
853 }
854 break;
855
856 case CONNECTION_STATE_NLA:
857 WINPR_ASSERT(FALSE); // TODO
858 break;
859
860 case CONNECTION_STATE_MCS_CREATE_REQUEST:
861 if (!rdp_server_accept_mcs_connect_initial(rdp, s))
862 {
863 WLog_ERR(TAG,
864 "%s - "
865 "rdp_server_accept_mcs_connect_initial() fail",
866 rdp_get_state_string(rdp));
867 }
868 else
869 ret = STATE_RUN_SUCCESS;
870
871 break;
872
873 case CONNECTION_STATE_MCS_ERECT_DOMAIN:
874 if (!rdp_server_accept_mcs_erect_domain_request(rdp, s))
875 {
876 WLog_ERR(TAG,
877 "%s - "
878 "rdp_server_accept_mcs_erect_domain_request() fail",
879 rdp_get_state_string(rdp));
880 }
881 else
882 ret = STATE_RUN_SUCCESS;
883
884 break;
885
886 case CONNECTION_STATE_MCS_ATTACH_USER:
887 if (!rdp_server_accept_mcs_attach_user_request(rdp, s))
888 {
889 WLog_ERR(TAG,
890 "%s - "
891 "rdp_server_accept_mcs_attach_user_request() fail",
892 rdp_get_state_string(rdp));
893 }
894 else
895 ret = STATE_RUN_SUCCESS;
896
897 break;
898
899 case CONNECTION_STATE_MCS_CHANNEL_JOIN_REQUEST:
900 if (!rdp_server_accept_mcs_channel_join_request(rdp, s))
901 {
902 WLog_ERR(TAG,
903 "%s - "
904 "rdp_server_accept_mcs_channel_join_request() fail",
905 rdp_get_state_string(rdp));
906 }
907 else
908 ret = STATE_RUN_SUCCESS;
909 break;
910
911 case CONNECTION_STATE_RDP_SECURITY_COMMENCEMENT:
912 ret = STATE_RUN_SUCCESS;
913
914 if (!rdp_server_establish_keys(rdp, s))
915 {
916 WLog_ERR(TAG,
917 "%s - "
918 "rdp_server_establish_keys() fail",
919 rdp_get_state_string(rdp));
920 ret = STATE_RUN_FAILED;
921 }
922
923 if (state_run_success(ret))
924 {
925 if (!rdp_server_transition_to_state(rdp, CONNECTION_STATE_SECURE_SETTINGS_EXCHANGE))
926 ret = STATE_RUN_FAILED;
927 else if (Stream_GetRemainingLength(s) > 0)
928 ret = STATE_RUN_CONTINUE; /* Rerun function */
929 }
930 break;
931
932 case CONNECTION_STATE_SECURE_SETTINGS_EXCHANGE:
933 if (rdp_recv_client_info(rdp, s))
934 {
935 if (rdp_server_transition_to_state(
936 rdp, CONNECTION_STATE_CONNECT_TIME_AUTO_DETECT_REQUEST))
937 ret = STATE_RUN_CONTINUE;
938 }
939 break;
940
941 case CONNECTION_STATE_CONNECT_TIME_AUTO_DETECT_REQUEST:
942 case CONNECTION_STATE_CONNECT_TIME_AUTO_DETECT_RESPONSE:
943 ret = peer_recv_handle_auto_detect(client, s);
944 break;
945
946 case CONNECTION_STATE_LICENSING:
947 ret = peer_recv_handle_licensing(client, s);
948 if (ret == STATE_RUN_CONTINUE)
949 {
950 if (!rdp_server_transition_to_state(
951 rdp, CONNECTION_STATE_MULTITRANSPORT_BOOTSTRAPPING_REQUEST))
952 ret = STATE_RUN_FAILED;
953 }
954 break;
955
956 case CONNECTION_STATE_MULTITRANSPORT_BOOTSTRAPPING_REQUEST:
957 if (settings->SupportMultitransport &&
958 ((settings->MultitransportFlags & INITIATE_REQUEST_PROTOCOL_UDPFECR) != 0))
959 {
960 /* only UDP reliable for now, nobody does lossy UDP (MS-RDPUDP only) these days */
961 ret = multitransport_server_request(rdp->multitransport,
962 INITIATE_REQUEST_PROTOCOL_UDPFECR);
963 switch (ret)
964 {
965 case STATE_RUN_SUCCESS:
966 rdp_server_transition_to_state(
967 rdp, CONNECTION_STATE_MULTITRANSPORT_BOOTSTRAPPING_RESPONSE);
968 break;
969 case STATE_RUN_CONTINUE:
970 /* mismatch on the supported kind of UDP transports */
971 rdp_server_transition_to_state(
972 rdp, CONNECTION_STATE_CAPABILITIES_EXCHANGE_DEMAND_ACTIVE);
973 break;
974 default:
975 break;
976 }
977 }
978 else
979 {
980 if (rdp_server_transition_to_state(
981 rdp, CONNECTION_STATE_CAPABILITIES_EXCHANGE_DEMAND_ACTIVE))
982 ret = STATE_RUN_CONTINUE; /* Rerun, initialize next state */
983 }
984 break;
985 case CONNECTION_STATE_MULTITRANSPORT_BOOTSTRAPPING_RESPONSE:
986 ret = peer_recv_pdu(client, s);
987 break;
988
989 case CONNECTION_STATE_CAPABILITIES_EXCHANGE_DEMAND_ACTIVE:
990 ret = rdp_peer_handle_state_demand_active(client);
991 break;
992
993 case CONNECTION_STATE_CAPABILITIES_EXCHANGE_MONITOR_LAYOUT:
994 if (freerdp_settings_get_bool(settings, FreeRDP_SupportMonitorLayoutPdu))
995 {
996 MONITOR_DEF* monitors = NULL;
997
998 IFCALL(client->AdjustMonitorsLayout, client);
999
1000 /* client supports the monitorLayout PDU, let's send him the monitors if any */
1001 ret = STATE_RUN_SUCCESS;
1002 if (freerdp_settings_get_uint32(settings, FreeRDP_MonitorCount) == 0)
1003 {
1004 const UINT32 w = freerdp_settings_get_uint32(settings, FreeRDP_DesktopWidth);
1005 const UINT32 h = freerdp_settings_get_uint32(settings, FreeRDP_DesktopHeight);
1006 const rdpMonitor primary = { .x = 0,
1007 .y = 0,
1008 .width = WINPR_ASSERTING_INT_CAST(int32_t, w),
1009 .height = WINPR_ASSERTING_INT_CAST(int32_t, h),
1010 .is_primary = TRUE,
1011 .orig_screen = 0,
1012 .attributes = { .physicalWidth = w,
1013 .physicalHeight = h,
1014 .orientation =
1015 ORIENTATION_LANDSCAPE,
1016 .desktopScaleFactor = 100,
1017 .deviceScaleFactor = 100 } };
1018 if (!freerdp_settings_set_pointer_array(settings, FreeRDP_MonitorDefArray, 0,
1019 &primary))
1020 ret = STATE_RUN_FAILED;
1021 else if (!freerdp_settings_set_uint32(settings, FreeRDP_MonitorCount, 1))
1022 ret = STATE_RUN_FAILED;
1023 }
1024 if (state_run_failed(ret))
1025 {
1026 }
1027 else if (!display_convert_rdp_monitor_to_monitor_def(
1028 settings->MonitorCount, settings->MonitorDefArray, &monitors))
1029 {
1030 ret = STATE_RUN_FAILED;
1031 }
1032 else if (!freerdp_display_send_monitor_layout(rdp->context, settings->MonitorCount,
1033 monitors))
1034 {
1035 ret = STATE_RUN_FAILED;
1036 }
1037 else
1038 ret = STATE_RUN_SUCCESS;
1039 free(monitors);
1040
1041 const size_t len = Stream_GetRemainingLength(s);
1042 if (!state_run_failed(ret) && (len > 0))
1043 ret = STATE_RUN_CONTINUE;
1044 }
1045 else
1046 {
1047 const size_t len = Stream_GetRemainingLength(s);
1048 if (len > 0)
1049 ret = STATE_RUN_CONTINUE;
1050 else
1051 ret = STATE_RUN_SUCCESS;
1052 }
1053 if (state_run_success(ret))
1054 {
1055 if (!rdp_server_transition_to_state(
1056 rdp, CONNECTION_STATE_CAPABILITIES_EXCHANGE_CONFIRM_ACTIVE))
1057 ret = STATE_RUN_FAILED;
1058 }
1059 break;
1060
1061 case CONNECTION_STATE_CAPABILITIES_EXCHANGE_CONFIRM_ACTIVE:
1066 ret = peer_recv_pdu(client, s);
1067 break;
1068
1069 case CONNECTION_STATE_FINALIZATION_SYNC:
1070 ret = peer_recv_pdu(client, s);
1071 if (rdp_finalize_is_flag_set(rdp, FINALIZE_CS_SYNCHRONIZE_PDU))
1072 {
1073 if (!rdp_server_transition_to_state(rdp, CONNECTION_STATE_FINALIZATION_COOPERATE))
1074 ret = STATE_RUN_FAILED;
1075 }
1076 else
1077 ret = peer_unexpected_client_message(rdp, FINALIZE_CS_SYNCHRONIZE_PDU);
1078 break;
1079 case CONNECTION_STATE_FINALIZATION_COOPERATE:
1080 ret = peer_recv_pdu(client, s);
1081 if (rdp_finalize_is_flag_set(rdp, FINALIZE_CS_CONTROL_COOPERATE_PDU))
1082 {
1083 if (!rdp_server_transition_to_state(rdp,
1084 CONNECTION_STATE_FINALIZATION_REQUEST_CONTROL))
1085 ret = STATE_RUN_FAILED;
1086 }
1087 else
1088 ret = peer_unexpected_client_message(rdp, FINALIZE_CS_CONTROL_COOPERATE_PDU);
1089 break;
1090 case CONNECTION_STATE_FINALIZATION_REQUEST_CONTROL:
1091 ret = peer_recv_pdu(client, s);
1092 if (rdp_finalize_is_flag_set(rdp, FINALIZE_CS_CONTROL_REQUEST_PDU))
1093 {
1094 if (!rdp_send_server_control_granted_pdu(rdp))
1095 ret = STATE_RUN_FAILED;
1096 else if (!rdp_server_transition_to_state(
1097 rdp, CONNECTION_STATE_FINALIZATION_PERSISTENT_KEY_LIST))
1098 ret = STATE_RUN_FAILED;
1099 }
1100 else
1101 ret = peer_unexpected_client_message(rdp, FINALIZE_CS_CONTROL_REQUEST_PDU);
1102 break;
1103 case CONNECTION_STATE_FINALIZATION_PERSISTENT_KEY_LIST:
1104 if (freerdp_settings_get_bool(settings, FreeRDP_BitmapCachePersistEnabled) &&
1105 !rdp_finalize_is_flag_set(rdp, FINALIZE_DEACTIVATE_REACTIVATE))
1106 {
1107 ret = peer_recv_pdu(client, s);
1108
1109 if (rdp_finalize_is_flag_set(rdp, FINALIZE_CS_PERSISTENT_KEY_LIST_PDU))
1110 {
1111 if (!rdp_server_transition_to_state(rdp,
1112 CONNECTION_STATE_FINALIZATION_FONT_LIST))
1113 ret = STATE_RUN_FAILED;
1114 }
1115 else
1116 ret = peer_unexpected_client_message(rdp,
1117 CONNECTION_STATE_FINALIZATION_FONT_LIST);
1118 }
1119 else
1120 {
1121 if (!rdp_server_transition_to_state(rdp, CONNECTION_STATE_FINALIZATION_FONT_LIST))
1122 ret = STATE_RUN_FAILED;
1123 else
1124 ret = STATE_RUN_CONTINUE;
1125 }
1126 break;
1127 case CONNECTION_STATE_FINALIZATION_FONT_LIST:
1128 ret = peer_recv_pdu(client, s);
1129 if (state_run_success(ret))
1130 {
1131 if (rdp_finalize_is_flag_set(rdp, FINALIZE_CS_FONT_LIST_PDU))
1132 {
1133 if (!rdp_server_transition_to_state(rdp, CONNECTION_STATE_ACTIVE))
1134 ret = STATE_RUN_FAILED;
1135 else
1136 {
1137 update_reset_state(rdp->update);
1138 ret = STATE_RUN_CONTINUE;
1139 }
1140 }
1141 else
1142 ret = peer_unexpected_client_message(rdp, FINALIZE_CS_FONT_LIST_PDU);
1143 }
1144 break;
1145
1146 case CONNECTION_STATE_ACTIVE:
1147 ret = rdp_peer_handle_state_active(client);
1148 if (ret >= STATE_RUN_ACTIVE)
1149 ret = peer_recv_pdu(client, s);
1150 break;
1151
1152 /* States that must not happen in server state machine */
1153 case CONNECTION_STATE_FINALIZATION_CLIENT_SYNC:
1154 case CONNECTION_STATE_FINALIZATION_CLIENT_COOPERATE:
1155 case CONNECTION_STATE_FINALIZATION_CLIENT_GRANTED_CONTROL:
1156 case CONNECTION_STATE_FINALIZATION_CLIENT_FONT_MAP:
1157 default:
1158 WLog_ERR(TAG, "%s state %" PRId32, rdp_get_state_string(rdp),
1159 WINPR_CXX_COMPAT_CAST(int32_t, rdp_get_state(rdp)));
1160 break;
1161 }
1162
1163 return ret;
1164}
1165
1166static state_run_t peer_recv_callback(rdpTransport* transport, wStream* s, void* extra)
1167{
1168 char buffer[64] = { 0 };
1169 state_run_t rc = STATE_RUN_FAILED;
1170 const size_t start = Stream_GetPosition(s);
1171 const rdpContext* context = transport_get_context(transport);
1172 DWORD level = WLOG_TRACE;
1173 static wLog* log = NULL;
1174 if (!log)
1175 log = WLog_Get(TAG);
1176
1177 WINPR_ASSERT(context);
1178 do
1179 {
1180 const rdpRdp* rdp = context->rdp;
1181 const char* old = rdp_get_state_string(rdp);
1182
1183 if (rc == STATE_RUN_TRY_AGAIN)
1184 Stream_SetPosition(s, start);
1185 rc = peer_recv_callback_internal(transport, s, extra);
1186
1187 const size_t len = Stream_GetRemainingLength(s);
1188 if ((len > 0) && !state_run_continue(rc))
1189 level = WLOG_WARN;
1190 WLog_Print(log, level,
1191 "(server)[%s -> %s] current return %s [%" PRIuz " bytes not processed]", old,
1192 rdp_get_state_string(rdp), state_run_result_string(rc, buffer, sizeof(buffer)),
1193 len);
1194 } while (state_run_continue(rc));
1195
1196 return rc;
1197}
1198
1199static BOOL freerdp_peer_close(freerdp_peer* client)
1200{
1201 UINT32 SelectedProtocol = 0;
1202 rdpContext* context = NULL;
1203
1204 WINPR_ASSERT(client);
1205
1206 context = client->context;
1207 WINPR_ASSERT(context);
1208 WINPR_ASSERT(context->settings);
1209 WINPR_ASSERT(context->rdp);
1210
1214 SelectedProtocol = nego_get_selected_protocol(context->rdp->nego);
1215
1216 if (SelectedProtocol & PROTOCOL_FAILED_NEGO)
1217 return TRUE;
1218
1224 if (!rdp_send_deactivate_all(context->rdp))
1225 return FALSE;
1226
1227 if (freerdp_settings_get_bool(context->settings, FreeRDP_SupportErrorInfoPdu))
1228 {
1229 rdp_send_error_info(context->rdp);
1230 }
1231
1232 return mcs_send_disconnect_provider_ultimatum(context->rdp->mcs,
1233 Disconnect_Ultimatum_provider_initiated);
1234}
1235
1236static void freerdp_peer_disconnect(freerdp_peer* client)
1237{
1238 rdpTransport* transport = NULL;
1239 WINPR_ASSERT(client);
1240
1241 transport = freerdp_get_transport(client->context);
1242 transport_disconnect(transport);
1243}
1244
1245static BOOL freerdp_peer_send_channel_data(freerdp_peer* client, UINT16 channelId, const BYTE* data,
1246 size_t size)
1247{
1248 WINPR_ASSERT(client);
1249 WINPR_ASSERT(client->context);
1250 WINPR_ASSERT(client->context->rdp);
1251 return rdp_send_channel_data(client->context->rdp, channelId, data, size);
1252}
1253
1254static BOOL freerdp_peer_send_server_redirection_pdu(freerdp_peer* peer,
1255 const rdpRedirection* redirection)
1256{
1257 BOOL rc = FALSE;
1258 WINPR_ASSERT(peer);
1259 WINPR_ASSERT(peer->context);
1260
1261 UINT16 sec_flags = 0;
1262 wStream* s = rdp_send_stream_pdu_init(peer->context->rdp, &sec_flags);
1263 if (!s)
1264 return FALSE;
1265 if (!rdp_write_enhanced_security_redirection_packet(s, redirection))
1266 goto fail;
1267 if (!rdp_send_pdu(peer->context->rdp, s, PDU_TYPE_SERVER_REDIRECTION, 0, sec_flags))
1268 goto fail;
1269 rc = rdp_reset_runtime_settings(peer->context->rdp);
1270fail:
1271 Stream_Release(s);
1272 return rc;
1273}
1274
1275static BOOL freerdp_peer_send_channel_packet(freerdp_peer* client, UINT16 channelId,
1276 size_t totalSize, UINT32 flags, const BYTE* data,
1277 size_t chunkSize)
1278{
1279 WINPR_ASSERT(client);
1280 WINPR_ASSERT(client->context);
1281 WINPR_ASSERT(client->context->rdp);
1282 return rdp_channel_send_packet(client->context->rdp, channelId, totalSize, flags, data,
1283 chunkSize);
1284}
1285
1286static BOOL freerdp_peer_is_write_blocked(freerdp_peer* peer)
1287{
1288 rdpTransport* transport = NULL;
1289 WINPR_ASSERT(peer);
1290 WINPR_ASSERT(peer->context);
1291 WINPR_ASSERT(peer->context->rdp);
1292 WINPR_ASSERT(peer->context->rdp->transport);
1293 transport = peer->context->rdp->transport;
1294 return transport_is_write_blocked(transport);
1295}
1296
1297static int freerdp_peer_drain_output_buffer(freerdp_peer* peer)
1298{
1299 rdpTransport* transport = NULL;
1300 WINPR_ASSERT(peer);
1301 WINPR_ASSERT(peer->context);
1302 WINPR_ASSERT(peer->context->rdp);
1303 WINPR_ASSERT(peer->context->rdp->transport);
1304 transport = peer->context->rdp->transport;
1305 return transport_drain_output_buffer(transport);
1306}
1307
1308static BOOL freerdp_peer_has_more_to_read(freerdp_peer* peer)
1309{
1310 WINPR_ASSERT(peer);
1311 WINPR_ASSERT(peer->context);
1312 WINPR_ASSERT(peer->context->rdp);
1313 return transport_have_more_bytes_to_read(peer->context->rdp->transport);
1314}
1315
1316static LicenseCallbackResult freerdp_peer_nolicense(freerdp_peer* peer,
1317 WINPR_ATTR_UNUSED wStream* s)
1318{
1319 rdpRdp* rdp = NULL;
1320
1321 WINPR_ASSERT(peer);
1322 WINPR_ASSERT(peer->context);
1323
1324 rdp = peer->context->rdp;
1325
1326 if (!license_send_valid_client_error_packet(rdp))
1327 {
1328 WLog_ERR(TAG, "freerdp_peer_nolicense: license_send_valid_client_error_packet() failed");
1329 return LICENSE_CB_ABORT;
1330 }
1331
1332 return LICENSE_CB_COMPLETED;
1333}
1334
1335BOOL freerdp_peer_context_new(freerdp_peer* client)
1336{
1337 return freerdp_peer_context_new_ex(client, NULL);
1338}
1339
1340void freerdp_peer_context_free(freerdp_peer* client)
1341{
1342 if (!client)
1343 return;
1344
1345 IFCALL(client->ContextFree, client, client->context);
1346
1347 if (client->context)
1348 {
1349 rdpContext* ctx = client->context;
1350
1351 (void)CloseHandle(ctx->channelErrorEvent);
1352 ctx->channelErrorEvent = NULL;
1353 free(ctx->errorDescription);
1354 ctx->errorDescription = NULL;
1355 rdp_free(ctx->rdp);
1356 ctx->rdp = NULL;
1357 metrics_free(ctx->metrics);
1358 ctx->metrics = NULL;
1359 stream_dump_free(ctx->dump);
1360 ctx->dump = NULL;
1361 free(ctx);
1362 }
1363 client->context = NULL;
1364}
1365
1366static const char* os_major_type_to_string(UINT16 osMajorType)
1367{
1368 switch (osMajorType)
1369 {
1370 case OSMAJORTYPE_UNSPECIFIED:
1371 return "Unspecified platform";
1372 case OSMAJORTYPE_WINDOWS:
1373 return "Windows platform";
1374 case OSMAJORTYPE_OS2:
1375 return "OS/2 platform";
1376 case OSMAJORTYPE_MACINTOSH:
1377 return "Macintosh platform";
1378 case OSMAJORTYPE_UNIX:
1379 return "UNIX platform";
1380 case OSMAJORTYPE_IOS:
1381 return "iOS platform";
1382 case OSMAJORTYPE_OSX:
1383 return "OS X platform";
1384 case OSMAJORTYPE_ANDROID:
1385 return "Android platform";
1386 case OSMAJORTYPE_CHROME_OS:
1387 return "Chrome OS platform";
1388 default:
1389 break;
1390 }
1391
1392 return "Unknown platform";
1393}
1394
1395const char* freerdp_peer_os_major_type_string(freerdp_peer* client)
1396{
1397 WINPR_ASSERT(client);
1398
1399 rdpContext* context = client->context;
1400 WINPR_ASSERT(context);
1401 WINPR_ASSERT(context->settings);
1402
1403 const UINT32 osMajorType = freerdp_settings_get_uint32(context->settings, FreeRDP_OsMajorType);
1404 WINPR_ASSERT(osMajorType <= UINT16_MAX);
1405 return os_major_type_to_string((UINT16)osMajorType);
1406}
1407
1408static const char* os_minor_type_to_string(UINT16 osMinorType)
1409{
1410 switch (osMinorType)
1411 {
1412 case OSMINORTYPE_UNSPECIFIED:
1413 return "Unspecified version";
1414 case OSMINORTYPE_WINDOWS_31X:
1415 return "Windows 3.1x";
1416 case OSMINORTYPE_WINDOWS_95:
1417 return "Windows 95";
1418 case OSMINORTYPE_WINDOWS_NT:
1419 return "Windows NT";
1420 case OSMINORTYPE_OS2_V21:
1421 return "OS/2 2.1";
1422 case OSMINORTYPE_POWER_PC:
1423 return "PowerPC";
1424 case OSMINORTYPE_MACINTOSH:
1425 return "Macintosh";
1426 case OSMINORTYPE_NATIVE_XSERVER:
1427 return "Native X Server";
1428 case OSMINORTYPE_PSEUDO_XSERVER:
1429 return "Pseudo X Server";
1430 case OSMINORTYPE_WINDOWS_RT:
1431 return "Windows RT";
1432 default:
1433 break;
1434 }
1435
1436 return "Unknown version";
1437}
1438
1439const char* freerdp_peer_os_minor_type_string(freerdp_peer* client)
1440{
1441 WINPR_ASSERT(client);
1442
1443 rdpContext* context = client->context;
1444 WINPR_ASSERT(context);
1445 WINPR_ASSERT(context->settings);
1446
1447 const UINT32 osMinorType = freerdp_settings_get_uint32(context->settings, FreeRDP_OsMinorType);
1448 WINPR_ASSERT(osMinorType <= UINT16_MAX);
1449 return os_minor_type_to_string((UINT16)osMinorType);
1450}
1451
1452freerdp_peer* freerdp_peer_new(int sockfd)
1453{
1454 freerdp_peer* client = (freerdp_peer*)calloc(1, sizeof(freerdp_peer));
1455
1456 if (!client)
1457 return NULL;
1458
1459 if (sockfd >= 0)
1460 {
1461 (void)freerdp_tcp_set_nodelay(WLog_Get(TAG), WLOG_DEBUG, sockfd);
1462 }
1463
1464 if (client)
1465 {
1466 client->sockfd = sockfd;
1467 client->ContextSize = sizeof(rdpContext);
1468 client->Initialize = freerdp_peer_initialize;
1469#if defined(WITH_FREERDP_DEPRECATED)
1470 client->GetFileDescriptor = freerdp_peer_get_fds;
1471#endif
1472 client->GetEventHandle = freerdp_peer_get_event_handle;
1473 client->GetEventHandles = freerdp_peer_get_event_handles;
1474 client->CheckFileDescriptor = freerdp_peer_check_fds;
1475 client->Close = freerdp_peer_close;
1476 client->Disconnect = freerdp_peer_disconnect;
1477 client->SendChannelData = freerdp_peer_send_channel_data;
1478 client->SendChannelPacket = freerdp_peer_send_channel_packet;
1479 client->SendServerRedirection = freerdp_peer_send_server_redirection_pdu;
1480 client->IsWriteBlocked = freerdp_peer_is_write_blocked;
1481 client->DrainOutputBuffer = freerdp_peer_drain_output_buffer;
1482 client->HasMoreToRead = freerdp_peer_has_more_to_read;
1483 client->VirtualChannelOpen = freerdp_peer_virtual_channel_open;
1484 client->VirtualChannelClose = freerdp_peer_virtual_channel_close;
1485 client->VirtualChannelWrite = freerdp_peer_virtual_channel_write;
1486 client->VirtualChannelRead = NULL; /* must be defined by server application */
1487 client->VirtualChannelGetData = freerdp_peer_virtual_channel_get_data;
1488 client->VirtualChannelSetData = freerdp_peer_virtual_channel_set_data;
1489 client->SetState = freerdp_peer_set_state;
1490 }
1491
1492 return client;
1493}
1494
1495void freerdp_peer_free(freerdp_peer* client)
1496{
1497 if (!client)
1498 return;
1499
1500 sspi_FreeAuthIdentity(&client->identity);
1501 if (client->sockfd >= 0)
1502 closesocket((SOCKET)client->sockfd);
1503 free(client);
1504}
1505
1506static BOOL freerdp_peer_transport_setup(freerdp_peer* client)
1507{
1508 rdpRdp* rdp = NULL;
1509
1510 WINPR_ASSERT(client);
1511 WINPR_ASSERT(client->context);
1512
1513 rdp = client->context->rdp;
1514 WINPR_ASSERT(rdp);
1515
1516 if (!transport_attach(rdp->transport, client->sockfd))
1517 return FALSE;
1518 client->sockfd = -1;
1519
1520 if (!transport_set_recv_callbacks(rdp->transport, peer_recv_callback, client))
1521 return FALSE;
1522
1523 if (!transport_set_blocking_mode(rdp->transport, FALSE))
1524 return FALSE;
1525
1526 return TRUE;
1527}
1528
1529BOOL freerdp_peer_context_new_ex(freerdp_peer* client, const rdpSettings* settings)
1530{
1531 rdpRdp* rdp = NULL;
1532 rdpContext* context = NULL;
1533 BOOL ret = TRUE;
1534
1535 if (!client)
1536 return FALSE;
1537
1538 WINPR_ASSERT(client->ContextSize >= sizeof(rdpContext));
1539 if (!(context = (rdpContext*)calloc(1, client->ContextSize)))
1540 goto fail;
1541
1542 client->context = context;
1543 context->peer = client;
1544 context->ServerMode = TRUE;
1545 context->log = WLog_Get(TAG);
1546 if (!context->log)
1547 goto fail;
1548
1549 if (settings)
1550 {
1551 context->settings = freerdp_settings_clone(settings);
1552 if (!context->settings)
1553 goto fail;
1554 }
1555
1556 context->dump = stream_dump_new();
1557 if (!context->dump)
1558 goto fail;
1559 if (!(context->metrics = metrics_new(context)))
1560 goto fail;
1561
1562 if (!(rdp = rdp_new(context)))
1563 goto fail;
1564
1565 rdp_log_build_warnings(rdp);
1566
1567#if defined(WITH_FREERDP_DEPRECATED)
1568 client->update = rdp->update;
1569 client->settings = rdp->settings;
1570 client->autodetect = rdp->autodetect;
1571#endif
1572 context->rdp = rdp;
1573 context->input = rdp->input;
1574 context->update = rdp->update;
1575 context->settings = rdp->settings;
1576 context->autodetect = rdp->autodetect;
1577 update_register_server_callbacks(rdp->update);
1578 autodetect_register_server_callbacks(rdp->autodetect);
1579
1580 if (!(context->channelErrorEvent = CreateEvent(NULL, TRUE, FALSE, NULL)))
1581 {
1582 WLog_ERR(TAG, "CreateEvent failed!");
1583 goto fail;
1584 }
1585
1586 if (!(context->errorDescription = calloc(1, 500)))
1587 {
1588 WLog_ERR(TAG, "calloc failed!");
1589 goto fail;
1590 }
1591
1592 if (!freerdp_peer_transport_setup(client))
1593 goto fail;
1594
1595 client->IsWriteBlocked = freerdp_peer_is_write_blocked;
1596 client->DrainOutputBuffer = freerdp_peer_drain_output_buffer;
1597 client->HasMoreToRead = freerdp_peer_has_more_to_read;
1598 client->LicenseCallback = freerdp_peer_nolicense;
1599 IFCALLRET(client->ContextNew, ret, client, client->context);
1600
1601 if (!ret)
1602 goto fail;
1603 return TRUE;
1604
1605fail:
1606 WLog_ERR(TAG, "ContextNew callback failed");
1607 freerdp_peer_context_free(client);
1608 return FALSE;
1609}
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 rdpSettings * freerdp_settings_clone(const rdpSettings *settings)
Creates a deep copy of settings.
WINPR_ATTR_NODISCARD 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_set_uint32(rdpSettings *settings, FreeRDP_Settings_Keys_UInt32 id, UINT32 param)
Sets 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.
FREERDP_API BOOL freerdp_settings_set_bool(rdpSettings *settings, FreeRDP_Settings_Keys_Bool id, BOOL param)
Sets a BOOL settings value.