Fixes for GnuTLS support on Win32. #528752, patch from Marc Maurer
authorDan Winship <danw@src.gnome.org>
Sun, 20 Apr 2008 23:11:54 +0000 (23:11 +0000)
committerDan Winship <danw@src.gnome.org>
Sun, 20 Apr 2008 23:11:54 +0000 (23:11 +0000)
* libsoup/soup-gnutls.c (soup_ssl_wrap_iochannel): add an argument
saying whether or not the socket is non-blocking, since there's no
way to determine this from the fd in WinSock.
(do_handshake, soup_gnutls_read, soup_gnutls_write): Update for
that.

* libsoup/soup-socket.c (soup_socket_start_proxy_ssl): Update for
that

* libsoup/soup-nossl.c (soup_ssl_wrap_iochannel): update the
declaration here too

* tests/ssl-test.c: Some updates to get this closer to working on
Windows...

svn path=/trunk/; revision=1137

ChangeLog
libsoup/soup-gnutls.c
libsoup/soup-nossl.c
libsoup/soup-socket.c
libsoup/soup-ssl.h
tests/ssl-test.c

index 4c81431..8254612 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,22 @@
+2008-04-20  Dan Winship  <danw@gnome.org>
+
+       Fixes for GnuTLS support on Win32. #528752, patch from Marc Maurer
+
+       * libsoup/soup-gnutls.c (soup_ssl_wrap_iochannel): add an argument
+       saying whether or not the socket is non-blocking, since there's no
+       way to determine this from the fd in WinSock.
+       (do_handshake, soup_gnutls_read, soup_gnutls_write): Update for
+       that.
+
+       * libsoup/soup-socket.c (soup_socket_start_proxy_ssl): Update for
+       that
+
+       * libsoup/soup-nossl.c (soup_ssl_wrap_iochannel): update the
+       declaration here too
+
+       * tests/ssl-test.c: Some updates to get this closer to working on
+       Windows...
+
 2008-04-14  Chris Lord  <chrislord.net@gmail.com>
 
        reviewed by: Dan Winship <danw@gnome.org>
index 340faa8..8f21cb8 100644 (file)
 
 #include <errno.h>
 #include <fcntl.h>
-#include <pthread.h>
 #include <stdlib.h>
 #include <string.h>
 
 #include <glib.h>
 
+#ifndef G_OS_WIN32
+#include <pthread.h>
+#endif
+
 #include <gcrypt.h>
 #include <gnutls/gnutls.h>
 #include <gnutls/x509.h>
@@ -44,6 +47,7 @@ typedef struct {
        GIOChannel channel;
        int fd;
        GIOChannel *real_sock;
+       gboolean non_blocking;
        gnutls_session session;
        SoupSSLCredentials *creds;
        char *hostname;
@@ -132,8 +136,6 @@ verify_certificate (gnutls_session session, const char *hostname, GError **err)
        return TRUE;
 }
 
