Esempio n. 1
0
DWORD rdg_get_event_handles(rdpRdg* rdg, HANDLE* events, DWORD count)
{
	DWORD nCount = 0;
	assert(rdg != NULL);

	if (rdg->tlsOut && rdg->tlsOut->bio)
	{
		if (events && (nCount < count))
		{
			BIO_get_event(rdg->tlsOut->bio, &events[nCount]);
			nCount++;
		}
		else
			return 0;
	}

	if (rdg->tlsIn && rdg->tlsIn->bio)
	{
		if (events && (nCount < count))
		{
			BIO_get_event(rdg->tlsIn->bio, &events[nCount]);
			nCount++;
		}
		else
			return 0;
	}

	return nCount;
}
Esempio n. 2
0
static HANDLE freerdp_peer_get_event_handle(freerdp_peer* client)
{
	HANDLE hEvent = NULL;
	rdpTransport* transport = client->context->rdp->transport;
	BIO_get_event(transport->frontBio, &hEvent);
	return hEvent;
}
Esempio n. 3
0
BOOL rdg_check_event_handles(rdpRdg* rdg)
{
	HANDLE event = NULL;

	assert(rdg != NULL);

	BIO_get_event(rdg->tlsOut->bio, &event);

	if (WaitForSingleObject(event, 0) == WAIT_OBJECT_0)
	{
		return rdg_out_channel_recv(rdg);
	}

	BIO_get_event(rdg->tlsIn->bio, &event);

	if (WaitForSingleObject(event, 0) == WAIT_OBJECT_0)
	{
		return rdg_in_channel_recv(rdg);
	}

	return TRUE;
}
Esempio n. 4
0
static long rdg_bio_ctrl(BIO* bio, int cmd, long arg1, void* arg2)
{
	int status = 0;
	rdpRdg* rdg = (rdpRdg*)bio->ptr;
	rdpTls* tlsOut = rdg->tlsOut;
	rdpTls* tlsIn = rdg->tlsIn;

	if (cmd == BIO_CTRL_FLUSH)
	{
		(void)BIO_flush(tlsOut->bio);
		(void)BIO_flush(tlsIn->bio);
		status = 1;
	}
	else if (cmd == BIO_C_GET_EVENT)
	{
		if (arg2)
		{
			BIO_get_event(rdg->tlsOut->bio, arg2);
			status = 1;
		}
	}
	else if (cmd == BIO_C_SET_NONBLOCK)
	{
		rdg->nonBlocking = arg1;
		status = 1;
	}
	else if (cmd == BIO_C_READ_BLOCKED)
	{
		status = 0;
	}
	else if (cmd == BIO_C_WRITE_BLOCKED)
	{
		status = 0;
	}
	else if (cmd == BIO_C_WAIT_READ)
	{
		int timeout = (int)arg1;
		return BIO_wait_read(tlsOut->bio, timeout);
	}
	else if (cmd == BIO_C_WAIT_WRITE)
	{
		status = 0;
	}

	return status;
}
Esempio n. 5
0
DWORD transport_get_event_handles(rdpTransport* transport, HANDLE* events, DWORD count)
{
	DWORD nCount = 0;
	DWORD tmp;

	if (!transport->GatewayEnabled)
	{
		if (events && (nCount < count))
		{
			if (BIO_get_event(transport->frontBio, &events[nCount]) != 1)
				return 0;
			nCount++;
		}
	}
	else
	{
		if (transport->rdg)
		{
			tmp = rdg_get_event_handles(transport->rdg, events, nCount - count);

			if (tmp == 0)
				return 0;

			nCount = tmp;
		}
		else if (transport->tsg)
		{
			tmp = tsg_get_event_handles(transport->tsg, events, nCount - count);

			if (tmp == 0)
				return 0;

			nCount = tmp;
		}
	}

	return nCount;
}
Esempio n. 6
0
int tls_do_handshake(rdpTls* tls, BOOL clientMode)
{
	CryptoCert cert;
	int verify_status;

	do
	{
#ifdef HAVE_POLL_H
		int fd;
		int status;
		struct pollfd pollfds;
#elif !defined(_WIN32)
		int fd;
		int status;
		fd_set rset;
		struct timeval tv;
#else
		HANDLE event;
		DWORD status;
#endif
		status = BIO_do_handshake(tls->bio);

		if (status == 1)
			break;

		if (!BIO_should_retry(tls->bio))
			return -1;

#ifndef _WIN32
		/* we select() only for read even if we should test both read and write
		 * depending of what have blocked */
		fd = BIO_get_fd(tls->bio, NULL);

		if (fd < 0)
		{
			WLog_ERR(TAG, "unable to retrieve BIO fd");
			return -1;
		}

#else
		BIO_get_event(tls->bio, &event);

		if (!event)
		{
			WLog_ERR(TAG, "unable to retrieve BIO event");
			return -1;
		}

#endif
#ifdef HAVE_POLL_H
		pollfds.fd = fd;
		pollfds.events = POLLIN;
		pollfds.revents = 0;

		do
		{
			status = poll(&pollfds, 1, 10 * 1000);
		}
		while ((status < 0) && (errno == EINTR));

#elif !defined(_WIN32)
		FD_ZERO(&rset);
		FD_SET(fd, &rset);
		tv.tv_sec = 0;
		tv.tv_usec = 10 * 1000; /* 10ms */
		status = _select(fd + 1, &rset, NULL, NULL, &tv);
#else
		status = WaitForSingleObject(event, 10);
#endif
#ifndef _WIN32

		if (status < 0)
		{
			WLog_ERR(TAG, "error during select()");
			return -1;
		}

#else

		if ((status != WAIT_OBJECT_0) && (status != WAIT_TIMEOUT))
		{
			WLog_ERR(TAG, "error during WaitForSingleObject(): 0x%04X", status);
			return -1;
		}

#endif
	}
	while (TRUE);

	cert = tls_get_certificate(tls, clientMode);

	if (!cert)
	{
		WLog_ERR(TAG, "tls_get_certificate failed to return the server certificate.");
		return -1;
	}

	tls->Bindings = tls_get_channel_bindings(cert->px509);

	if (!tls->Bindings)
	{
		WLog_ERR(TAG, "unable to retrieve bindings");
		verify_status = -1;
		goto out;
	}

	if (!crypto_cert_get_public_key(cert, &tls->PublicKey, &tls->PublicKeyLength))
	{
		WLog_ERR(TAG,
		         "crypto_cert_get_public_key failed to return the server public key.");
		verify_status = -1;
		goto out;
	}

	/* server-side NLA needs public keys (keys from us, the server) but no certificate verify */
	verify_status = 1;

	if (clientMode)
	{
		verify_status = tls_verify_certificate(tls, cert, tls->hostname, tls->port);

		if (verify_status < 1)
		{
			WLog_ERR(TAG, "certificate not trusted, aborting.");
			tls_send_alert(tls);
			verify_status = 0;
		}
	}

out:
	tls_free_certificate(cert);
	return verify_status;
}
Esempio n. 7
0
static long rdg_bio_ctrl(BIO* bio, int cmd, long arg1, void* arg2)
{
	int status = 0;
	rdpRdg* rdg = (rdpRdg*) BIO_get_data(bio);
	rdpTls* tlsOut = rdg->tlsOut;
	rdpTls* tlsIn = rdg->tlsIn;

	if (cmd == BIO_CTRL_FLUSH)
	{
		(void)BIO_flush(tlsOut->bio);
		(void)BIO_flush(tlsIn->bio);
		status = 1;
	}
	else if (cmd == BIO_C_GET_EVENT)
	{
		if (arg2)
		{
			BIO_get_event(rdg->tlsOut->bio, arg2);
			status = 1;
		}
	}
	else if (cmd == BIO_C_SET_NONBLOCK)
	{
		status = 1;
	}
	else if (cmd == BIO_C_READ_BLOCKED)
	{
		BIO* bio = tlsOut->bio;
		status = BIO_read_blocked(bio);
	}
	else if (cmd == BIO_C_WRITE_BLOCKED)
	{
		BIO* bio = tlsIn->bio;
		status = BIO_write_blocked(bio);
	}
	else if (cmd == BIO_C_WAIT_READ)
	{
		int timeout = (int) arg1;
		BIO* bio = tlsOut->bio;

		if (BIO_read_blocked(bio))
			return BIO_wait_read(bio, timeout);
		else if (BIO_write_blocked(bio))
			return BIO_wait_write(bio, timeout);
		else
			status = 1;
	}
	else if (cmd == BIO_C_WAIT_WRITE)
	{
		int timeout = (int) arg1;
		BIO* bio = tlsIn->bio;

		if (BIO_write_blocked(bio))
			status = BIO_wait_write(bio, timeout);
		else if (BIO_read_blocked(bio))
			status = BIO_wait_read(bio, timeout);
		else
			status = 1;
	}

	return status;
}
Esempio n. 8
0
DWORD transport_get_event_handles(rdpTransport* transport, HANDLE* events,
                                  DWORD count)
{
	DWORD nCount = 1; /* always the reread Event */
	DWORD tmp;

	if (events)
	{
		if (count < 1)
		{
			WLog_Print(transport->log, WLOG_ERROR, "%s: provided handles array is too small", __FUNCTION__);
			return 0;
		}

		events[0] = transport->rereadEvent;
	}

	if (!transport->GatewayEnabled)
	{
		nCount++;

		if (events)
		{
			if (nCount > count)
			{
				WLog_Print(transport->log, WLOG_ERROR,
				           "%s: provided handles array is too small (count=%"PRIu32" nCount=%"PRIu32")",
				           __FUNCTION__, count, nCount);
				return 0;
			}

			if (BIO_get_event(transport->frontBio, &events[1]) != 1)
			{
				WLog_Print(transport->log, WLOG_ERROR, "%s: error getting the frontBio handle", __FUNCTION__);
				return 0;
			}
		}
	}
	else
	{
		if (transport->rdg)
		{
			tmp = rdg_get_event_handles(transport->rdg, &events[1], count - 1);

			if (tmp == 0)
				return 0;

			nCount += tmp;
		}
		else if (transport->tsg)
		{
			tmp = tsg_get_event_handles(transport->tsg, &events[1], count - 1);

			if (tmp == 0)
				return 0;

			nCount += tmp;
		}
	}

	return nCount;
}