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