Merge branch 'master' of git://github.com/awakecoding/FreeRDP
This commit is contained in:
commit
0f56b1a3dd
@ -81,6 +81,7 @@ struct rdp_tls
|
|||||||
int port;
|
int port;
|
||||||
int alertLevel;
|
int alertLevel;
|
||||||
int alertDescription;
|
int alertDescription;
|
||||||
|
BOOL isGatewayTransport;
|
||||||
};
|
};
|
||||||
|
|
||||||
FREERDP_API int tls_connect(rdpTls* tls, BIO *underlying);
|
FREERDP_API int tls_connect(rdpTls* tls, BIO *underlying);
|
||||||
|
@ -220,18 +220,18 @@ BOOL nego_tcp_connect(rdpNego* nego)
|
|||||||
{
|
{
|
||||||
/* Attempt a direct connection first, and then fallback to using the gateway */
|
/* Attempt a direct connection first, and then fallback to using the gateway */
|
||||||
transport_set_gateway_enabled(nego->transport, FALSE);
|
transport_set_gateway_enabled(nego->transport, FALSE);
|
||||||
nego->tcp_connected = transport_connect(nego->transport, nego->hostname, nego->port);
|
nego->tcp_connected = transport_connect(nego->transport, nego->hostname, nego->port, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!nego->tcp_connected)
|
if (!nego->tcp_connected)
|
||||||
{
|
{
|
||||||
transport_set_gateway_enabled(nego->transport, TRUE);
|
transport_set_gateway_enabled(nego->transport, TRUE);
|
||||||
nego->tcp_connected = transport_connect(nego->transport, nego->hostname, nego->port);
|
nego->tcp_connected = transport_connect(nego->transport, nego->hostname, nego->port, 15);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
nego->tcp_connected = transport_connect(nego->transport, nego->hostname, nego->port);
|
nego->tcp_connected = transport_connect(nego->transport, nego->hostname, nego->port, 15);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -284,8 +284,9 @@ void tcp_get_mac_address(rdpTcp* tcp)
|
|||||||
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); */
|
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); */
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL tcp_connect(rdpTcp* tcp, const char* hostname, int port)
|
BOOL tcp_connect(rdpTcp* tcp, const char* hostname, int port, int timeout)
|
||||||
{
|
{
|
||||||
|
int status;
|
||||||
UINT32 option_value;
|
UINT32 option_value;
|
||||||
socklen_t option_len;
|
socklen_t option_len;
|
||||||
|
|
||||||
@ -295,26 +296,55 @@ BOOL tcp_connect(rdpTcp* tcp, const char* hostname, int port)
|
|||||||
if (hostname[0] == '/')
|
if (hostname[0] == '/')
|
||||||
{
|
{
|
||||||
tcp->sockfd = freerdp_uds_connect(hostname);
|
tcp->sockfd = freerdp_uds_connect(hostname);
|
||||||
|
|
||||||
if (tcp->sockfd < 0)
|
if (tcp->sockfd < 0)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
tcp->socketBio = BIO_new_fd(tcp->sockfd, 1);
|
tcp->socketBio = BIO_new_fd(tcp->sockfd, 1);
|
||||||
|
|
||||||
if (!tcp->socketBio)
|
if (!tcp->socketBio)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
fd_set cfds;
|
||||||
|
struct timeval tv;
|
||||||
|
|
||||||
tcp->socketBio = BIO_new(BIO_s_connect());
|
tcp->socketBio = BIO_new(BIO_s_connect());
|
||||||
|
|
||||||
if (!tcp->socketBio)
|
if (!tcp->socketBio)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (BIO_set_conn_hostname(tcp->socketBio, hostname) < 0 || BIO_set_conn_int_port(tcp->socketBio, &port) < 0)
|
if (BIO_set_conn_hostname(tcp->socketBio, hostname) < 0 || BIO_set_conn_int_port(tcp->socketBio, &port) < 0)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (BIO_do_connect(tcp->socketBio) <= 0)
|
BIO_set_nbio(tcp->socketBio, 1);
|
||||||
|
|
||||||
|
status = BIO_do_connect(tcp->socketBio);
|
||||||
|
|
||||||
|
if ((status <= 0) && !BIO_should_retry(tcp->socketBio))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
tcp->sockfd = BIO_get_fd(tcp->socketBio, NULL);
|
tcp->sockfd = BIO_get_fd(tcp->socketBio, NULL);
|
||||||
|
|
||||||
|
if (tcp->sockfd < 0)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (status <= 0)
|
||||||
|
{
|
||||||
|
FD_ZERO(&cfds);
|
||||||
|
FD_SET(tcp->sockfd, &cfds);
|
||||||
|
|
||||||
|
tv.tv_sec = timeout;
|
||||||
|
tv.tv_usec = 0;
|
||||||
|
|
||||||
|
status = select(tcp->sockfd + 1, NULL, &cfds, NULL, &tv);
|
||||||
|
|
||||||
|
if (status == 0)
|
||||||
|
{
|
||||||
|
return FALSE; /* timeout */
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SetEventFileDescriptor(tcp->event, tcp->sockfd);
|
SetEventFileDescriptor(tcp->event, tcp->sockfd);
|
||||||
@ -324,6 +354,7 @@ BOOL tcp_connect(rdpTcp* tcp, const char* hostname, int port)
|
|||||||
|
|
||||||
option_value = 1;
|
option_value = 1;
|
||||||
option_len = sizeof(option_value);
|
option_len = sizeof(option_value);
|
||||||
|
|
||||||
if (setsockopt(tcp->sockfd, IPPROTO_TCP, TCP_NODELAY, (void*) &option_value, option_len) < 0)
|
if (setsockopt(tcp->sockfd, IPPROTO_TCP, TCP_NODELAY, (void*) &option_value, option_len) < 0)
|
||||||
fprintf(stderr, "%s: unable to set TCP_NODELAY\n", __FUNCTION__);
|
fprintf(stderr, "%s: unable to set TCP_NODELAY\n", __FUNCTION__);
|
||||||
|
|
||||||
@ -334,6 +365,7 @@ BOOL tcp_connect(rdpTcp* tcp, const char* hostname, int port)
|
|||||||
{
|
{
|
||||||
option_value = 1024 * 32;
|
option_value = 1024 * 32;
|
||||||
option_len = sizeof(option_value);
|
option_len = sizeof(option_value);
|
||||||
|
|
||||||
if (setsockopt(tcp->sockfd, SOL_SOCKET, SO_RCVBUF, (void*) &option_value, option_len) < 0)
|
if (setsockopt(tcp->sockfd, SOL_SOCKET, SO_RCVBUF, (void*) &option_value, option_len) < 0)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "%s: unable to set receive buffer len\n", __FUNCTION__);
|
fprintf(stderr, "%s: unable to set receive buffer len\n", __FUNCTION__);
|
||||||
@ -346,15 +378,17 @@ BOOL tcp_connect(rdpTcp* tcp, const char* hostname, int port)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
tcp->bufferedBio = BIO_new(BIO_s_buffered_socket());
|
tcp->bufferedBio = BIO_new(BIO_s_buffered_socket());
|
||||||
|
|
||||||
if (!tcp->bufferedBio)
|
if (!tcp->bufferedBio)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
tcp->bufferedBio->ptr = tcp;
|
tcp->bufferedBio->ptr = tcp;
|
||||||
|
|
||||||
tcp->bufferedBio = BIO_push(tcp->bufferedBio, tcp->socketBio);
|
tcp->bufferedBio = BIO_push(tcp->bufferedBio, tcp->socketBio);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BOOL tcp_disconnect(rdpTcp* tcp)
|
BOOL tcp_disconnect(rdpTcp* tcp)
|
||||||
{
|
{
|
||||||
freerdp_tcp_disconnect(tcp->sockfd);
|
freerdp_tcp_disconnect(tcp->sockfd);
|
||||||
@ -504,6 +538,7 @@ rdpTcp* tcp_new(rdpSettings* settings)
|
|||||||
rdpTcp* tcp;
|
rdpTcp* tcp;
|
||||||
|
|
||||||
tcp = (rdpTcp*) calloc(1, sizeof(rdpTcp));
|
tcp = (rdpTcp*) calloc(1, sizeof(rdpTcp));
|
||||||
|
|
||||||
if (!tcp)
|
if (!tcp)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@ -515,6 +550,7 @@ rdpTcp* tcp_new(rdpSettings* settings)
|
|||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
tcp->event = CreateFileDescriptorEvent(NULL, FALSE, FALSE, tcp->sockfd);
|
tcp->event = CreateFileDescriptorEvent(NULL, FALSE, FALSE, tcp->sockfd);
|
||||||
|
|
||||||
if (!tcp->event || tcp->event == INVALID_HANDLE_VALUE)
|
if (!tcp->event || tcp->event == INVALID_HANDLE_VALUE)
|
||||||
goto out_ringbuffer;
|
goto out_ringbuffer;
|
||||||
#endif
|
#endif
|
||||||
|
@ -60,7 +60,7 @@ struct rdp_tcp
|
|||||||
HANDLE event;
|
HANDLE event;
|
||||||
};
|
};
|
||||||
|
|
||||||
BOOL tcp_connect(rdpTcp* tcp, const char* hostname, int port);
|
BOOL tcp_connect(rdpTcp* tcp, const char* hostname, int port, int timeout);
|
||||||
BOOL tcp_disconnect(rdpTcp* tcp);
|
BOOL tcp_disconnect(rdpTcp* tcp);
|
||||||
int tcp_read(rdpTcp* tcp, BYTE* data, int length);
|
int tcp_read(rdpTcp* tcp, BYTE* data, int length);
|
||||||
int tcp_write(rdpTcp* tcp, BYTE* data, int length);
|
int tcp_write(rdpTcp* tcp, BYTE* data, int length);
|
||||||
|
@ -268,6 +268,8 @@ BOOL transport_connect_tls(rdpTransport* transport)
|
|||||||
if (targetTls->port == 0)
|
if (targetTls->port == 0)
|
||||||
targetTls->port = 3389;
|
targetTls->port = 3389;
|
||||||
|
|
||||||
|
targetTls->isGatewayTransport = FALSE;
|
||||||
|
|
||||||
tls_status = tls_connect(targetTls, targetBio);
|
tls_status = tls_connect(targetTls, targetBio);
|
||||||
|
|
||||||
if (tls_status < 1)
|
if (tls_status < 1)
|
||||||
@ -373,6 +375,7 @@ BOOL transport_tsg_connect(rdpTransport* transport, const char* hostname, UINT16
|
|||||||
context = instance->context;
|
context = instance->context;
|
||||||
|
|
||||||
tsg = tsg_new(transport);
|
tsg = tsg_new(transport);
|
||||||
|
|
||||||
if (!tsg)
|
if (!tsg)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
@ -383,12 +386,15 @@ BOOL transport_tsg_connect(rdpTransport* transport, const char* hostname, UINT16
|
|||||||
if (!transport->TlsIn)
|
if (!transport->TlsIn)
|
||||||
{
|
{
|
||||||
transport->TlsIn = tls_new(settings);
|
transport->TlsIn = tls_new(settings);
|
||||||
|
|
||||||
if (!transport->TlsIn)
|
if (!transport->TlsIn)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!transport->TlsOut)
|
if (!transport->TlsOut)
|
||||||
{
|
{
|
||||||
transport->TlsOut = tls_new(settings);
|
transport->TlsOut = tls_new(settings);
|
||||||
|
|
||||||
if (!transport->TlsOut)
|
if (!transport->TlsOut)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
@ -400,8 +406,10 @@ BOOL transport_tsg_connect(rdpTransport* transport, const char* hostname, UINT16
|
|||||||
transport->TlsIn->hostname = transport->TlsOut->hostname = settings->GatewayHostname;
|
transport->TlsIn->hostname = transport->TlsOut->hostname = settings->GatewayHostname;
|
||||||
transport->TlsIn->port = transport->TlsOut->port = settings->GatewayPort;
|
transport->TlsIn->port = transport->TlsOut->port = settings->GatewayPort;
|
||||||
|
|
||||||
|
transport->TlsIn->isGatewayTransport = TRUE;
|
||||||
|
|
||||||
tls_status = tls_connect(transport->TlsIn, transport->TcpIn->bufferedBio);
|
tls_status = tls_connect(transport->TlsIn, transport->TcpIn->bufferedBio);
|
||||||
|
|
||||||
if (tls_status < 1)
|
if (tls_status < 1)
|
||||||
{
|
{
|
||||||
if (tls_status < 0)
|
if (tls_status < 0)
|
||||||
@ -418,7 +426,10 @@ BOOL transport_tsg_connect(rdpTransport* transport, const char* hostname, UINT16
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
transport->TlsOut->isGatewayTransport = TRUE;
|
||||||
|
|
||||||
tls_status = tls_connect(transport->TlsOut, transport->TcpOut->bufferedBio);
|
tls_status = tls_connect(transport->TlsOut, transport->TcpOut->bufferedBio);
|
||||||
|
|
||||||
if (tls_status < 1)
|
if (tls_status < 1)
|
||||||
{
|
{
|
||||||
if (tls_status < 0)
|
if (tls_status < 0)
|
||||||
@ -440,10 +451,11 @@ BOOL transport_tsg_connect(rdpTransport* transport, const char* hostname, UINT16
|
|||||||
|
|
||||||
transport->frontBio = BIO_new(BIO_s_tsg());
|
transport->frontBio = BIO_new(BIO_s_tsg());
|
||||||
transport->frontBio->ptr = tsg;
|
transport->frontBio->ptr = tsg;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL transport_connect(rdpTransport* transport, const char* hostname, UINT16 port)
|
BOOL transport_connect(rdpTransport* transport, const char* hostname, UINT16 port, int timeout)
|
||||||
{
|
{
|
||||||
BOOL status = FALSE;
|
BOOL status = FALSE;
|
||||||
rdpSettings* settings = transport->settings;
|
rdpSettings* settings = transport->settings;
|
||||||
@ -456,21 +468,22 @@ BOOL transport_connect(rdpTransport* transport, const char* hostname, UINT16 por
|
|||||||
transport->SplitInputOutput = TRUE;
|
transport->SplitInputOutput = TRUE;
|
||||||
transport->TcpOut = tcp_new(settings);
|
transport->TcpOut = tcp_new(settings);
|
||||||
|
|
||||||
if (!tcp_connect(transport->TcpIn, settings->GatewayHostname, settings->GatewayPort) ||
|
if (!tcp_connect(transport->TcpIn, settings->GatewayHostname, settings->GatewayPort, timeout) ||
|
||||||
!tcp_set_blocking_mode(transport->TcpIn, FALSE))
|
!tcp_set_blocking_mode(transport->TcpIn, FALSE))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (!tcp_connect(transport->TcpOut, settings->GatewayHostname, settings->GatewayPort) ||
|
if (!tcp_connect(transport->TcpOut, settings->GatewayHostname, settings->GatewayPort, timeout) ||
|
||||||
!tcp_set_blocking_mode(transport->TcpOut, FALSE))
|
!tcp_set_blocking_mode(transport->TcpOut, FALSE))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (!transport_tsg_connect(transport, hostname, port))
|
if (!transport_tsg_connect(transport, hostname, port))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
status = TRUE;
|
status = TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
status = tcp_connect(transport->TcpIn, hostname, port);
|
status = tcp_connect(transport->TcpIn, hostname, port, timeout);
|
||||||
|
|
||||||
transport->SplitInputOutput = FALSE;
|
transport->SplitInputOutput = FALSE;
|
||||||
transport->TcpOut = transport->TcpIn;
|
transport->TcpOut = transport->TcpIn;
|
||||||
@ -635,6 +648,7 @@ static int transport_wait_for_read(rdpTransport* transport)
|
|||||||
rdpTcp *tcpIn;
|
rdpTcp *tcpIn;
|
||||||
|
|
||||||
tcpIn = transport->TcpIn;
|
tcpIn = transport->TcpIn;
|
||||||
|
|
||||||
if (tcpIn->readBlocked)
|
if (tcpIn->readBlocked)
|
||||||
{
|
{
|
||||||
rsetPtr = &rset;
|
rsetPtr = &rset;
|
||||||
@ -660,7 +674,6 @@ static int transport_wait_for_read(rdpTransport* transport)
|
|||||||
return select(tcpIn->sockfd + 1, rsetPtr, wsetPtr, NULL, &tv);
|
return select(tcpIn->sockfd + 1, rsetPtr, wsetPtr, NULL, &tv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int transport_wait_for_write(rdpTransport* transport)
|
static int transport_wait_for_write(rdpTransport* transport)
|
||||||
{
|
{
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
|
@ -86,7 +86,7 @@ struct rdp_transport
|
|||||||
};
|
};
|
||||||
|
|
||||||
wStream* transport_send_stream_init(rdpTransport* transport, int size);
|
wStream* transport_send_stream_init(rdpTransport* transport, int size);
|
||||||
BOOL transport_connect(rdpTransport* transport, const char* hostname, UINT16 port);
|
BOOL transport_connect(rdpTransport* transport, const char* hostname, UINT16 port, int timeout);
|
||||||
void transport_attach(rdpTransport* transport, int sockfd);
|
void transport_attach(rdpTransport* transport, int sockfd);
|
||||||
BOOL transport_disconnect(rdpTransport* transport);
|
BOOL transport_disconnect(rdpTransport* transport);
|
||||||
BOOL transport_connect_rdp(rdpTransport* transport);
|
BOOL transport_connect_rdp(rdpTransport* transport);
|
||||||
|
@ -591,7 +591,7 @@ int tls_verify_certificate(rdpTls* tls, CryptoCert cert, char* hostname, int por
|
|||||||
|
|
||||||
if (instance->VerifyX509Certificate)
|
if (instance->VerifyX509Certificate)
|
||||||
{
|
{
|
||||||
status = instance->VerifyX509Certificate(instance, pemCert, length, hostname, port, 0);
|
status = instance->VerifyX509Certificate(instance, pemCert, length, hostname, port, tls->isGatewayTransport);
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(stderr, "%s: (length = %d) status: %d\n%s\n", __FUNCTION__, length, status, pemCert);
|
fprintf(stderr, "%s: (length = %d) status: %d\n%s\n", __FUNCTION__, length, status, pemCert);
|
||||||
@ -799,6 +799,7 @@ rdpTls* tls_new(rdpSettings* settings)
|
|||||||
rdpTls* tls;
|
rdpTls* tls;
|
||||||
|
|
||||||
tls = (rdpTls*) calloc(1, sizeof(rdpTls));
|
tls = (rdpTls*) calloc(1, sizeof(rdpTls));
|
||||||
|
|
||||||
if (!tls)
|
if (!tls)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@ -807,11 +808,13 @@ rdpTls* tls_new(rdpSettings* settings)
|
|||||||
|
|
||||||
tls->settings = settings;
|
tls->settings = settings;
|
||||||
tls->certificate_store = certificate_store_new(settings);
|
tls->certificate_store = certificate_store_new(settings);
|
||||||
|
|
||||||
if (!tls->certificate_store)
|
if (!tls->certificate_store)
|
||||||
goto out_free;
|
goto out_free;
|
||||||
|
|
||||||
tls->alertLevel = TLS_ALERT_LEVEL_WARNING;
|
tls->alertLevel = TLS_ALERT_LEVEL_WARNING;
|
||||||
tls->alertDescription = TLS_ALERT_DESCRIPTION_CLOSE_NOTIFY;
|
tls->alertDescription = TLS_ALERT_DESCRIPTION_CLOSE_NOTIFY;
|
||||||
|
|
||||||
return tls;
|
return tls;
|
||||||
|
|
||||||
out_free:
|
out_free:
|
||||||
|
Loading…
Reference in New Issue
Block a user