BOOL transport_set_blocking_mode(rdpTransport* transport, BOOL blocking) { transport->blocking = blocking; if (!BIO_set_nonblock(transport->frontBio, blocking ? FALSE : TRUE)) return FALSE; return TRUE; }
BOOL rdg_tls_out_connect(rdpRdg* rdg, const char* hostname, UINT16 port, int timeout) { int sockfd = 0; int status = 0; BIO* socketBio = NULL; BIO* bufferedBio = NULL; rdpSettings* settings = rdg->settings; assert(hostname != NULL); sockfd = freerdp_tcp_connect(rdg->context, settings, settings->GatewayHostname, settings->GatewayPort, timeout); if (sockfd < 1) { return FALSE; } socketBio = BIO_new(BIO_s_simple_socket()); if (!socketBio) { closesocket(sockfd); return FALSE; } BIO_set_fd(socketBio, sockfd, BIO_CLOSE); bufferedBio = BIO_new(BIO_s_buffered_socket()); if (!bufferedBio) { BIO_free(socketBio); return FALSE; } bufferedBio = BIO_push(bufferedBio, socketBio); status = BIO_set_nonblock(bufferedBio, TRUE); if (!status) { BIO_free_all(bufferedBio); return FALSE; } rdg->tlsOut->hostname = settings->GatewayHostname; rdg->tlsOut->port = settings->GatewayPort; rdg->tlsOut->isGatewayTransport = TRUE; status = tls_connect(rdg->tlsOut, bufferedBio); if (status < 1) { return FALSE; } return TRUE; }
BOOL transport_connect(rdpTransport* transport, const char* hostname, UINT16 port, int timeout) { int sockfd; BOOL status = FALSE; rdpSettings* settings = transport->settings; rdpContext* context = transport->context; transport->async = settings->AsyncTransport; if (transport->GatewayEnabled) { if (!status && settings->GatewayHttpTransport) { transport->rdg = rdg_new(transport); if (!transport->rdg) return FALSE; status = rdg_connect(transport->rdg, hostname, port, timeout); if (status) { transport->frontBio = transport->rdg->frontBio; BIO_set_nonblock(transport->frontBio, 0); transport->layer = TRANSPORT_LAYER_TSG; status = TRUE; } else { rdg_free(transport->rdg); transport->rdg = NULL; } } if (!status && settings->GatewayRpcTransport) { transport->tsg = tsg_new(transport); if (!transport->tsg) return FALSE; status = tsg_connect(transport->tsg, hostname, port, timeout); if (status) { transport->frontBio = transport->tsg->bio; transport->layer = TRANSPORT_LAYER_TSG; status = TRUE; } else { tsg_free(transport->tsg); transport->tsg = NULL; } } } else { sockfd = freerdp_tcp_connect(context, settings, hostname, port, timeout); if (sockfd < 1) return FALSE; if (!transport_attach(transport, sockfd)) return FALSE; status = TRUE; } if (status) { if (transport->async) { if (!(transport->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL))) { WLog_ERR(TAG, "Failed to create transport stop event"); return FALSE; } if (!(transport->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) transport_client_thread, transport, 0, NULL))) { WLog_ERR(TAG, "Failed to create transport client thread"); CloseHandle(transport->stopEvent); transport->stopEvent = NULL; return FALSE; } } } return status; }
static BOOL rdg_tls_connect(rdpRdg* rdg, rdpTls* tls, const char* peerAddress, int timeout) { int sockfd = 0; int status = 0; BIO* socketBio = NULL; BIO* bufferedBio = NULL; rdpSettings* settings = rdg->settings; const char* peerHostname = settings->GatewayHostname; UINT16 peerPort = settings->GatewayPort; const char* proxyUsername, *proxyPassword; BOOL isProxyConnection = proxy_prepare(settings, &peerHostname, &peerPort, &proxyUsername, &proxyPassword); sockfd = freerdp_tcp_connect(rdg->context, settings, peerAddress ? peerAddress : peerHostname, peerPort, timeout); if (sockfd < 0) { return FALSE; } socketBio = BIO_new(BIO_s_simple_socket()); if (!socketBio) { closesocket(sockfd); return FALSE; } BIO_set_fd(socketBio, sockfd, BIO_CLOSE); bufferedBio = BIO_new(BIO_s_buffered_socket()); if (!bufferedBio) { closesocket(sockfd); BIO_free(socketBio); return FALSE; } bufferedBio = BIO_push(bufferedBio, socketBio); status = BIO_set_nonblock(bufferedBio, TRUE); if (isProxyConnection) { if (!proxy_connect(settings, bufferedBio, proxyUsername, proxyPassword, settings->GatewayHostname, settings->GatewayPort)) return FALSE; } if (!status) { BIO_free_all(bufferedBio); return FALSE; } tls->hostname = settings->GatewayHostname; tls->port = settings->GatewayPort; tls->isGatewayTransport = TRUE; status = tls_connect(tls, bufferedBio); return (status >= 1); }
BOOL transport_connect(rdpTransport* transport, const char* hostname, UINT16 port, int timeout) { int sockfd; BOOL status = FALSE; rdpSettings* settings = transport->settings; rdpContext* context = transport->context; BOOL rpcFallback = !settings->GatewayHttpTransport; if (transport->GatewayEnabled) { if (!status && settings->GatewayHttpTransport) { transport->rdg = rdg_new(transport); if (!transport->rdg) return FALSE; status = rdg_connect(transport->rdg, timeout, &rpcFallback); if (status) { transport->frontBio = transport->rdg->frontBio; BIO_set_nonblock(transport->frontBio, 0); transport->layer = TRANSPORT_LAYER_TSG; status = TRUE; } else { rdg_free(transport->rdg); transport->rdg = NULL; } } if (!status && settings->GatewayRpcTransport && rpcFallback) { transport->tsg = tsg_new(transport); if (!transport->tsg) return FALSE; status = tsg_connect(transport->tsg, hostname, port, timeout); if (status) { transport->frontBio = tsg_get_bio(transport->tsg); transport->layer = TRANSPORT_LAYER_TSG; status = TRUE; } else { tsg_free(transport->tsg); transport->tsg = NULL; } } } else { UINT16 peerPort; const char* proxyHostname, *proxyUsername, *proxyPassword; BOOL isProxyConnection = proxy_prepare(settings, &proxyHostname, &peerPort, &proxyUsername, &proxyPassword); if (isProxyConnection) sockfd = freerdp_tcp_connect(context, settings, proxyHostname, peerPort, timeout); else sockfd = freerdp_tcp_connect(context, settings, hostname, port, timeout); if (sockfd < 0) return FALSE; if (!transport_attach(transport, sockfd)) return FALSE; if (isProxyConnection) { if (!proxy_connect(settings, transport->frontBio, proxyUsername, proxyPassword, hostname, port)) return FALSE; } status = TRUE; } return status; }
static int rpc_channel_tls_connect(RpcChannel* channel, int timeout) { int sockfd; rdpTls* tls; int tlsStatus; BIO* socketBio; BIO* bufferedBio; rdpRpc* rpc = channel->rpc; rdpContext* context = rpc->context; rdpSettings* settings = context->settings; const char* peerHostname = settings->GatewayHostname; UINT16 peerPort = settings->GatewayPort; const char *proxyUsername = settings->ProxyUsername, *proxyPassword = settings->ProxyPassword; BOOL isProxyConnection = proxy_prepare(settings, &peerHostname, &peerPort, &proxyUsername, &proxyPassword); sockfd = freerdp_tcp_connect(context, settings, peerHostname, peerPort, timeout); if (sockfd < 1) return -1; socketBio = BIO_new(BIO_s_simple_socket()); if (!socketBio) return FALSE; BIO_set_fd(socketBio, sockfd, BIO_CLOSE); bufferedBio = BIO_new(BIO_s_buffered_socket()); if (!bufferedBio) return FALSE; bufferedBio = BIO_push(bufferedBio, socketBio); if (!BIO_set_nonblock(bufferedBio, TRUE)) return -1; if (isProxyConnection) { if (!proxy_connect(settings, bufferedBio, proxyUsername, proxyPassword, settings->GatewayHostname, settings->GatewayPort)) return -1; } channel->bio = bufferedBio; tls = channel->tls = tls_new(settings); if (!tls) return -1; tls->hostname = settings->GatewayHostname; tls->port = settings->GatewayPort; tls->isGatewayTransport = TRUE; tlsStatus = tls_connect(tls, bufferedBio); if (tlsStatus < 1) { if (tlsStatus < 0) { if (!freerdp_get_last_error(context)) freerdp_set_last_error(context, FREERDP_ERROR_TLS_CONNECT_FAILED); } else { if (!freerdp_get_last_error(context)) freerdp_set_last_error(context, FREERDP_ERROR_CONNECT_CANCELLED); } return -1; } return 1; }