예제 #1
0
파일: transport.c 프로젝트: ilammy/FreeRDP
BOOL transport_disconnect(rdpTransport* transport)
{
	BOOL status = TRUE;

	if (!transport)
		return FALSE;

	if (transport->tls)
	{
		tls_free(transport->tls);
		transport->tls = NULL;
	}
	else
	{
		if (transport->frontBio)
			BIO_free_all(transport->frontBio);
	}

	if (transport->tsg)
	{
		tsg_free(transport->tsg);
		transport->tsg = NULL;
	}

	if (transport->rdg)
	{
		rdg_free(transport->rdg);
		transport->rdg = NULL;
	}

	transport->frontBio = NULL;
	transport->layer = TRANSPORT_LAYER_TCP;
	return status;
}
예제 #2
0
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;
}
예제 #3
0
파일: rdg.c 프로젝트: mfleisz/FreeRDP
rdpRdg* rdg_new(rdpTransport* transport)
{
	rdpRdg* rdg;
	RPC_CSTR stringUuid;
	char bracedUuid[40];
	RPC_STATUS rpcStatus;
	assert(transport != NULL);
	rdg = (rdpRdg*) calloc(1, sizeof(rdpRdg));

	if (rdg)
	{
		rdg->state = RDG_CLIENT_STATE_INITIAL;
		rdg->context = transport->context;
		rdg->settings = rdg->context->settings;
		rdg->extAuth = HTTP_EXTENDED_AUTH_NONE;

		if (rdg->settings->GatewayAccessToken)
			rdg->extAuth = HTTP_EXTENDED_AUTH_PAA;

		UuidCreate(&rdg->guid);
		rpcStatus = UuidToStringA(&rdg->guid, &stringUuid);

		if (rpcStatus == RPC_S_OUT_OF_MEMORY)
			goto rdg_alloc_error;

		sprintf_s(bracedUuid, sizeof(bracedUuid), "{%s}", stringUuid);
		RpcStringFreeA(&stringUuid);
		rdg->tlsOut = tls_new(rdg->settings);

		if (!rdg->tlsOut)
			goto rdg_alloc_error;

		rdg->tlsIn = tls_new(rdg->settings);

		if (!rdg->tlsIn)
			goto rdg_alloc_error;

		rdg->http = http_context_new();

		if (!rdg->http)
			goto rdg_alloc_error;

		http_context_set_uri(rdg->http, "/remoteDesktopGateway/");
		http_context_set_accept(rdg->http, "*/*");
		http_context_set_cache_control(rdg->http, "no-cache");
		http_context_set_pragma(rdg->http, "no-cache");
		http_context_set_connection(rdg->http, "Keep-Alive");
		http_context_set_user_agent(rdg->http, "MS-RDGateway/1.0");
		http_context_set_host(rdg->http, rdg->settings->GatewayHostname);
		http_context_set_rdg_connection_id(rdg->http, bracedUuid);

		if (!rdg->http->URI || !rdg->http->Accept || !rdg->http->CacheControl ||
		    !rdg->http->Pragma || !rdg->http->Connection || !rdg->http->UserAgent
		    || !rdg->http->Host || !rdg->http->RdgConnectionId)
		{
			goto rdg_alloc_error;
		}

		if (rdg->extAuth != HTTP_EXTENDED_AUTH_NONE)
		{
			switch (rdg->extAuth)
			{
				case HTTP_EXTENDED_AUTH_PAA:
					http_context_set_rdg_auth_scheme(rdg->http, "PAA");

					if (!rdg->http->RdgAuthScheme)
						goto rdg_alloc_error;

					break;

				default:
					WLog_DBG(TAG, "RDG extended authentication method %d not supported", rdg->extAuth);
			}
		}

		rdg->frontBio = BIO_new(BIO_s_rdg());

		if (!rdg->frontBio)
			goto rdg_alloc_error;

		BIO_set_data(rdg->frontBio, rdg);
		InitializeCriticalSection(&rdg->writeSection);
	}

	return rdg;
rdg_alloc_error:
	rdg_free(rdg);
	return NULL;
}
예제 #4
0
rdpRdg* rdg_new(rdpTransport* transport)
{
	rdpRdg* rdg;
	RPC_CSTR stringUuid;
	char bracedUuid[40];
	RPC_STATUS rpcStatus;

	assert(transport != NULL);

	rdg = (rdpRdg*) calloc(1, sizeof(rdpRdg));

	if (rdg)
	{
		rdg->state = RDG_CLIENT_STATE_INITIAL;
		rdg->context = transport->context;
		rdg->settings = rdg->context->settings;

		UuidCreate(&rdg->guid);

		rpcStatus = UuidToStringA(&rdg->guid, &stringUuid);

		if (rpcStatus == RPC_S_OUT_OF_MEMORY)
			goto rdg_alloc_error;

		sprintf_s(bracedUuid, sizeof(bracedUuid), "{%s}", stringUuid);
		RpcStringFreeA(&stringUuid);

		rdg->tlsOut = tls_new(rdg->settings);

		if (!rdg->tlsOut)
			goto rdg_alloc_error;

		rdg->tlsIn = tls_new(rdg->settings);

		if (!rdg->tlsIn)
			goto rdg_alloc_error;

		rdg->http = http_context_new();

		if (!rdg->http)
			goto rdg_alloc_error;

		http_context_set_uri(rdg->http, "/remoteDesktopGateway/");
		http_context_set_accept(rdg->http, "*/*");
		http_context_set_cache_control(rdg->http, "no-cache");
		http_context_set_pragma(rdg->http, "no-cache");
		http_context_set_connection(rdg->http, "Keep-Alive");
		http_context_set_user_agent(rdg->http, "MS-RDGateway/1.0");
		http_context_set_host(rdg->http, rdg->settings->GatewayHostname);
		http_context_set_rdg_connection_id(rdg->http, bracedUuid);

		if (!rdg->http->URI || !rdg->http->Accept || !rdg->http->CacheControl ||
				!rdg->http->Pragma || !rdg->http->Connection || !rdg->http->UserAgent
				|| !rdg->http->Host || !rdg->http->RdgConnectionId)
		{
			goto rdg_alloc_error;
		}

		rdg->frontBio = BIO_new(BIO_s_rdg());

		if (!rdg->frontBio)
			goto rdg_alloc_error;

		rdg->frontBio->ptr = rdg;

		rdg->readEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

		if (!rdg->readEvent)
			goto rdg_alloc_error;
        
		InitializeCriticalSection(&rdg->writeSection);
	}

	return rdg;

rdg_alloc_error:
	rdg_free(rdg);
	return NULL;
}
예제 #5
0
파일: transport.c 프로젝트: ilammy/FreeRDP
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;
}