aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Bolte <matthias.bolte@googlemail.com>2010-11-20 18:04:42 +0100
committerMatthias Bolte <matthias.bolte@googlemail.com>2010-11-23 18:31:42 +0100
commit9abe1e4358efe15608ceb452c4c07ae9d3b5ab6d (patch)
tree75b7b59e183ad418114e3f26fca577fb1c9b0c6d
parenttests: Fix dispatching internal error reports (diff)
downloadlibvirt-9abe1e4358efe15608ceb452c4c07ae9d3b5ab6d.tar.gz
libvirt-9abe1e4358efe15608ceb452c4c07ae9d3b5ab6d.tar.bz2
libvirt-9abe1e4358efe15608ceb452c4c07ae9d3b5ab6d.zip
remote: Fix TLS transport on Windows
gnulib wraps Windows' SOCKET handle based send() and recv() functions into file descriptor based ones that are used in libvirt. Even though GnuTLS is using gnulib too, it explicitly doesn't use gnulib's replacement functions on Windows. By default GnuTLS uses the SOCKET handle based send() and recv(). This makes gnutls_handshake() fail internally with a WSAENOTSOCK error because libvirt passes a file descriptor; GnuTLS needs the SOCKET handle. To avoid this mismatch make sure that GnuTLS uses gnulib's replacment functions, by setting custom pull() and push() functions for GnuTLS.
-rw-r--r--src/remote/remote_driver.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index f45476a21..47a66dc3d 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -1212,6 +1212,20 @@ initialize_gnutls(void)
static int verify_certificate (virConnectPtr conn, struct private_data *priv, gnutls_session_t session);
+#if HAVE_WINSOCK2_H
+static ssize_t
+custom_gnutls_push(void *s, const void *buf, size_t len)
+{
+ return send((size_t)s, buf, len, 0);
+}
+
+static ssize_t
+custom_gnutls_pull(void *s, void *buf, size_t len)
+{
+ return recv((size_t)s, buf, len, 0);
+}
+#endif
+
static gnutls_session_t
negotiate_gnutls_on_connection (virConnectPtr conn,
struct private_data *priv,
@@ -1266,6 +1280,13 @@ negotiate_gnutls_on_connection (virConnectPtr conn,
gnutls_transport_set_ptr (session,
(gnutls_transport_ptr_t) (long) priv->sock);
+#if HAVE_WINSOCK2_H
+ /* Make sure GnuTLS uses gnulib's replacment functions for send() and
+ * recv() on Windows */
+ gnutls_transport_set_push_function(session, custom_gnutls_push);
+ gnutls_transport_set_pull_function(session, custom_gnutls_pull);
+#endif
+
/* Perform the TLS handshake. */
again:
err = gnutls_handshake (session);