summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Winship <danw@src.gnome.org>2008-04-20 23:11:54 +0000
committerDan Winship <danw@src.gnome.org>2008-04-20 23:11:54 +0000
commit1012ecb39d1081732ff5bb9f6911f8ea2a8a783a (patch)
tree7bf1b36ad81e6b5f235d6d7d821635e0392a2f9f
parentd60f365466271d1db404d7397c53de9407ffb8a3 (diff)
downloadlibsoup-1012ecb39d1081732ff5bb9f6911f8ea2a8a783a.tar.gz
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... svn path=/trunk/; revision=1137
-rw-r--r--ChangeLog19
-rw-r--r--libsoup/soup-gnutls.c25
-rw-r--r--libsoup/soup-nossl.c5
-rw-r--r--libsoup/soup-socket.c3
-rw-r--r--libsoup/soup-ssl.h1
-rw-r--r--tests/ssl-test.c21
6 files changed, 54 insertions, 20 deletions
diff --git a/ChangeLog b/ChangeLog
index 4c81431a..8254612e 100644
--- 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>
diff --git a/libsoup/soup-gnutls.c b/libsoup/soup-gnutls.c
index 340faa89..8f21cb8b 100644
--- a/libsoup/soup-gnutls.c
+++ b/libsoup/soup-gnutls.c
@@ -13,12 +13,15 @@
#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 ();
diff --git a/libsoup/soup-nossl.c b/libsoup/soup-nossl.c
index f8e3888f..70088c77 100644
--- a/libsoup/soup-nossl.c
+++ b/libsoup/soup-nossl.c
@@ -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;
}
diff --git a/libsoup/soup-socket.c b/libsoup/soup-socket.c
index b1c2252a..e5020865 100644
--- a/libsoup/soup-socket.c
+++ b/libsoup/soup-socket.c
@@ -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);
diff --git a/libsoup/soup-ssl.h b/libsoup/soup-ssl.h
index 37f6e41a..f4e3eab1 100644
--- a/libsoup/soup-ssl.h
+++ b/libsoup/soup-ssl.h
@@ -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);
diff --git a/tests/ssl-test.c b/tests/ssl-test.c
index 8dda7362..3c22dbbc 100644
--- a/tests/ssl-test.c
+++ b/tests/ssl-test.c
@@ -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"
@@ -14,6 +12,12 @@
#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);
}