diff options
-rw-r--r-- | lib/http_client.c | 5 | ||||
-rw-r--r-- | lib/ssl_client.h | 10 | ||||
-rw-r--r-- | lib/ssl_gnutls.c | 20 | ||||
-rw-r--r-- | lib/ssl_nss.c | 1 | ||||
-rw-r--r-- | lib/ssl_openssl.c | 9 |
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 ) ? |