-#define SOUP_GNUTLS_CHANNEL_NONBLOCKING(chan) (fcntl ((chan)->fd, F_GETFL, 0) & O_NONBLOCK)
-
 static GIOStatus
 do_handshake (SoupGNUTLSChannel *chan, GError **err)
 {
@@ -143,7 +145,7 @@ again:
        result = gnutls_handshake (chan->session);
 
        if (result == GNUTLS_E_AGAIN || result == GNUTLS_E_INTERRUPTED) {
-               if (SOUP_GNUTLS_CHANNEL_NONBLOCKING (chan)) {
+               if (chan->non_blocking) {
                        g_set_error (err, SOUP_SSL_ERROR,
                                     (gnutls_record_get_direction (chan->session) ?
                                      SOUP_SSL_ERROR_HANDSHAKE_NEEDS_WRITE :
@@ -199,7 +201,7 @@ again:
        }
 
        if (result == GNUTLS_E_INTERRUPTED || result == GNUTLS_E_AGAIN) {
-               if (SOUP_GNUTLS_CHANNEL_NONBLOCKING (chan))
+               if (chan->non_blocking)
                        return G_IO_STATUS_AGAIN;
                else
                        goto again;
@@ -251,7 +253,7 @@ again:
        }
 
        if (result == GNUTLS_E_INTERRUPTED || result == GNUTLS_E_AGAIN) {
-               if (SOUP_GNUTLS_CHANNEL_NONBLOCKING (chan))
+               if (chan->non_blocking)
                        return G_IO_STATUS_AGAIN;
                else
                        goto again;
@@ -370,6 +372,7 @@ init_dh_params (void)
 /**
  * soup_ssl_wrap_iochannel:
  * @sock: a #GIOChannel wrapping a TCP socket.
+ * @non_blocking: whether the underlying socket is blocking or not
  * @type: whether this is a client or server socket
  * @remote_host: the hostname of the remote machine
  * @creds: a client or server credentials structure
@@ -381,8 +384,9 @@ init_dh_params (void)
  * failure.
  **/
 GIOChannel *
-soup_ssl_wrap_iochannel (GIOChannel *sock, SoupSSLType type,
-                        const char *remote_host, SoupSSLCredentials *creds)
+soup_ssl_wrap_iochannel (GIOChannel *sock, gboolean non_blocking, 
+                        SoupSSLType type, const char *remote_host, 
+                        SoupSSLCredentials *creds)
 {
        SoupGNUTLSChannel *chan = NULL;
        GIOChannel *gchan = NULL;
@@ -423,6 +427,7 @@ soup_ssl_wrap_iochannel (GIOChannel *sock, SoupSSLType type,
        chan->creds = creds;
        chan->hostname = g_strdup (remote_host);
        chan->type = type;
+       chan->non_blocking = non_blocking;
        g_io_channel_ref (sock);
 
        gchan = (GIOChannel *) chan;
@@ -439,7 +444,7 @@ soup_ssl_wrap_iochannel (GIOChannel *sock, SoupSSLType type,
        return NULL;
 }
 
-#ifdef GCRY_THREAD_OPTION_PTHREAD_IMPL
+#if defined(GCRY_THREAD_OPTION_PTHREAD_IMPL) && !defined(G_OS_WIN32)
 GCRY_THREAD_OPTION_PTHREAD_IMPL;
 #endif
 
@@ -449,7 +454,7 @@ soup_gnutls_init (void)
        static volatile gsize inited_gnutls = 0;
 
        if (g_once_init_enter (&inited_gnutls)) {
-#ifdef GCRY_THREAD_OPTION_PTHREAD_IMPL
+#if defined(GCRY_THREAD_OPTION_PTHREAD_IMPL) && !defined(G_OS_WIN32)
                gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
 #endif
                gnutls_global_init ();
index f8e3888..70088c7 100644 (file)
@@ -17,8 +17,9 @@
 const gboolean soup_ssl_supported = FALSE;
 
 GIOChannel *
-soup_ssl_wrap_iochannel (GIOChannel *sock, SoupSSLType type,
-                        const char *hostname, SoupSSLCredentials *creds)
+soup_ssl_wrap_iochannel (GIOChannel *sock, gboolean non_blocking,
+                        SoupSSLType type, const char *hostname,
+                        SoupSSLCredentials *creds)
 {
        return NULL;
 }
index b1c2252..e502086 100644 (file)
@@ -9,6 +9,7 @@
 #include <config.h>
 #endif
 
+#include <stdio.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <signal.h>
@@ -856,7 +857,7 @@ soup_socket_start_proxy_ssl (SoupSocket *sock, const char *ssl_host,
 
        real_chan = priv->iochannel;
        ssl_chan = soup_ssl_wrap_iochannel (
-               real_chan, priv->is_server ?
+               real_chan, priv->non_blocking, priv->is_server ?
                SOUP_SSL_TYPE_SERVER : SOUP_SSL_TYPE_CLIENT,
                ssl_host, priv->ssl_creds);
 
index 37f6e41..f4e3eab 100644 (file)
@@ -23,6 +23,7 @@ SoupSSLCredentials *soup_ssl_get_server_credentials  (const char         *cert_f
 void                soup_ssl_free_server_credentials (SoupSSLCredentials *creds);
 
 GIOChannel         *soup_ssl_wrap_iochannel          (GIOChannel         *sock,
+                                                     gboolean            non_blocking,
                                                      SoupSSLType         type,
                                                      const char         *remote_host,
                                                      SoupSSLCredentials *creds);
index 8dda736..3c22dbb 100644 (file)
@@ -4,8 +4,6 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
 
 #include "libsoup/soup-address.h"
 #include "libsoup/soup-socket.h"
 #define BUFSIZE 1024
 #define DH_BITS 1024
 
+#ifndef G_OS_WIN32
+#define SOCKET_PRINT_ERROR(M) perror(M);
+#else
+#define SOCKET_PRINT_ERROR(M) g_error("%s: %d", M, WSAGetLastError());
+#endif
+
 static GMainLoop *loop;
 static gnutls_dh_params_t dh_params;
 
@@ -64,8 +68,8 @@ server_write (gnutls_session_t session, char *buf, int bufsize)
        }
 }
 
-static const char *ssl_cert_file = SRCDIR "/test-cert.pem";
-static const char *ssl_key_file = SRCDIR "/test-key.pem";
+static const char *ssl_cert_file = SRCDIR G_DIR_SEPARATOR_S "test-cert.pem";
+static const char *ssl_key_file = SRCDIR G_DIR_SEPARATOR_S "test-key.pem";
 
 static gpointer
 server_thread (gpointer user_data)
@@ -226,6 +230,9 @@ main (int argc, char **argv)
        g_thread_init (NULL);
        g_type_init ();
 
+       /* On Windows, this will call WSAStartup() */
+       soup_address_get_type ();
+
        while ((opt = getopt (argc, argv, "c:d:k:")) != -1) {
                switch (opt) {
                case 'c':
@@ -253,7 +260,7 @@ main (int argc, char **argv)
        /* Create server socket */
        listener = socket (AF_INET, SOCK_STREAM, 0);
        if (listener == -1) {
-               perror ("creating listening socket");
+               SOCKET_PRINT_ERROR ("creating listening socket");
                exit (1);
        }
 
@@ -262,12 +269,12 @@ main (int argc, char **argv)
        sin.sin_addr.s_addr = INADDR_ANY;
 
        if (bind (listener, (struct sockaddr *) &sin, sizeof (sin))  == -1) {
-               perror ("binding listening socket");
+               SOCKET_PRINT_ERROR ("binding listening socket");
                exit (1);
        }
 
        if (listen (listener, 1) == -1) {
-               perror ("listening on socket");
+               SOCKET_PRINT_ERROR ("listening on socket");
                exit (1);
        }