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