aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWilmer van der Gaast <wilmer@gaast.net>2011-11-14 18:43:03 +0800
committerWilmer van der Gaast <wilmer@gaast.net>2011-11-14 18:43:03 +0800
commit80acb6db8133ebd16c3257d33721994ed164ba9f (patch)
tree68775e4feeb4aa81f19524a8389d5a8d7ad91b8b
parent03a8f8ec82719512f059fdd2c0dca3bb919b059c (diff)
GnuTLS now also needs ssl_pending() implemented. Bug #860.
-rw-r--r--lib/http_client.c5
-rw-r--r--lib/ssl_client.h10
-rw-r--r--lib/ssl_gnutls.c20
-rw-r--r--lib/ssl_nss.c1
-rw-r--r--lib/ssl_openssl.c9
5 files changed, 28 insertions, 17 deletions
diff --git a/lib/http_client.c b/lib/http_client.c
index 84914388..8bd543af 100644
--- a/lib/http_client.c
+++ b/lib/http_client.c
@@ -239,7 +239,10 @@ static gboolean http_incoming_data( gpointer data, int source, b_input_condition
req->ssl ? ssl_getdirection( req->ssl ) : B_EV_IO_READ,
http_incoming_data, req );
- return FALSE;
+ if( ssl_pending( req->ssl ) )
+ return http_incoming_data( data, source, cond );
+ else
+ return FALSE;
got_reply:
/* Maybe if the webserver is overloaded, or when there's bad SSL
diff --git a/lib/ssl_client.h b/lib/ssl_client.h
index d0340840..091335c5 100644
--- a/lib/ssl_client.h
+++ b/lib/ssl_client.h
@@ -62,7 +62,15 @@ G_MODULE_EXPORT void *ssl_starttls( int fd, ssl_input_function func, gpointer da
G_MODULE_EXPORT int ssl_read( void *conn, char *buf, int len );
G_MODULE_EXPORT int ssl_write( void *conn, const char *buf, int len );
-/* See ssl_openssl.c for an explanation. */
+/* Now needed by most SSL libs. See for more info:
+ http://www.gnu.org/software/gnutls/manual/gnutls.html#index-gnutls_005frecord_005fcheck_005fpending-209
+ http://www.openssl.org/docs/ssl/SSL_pending.html
+
+ Required because OpenSSL empties the TCP buffer completely but doesn't
+ necessarily give us all the unencrypted data. Or maybe you didn't ask
+ for all of it because your buffer is too small.
+
+ Returns 0 if there's nothing left, 1 if there's more data. */
G_MODULE_EXPORT int ssl_pending( void *conn );
/* Abort the SSL connection and disconnect the socket. Do not use close()
diff --git a/lib/ssl_gnutls.c b/lib/ssl_gnutls.c
index 72517e72..d72b17f5 100644
--- a/lib/ssl_gnutls.c
+++ b/lib/ssl_gnutls.c
@@ -134,7 +134,9 @@ static gboolean ssl_connected( gpointer data, gint source, b_input_condition con
gnutls_certificate_allocate_credentials( &conn->xcred );
gnutls_init( &conn->session, GNUTLS_CLIENT );
- gnutls_transport_set_lowat( conn->session, 1 );
+#if GNUTLS_VERSION_NUMBER < 0x020c00
+ gnutls_transport_set_lowat( conn->session, 0 );
+#endif
gnutls_set_default_priority( conn->session );
gnutls_credentials_set( conn->session, GNUTLS_CRD_CERTIFICATE, conn->xcred );
@@ -186,7 +188,7 @@ int ssl_read( void *conn, char *buf, int len )
if( !((struct scd*)conn)->established )
{
ssl_errno = SSL_NOHANDSHAKE;
- return( -1 );
+ return -1;
}
st = gnutls_record_recv( ((struct scd*)conn)->session, buf, len );
@@ -207,7 +209,7 @@ int ssl_write( void *conn, const char *buf, int len )
if( !((struct scd*)conn)->established )
{
ssl_errno = SSL_NOHANDSHAKE;
- return( -1 );
+ return -1;
}
st = gnutls_record_send( ((struct scd*)conn)->session, buf, len );
@@ -221,10 +223,18 @@ int ssl_write( void *conn, const char *buf, int len )
return st;
}
-/* See ssl_openssl.c for an explanation. */
int ssl_pending( void *conn )
{
- return 0;
+ if( conn == NULL )
+ return 0;
+
+ if( !((struct scd*)conn)->established )
+ {
+ ssl_errno = SSL_NOHANDSHAKE;
+ return 0;
+ }
+
+ return gnutls_record_check_pending( ((struct scd*)conn)->session ) != 0;
}
void ssl_disconnect( void *conn_ )
diff --git a/lib/ssl_nss.c b/lib/ssl_nss.c
index 512c7655..ec524ca6 100644
--- a/lib/ssl_nss.c
+++ b/lib/ssl_nss.c
@@ -206,7 +206,6 @@ int ssl_write( void *conn, const char *buf, int len )
return( PR_Write ( ((struct scd*)conn)->prfd, buf, len ) );
}
-/* See ssl_openssl.c for an explanation. */
int ssl_pending( void *conn )
{
struct scd *c = (struct scd *) conn;
diff --git a/lib/ssl_openssl.c b/lib/ssl_openssl.c
index 64bc9257..5f64042d 100644
--- a/lib/ssl_openssl.c
+++ b/lib/ssl_openssl.c
@@ -240,15 +240,6 @@ int ssl_write( void *conn, const char *buf, int len )
return st;
}
-/* Only OpenSSL *really* needs this (and well, maybe NSS). See for more info:
- http://www.gnu.org/software/gnutls/manual/gnutls.html#index-gnutls_005frecord_005fcheck_005fpending-209
- http://www.openssl.org/docs/ssl/SSL_pending.html
-
- Required because OpenSSL empties the TCP buffer completely but doesn't
- necessarily give us all the unencrypted data.
-
- Returns 0 if there's nothing left or if we don't have to care (GnuTLS),
- 1 if there's more data. */
int ssl_pending( void *conn )
{
return ( ((struct scd*)conn) && ((struct scd*)conn)->established ) ?