FreeRDP
transport.c
1 
20 #include <freerdp/config.h>
21 
22 #include "settings.h"
23 
24 #include <winpr/assert.h>
25 
26 #include <winpr/crt.h>
27 #include <winpr/synch.h>
28 #include <winpr/print.h>
29 #include <winpr/stream.h>
30 #include <winpr/winsock.h>
31 #include <winpr/crypto.h>
32 
33 #include <freerdp/log.h>
34 #include <freerdp/error.h>
35 #include <freerdp/utils/ringbuffer.h>
36 
37 #include <openssl/bio.h>
38 #include <time.h>
39 #include <errno.h>
40 #include <fcntl.h>
41 
42 #ifndef _WIN32
43 #include <netdb.h>
44 #include <sys/socket.h>
45 #endif /* _WIN32 */
46 
47 #ifdef FREERDP_HAVE_VALGRIND_MEMCHECK_H
48 #include <valgrind/memcheck.h>
49 #endif
50 
51 #include "tpkt.h"
52 #include "fastpath.h"
53 #include "transport.h"
54 #include "rdp.h"
55 #include "proxy.h"
56 #include "utils.h"
57 #include "state.h"
58 #include "childsession.h"
59 
60 #include "gateway/rdg.h"
61 #include "gateway/wst.h"
62 #include "gateway/arm.h"
63 
64 #define TAG FREERDP_TAG("core.transport")
65 
66 #define BUFFER_SIZE 16384
67 
68 struct rdp_transport
69 {
70  TRANSPORT_LAYER layer;
71  BIO* frontBio;
72  rdpRdg* rdg;
73  rdpTsg* tsg;
74  rdpWst* wst;
75  rdpTls* tls;
76  rdpContext* context;
77  rdpNla* nla;
78  void* ReceiveExtra;
79  wStream* ReceiveBuffer;
80  TransportRecv ReceiveCallback;
81  wStreamPool* ReceivePool;
82  HANDLE connectedEvent;
83  BOOL NlaMode;
84  BOOL RdstlsMode;
85  BOOL AadMode;
86  BOOL blocking;
87  BOOL GatewayEnabled;
88  CRITICAL_SECTION ReadLock;
89  CRITICAL_SECTION WriteLock;
90  ULONG written;
91  HANDLE rereadEvent;
92  BOOL haveMoreBytesToRead;
93  wLog* log;
94  rdpTransportIo io;
95  HANDLE ioEvent;
96  BOOL useIoEvent;
97  BOOL earlyUserAuth;
98 };
99 
100 static void transport_ssl_cb(const SSL* ssl, int where, int ret)
101 {
102  if (where & SSL_CB_ALERT)
103  {
104  rdpTransport* transport = (rdpTransport*)SSL_get_app_data(ssl);
105  WINPR_ASSERT(transport);
106 
107  switch (ret)
108  {
109  case (SSL3_AL_FATAL << 8) | SSL_AD_ACCESS_DENIED:
110  {
111  if (!freerdp_get_last_error(transport_get_context(transport)))
112  {
113  WLog_Print(transport->log, WLOG_ERROR, "ACCESS DENIED");
114  freerdp_set_last_error_log(transport_get_context(transport),
115  FREERDP_ERROR_AUTHENTICATION_FAILED);
116  }
117  }
118  break;
119 
120  case (SSL3_AL_FATAL << 8) | SSL_AD_INTERNAL_ERROR:
121  {
122  if (transport->NlaMode)
123  {
124  if (!freerdp_get_last_error(transport_get_context(transport)))
125  {
126  UINT32 kret = 0;
127  if (transport->nla)
128  kret = nla_get_error(transport->nla);
129  if (kret == 0)
130  kret = FREERDP_ERROR_CONNECT_PASSWORD_CERTAINLY_EXPIRED;
131  freerdp_set_last_error_log(transport_get_context(transport), kret);
132  }
133  }
134 
135  break;
136 
137  case (SSL3_AL_WARNING << 8) | SSL3_AD_CLOSE_NOTIFY:
138  break;
139 
140  default:
141  WLog_Print(transport->log, WLOG_WARN,
142  "Unhandled SSL error (where=%d, ret=%d [%s, %s])", where, ret,
143  SSL_alert_type_string_long(ret), SSL_alert_desc_string_long(ret));
144  break;
145  }
146  }
147  }
148 }
149 
150 wStream* transport_send_stream_init(rdpTransport* transport, size_t size)
151 {
152  wStream* s = NULL;
153  WINPR_ASSERT(transport);
154 
155  if (!(s = StreamPool_Take(transport->ReceivePool, size)))
156  return NULL;
157 
158  if (!Stream_EnsureCapacity(s, size))
159  {
160  Stream_Release(s);
161  return NULL;
162  }
163 
164  Stream_SetPosition(s, 0);
165  return s;
166 }
167 
168 BOOL transport_attach(rdpTransport* transport, int sockfd)
169 {
170  if (!transport)
171  return FALSE;
172  return IFCALLRESULT(FALSE, transport->io.TransportAttach, transport, sockfd);
173 }
174 
175 static BOOL transport_default_attach(rdpTransport* transport, int sockfd)
176 {
177  BIO* socketBio = NULL;
178  BIO* bufferedBio = NULL;
179  const rdpSettings* settings = NULL;
180  rdpContext* context = transport_get_context(transport);
181 
182  if (sockfd < 0)
183  {
184  WLog_WARN(TAG, "Running peer without socket (sockfd=%d)", sockfd);
185  return TRUE;
186  }
187 
188  settings = context->settings;
189  WINPR_ASSERT(settings);
190 
191  if (sockfd >= 0)
192  {
193  if (!freerdp_tcp_set_keep_alive_mode(settings, sockfd))
194  goto fail;
195 
196  socketBio = BIO_new(BIO_s_simple_socket());
197 
198  if (!socketBio)
199  goto fail;
200  }
201 
202  bufferedBio = BIO_new(BIO_s_buffered_socket());
203  if (!bufferedBio)
204  goto fail;
205 
206  if (socketBio)
207  {
208  bufferedBio = BIO_push(bufferedBio, socketBio);
209  if (!bufferedBio)
210  goto fail;
211 
212  /* Attach the socket only when this function can no longer fail.
213  * This ensures solid ownership:
214  * - if this function fails, the caller is responsible to clean up
215  * - if this function is successful, the caller MUST NOT close the socket any more.
216  */
217  BIO_set_fd(socketBio, sockfd, BIO_CLOSE);
218  }
219  transport->frontBio = bufferedBio;
220  return TRUE;
221 fail:
222 
223  if (socketBio)
224  BIO_free_all(socketBio);
225  else
226  closesocket(sockfd);
227 
228  return FALSE;
229 }
230 
231 BOOL transport_connect_rdp(rdpTransport* transport)
232 {
233  if (!transport)
234  return FALSE;
235 
236  switch (utils_authenticate(transport_get_context(transport)->instance, AUTH_RDP, FALSE))
237  {
238  case AUTH_SKIP:
239  case AUTH_SUCCESS:
240  case AUTH_NO_CREDENTIALS:
241  return TRUE;
242  case AUTH_CANCELLED:
243  freerdp_set_last_error_if_not(transport_get_context(transport),
244  FREERDP_ERROR_CONNECT_CANCELLED);
245  return FALSE;
246  default:
247  return FALSE;
248  }
249 }
250 
251 BOOL transport_connect_tls(rdpTransport* transport)
252 {
253  const rdpSettings* settings = NULL;
254  rdpContext* context = transport_get_context(transport);
255 
256  settings = context->settings;
257  WINPR_ASSERT(settings);
258 
259  /* Only prompt for password if we use TLS (NLA also calls this function) */
260  if (settings->SelectedProtocol == PROTOCOL_SSL)
261  {
262  switch (utils_authenticate(context->instance, AUTH_TLS, FALSE))
263  {
264  case AUTH_SKIP:
265  case AUTH_SUCCESS:
266  case AUTH_NO_CREDENTIALS:
267  break;
268  case AUTH_CANCELLED:
269  freerdp_set_last_error_if_not(context, FREERDP_ERROR_CONNECT_CANCELLED);
270  return FALSE;
271  default:
272  return FALSE;
273  }
274  }
275 
276  return IFCALLRESULT(FALSE, transport->io.TLSConnect, transport);
277 }
278 
279 static BOOL transport_default_connect_tls(rdpTransport* transport)
280 {
281  int tlsStatus = 0;
282  rdpTls* tls = NULL;
283  rdpContext* context = NULL;
284  rdpSettings* settings = NULL;
285 
286  WINPR_ASSERT(transport);
287 
288  context = transport_get_context(transport);
289  WINPR_ASSERT(context);
290 
291  settings = context->settings;
292  WINPR_ASSERT(settings);
293 
294  if (!(tls = freerdp_tls_new(context)))
295  return FALSE;
296 
297  transport->tls = tls;
298 
299  if (transport->GatewayEnabled)
300  transport->layer = TRANSPORT_LAYER_TSG_TLS;
301  else
302  transport->layer = TRANSPORT_LAYER_TLS;
303 
304  tls->hostname = settings->ServerHostname;
305  tls->serverName = settings->UserSpecifiedServerName;
306  tls->port = MIN(UINT16_MAX, settings->ServerPort);
307 
308  if (tls->port == 0)
309  tls->port = 3389;
310 
311  tls->isGatewayTransport = FALSE;
312  tlsStatus = freerdp_tls_connect(tls, transport->frontBio);
313 
314  if (tlsStatus < 1)
315  {
316  if (tlsStatus < 0)
317  {
318  freerdp_set_last_error_if_not(context, FREERDP_ERROR_TLS_CONNECT_FAILED);
319  }
320  else
321  {
322  freerdp_set_last_error_if_not(context, FREERDP_ERROR_CONNECT_CANCELLED);
323  }
324 
325  return FALSE;
326  }
327 
328  transport->frontBio = tls->bio;
329 
330  /* See libfreerdp/crypto/tls.c transport_default_connect_tls
331  *
332  * we are wrapping a SSL object in the BIO and actually want to set
333  *
334  * SSL_set_info_callback there. So ensure our callback is of appropriate
335  * type for that instead of what the function prototype suggests.
336  */
337  typedef void (*ssl_cb_t)(const SSL* ssl, int type, int val);
338  ssl_cb_t fkt = transport_ssl_cb;
339 
340  BIO_info_cb* bfkt = WINPR_FUNC_PTR_CAST(fkt, BIO_info_cb*);
341  BIO_callback_ctrl(tls->bio, BIO_CTRL_SET_CALLBACK, bfkt);
342  SSL_set_app_data(tls->ssl, transport);
343 
344  if (!transport->frontBio)
345  {
346  WLog_Print(transport->log, WLOG_ERROR, "unable to prepend a filtering TLS bio");
347  return FALSE;
348  }
349 
350  return TRUE;
351 }
352 
353 BOOL transport_connect_nla(rdpTransport* transport, BOOL earlyUserAuth)
354 {
355  rdpContext* context = NULL;
356  rdpSettings* settings = NULL;
357  rdpRdp* rdp = NULL;
358  if (!transport)
359  return FALSE;
360 
361  context = transport_get_context(transport);
362  WINPR_ASSERT(context);
363 
364  settings = context->settings;
365  WINPR_ASSERT(settings);
366 
367  rdp = context->rdp;
368  WINPR_ASSERT(rdp);
369 
370  if (!transport_connect_tls(transport))
371  return FALSE;
372 
373  if (!settings->Authentication)
374  return TRUE;
375 
376  nla_free(rdp->nla);
377  rdp->nla = nla_new(context, transport);
378 
379  if (!rdp->nla)
380  return FALSE;
381 
382  nla_set_early_user_auth(rdp->nla, earlyUserAuth);
383 
384  transport_set_nla_mode(transport, TRUE);
385 
386  if (settings->AuthenticationServiceClass)
387  {
388  if (!nla_set_service_principal(rdp->nla, settings->AuthenticationServiceClass,
390  return FALSE;
391  }
392 
393  if (nla_client_begin(rdp->nla) < 0)
394  {
395  WLog_Print(transport->log, WLOG_ERROR, "NLA begin failed");
396 
397  freerdp_set_last_error_if_not(context, FREERDP_ERROR_AUTHENTICATION_FAILED);
398 
399  transport_set_nla_mode(transport, FALSE);
400  return FALSE;
401  }
402 
403  return rdp_client_transition_to_state(rdp, CONNECTION_STATE_NLA);
404 }
405 
406 BOOL transport_connect_rdstls(rdpTransport* transport)
407 {
408  BOOL rc = FALSE;
409  rdpRdstls* rdstls = NULL;
410  rdpContext* context = NULL;
411 
412  WINPR_ASSERT(transport);
413 
414  context = transport_get_context(transport);
415  WINPR_ASSERT(context);
416 
417  if (!transport_connect_tls(transport))
418  goto fail;
419 
420  rdstls = rdstls_new(context, transport);
421  if (!rdstls)
422  goto fail;
423 
424  transport_set_rdstls_mode(transport, TRUE);
425 
426  if (rdstls_authenticate(rdstls) < 0)
427  {
428  WLog_Print(transport->log, WLOG_ERROR, "RDSTLS authentication failed");
429  freerdp_set_last_error_if_not(context, FREERDP_ERROR_AUTHENTICATION_FAILED);
430  goto fail;
431  }
432 
433  transport_set_rdstls_mode(transport, FALSE);
434  rc = TRUE;
435 fail:
436  rdstls_free(rdstls);
437  return rc;
438 }
439 
440 BOOL transport_connect_aad(rdpTransport* transport)
441 {
442  rdpContext* context = NULL;
443  rdpSettings* settings = NULL;
444  rdpRdp* rdp = NULL;
445  if (!transport)
446  return FALSE;
447 
448  context = transport_get_context(transport);
449  WINPR_ASSERT(context);
450 
451  settings = context->settings;
452  WINPR_ASSERT(settings);
453 
454  rdp = context->rdp;
455  WINPR_ASSERT(rdp);
456 
457  if (!transport_connect_tls(transport))
458  return FALSE;
459 
460  if (!settings->Authentication)
461  return TRUE;
462 
463  if (!rdp->aad)
464  return FALSE;
465 
466  transport_set_aad_mode(transport, TRUE);
467 
468  if (aad_client_begin(rdp->aad) < 0)
469  {
470  WLog_Print(transport->log, WLOG_ERROR, "AAD begin failed");
471 
472  freerdp_set_last_error_if_not(context, FREERDP_ERROR_AUTHENTICATION_FAILED);
473 
474  transport_set_aad_mode(transport, FALSE);
475  return FALSE;
476  }
477 
478  return rdp_client_transition_to_state(rdp, CONNECTION_STATE_AAD);
479 }
480 
481 BOOL transport_connect(rdpTransport* transport, const char* hostname, UINT16 port, DWORD timeout)
482 {
483  BOOL status = FALSE;
484  rdpSettings* settings = NULL;
485  rdpContext* context = transport_get_context(transport);
486  BOOL rpcFallback = 0;
487 
488  WINPR_ASSERT(context);
489  WINPR_ASSERT(hostname);
490 
491  settings = context->settings;
492  WINPR_ASSERT(settings);
493 
494  rpcFallback = !settings->GatewayHttpTransport;
495 
496  if (transport->GatewayEnabled)
497  {
498  if (settings->GatewayUrl)
499  {
500  WINPR_ASSERT(!transport->wst);
501  transport->wst = wst_new(context);
502 
503  if (!transport->wst)
504  return FALSE;
505 
506  status = wst_connect(transport->wst, timeout);
507 
508  if (status)
509  {
510  transport->frontBio = wst_get_front_bio_and_take_ownership(transport->wst);
511  WINPR_ASSERT(transport->frontBio);
512  BIO_set_nonblock(transport->frontBio, 0);
513  transport->layer = TRANSPORT_LAYER_TSG;
514  status = TRUE;
515  }
516  else
517  {
518  wst_free(transport->wst);
519  transport->wst = NULL;
520  }
521  }
522  if (!status && settings->GatewayHttpTransport)
523  {
524  WINPR_ASSERT(!transport->rdg);
525  transport->rdg = rdg_new(context);
526 
527  if (!transport->rdg)
528  return FALSE;
529 
530  status = rdg_connect(transport->rdg, timeout, &rpcFallback);
531 
532  if (status)
533  {
534  transport->frontBio = rdg_get_front_bio_and_take_ownership(transport->rdg);
535  WINPR_ASSERT(transport->frontBio);
536  BIO_set_nonblock(transport->frontBio, 0);
537  transport->layer = TRANSPORT_LAYER_TSG;
538  status = TRUE;
539  }
540  else
541  {
542  rdg_free(transport->rdg);
543  transport->rdg = NULL;
544  }
545  }
546 
547  if (!status && settings->GatewayRpcTransport && rpcFallback)
548  {
549  WINPR_ASSERT(!transport->tsg);
550  transport->tsg = tsg_new(transport);
551 
552  if (!transport->tsg)
553  return FALSE;
554 
555  /* Reset error condition from RDG */
556  freerdp_set_last_error_log(context, FREERDP_ERROR_SUCCESS);
557  status = tsg_connect(transport->tsg, hostname, port, timeout);
558 
559  if (status)
560  {
561  transport->frontBio = tsg_get_bio(transport->tsg);
562  transport->layer = TRANSPORT_LAYER_TSG;
563  status = TRUE;
564  }
565  else
566  {
567  tsg_free(transport->tsg);
568  transport->tsg = NULL;
569  }
570  }
571  }
572  else
573  {
574  UINT16 peerPort = 0;
575  const char* proxyHostname = NULL;
576  const char* proxyUsername = NULL;
577  const char* proxyPassword = NULL;
578  BOOL isProxyConnection =
579  proxy_prepare(settings, &proxyHostname, &peerPort, &proxyUsername, &proxyPassword);
580 
581  rdpTransportLayer* layer = NULL;
582  if (isProxyConnection)
583  layer = transport_connect_layer(transport, proxyHostname, peerPort, timeout);
584  else
585  layer = transport_connect_layer(transport, hostname, port, timeout);
586 
587  if (!layer)
588  return FALSE;
589 
590  if (!transport_attach_layer(transport, layer))
591  {
592  transport_layer_free(layer);
593  return FALSE;
594  }
595 
596  if (isProxyConnection)
597  {
598  if (!proxy_connect(context, transport->frontBio, proxyUsername, proxyPassword, hostname,
599  port))
600  return FALSE;
601  }
602 
603  status = TRUE;
604  }
605 
606  return status;
607 }
608 
609 BOOL transport_connect_childsession(rdpTransport* transport)
610 {
611  WINPR_ASSERT(transport);
612 
613  transport->frontBio = createChildSessionBio();
614  if (!transport->frontBio)
615  return FALSE;
616 
617  transport->layer = TRANSPORT_LAYER_TSG;
618  return TRUE;
619 }
620 
621 BOOL transport_accept_rdp(rdpTransport* transport)
622 {
623  if (!transport)
624  return FALSE;
625  /* RDP encryption */
626  return TRUE;
627 }
628 
629 BOOL transport_accept_tls(rdpTransport* transport)
630 {
631  if (!transport)
632  return FALSE;
633  return IFCALLRESULT(FALSE, transport->io.TLSAccept, transport);
634 }
635 
636 static BOOL transport_default_accept_tls(rdpTransport* transport)
637 {
638  rdpContext* context = transport_get_context(transport);
639  rdpSettings* settings = NULL;
640 
641  WINPR_ASSERT(context);
642 
643  settings = context->settings;
644  WINPR_ASSERT(settings);
645 
646  if (!transport->tls)
647  transport->tls = freerdp_tls_new(context);
648 
649  transport->layer = TRANSPORT_LAYER_TLS;
650 
651  if (!freerdp_tls_accept(transport->tls, transport->frontBio, settings))
652  return FALSE;
653 
654  transport->frontBio = transport->tls->bio;
655  return TRUE;
656 }
657 
658 BOOL transport_accept_nla(rdpTransport* transport)
659 {
660  rdpContext* context = transport_get_context(transport);
661  rdpSettings* settings = NULL;
662 
663  WINPR_ASSERT(context);
664 
665  settings = context->settings;
666  WINPR_ASSERT(settings);
667 
668  if (!IFCALLRESULT(FALSE, transport->io.TLSAccept, transport))
669  return FALSE;
670 
671  /* Network Level Authentication */
672 
673  if (!settings->Authentication)
674  return TRUE;
675 
676  if (!transport->nla)
677  {
678  transport->nla = nla_new(context, transport);
679  transport_set_nla_mode(transport, TRUE);
680  }
681 
682  if (nla_authenticate(transport->nla) < 0)
683  {
684  WLog_Print(transport->log, WLOG_ERROR, "client authentication failure");
685  transport_set_nla_mode(transport, FALSE);
686  nla_free(transport->nla);
687  transport->nla = NULL;
688  freerdp_tls_set_alert_code(transport->tls, TLS_ALERT_LEVEL_FATAL,
689  TLS_ALERT_DESCRIPTION_ACCESS_DENIED);
690  freerdp_tls_send_alert(transport->tls);
691  return FALSE;
692  }
693 
694  /* don't free nla module yet, we need to copy the credentials from it first */
695  transport_set_nla_mode(transport, FALSE);
696  return TRUE;
697 }
698 
699 BOOL transport_accept_rdstls(rdpTransport* transport)
700 {
701  BOOL rc = FALSE;
702  rdpRdstls* rdstls = NULL;
703  rdpContext* context = NULL;
704 
705  WINPR_ASSERT(transport);
706 
707  context = transport_get_context(transport);
708  WINPR_ASSERT(context);
709 
710  if (!IFCALLRESULT(FALSE, transport->io.TLSAccept, transport))
711  goto fail;
712 
713  rdstls = rdstls_new(context, transport);
714  if (!rdstls)
715  goto fail;
716 
717  transport_set_rdstls_mode(transport, TRUE);
718 
719  if (rdstls_authenticate(rdstls) < 0)
720  {
721  WLog_Print(transport->log, WLOG_ERROR, "client authentication failure");
722  freerdp_tls_set_alert_code(transport->tls, TLS_ALERT_LEVEL_FATAL,
723  TLS_ALERT_DESCRIPTION_ACCESS_DENIED);
724  freerdp_tls_send_alert(transport->tls);
725  goto fail;
726  }
727 
728  transport_set_rdstls_mode(transport, FALSE);
729  rc = TRUE;
730 fail:
731  rdstls_free(rdstls);
732  return rc;
733 }
734 
735 #define WLog_ERR_BIO(transport, biofunc, bio) \
736  transport_bio_error_log(transport, biofunc, bio, __FILE__, __func__, __LINE__)
737 
738 static void transport_bio_error_log(rdpTransport* transport, LPCSTR biofunc, BIO* bio, LPCSTR file,
739  LPCSTR func, DWORD line)
740 {
741  unsigned long sslerr = 0;
742  int saveerrno = 0;
743  DWORD level = 0;
744 
745  WINPR_ASSERT(transport);
746 
747  saveerrno = errno;
748  level = WLOG_ERROR;
749 
750  if (level < WLog_GetLogLevel(transport->log))
751  return;
752 
753  if (ERR_peek_error() == 0)
754  {
755  char ebuffer[256] = { 0 };
756  const char* fmt = "%s returned a system error %d: %s";
757  if (saveerrno == 0)
758  fmt = "%s retries exceeded";
759  WLog_PrintMessage(transport->log, WLOG_MESSAGE_TEXT, level, line, file, func, fmt, biofunc,
760  saveerrno, winpr_strerror(saveerrno, ebuffer, sizeof(ebuffer)));
761  return;
762  }
763 
764  while ((sslerr = ERR_get_error()))
765  {
766  char buf[120] = { 0 };
767  const char* fmt = "%s returned an error: %s";
768 
769  ERR_error_string_n(sslerr, buf, 120);
770  WLog_PrintMessage(transport->log, WLOG_MESSAGE_TEXT, level, line, file, func, fmt, biofunc,
771  buf);
772  }
773 }
774 
775 static SSIZE_T transport_read_layer(rdpTransport* transport, BYTE* data, size_t bytes)
776 {
777  SSIZE_T read = 0;
778  rdpRdp* rdp = NULL;
779  rdpContext* context = NULL;
780 
781  WINPR_ASSERT(transport);
782 
783  context = transport_get_context(transport);
784  WINPR_ASSERT(context);
785 
786  rdp = context->rdp;
787  WINPR_ASSERT(rdp);
788 
789  if (!transport->frontBio || (bytes > SSIZE_MAX))
790  {
791  transport->layer = TRANSPORT_LAYER_CLOSED;
792  freerdp_set_last_error_if_not(context, FREERDP_ERROR_CONNECT_TRANSPORT_FAILED);
793  return -1;
794  }
795 
796  while (read < (SSIZE_T)bytes)
797  {
798  const SSIZE_T tr = (SSIZE_T)bytes - read;
799  int r = (int)((tr > INT_MAX) ? INT_MAX : tr);
800  ERR_clear_error();
801  int status = BIO_read(transport->frontBio, data + read, r);
802 
803  if (freerdp_shall_disconnect_context(context))
804  return -1;
805 
806  if (status <= 0)
807  {
808  if (!transport->frontBio || !BIO_should_retry(transport->frontBio))
809  {
810  /* something unexpected happened, let's close */
811  if (!transport->frontBio)
812  {
813  WLog_Print(transport->log, WLOG_ERROR, "BIO_read: transport->frontBio null");
814  return -1;
815  }
816 
817  WLog_ERR_BIO(transport, "BIO_read", transport->frontBio);
818  transport->layer = TRANSPORT_LAYER_CLOSED;
819  freerdp_set_last_error_if_not(context, FREERDP_ERROR_CONNECT_TRANSPORT_FAILED);
820  return -1;
821  }
822 
823  /* non blocking will survive a partial read */
824  if (!transport->blocking)
825  return read;
826 
827  /* blocking means that we can't continue until we have read the number of requested
828  * bytes */
829  if (BIO_wait_read(transport->frontBio, 100) < 0)
830  {
831  WLog_ERR_BIO(transport, "BIO_wait_read", transport->frontBio);
832  return -1;
833  }
834 
835  continue;
836  }
837 
838 #ifdef FREERDP_HAVE_VALGRIND_MEMCHECK_H
839  VALGRIND_MAKE_MEM_DEFINED(data + read, bytes - read);
840 #endif
841  read += status;
842  rdp->inBytes += status;
843  }
844 
845  return read;
846 }
847 
862 static SSIZE_T transport_read_layer_bytes(rdpTransport* transport, wStream* s, size_t toRead)
863 {
864  SSIZE_T status = 0;
865  if (!transport)
866  return -1;
867 
868  if (toRead > SSIZE_MAX)
869  return 0;
870 
871  status = IFCALLRESULT(-1, transport->io.ReadBytes, transport, Stream_Pointer(s), toRead);
872 
873  if (status <= 0)
874  return status;
875 
876  Stream_Seek(s, (size_t)status);
877  return status == (SSIZE_T)toRead ? 1 : 0;
878 }
879 
892 int transport_read_pdu(rdpTransport* transport, wStream* s)
893 {
894  if (!transport)
895  return -1;
896  return IFCALLRESULT(-1, transport->io.ReadPdu, transport, s);
897 }
898 
899 static SSIZE_T parse_nla_mode_pdu(rdpTransport* transport, wStream* stream)
900 {
901  SSIZE_T pduLength = 0;
902  wStream sbuffer = { 0 };
903  wStream* s = Stream_StaticConstInit(&sbuffer, Stream_Buffer(stream), Stream_Length(stream));
904  /*
905  * In case NlaMode is set TSRequest package(s) are expected
906  * 0x30 = DER encoded data with these bits set:
907  * bit 6 P/C constructed
908  * bit 5 tag number - sequence
909  */
910  UINT8 typeEncoding = 0;
911  if (Stream_GetRemainingLength(s) < 1)
912  return 0;
913  Stream_Read_UINT8(s, typeEncoding);
914  if (typeEncoding == 0x30)
915  {
916  /* TSRequest (NLA) */
917  UINT8 lengthEncoding = 0;
918  if (Stream_GetRemainingLength(s) < 1)
919  return 0;
920  Stream_Read_UINT8(s, lengthEncoding);
921  if (lengthEncoding & 0x80)
922  {
923  if ((lengthEncoding & ~(0x80)) == 1)
924  {
925  UINT8 length = 0;
926  if (Stream_GetRemainingLength(s) < 1)
927  return 0;
928  Stream_Read_UINT8(s, length);
929  pduLength = length;
930  pduLength += 3;
931  }
932  else if ((lengthEncoding & ~(0x80)) == 2)
933  {
934  /* check for header bytes already was readed in previous calls */
935  UINT16 length = 0;
936  if (Stream_GetRemainingLength(s) < 2)
937  return 0;
938  Stream_Read_UINT16_BE(s, length);
939  pduLength = length;
940  pduLength += 4;
941  }
942  else
943  {
944  WLog_Print(transport->log, WLOG_ERROR, "Error reading TSRequest!");
945  return -1;
946  }
947  }
948  else
949  {
950  pduLength = lengthEncoding;
951  pduLength += 2;
952  }
953  }
954 
955  return pduLength;
956 }
957 
958 static SSIZE_T parse_default_mode_pdu(rdpTransport* transport, wStream* stream)
959 {
960  SSIZE_T pduLength = 0;
961  wStream sbuffer = { 0 };
962  wStream* s = Stream_StaticConstInit(&sbuffer, Stream_Buffer(stream), Stream_Length(stream));
963 
964  UINT8 version = 0;
965  if (Stream_GetRemainingLength(s) < 1)
966  return 0;
967  Stream_Read_UINT8(s, version);
968  if (version == 0x03)
969  {
970  /* TPKT header */
971  UINT16 length = 0;
972  if (Stream_GetRemainingLength(s) < 3)
973  return 0;
974  Stream_Seek(s, 1);
975  Stream_Read_UINT16_BE(s, length);
976  pduLength = length;
977 
978  /* min and max values according to ITU-T Rec. T.123 (01/2007) section 8 */
979  if ((pduLength < 7) || (pduLength > 0xFFFF))
980  {
981  WLog_Print(transport->log, WLOG_ERROR, "tpkt - invalid pduLength: %" PRIdz, pduLength);
982  return -1;
983  }
984  }
985  else
986  {
987  /* Fast-Path Header */
988  UINT8 length1 = 0;
989  if (Stream_GetRemainingLength(s) < 1)
990  return 0;
991  Stream_Read_UINT8(s, length1);
992  if (length1 & 0x80)
993  {
994  UINT8 length2 = 0;
995  if (Stream_GetRemainingLength(s) < 1)
996  return 0;
997  Stream_Read_UINT8(s, length2);
998  pduLength = ((length1 & 0x7F) << 8) | length2;
999  }
1000  else
1001  pduLength = length1;
1002 
1003  /*
1004  * fast-path has 7 bits for length so the maximum size, including headers is 0x8000
1005  * The theoretical minimum fast-path PDU consists only of two header bytes plus one
1006  * byte for data (e.g. fast-path input synchronize pdu)
1007  */
1008  if (pduLength < 3 || pduLength > 0x8000)
1009  {
1010  WLog_Print(transport->log, WLOG_ERROR, "fast path - invalid pduLength: %" PRIdz,
1011  pduLength);
1012  return -1;
1013  }
1014  }
1015 
1016  return pduLength;
1017 }
1018 
1019 SSIZE_T transport_parse_pdu(rdpTransport* transport, wStream* s, BOOL* incomplete)
1020 {
1021  size_t pduLength = 0;
1022 
1023  if (!transport)
1024  return -1;
1025 
1026  if (!s)
1027  return -1;
1028 
1029  if (incomplete)
1030  *incomplete = TRUE;
1031 
1032  Stream_SealLength(s);
1033  if (transport->NlaMode)
1034  pduLength = parse_nla_mode_pdu(transport, s);
1035  else if (transport->RdstlsMode)
1036  pduLength = rdstls_parse_pdu(transport->log, s);
1037  else
1038  pduLength = parse_default_mode_pdu(transport, s);
1039 
1040  if (pduLength == 0)
1041  return 0;
1042 
1043  if (pduLength > SSIZE_MAX)
1044  return -1;
1045 
1046  const size_t len = Stream_Length(s);
1047  if (len > pduLength)
1048  return -1;
1049 
1050  if (incomplete)
1051  *incomplete = len < pduLength;
1052 
1053  return (int)pduLength;
1054 }
1055 
1056 static int transport_default_read_pdu(rdpTransport* transport, wStream* s)
1057 {
1058  BOOL incomplete = 0;
1059  SSIZE_T status = 0;
1060  size_t pduLength = 0;
1061  size_t position = 0;
1062 
1063  WINPR_ASSERT(transport);
1064  WINPR_ASSERT(s);
1065 
1066  /* RDS AAD Auth PDUs have no length indicator. We need to determine the end of the PDU by
1067  * reading in one byte at a time until we encounter the terminating null byte */
1068  if (transport->AadMode)
1069  {
1070  BYTE c = '\0';
1071  do
1072  {
1073  const SSIZE_T rc = transport_read_layer(transport, &c, 1);
1074  if (rc != 1)
1075  return (rc == 0) ? 0 : -1;
1076  if (!Stream_EnsureRemainingCapacity(s, 1))
1077  return -1;
1078  Stream_Write_UINT8(s, c);
1079  } while (c != '\0');
1080  }
1081  else if (transport->earlyUserAuth)
1082  {
1083  if (!Stream_EnsureCapacity(s, 4))
1084  return -1;
1085  const SSIZE_T rc = transport_read_layer_bytes(transport, s, 4);
1086  if (rc != 1)
1087  return (rc == 0) ? 0 : -1;
1088  }
1089  else
1090  {
1091  /* Read in pdu length */
1092  status = transport_parse_pdu(transport, s, &incomplete);
1093  while ((status == 0) && incomplete)
1094  {
1095  if (!Stream_EnsureRemainingCapacity(s, 1))
1096  return -1;
1097  SSIZE_T rc = transport_read_layer_bytes(transport, s, 1);
1098  if (rc > INT32_MAX)
1099  return INT32_MAX;
1100  if (rc != 1)
1101  return (int)rc;
1102  status = transport_parse_pdu(transport, s, &incomplete);
1103  }
1104 
1105  if (status < 0)
1106  return -1;
1107 
1108  pduLength = (size_t)status;
1109 
1110  /* Read in rest of the PDU */
1111  if (!Stream_EnsureCapacity(s, pduLength))
1112  return -1;
1113 
1114  position = Stream_GetPosition(s);
1115  if (position > pduLength)
1116  return -1;
1117 
1118  status = transport_read_layer_bytes(transport, s, pduLength - Stream_GetPosition(s));
1119 
1120  if (status != 1)
1121  {
1122  if ((status < INT32_MIN) || (status > INT32_MAX))
1123  return -1;
1124  return (int)status;
1125  }
1126 
1127  if (Stream_GetPosition(s) >= pduLength)
1128  WLog_Packet(transport->log, WLOG_TRACE, Stream_Buffer(s), pduLength,
1129  WLOG_PACKET_INBOUND);
1130  }
1131 
1132  Stream_SealLength(s);
1133  Stream_SetPosition(s, 0);
1134  const size_t len = Stream_Length(s);
1135  if (len > INT32_MAX)
1136  return -1;
1137  return (int)len;
1138 }
1139 
1140 int transport_write(rdpTransport* transport, wStream* s)
1141 {
1142  if (!transport)
1143  return -1;
1144 
1145  return IFCALLRESULT(-1, transport->io.WritePdu, transport, s);
1146 }
1147 
1148 static int transport_default_write(rdpTransport* transport, wStream* s)
1149 {
1150  int status = -1;
1151  rdpContext* context = transport_get_context(transport);
1152 
1153  WINPR_ASSERT(transport);
1154  WINPR_ASSERT(context);
1155 
1156  if (!s)
1157  return -1;
1158 
1159  Stream_AddRef(s);
1160 
1161  rdpRdp* rdp = context->rdp;
1162  if (!rdp)
1163  goto fail;
1164 
1165  EnterCriticalSection(&(transport->WriteLock));
1166  if (!transport->frontBio)
1167  goto out_cleanup;
1168 
1169  size_t length = Stream_GetPosition(s);
1170  size_t writtenlength = length;
1171  Stream_SetPosition(s, 0);
1172 
1173  if (length > 0)
1174  {
1175  rdp->outBytes += length;
1176  WLog_Packet(transport->log, WLOG_TRACE, Stream_Buffer(s), length, WLOG_PACKET_OUTBOUND);
1177  }
1178 
1179  while (length > 0)
1180  {
1181  ERR_clear_error();
1182  const int towrite = (length > INT32_MAX) ? INT32_MAX : (int)length;
1183  status = BIO_write(transport->frontBio, Stream_ConstPointer(s), towrite);
1184 
1185  if (status <= 0)
1186  {
1187  /* the buffered BIO that is at the end of the chain always says OK for writing,
1188  * so a retry means that for any reason we need to read. The most probable
1189  * is a SSL or TSG BIO in the chain.
1190  */
1191  if (!BIO_should_retry(transport->frontBio))
1192  {
1193  WLog_ERR_BIO(transport, "BIO_should_retry", transport->frontBio);
1194  goto out_cleanup;
1195  }
1196 
1197  /* non-blocking can live with blocked IOs */
1198  if (!transport->blocking)
1199  {
1200  WLog_ERR_BIO(transport, "BIO_write", transport->frontBio);
1201  goto out_cleanup;
1202  }
1203 
1204  if (BIO_wait_write(transport->frontBio, 100) < 0)
1205  {
1206  WLog_ERR_BIO(transport, "BIO_wait_write", transport->frontBio);
1207  status = -1;
1208  goto out_cleanup;
1209  }
1210 
1211  continue;
1212  }
1213 
1214  WINPR_ASSERT(context->settings);
1215  if (transport->blocking || context->settings->WaitForOutputBufferFlush)
1216  {
1217  while (BIO_write_blocked(transport->frontBio))
1218  {
1219  if (BIO_wait_write(transport->frontBio, 100) < 0)
1220  {
1221  WLog_Print(transport->log, WLOG_ERROR, "error when selecting for write");
1222  status = -1;
1223  goto out_cleanup;
1224  }
1225 
1226  if (BIO_flush(transport->frontBio) < 1)
1227  {
1228  WLog_Print(transport->log, WLOG_ERROR, "error when flushing outputBuffer");
1229  status = -1;
1230  goto out_cleanup;
1231  }
1232  }
1233  }
1234 
1235  length -= (size_t)status;
1236  Stream_Seek(s, (size_t)status);
1237  }
1238 
1239  transport->written += writtenlength;
1240 out_cleanup:
1241 
1242  if (status < 0)
1243  {
1244  /* A write error indicates that the peer has dropped the connection */
1245  transport->layer = TRANSPORT_LAYER_CLOSED;
1246  freerdp_set_last_error_if_not(context, FREERDP_ERROR_CONNECT_TRANSPORT_FAILED);
1247  }
1248 
1249  LeaveCriticalSection(&(transport->WriteLock));
1250 fail:
1251  Stream_Release(s);
1252  return status;
1253 }
1254 
1255 BOOL transport_get_public_key(rdpTransport* transport, const BYTE** data, DWORD* length)
1256 {
1257  return IFCALLRESULT(FALSE, transport->io.GetPublicKey, transport, data, length);
1258 }
1259 
1260 static BOOL transport_default_get_public_key(rdpTransport* transport, const BYTE** data,
1261  DWORD* length)
1262 {
1263  rdpTls* tls = transport_get_tls(transport);
1264  if (!tls)
1265  return FALSE;
1266 
1267  *data = tls->PublicKey;
1268  *length = tls->PublicKeyLength;
1269 
1270  return TRUE;
1271 }
1272 
1273 DWORD transport_get_event_handles(rdpTransport* transport, HANDLE* events, DWORD count)
1274 {
1275  DWORD nCount = 0; /* always the reread Event */
1276 
1277  WINPR_ASSERT(transport);
1278  WINPR_ASSERT(events);
1279  WINPR_ASSERT(count > 0);
1280 
1281  if (events)
1282  {
1283  if (count < 1)
1284  {
1285  WLog_Print(transport->log, WLOG_ERROR, "provided handles array is too small");
1286  return 0;
1287  }
1288 
1289  events[nCount++] = transport->rereadEvent;
1290 
1291  if (transport->useIoEvent)
1292  {
1293  if (count < 2)
1294  return 0;
1295  events[nCount++] = transport->ioEvent;
1296  }
1297  }
1298 
1299  if (!transport->GatewayEnabled)
1300  {
1301  if (events)
1302  {
1303  if (nCount >= count)
1304  {
1305  WLog_Print(transport->log, WLOG_ERROR,
1306  "provided handles array is too small (count=%" PRIu32 " nCount=%" PRIu32
1307  ")",
1308  count, nCount);
1309  return 0;
1310  }
1311 
1312  if (transport->frontBio)
1313  {
1314  if (BIO_get_event(transport->frontBio, &events[nCount]) != 1)
1315  {
1316  WLog_Print(transport->log, WLOG_ERROR, "error getting the frontBio handle");
1317  return 0;
1318  }
1319  nCount++;
1320  }
1321  }
1322  }
1323  else
1324  {
1325  if (transport->rdg)
1326  {
1327  const DWORD tmp =
1328  rdg_get_event_handles(transport->rdg, &events[nCount], count - nCount);
1329 
1330  if (tmp == 0)
1331  return 0;
1332 
1333  nCount += tmp;
1334  }
1335  else if (transport->tsg)
1336  {
1337  const DWORD tmp =
1338  tsg_get_event_handles(transport->tsg, &events[nCount], count - nCount);
1339 
1340  if (tmp == 0)
1341  return 0;
1342 
1343  nCount += tmp;
1344  }
1345  else if (transport->wst)
1346  {
1347  const DWORD tmp =
1348  wst_get_event_handles(transport->wst, &events[nCount], count - nCount);
1349 
1350  if (tmp == 0)
1351  return 0;
1352 
1353  nCount += tmp;
1354  }
1355  }
1356 
1357  return nCount;
1358 }
1359 
1360 #if defined(WITH_FREERDP_DEPRECATED)
1361 void transport_get_fds(rdpTransport* transport, void** rfds, int* rcount)
1362 {
1363  DWORD nCount = 0;
1364  HANDLE events[MAXIMUM_WAIT_OBJECTS] = { 0 };
1365 
1366  WINPR_ASSERT(transport);
1367  WINPR_ASSERT(rfds);
1368  WINPR_ASSERT(rcount);
1369 
1370  nCount = transport_get_event_handles(transport, events, ARRAYSIZE(events));
1371  *rcount = nCount + 1;
1372 
1373  for (DWORD index = 0; index < nCount; index++)
1374  {
1375  rfds[index] = GetEventWaitObject(events[index]);
1376  }
1377 
1378  rfds[nCount] = GetEventWaitObject(transport->rereadEvent);
1379 }
1380 #endif
1381 
1382 BOOL transport_is_write_blocked(rdpTransport* transport)
1383 {
1384  WINPR_ASSERT(transport);
1385  WINPR_ASSERT(transport->frontBio);
1386  return BIO_write_blocked(transport->frontBio) != 0;
1387 }
1388 
1389 int transport_drain_output_buffer(rdpTransport* transport)
1390 {
1391  BOOL status = FALSE;
1392 
1393  WINPR_ASSERT(transport);
1394  WINPR_ASSERT(transport->frontBio);
1395  if (BIO_write_blocked(transport->frontBio))
1396  {
1397  if (BIO_flush(transport->frontBio) < 1)
1398  return -1;
1399 
1400  const long rc = BIO_write_blocked(transport->frontBio);
1401  status = (rc != 0);
1402  }
1403 
1404  return status;
1405 }
1406 
1407 int transport_check_fds(rdpTransport* transport)
1408 {
1409  int status = 0;
1410  state_run_t recv_status = STATE_RUN_FAILED;
1411  wStream* received = NULL;
1412  rdpContext* context = transport_get_context(transport);
1413 
1414  WINPR_ASSERT(context);
1415 
1416  if (transport->layer == TRANSPORT_LAYER_CLOSED)
1417  {
1418  WLog_Print(transport->log, WLOG_DEBUG, "transport_check_fds: transport layer closed");
1419  freerdp_set_last_error_if_not(context, FREERDP_ERROR_CONNECT_TRANSPORT_FAILED);
1420  return -1;
1421  }
1422 
1432  if ((status = transport_read_pdu(transport, transport->ReceiveBuffer)) <= 0)
1433  {
1434  if (status < 0)
1435  WLog_Print(transport->log, WLOG_DEBUG, "transport_check_fds: transport_read_pdu() - %i",
1436  status);
1437  if (transport->haveMoreBytesToRead)
1438  {
1439  transport->haveMoreBytesToRead = FALSE;
1440  (void)ResetEvent(transport->rereadEvent);
1441  }
1442  return status;
1443  }
1444 
1445  received = transport->ReceiveBuffer;
1446 
1447  if (!(transport->ReceiveBuffer = StreamPool_Take(transport->ReceivePool, 0)))
1448  return -1;
1449 
1456  WINPR_ASSERT(transport->ReceiveCallback);
1457  recv_status = transport->ReceiveCallback(transport, received, transport->ReceiveExtra);
1458  Stream_Release(received);
1459 
1460  if (state_run_failed(recv_status))
1461  {
1462  char buffer[64] = { 0 };
1463  WLog_Print(transport->log, WLOG_ERROR,
1464  "transport_check_fds: transport->ReceiveCallback() - %s",
1465  state_run_result_string(recv_status, buffer, ARRAYSIZE(buffer)));
1466  return -1;
1467  }
1468 
1469  /* Run this again to be sure we consumed all input data.
1470  * This will be repeated until a (not fully) received packet is in buffer
1471  */
1472  if (!transport->haveMoreBytesToRead)
1473  {
1474  transport->haveMoreBytesToRead = TRUE;
1475  (void)SetEvent(transport->rereadEvent);
1476  }
1477  return recv_status;
1478 }
1479 
1480 BOOL transport_set_blocking_mode(rdpTransport* transport, BOOL blocking)
1481 {
1482  WINPR_ASSERT(transport);
1483 
1484  return IFCALLRESULT(FALSE, transport->io.SetBlockingMode, transport, blocking);
1485 }
1486 
1487 static BOOL transport_default_set_blocking_mode(rdpTransport* transport, BOOL blocking)
1488 {
1489  WINPR_ASSERT(transport);
1490 
1491  transport->blocking = blocking;
1492 
1493  if (transport->frontBio)
1494  {
1495  if (!BIO_set_nonblock(transport->frontBio, blocking ? FALSE : TRUE))
1496  return FALSE;
1497  }
1498 
1499  return TRUE;
1500 }
1501 
1502 rdpTransportLayer* transport_connect_layer(rdpTransport* transport, const char* hostname, int port,
1503  DWORD timeout)
1504 {
1505  WINPR_ASSERT(transport);
1506 
1507  return IFCALLRESULT(NULL, transport->io.ConnectLayer, transport, hostname, port, timeout);
1508 }
1509 
1510 static rdpTransportLayer* transport_default_connect_layer(rdpTransport* transport,
1511  const char* hostname, int port,
1512  DWORD timeout)
1513 {
1514  rdpContext* context = transport_get_context(transport);
1515  WINPR_ASSERT(context);
1516 
1517  return freerdp_tcp_connect_layer(context, hostname, port, timeout);
1518 }
1519 
1520 BOOL transport_attach_layer(rdpTransport* transport, rdpTransportLayer* layer)
1521 {
1522  WINPR_ASSERT(transport);
1523  WINPR_ASSERT(layer);
1524 
1525  return IFCALLRESULT(FALSE, transport->io.AttachLayer, transport, layer);
1526 }
1527 
1528 static BOOL transport_default_attach_layer(rdpTransport* transport, rdpTransportLayer* layer)
1529 {
1530  BIO* layerBio = BIO_new(BIO_s_transport_layer());
1531  if (!layerBio)
1532  goto fail;
1533 
1534  BIO* bufferedBio = BIO_new(BIO_s_buffered_socket());
1535  if (!bufferedBio)
1536  goto fail;
1537 
1538  bufferedBio = BIO_push(bufferedBio, layerBio);
1539  if (!bufferedBio)
1540  goto fail;
1541 
1542  /* BIO takes over the layer reference at this point. */
1543  BIO_set_data(layerBio, layer);
1544 
1545  transport->frontBio = bufferedBio;
1546 
1547  return TRUE;
1548 
1549 fail:
1550  if (layerBio)
1551  BIO_free_all(layerBio);
1552 
1553  return FALSE;
1554 }
1555 
1556 void transport_set_gateway_enabled(rdpTransport* transport, BOOL GatewayEnabled)
1557 {
1558  WINPR_ASSERT(transport);
1559  transport->GatewayEnabled = GatewayEnabled;
1560 }
1561 
1562 void transport_set_nla_mode(rdpTransport* transport, BOOL NlaMode)
1563 {
1564  WINPR_ASSERT(transport);
1565  transport->NlaMode = NlaMode;
1566 }
1567 
1568 void transport_set_rdstls_mode(rdpTransport* transport, BOOL RdstlsMode)
1569 {
1570  WINPR_ASSERT(transport);
1571  transport->RdstlsMode = RdstlsMode;
1572 }
1573 
1574 void transport_set_aad_mode(rdpTransport* transport, BOOL AadMode)
1575 {
1576  WINPR_ASSERT(transport);
1577  transport->AadMode = AadMode;
1578 }
1579 
1580 BOOL transport_disconnect(rdpTransport* transport)
1581 {
1582  if (!transport)
1583  return FALSE;
1584  return IFCALLRESULT(FALSE, transport->io.TransportDisconnect, transport);
1585 }
1586 
1587 static BOOL transport_default_disconnect(rdpTransport* transport)
1588 {
1589  BOOL status = TRUE;
1590 
1591  if (!transport)
1592  return FALSE;
1593 
1594  if (transport->tls)
1595  {
1596  freerdp_tls_free(transport->tls);
1597  transport->tls = NULL;
1598  }
1599  else
1600  {
1601  if (transport->frontBio)
1602  BIO_free_all(transport->frontBio);
1603  }
1604 
1605  if (transport->tsg)
1606  {
1607  tsg_free(transport->tsg);
1608  transport->tsg = NULL;
1609  }
1610 
1611  if (transport->rdg)
1612  {
1613  rdg_free(transport->rdg);
1614  transport->rdg = NULL;
1615  }
1616 
1617  if (transport->wst)
1618  {
1619  wst_free(transport->wst);
1620  transport->wst = NULL;
1621  }
1622 
1623  transport->frontBio = NULL;
1624  transport->layer = TRANSPORT_LAYER_TCP;
1625  transport->earlyUserAuth = FALSE;
1626  return status;
1627 }
1628 
1629 rdpTransport* transport_new(rdpContext* context)
1630 {
1631  rdpTransport* transport = (rdpTransport*)calloc(1, sizeof(rdpTransport));
1632 
1633  WINPR_ASSERT(context);
1634  if (!transport)
1635  return NULL;
1636 
1637  transport->log = WLog_Get(TAG);
1638 
1639  if (!transport->log)
1640  goto fail;
1641 
1642  // transport->io.DataHandler = transport_data_handler;
1643  transport->io.TCPConnect = freerdp_tcp_default_connect;
1644  transport->io.TLSConnect = transport_default_connect_tls;
1645  transport->io.TLSAccept = transport_default_accept_tls;
1646  transport->io.TransportAttach = transport_default_attach;
1647  transport->io.TransportDisconnect = transport_default_disconnect;
1648  transport->io.ReadPdu = transport_default_read_pdu;
1649  transport->io.WritePdu = transport_default_write;
1650  transport->io.ReadBytes = transport_read_layer;
1651  transport->io.GetPublicKey = transport_default_get_public_key;
1652  transport->io.SetBlockingMode = transport_default_set_blocking_mode;
1653  transport->io.ConnectLayer = transport_default_connect_layer;
1654  transport->io.AttachLayer = transport_default_attach_layer;
1655 
1656  transport->context = context;
1657  transport->ReceivePool = StreamPool_New(TRUE, BUFFER_SIZE);
1658 
1659  if (!transport->ReceivePool)
1660  goto fail;
1661 
1662  /* receive buffer for non-blocking read. */
1663  transport->ReceiveBuffer = StreamPool_Take(transport->ReceivePool, 0);
1664 
1665  if (!transport->ReceiveBuffer)
1666  goto fail;
1667 
1668  transport->connectedEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
1669 
1670  if (!transport->connectedEvent || transport->connectedEvent == INVALID_HANDLE_VALUE)
1671  goto fail;
1672 
1673  transport->rereadEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
1674 
1675  if (!transport->rereadEvent || transport->rereadEvent == INVALID_HANDLE_VALUE)
1676  goto fail;
1677 
1678  transport->ioEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
1679 
1680  if (!transport->ioEvent || transport->ioEvent == INVALID_HANDLE_VALUE)
1681  goto fail;
1682 
1683  transport->haveMoreBytesToRead = FALSE;
1684  transport->blocking = TRUE;
1685  transport->GatewayEnabled = FALSE;
1686  transport->layer = TRANSPORT_LAYER_TCP;
1687 
1688  if (!InitializeCriticalSectionAndSpinCount(&(transport->ReadLock), 4000))
1689  goto fail;
1690 
1691  if (!InitializeCriticalSectionAndSpinCount(&(transport->WriteLock), 4000))
1692  goto fail;
1693 
1694  return transport;
1695 fail:
1696  WINPR_PRAGMA_DIAG_PUSH
1697  WINPR_PRAGMA_DIAG_IGNORED_MISMATCHED_DEALLOC
1698  transport_free(transport);
1699  WINPR_PRAGMA_DIAG_POP
1700  return NULL;
1701 }
1702 
1703 void transport_free(rdpTransport* transport)
1704 {
1705  if (!transport)
1706  return;
1707 
1708  transport_disconnect(transport);
1709 
1710  if (transport->ReceiveBuffer)
1711  Stream_Release(transport->ReceiveBuffer);
1712 
1713  nla_free(transport->nla);
1714  StreamPool_Free(transport->ReceivePool);
1715  (void)CloseHandle(transport->connectedEvent);
1716  (void)CloseHandle(transport->rereadEvent);
1717  (void)CloseHandle(transport->ioEvent);
1718  DeleteCriticalSection(&(transport->ReadLock));
1719  DeleteCriticalSection(&(transport->WriteLock));
1720  free(transport);
1721 }
1722 
1723 BOOL transport_set_io_callbacks(rdpTransport* transport, const rdpTransportIo* io_callbacks)
1724 {
1725  if (!transport || !io_callbacks)
1726  return FALSE;
1727 
1728  transport->io = *io_callbacks;
1729  return TRUE;
1730 }
1731 
1732 const rdpTransportIo* transport_get_io_callbacks(rdpTransport* transport)
1733 {
1734  if (!transport)
1735  return NULL;
1736  return &transport->io;
1737 }
1738 
1739 rdpContext* transport_get_context(rdpTransport* transport)
1740 {
1741  WINPR_ASSERT(transport);
1742  return transport->context;
1743 }
1744 
1745 rdpTransport* freerdp_get_transport(rdpContext* context)
1746 {
1747  WINPR_ASSERT(context);
1748  WINPR_ASSERT(context->rdp);
1749  return context->rdp->transport;
1750 }
1751 
1752 BOOL transport_set_nla(rdpTransport* transport, rdpNla* nla)
1753 {
1754  WINPR_ASSERT(transport);
1755  nla_free(transport->nla);
1756  transport->nla = nla;
1757  return TRUE;
1758 }
1759 
1760 rdpNla* transport_get_nla(rdpTransport* transport)
1761 {
1762  WINPR_ASSERT(transport);
1763  return transport->nla;
1764 }
1765 
1766 BOOL transport_set_tls(rdpTransport* transport, rdpTls* tls)
1767 {
1768  WINPR_ASSERT(transport);
1769  freerdp_tls_free(transport->tls);
1770  transport->tls = tls;
1771  return TRUE;
1772 }
1773 
1774 rdpTls* transport_get_tls(rdpTransport* transport)
1775 {
1776  WINPR_ASSERT(transport);
1777  return transport->tls;
1778 }
1779 
1780 BOOL transport_set_tsg(rdpTransport* transport, rdpTsg* tsg)
1781 {
1782  WINPR_ASSERT(transport);
1783  tsg_free(transport->tsg);
1784  transport->tsg = tsg;
1785  return TRUE;
1786 }
1787 
1788 rdpTsg* transport_get_tsg(rdpTransport* transport)
1789 {
1790  WINPR_ASSERT(transport);
1791  return transport->tsg;
1792 }
1793 
1794 wStream* transport_take_from_pool(rdpTransport* transport, size_t size)
1795 {
1796  WINPR_ASSERT(transport);
1797  return StreamPool_Take(transport->ReceivePool, size);
1798 }
1799 
1800 ULONG transport_get_bytes_sent(rdpTransport* transport, BOOL resetCount)
1801 {
1802  ULONG rc = 0;
1803  WINPR_ASSERT(transport);
1804  rc = transport->written;
1805  if (resetCount)
1806  transport->written = 0;
1807  return rc;
1808 }
1809 
1810 TRANSPORT_LAYER transport_get_layer(rdpTransport* transport)
1811 {
1812  WINPR_ASSERT(transport);
1813  return transport->layer;
1814 }
1815 
1816 BOOL transport_set_layer(rdpTransport* transport, TRANSPORT_LAYER layer)
1817 {
1818  WINPR_ASSERT(transport);
1819  transport->layer = layer;
1820  return TRUE;
1821 }
1822 
1823 BOOL transport_set_connected_event(rdpTransport* transport)
1824 {
1825  WINPR_ASSERT(transport);
1826  return SetEvent(transport->connectedEvent);
1827 }
1828 
1829 BOOL transport_set_recv_callbacks(rdpTransport* transport, TransportRecv recv, void* extra)
1830 {
1831  WINPR_ASSERT(transport);
1832  transport->ReceiveCallback = recv;
1833  transport->ReceiveExtra = extra;
1834  return TRUE;
1835 }
1836 
1837 BOOL transport_get_blocking(rdpTransport* transport)
1838 {
1839  WINPR_ASSERT(transport);
1840  return transport->blocking;
1841 }
1842 
1843 BOOL transport_set_blocking(rdpTransport* transport, BOOL blocking)
1844 {
1845  WINPR_ASSERT(transport);
1846  transport->blocking = blocking;
1847  return TRUE;
1848 }
1849 
1850 BOOL transport_have_more_bytes_to_read(rdpTransport* transport)
1851 {
1852  WINPR_ASSERT(transport);
1853  return transport->haveMoreBytesToRead;
1854 }
1855 
1856 int transport_tcp_connect(rdpTransport* transport, const char* hostname, int port, DWORD timeout)
1857 {
1858  rdpContext* context = transport_get_context(transport);
1859  WINPR_ASSERT(context);
1860  WINPR_ASSERT(context->settings);
1861  return IFCALLRESULT(-1, transport->io.TCPConnect, context, context->settings, hostname, port,
1862  timeout);
1863 }
1864 
1865 HANDLE transport_get_front_bio(rdpTransport* transport)
1866 {
1867  HANDLE hEvent = NULL;
1868  WINPR_ASSERT(transport);
1869  WINPR_ASSERT(transport->frontBio);
1870 
1871  BIO_get_event(transport->frontBio, &hEvent);
1872  return hEvent;
1873 }
1874 
1875 BOOL transport_io_callback_set_event(rdpTransport* transport, BOOL set)
1876 {
1877  WINPR_ASSERT(transport);
1878  transport->useIoEvent = TRUE;
1879  if (!set)
1880  return ResetEvent(transport->ioEvent);
1881  return SetEvent(transport->ioEvent);
1882 }
1883 
1884 void transport_set_early_user_auth_mode(rdpTransport* transport, BOOL EUAMode)
1885 {
1886  WINPR_ASSERT(transport);
1887  transport->earlyUserAuth = EUAMode;
1888  WLog_Print(transport->log, WLOG_DEBUG, "Early User Auth Mode: %s", EUAMode ? "on" : "off");
1889 }
1890 
1891 rdpTransportLayer* transport_layer_new(rdpTransport* transport, size_t contextSize)
1892 {
1893  rdpTransportLayer* layer = (rdpTransportLayer*)calloc(1, sizeof(rdpTransportLayer));
1894  if (!layer)
1895  return NULL;
1896 
1897  if (contextSize)
1898  {
1899  layer->userContext = calloc(1, contextSize);
1900  if (!layer->userContext)
1901  {
1902  free(layer);
1903  return NULL;
1904  }
1905  }
1906 
1907  return layer;
1908 }
1909 
1910 void transport_layer_free(rdpTransportLayer* layer)
1911 {
1912  if (!layer)
1913  return;
1914 
1915  IFCALL(layer->Close, layer->userContext);
1916  free(layer->userContext);
1917  free(layer);
1918 }
1919 
1920 static int transport_layer_bio_write(BIO* bio, const char* buf, int size)
1921 {
1922  if (!buf || !size)
1923  return 0;
1924  if (size < 0)
1925  return -1;
1926 
1927  WINPR_ASSERT(bio);
1928 
1929  rdpTransportLayer* layer = (rdpTransportLayer*)BIO_get_data(bio);
1930  if (!layer)
1931  return -1;
1932 
1933  BIO_clear_flags(bio, BIO_FLAGS_WRITE | BIO_FLAGS_SHOULD_RETRY);
1934 
1935  int status = IFCALLRESULT(-1, layer->Write, layer->userContext, buf, size);
1936 
1937  if (status >= 0 && status < size)
1938  BIO_set_flags(bio, (BIO_FLAGS_WRITE | BIO_FLAGS_SHOULD_RETRY));
1939 
1940  return status;
1941 }
1942 
1943 static int transport_layer_bio_read(BIO* bio, char* buf, int size)
1944 {
1945  if (!buf || !size)
1946  return 0;
1947  if (size < 0)
1948  return -1;
1949 
1950  WINPR_ASSERT(bio);
1951 
1952  rdpTransportLayer* layer = (rdpTransportLayer*)BIO_get_data(bio);
1953  if (!layer)
1954  return -1;
1955 
1956  BIO_clear_flags(bio, BIO_FLAGS_READ | BIO_FLAGS_SHOULD_RETRY);
1957 
1958  int status = IFCALLRESULT(-1, layer->Read, layer->userContext, buf, size);
1959 
1960  if (status == 0)
1961  BIO_set_flags(bio, (BIO_FLAGS_READ | BIO_FLAGS_SHOULD_RETRY));
1962 
1963  return status;
1964 }
1965 
1966 static int transport_layer_bio_puts(BIO* bio, const char* str)
1967 {
1968  return 1;
1969 }
1970 
1971 static int transport_layer_bio_gets(BIO* bio, char* str, int size)
1972 {
1973  return 1;
1974 }
1975 
1976 static long transport_layer_bio_ctrl(BIO* bio, int cmd, long arg1, void* arg2)
1977 {
1978  WINPR_ASSERT(bio);
1979 
1980  rdpTransportLayer* layer = (rdpTransportLayer*)BIO_get_data(bio);
1981  if (!layer)
1982  return -1;
1983 
1984  int status = -1;
1985  switch (cmd)
1986  {
1987  case BIO_C_GET_EVENT:
1988  *((HANDLE*)arg2) = IFCALLRESULT(NULL, layer->GetEvent, layer->userContext);
1989  status = 1;
1990  break;
1991 
1992  case BIO_C_SET_NONBLOCK:
1993  status = 1;
1994  break;
1995 
1996  case BIO_C_WAIT_READ:
1997  {
1998  int timeout = (int)arg1;
1999  BOOL r = IFCALLRESULT(FALSE, layer->Wait, layer->userContext, FALSE, timeout);
2000  /* Convert timeout to error return */
2001  if (!r)
2002  {
2003  errno = ETIMEDOUT;
2004  status = 0;
2005  }
2006  else
2007  status = 1;
2008  break;
2009  }
2010 
2011  case BIO_C_WAIT_WRITE:
2012  {
2013  int timeout = (int)arg1;
2014  BOOL r = IFCALLRESULT(FALSE, layer->Wait, layer->userContext, TRUE, timeout);
2015  /* Convert timeout to error return */
2016  if (!r)
2017  {
2018  errno = ETIMEDOUT;
2019  status = 0;
2020  }
2021  else
2022  status = 1;
2023  break;
2024  }
2025 
2026  case BIO_CTRL_GET_CLOSE:
2027  status = BIO_get_shutdown(bio);
2028  break;
2029 
2030  case BIO_CTRL_SET_CLOSE:
2031  BIO_set_shutdown(bio, (int)arg1);
2032  status = 1;
2033  break;
2034 
2035  case BIO_CTRL_FLUSH:
2036  case BIO_CTRL_DUP:
2037  status = 1;
2038  break;
2039 
2040  default:
2041  status = 0;
2042  break;
2043  }
2044 
2045  return status;
2046 }
2047 
2048 static int transport_layer_bio_new(BIO* bio)
2049 {
2050  WINPR_ASSERT(bio);
2051 
2052  BIO_set_flags(bio, BIO_FLAGS_SHOULD_RETRY);
2053  BIO_set_init(bio, 1);
2054  return 1;
2055 }
2056 
2057 static int transport_layer_bio_free(BIO* bio)
2058 {
2059  if (!bio)
2060  return 0;
2061 
2062  rdpTransportLayer* layer = (rdpTransportLayer*)BIO_get_data(bio);
2063  if (layer)
2064  transport_layer_free(layer);
2065 
2066  BIO_set_data(bio, NULL);
2067  BIO_set_init(bio, 0);
2068  BIO_set_flags(bio, 0);
2069 
2070  return 1;
2071 }
2072 
2073 BIO_METHOD* BIO_s_transport_layer(void)
2074 {
2075  static BIO_METHOD* bio_methods = NULL;
2076 
2077  if (bio_methods == NULL)
2078  {
2079  if (!(bio_methods = BIO_meth_new(BIO_TYPE_SIMPLE, "TransportLayer")))
2080  return NULL;
2081 
2082  BIO_meth_set_write(bio_methods, transport_layer_bio_write);
2083  BIO_meth_set_read(bio_methods, transport_layer_bio_read);
2084  BIO_meth_set_puts(bio_methods, transport_layer_bio_puts);
2085  BIO_meth_set_gets(bio_methods, transport_layer_bio_gets);
2086  BIO_meth_set_ctrl(bio_methods, transport_layer_bio_ctrl);
2087  BIO_meth_set_create(bio_methods, transport_layer_bio_new);
2088  BIO_meth_set_destroy(bio_methods, transport_layer_bio_free);
2089  }
2090 
2091  return bio_methods;
2092 }
FREERDP_API const char * freerdp_settings_get_server_name(const rdpSettings *settings)
A helper function to return the correct server name.