Commit 980dfa60 authored by Christian Beier's avatar Christian Beier

Fix libvncclient TLS for Windows builds.

GnuTLS seems to expect proper errno values internally. So set them in our
custom push/pull functions. Parts of the patch stolen from libcurl, thanks!
Signed-off-by: 's avatarChristian Beier <dontmind@freeshell.org>
parent 8909e9fe
...@@ -19,6 +19,14 @@ ...@@ -19,6 +19,14 @@
#include <rfb/rfbclient.h> #include <rfb/rfbclient.h>
#include <errno.h> #include <errno.h>
#ifdef WIN32
#undef SOCKET
#include <windows.h> /* for Sleep() */
#define sleep(X) Sleep(1000*X) /* MinGW32 has no sleep() */
#include <winsock2.h>
#define read(sock,buf,len) recv(sock,buf,len,0)
#define write(sock,buf,len) send(sock,buf,len,0)
#endif
#include "tls.h" #include "tls.h"
#ifdef LIBVNCSERVER_WITH_CLIENT_TLS #ifdef LIBVNCSERVER_WITH_CLIENT_TLS
...@@ -51,6 +59,33 @@ InitializeTLS(void) ...@@ -51,6 +59,33 @@ InitializeTLS(void)
return TRUE; return TRUE;
} }
/*
* On Windows, translate WSAGetLastError() to errno values as GNU TLS does it
* internally too. This is necessary because send() and recv() on Windows
* don't set errno when they fail but GNUTLS expects a proper errno value.
*
* Use gnutls_transport_set_global_errno() like the GNU TLS documentation
* suggests to avoid problems with different errno variables when GNU TLS and
* libvncclient are linked to different versions of msvcrt.dll.
*/
#ifdef WIN32
static void WSAtoTLSErrno()
{
switch(WSAGetLastError()) {
case WSAEWOULDBLOCK:
gnutls_transport_set_global_errno(EAGAIN);
break;
case WSAEINTR:
gnutls_transport_set_global_errno(EINTR);
break;
default:
gnutls_transport_set_global_errno(EIO);
break;
}
}
#endif
static ssize_t static ssize_t
PushTLS(gnutls_transport_ptr_t transport, const void *data, size_t len) PushTLS(gnutls_transport_ptr_t transport, const void *data, size_t len)
{ {
...@@ -63,7 +98,7 @@ PushTLS(gnutls_transport_ptr_t transport, const void *data, size_t len) ...@@ -63,7 +98,7 @@ PushTLS(gnutls_transport_ptr_t transport, const void *data, size_t len)
if (ret < 0) if (ret < 0)
{ {
#ifdef WIN32 #ifdef WIN32
errno=WSAGetLastError(); WSAtoTLSErrno();
#endif #endif
if (errno == EINTR) continue; if (errno == EINTR) continue;
return -1; return -1;
...@@ -85,7 +120,7 @@ PullTLS(gnutls_transport_ptr_t transport, void *data, size_t len) ...@@ -85,7 +120,7 @@ PullTLS(gnutls_transport_ptr_t transport, void *data, size_t len)
if (ret < 0) if (ret < 0)
{ {
#ifdef WIN32 #ifdef WIN32
errno=WSAGetLastError(); WSAtoTLSErrno();
#endif #endif
if (errno == EINTR) continue; if (errno == EINTR) continue;
return -1; return -1;
...@@ -112,9 +147,7 @@ InitializeTLSSession(rfbClient* client, rfbBool anonTLS) ...@@ -112,9 +147,7 @@ InitializeTLSSession(rfbClient* client, rfbBool anonTLS)
(ret = gnutls_certificate_type_set_priority(client->tlsSession, rfbCertTypePriority)) < 0 || (ret = gnutls_certificate_type_set_priority(client->tlsSession, rfbCertTypePriority)) < 0 ||
(ret = gnutls_protocol_set_priority(client->tlsSession, rfbProtoPriority)) < 0) (ret = gnutls_protocol_set_priority(client->tlsSession, rfbProtoPriority)) < 0)
{ {
FreeTLS(client); rfbClientLog("Warning: Failed to set TLS priority: %s.\n", gnutls_strerror(ret));
rfbClientLog("Failed to set TLS priority: %s.\n", gnutls_strerror(ret));
return FALSE;
} }
gnutls_transport_set_ptr(client->tlsSession, (gnutls_transport_ptr_t)client); gnutls_transport_set_ptr(client->tlsSession, (gnutls_transport_ptr_t)client);
...@@ -192,6 +225,7 @@ ReadVeNCryptSecurityType(rfbClient* client, uint32_t *result) ...@@ -192,6 +225,7 @@ ReadVeNCryptSecurityType(rfbClient* client, uint32_t *result)
rfbClientLog("List of security types is ZERO. Giving up.\n"); rfbClientLog("List of security types is ZERO. Giving up.\n");
return FALSE; return FALSE;
} }
if (count>sizeof(tAuth)) if (count>sizeof(tAuth))
{ {
rfbClientLog("%d security types are too many; maximum is %d\n", count, sizeof(tAuth)); rfbClientLog("%d security types are too many; maximum is %d\n", count, sizeof(tAuth));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment