commit 5f908b7672d2975d72638c5d22a186d4e2163d21
Author: Oswald Buddenhagen <o...@users.sf.net>
Date:   Sun Jul 28 11:35:02 2019 +0200

    attempt to improve ssl error handling (again)
    
    the error queue may contain multiple errors, so make sure to drain it
    completely. also, don't try to fall back to errno in case of
    SSL_ERROR_SSL.

 src/common.h |  1 +
 src/socket.c | 67 ++++++++++++++++++++++++++++++++++++----------------
 2 files changed, 48 insertions(+), 20 deletions(-)

diff --git a/src/common.h b/src/common.h
index c731126..d45929c 100644
--- a/src/common.h
+++ b/src/common.h
@@ -33,6 +33,7 @@
 typedef unsigned char uchar;
 typedef unsigned short ushort;
 typedef unsigned int uint;
+typedef unsigned long ulong;
 
 #define as(ar) (sizeof(ar)/sizeof(ar[0]))
 
diff --git a/src/socket.c b/src/socket.c
index eae3b74..7354c6f 100644
--- a/src/socket.c
+++ b/src/socket.c
@@ -63,6 +63,34 @@ socket_fail( conn_t *conn )
 }
 
 #ifdef HAVE_LIBSSL
+static void ATTR_PRINTFLIKE(1, 2)
+print_ssl_errors( const char *fmt, ... )
+{
+       char *action;
+       va_list va;
+       ulong err;
+
+       va_start( va, fmt );
+       nfvasprintf( &action, fmt, va );
+       va_end( va );
+       while ((err = ERR_get_error()))
+               error( "Error while %s: %s\n", action, ERR_error_string( err, 0 
) );
+       free( action );
+}
+
+static int
+print_ssl_socket_errors( const char *func, conn_t *conn )
+{
+       ulong err;
+       int num = 0;
+
+       while ((err = ERR_get_error())) {
+               error( "Socket error: secure %s %s: %s\n", func, conn->name, 
ERR_error_string( err, 0 ) );
+               num++;
+       }
+       return num;
+}
+
 static int
 ssl_return( const char *func, conn_t *conn, int ret )
 {
@@ -76,20 +104,20 @@ ssl_return( const char *func, conn_t *conn, int ret )
                FALLTHROUGH
        case SSL_ERROR_WANT_READ:
                return 0;
-       case SSL_ERROR_SYSCALL:
        case SSL_ERROR_SSL:
-               if (!(err = ERR_get_error())) {
-                       if (ret == 0) {
+               print_ssl_socket_errors( func, conn );
+               break;
+       case SSL_ERROR_SYSCALL:
+               if (print_ssl_socket_errors( func, conn ))
+                       break;
+               if (ret == 0) {
        case SSL_ERROR_ZERO_RETURN:
-                               /* Callers take the short path out, so signal 
higher layers from here. */
-                               conn->state = SCK_EOF;
-                               conn->read_callback( conn->callback_aux );
-                               return -1;
-                       }
-                       sys_error( "Socket error: secure %s %s", func, 
conn->name );
-               } else {
-                       error( "Socket error: secure %s %s: %s\n", func, 
conn->name, ERR_error_string( err, 0 ) );
+                       /* Callers take the short path out, so signal higher 
layers from here. */
+                       conn->state = SCK_EOF;
+                       conn->read_callback( conn->callback_aux );
+                       return -1;
                }
+               sys_error( "Socket error: secure %s %s", func, conn->name );
                break;
        default:
                error( "Socket error: secure %s %s: unhandled SSL error %d\n", 
func, conn->name, err );
@@ -233,25 +261,24 @@ init_ssl_ctx( const server_conf_t *conf )
        SSL_CTX_set_options( mconf->SSLContext, options );
 
        if (conf->cert_file && !SSL_CTX_load_verify_locations( 
mconf->SSLContext, conf->cert_file, 0 )) {
-               error( "Error while loading certificate file '%s': %s\n",
-                      conf->cert_file, ERR_error_string( ERR_get_error(), 0 ) 
);
+               print_ssl_errors( "loading certificate file '%s'", 
conf->cert_file );
                return 0;
        }
        mconf->trusted_certs = (_STACK *)sk_X509_OBJECT_dup( 
X509_STORE_get0_objects( SSL_CTX_get_cert_store( mconf->SSLContext ) ) );
-       if (mconf->system_certs && !SSL_CTX_set_default_verify_paths( 
mconf->SSLContext ))
-               warn( "Warning: Unable to load default certificate files: %s\n",
-                     ERR_error_string( ERR_get_error(), 0 ) );
+       if (mconf->system_certs && !SSL_CTX_set_default_verify_paths( 
mconf->SSLContext )) {
+               ulong err;
+               while ((err = ERR_get_error()))
+                       warn( "Warning: Unable to load default certificate 
files: %s\n", ERR_error_string( err, 0 ) );
+       }
 
        SSL_CTX_set_verify( mconf->SSLContext, SSL_VERIFY_NONE, NULL );
 
        if (conf->client_certfile && !SSL_CTX_use_certificate_chain_file( 
mconf->SSLContext, conf->client_certfile)) {
-               error( "Error while loading client certificate file '%s': %s\n",
-                      conf->client_certfile, ERR_error_string( 
ERR_get_error(), 0 ) );
+               print_ssl_errors( "loading client certificate file '%s'", 
conf->client_certfile );
                return 0;
        }
        if (conf->client_keyfile && !SSL_CTX_use_PrivateKey_file( 
mconf->SSLContext, conf->client_keyfile, SSL_FILETYPE_PEM)) {
-               error( "Error while loading client private key '%s': %s\n",
-                      conf->client_keyfile, ERR_error_string( ERR_get_error(), 
0 ) );
+               print_ssl_errors( "loading client private key '%s'", 
conf->client_keyfile );
                return 0;
        }
 


_______________________________________________
isync-devel mailing list
isync-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/isync-devel

Reply via email to