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; }