libfreerdp-core: fix gateway connectivity on Windows

This commit is contained in:
Marc-André Moreau 2015-09-17 14:32:40 -04:00
parent 8a5c55788b
commit 9c35b73fb6
2 changed files with 44 additions and 12 deletions

View File

@ -234,21 +234,25 @@ BOOL ntlm_authenticate(rdpNtlm* ntlm)
WLog_VRB(TAG, "InitializeSecurityContext status %s [%08X]",
GetSecurityStatusString(status), status);
if ((status == SEC_I_COMPLETE_AND_CONTINUE) || (status == SEC_I_COMPLETE_NEEDED) || (status == SEC_E_OK))
{
if (ntlm->table->CompleteAuthToken)
if ((status != SEC_E_OK) && ntlm->table->CompleteAuthToken)
{
SECURITY_STATUS cStatus;
cStatus = ntlm->table->CompleteAuthToken(&ntlm->context, &ntlm->outputBufferDesc);
if (cStatus != SEC_E_OK)
{
WLog_WARN(TAG, "CompleteAuthToken status %s [%08X]",
GetSecurityStatusString(cStatus), cStatus);
GetSecurityStatusString(cStatus), cStatus);
return FALSE;
}
}
status = ntlm->table->QueryContextAttributes(&ntlm->context, SECPKG_ATTR_SIZES, &ntlm->ContextSizes);
if (status != SEC_E_OK)
{
WLog_ERR(TAG, "QueryContextAttributes SECPKG_ATTR_SIZES failure %s [%08X]",

View File

@ -637,17 +637,23 @@ BOOL tls_prepare(rdpTls* tls, BIO* underlying, const SSL_METHOD* method, int opt
int tls_do_handshake(rdpTls* tls, BOOL clientMode)
{
CryptoCert cert;
int verify_status, status;
int verify_status;
do
{
#ifdef HAVE_POLL_H
struct pollfd pollfds;
#else
struct timeval tv;
fd_set rset;
#endif
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);
@ -657,6 +663,7 @@ int tls_do_handshake(rdpTls* tls, BOOL clientMode)
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);
@ -666,6 +673,15 @@ int tls_do_handshake(rdpTls* tls, BOOL clientMode)
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;
@ -677,23 +693,35 @@ int tls_do_handshake(rdpTls* tls, BOOL clientMode)
status = poll(&pollfds, 1, 10 * 1000);
}
while ((status < 0) && (errno == EINTR));
#else
#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.");
@ -701,6 +729,7 @@ int tls_do_handshake(rdpTls* tls, BOOL clientMode)
}
tls->Bindings = tls_get_channel_bindings(cert->px509);
if (!tls->Bindings)
{
WLog_ERR(TAG, "unable to retrieve bindings");
@ -715,10 +744,9 @@ int tls_do_handshake(rdpTls* tls, BOOL clientMode)
goto out;
}
/* Note: server-side NLA needs public keys (keys from us, the server) but no
* certificate verify
*/
/* 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);