libfreerdp-core: fix gateway connectivity on Windows
authorMarc-André Moreau <marcandre.moreau@gmail.com>
Thu, 17 Sep 2015 18:32:40 +0000 (14:32 -0400)
committerMarc-André Moreau <marcandre.moreau@gmail.com>
Thu, 17 Sep 2015 18:32:40 +0000 (14:32 -0400)
libfreerdp/core/gateway/ntlm.c
libfreerdp/crypto/tls.c

index eec770b..c9795b6 100644 (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]",
index 3259bcc..82ecea9 100644 (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
+               int fd;
+               int status;
                struct pollfd pollfds;
-#else
-               struct timeval tv;
+#elif !defined(_WIN32)
+               int fd;
+               int status;
                fd_set rset;
+               struct timeval tv;
+#else
+               HANDLE event;
+               DWORD status;
 #endif
-               int fd;
 
                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);