[Pgpool-hackers] [PATCH] Add descriptive error messages for OpenSSL related failures
Sean Finney
sean at stickybit.se
Tue Feb 2 15:41:51 UTC 2010
All previously handled errors related to the OpenSSL engine are now
handled with a macro and a small static function in order to both
produce more informative errors as well as commonize some duplicate
code in pool_ssl.c
---
pool_ssl.c | 103 +++++++++++++++++++++++++++++++++++------------------------
1 files changed, 61 insertions(+), 42 deletions(-)
diff --git a/pool_ssl.c b/pool_ssl.c
index 28adad7..e734dfa 100644
--- a/pool_ssl.c
+++ b/pool_ssl.c
@@ -29,6 +29,22 @@
#ifdef USE_SSL
+#define SSL_RETURN_VOID_IF(cond, msg) \
+ do { \
+ if ( (cond) ) { \
+ perror_ssl( (msg) ); \
+ return; \
+ } \
+ } while (0);
+
+#define SSL_RETURN_ERROR_IF(cond, msg) \
+ do { \
+ if ( (cond) ) { \
+ perror_ssl( (msg) ); \
+ return -1; \
+ } \
+ } while (0);
+
#include <arpa/inet.h> /* for htonl() */
/* Major/minor codes to negotiate SSL prior to startup packet */
@@ -40,6 +56,9 @@ enum ssl_conn_type { ssl_conn_clientserver, ssl_conn_serverclient };
/* perform per-connection ssl initialization. returns nonzero on error */
static int init_ssl_ctx(POOL_CONNECTION *cp, enum ssl_conn_type conntype);
+/* OpenSSL error message */
+static void perror_ssl(const char *context);
+
/* attempt to negotiate a secure connection */
void pool_ssl_negotiate_clientserver(POOL_CONNECTION *cp) {
int ssl_packet[2] = { htonl(sizeof(int)*2), htonl(NEGOTIATE_SSL_CODE) };
@@ -58,11 +77,9 @@ void pool_ssl_negotiate_clientserver(POOL_CONNECTION *cp) {
switch (server_response) {
case 'S':
SSL_set_fd(cp->ssl, cp->fd);
- if (SSL_connect(cp->ssl) < 0) {
- pool_error("pool_ssl: SSL_connect failed: %ld", ERR_get_error());
- } else {
- cp->ssl_active = 1;
- }
+ SSL_RETURN_VOID_IF( (SSL_connect(cp->ssl) < 0),
+ "SSL_connect");
+ cp->ssl_active = 1;
break;
case 'N':
pool_error("pool_ssl: server doesn't want to talk SSL");
@@ -87,11 +104,8 @@ void pool_ssl_negotiate_serverclient(POOL_CONNECTION *cp) {
pool_write_and_flush(cp, "S", 1);
SSL_set_fd(cp->ssl, cp->fd);
- if (SSL_accept(cp->ssl) < 0) {
- pool_error("pool_ssl: SSL_accept failed: %ld", ERR_get_error());
- } else {
- cp->ssl_active = 1;
- }
+ SSL_RETURN_VOID_IF( (SSL_accept(cp->ssl) < 0), "SSL_accept");
+ cp->ssl_active = 1;
}
}
@@ -119,25 +133,18 @@ static int init_ssl_ctx(POOL_CONNECTION *cp, enum ssl_conn_type conntype) {
/* initialize SSL members */
cp->ssl_ctx = SSL_CTX_new(TLSv1_method());
- if (! cp->ssl_ctx) {
- pool_error("pool_ssl: SSL_CTX_new failed: %ld", ERR_get_error());
- error = -1;
- }
+ SSL_RETURN_ERROR_IF( (! cp->ssl_ctx), "SSL_CTX_new" );
if ( conntype == ssl_conn_serverclient) {
- if ( (!error) && SSL_CTX_use_certificate_file(cp->ssl_ctx,
- pool_config->ssl_cert,
- SSL_FILETYPE_PEM) <= 0) {
- pool_error("pool_ssl: SSL cert failure: %ld", ERR_get_error());
- error = -1;
- }
-
- if ( (!error) && SSL_CTX_use_PrivateKey_file(cp->ssl_ctx,
- pool_config->ssl_key,
- SSL_FILETYPE_PEM) <= 0) {
- pool_error("pool_ssl: SSL key failure: %ld", ERR_get_error());
- error = -1;
- }
+ error = SSL_CTX_use_certificate_file(cp->ssl_ctx,
+ pool_config->ssl_cert,
+ SSL_FILETYPE_PEM);
+ SSL_RETURN_ERROR_IF( (error <= 0), "Loading SSL certificate");
+
+ error = SSL_CTX_use_PrivateKey_file(cp->ssl_ctx,
+ pool_config->ssl_key,
+ SSL_FILETYPE_PEM);
+ SSL_RETURN_ERROR_IF( (error <= 0), "Loading SSL private key");
} else {
/* set extra verification if ssl_ca_cert or ssl_ca_cert_dir are set */
if (strlen(pool_config->ssl_ca_cert))
@@ -145,26 +152,38 @@ static int init_ssl_ctx(POOL_CONNECTION *cp, enum ssl_conn_type conntype) {
if (strlen(pool_config->ssl_ca_cert_dir))
cacert_dir = pool_config->ssl_ca_cert_dir;
- if ( (!error) && (cacert || cacert_dir) ) {
- if (! SSL_CTX_load_verify_locations(cp->ssl_ctx, cacert, cacert_dir)) {
- pool_error("pool_ssl: SSL CA load error: %ld", ERR_get_error());
- error = -1;
- } else {
- SSL_CTX_set_verify(cp->ssl_ctx, SSL_VERIFY_PEER, NULL);
- }
+ if ( cacert || cacert_dir ) {
+ error = (!SSL_CTX_load_verify_locations(cp->ssl_ctx,
+ cacert,
+ cacert_dir));
+ SSL_RETURN_ERROR_IF(error, "SSL verification setup");
+ SSL_CTX_set_verify(cp->ssl_ctx, SSL_VERIFY_PEER, NULL);
}
-
}
- if (! error) {
- cp->ssl = SSL_new(cp->ssl_ctx);
- if (! cp->ssl) {
- pool_error("pool_ssl: SSL_new failed: %ld", ERR_get_error());
- error = -1;
- }
+ cp->ssl = SSL_new(cp->ssl_ctx);
+ SSL_RETURN_ERROR_IF( (! cp->ssl), "SSL_new");
+
+ return 0;
+}
+
+static void perror_ssl(const char *context) {
+ unsigned long err;
+ static const char *no_err_reason = "no SSL error reported";
+ const char *reason;
+
+ err = ERR_get_error();
+ if (! err) {
+ reason = no_err_reason;
+ } else {
+ reason = ERR_reason_error_string(err);
}
- return error;
+ if (reason != NULL) {
+ pool_error("pool_ssl: %s: %s", context, reason);
+ } else {
+ pool_error("pool_ssl: %s: Unknown SSL error %lu", context, err);
+ }
}
#else /* USE_SSL: wrap / no-op ssl functionality if it's not available */
--
1.6.6
More information about the Pgpool-hackers
mailing list