From c492473ade3960de94b8fcb9f0ff4663856faffa Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?P=C5=99emysl=20Janouch?=
Date: Sat, 14 Feb 2015 07:58:38 +0100
Subject: [PATCH] Split function, fix resource leak
---
kike.c | 100 ++++++++++++++++++++++++++++++---------------------------
1 file changed, 52 insertions(+), 48 deletions(-)
diff --git a/kike.c b/kike.c
index 9810e25..fd42c4f 100644
--- a/kike.c
+++ b/kike.c
@@ -2735,6 +2735,51 @@ irc_ssl_verify_callback (int verify_ok, X509_STORE_CTX *ctx)
return 1;
}
+static bool
+irc_initialize_ssl_ctx (struct server_context *ctx,
+ const char *cert_path, const char *key_path, struct error **e)
+{
+ ctx->ssl_ctx = SSL_CTX_new (SSLv23_server_method ());
+ if (!ctx->ssl_ctx)
+ {
+ // XXX: these error strings are really nasty; also there could be
+ // multiple errors on the OpenSSL stack.
+ error_set (e, "%s: %s", "could not initialize SSL",
+ ERR_error_string (ERR_get_error (), NULL));
+ return false;
+ }
+ SSL_CTX_set_verify (ctx->ssl_ctx,
+ SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, irc_ssl_verify_callback);
+ // XXX: maybe we should call SSL_CTX_set_options() for some workarounds
+
+ const unsigned char session_id_context[SSL_MAX_SSL_SESSION_ID_LENGTH]
+ = PROGRAM_NAME;
+ (void) SSL_CTX_set_session_id_context (ctx->ssl_ctx,
+ session_id_context, sizeof session_id_context);
+
+ // Gah, spare me your awkward semantics, I just want to push data!
+ // XXX: do we want SSL_MODE_AUTO_RETRY as well? I guess not.
+ SSL_CTX_set_mode (ctx->ssl_ctx,
+ SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER | SSL_MODE_ENABLE_PARTIAL_WRITE);
+
+ // XXX: perhaps we should read the files ourselves for better messages
+ if (!SSL_CTX_use_certificate_chain_file (ctx->ssl_ctx, cert_path))
+ error_set (e, "%s: %s", "setting the SSL client certificate failed",
+ ERR_error_string (ERR_get_error (), NULL));
+ else if (!SSL_CTX_use_PrivateKey_file
+ (ctx->ssl_ctx, key_path, SSL_FILETYPE_PEM))
+ error_set (e, "%s: %s", "setting the SSL private key failed",
+ ERR_error_string (ERR_get_error (), NULL));
+ else
+ // TODO: SSL_CTX_check_private_key()? It has probably already been
+ // checked by SSL_CTX_use_PrivateKey_file() above.
+ return true;
+
+ SSL_CTX_free (ctx->ssl_ctx);
+ ctx->ssl_ctx = NULL;
+ return false;
+}
+
static bool
irc_initialize_ssl (struct server_context *ctx, struct error **e)
{
@@ -2753,61 +2798,20 @@ irc_initialize_ssl (struct server_context *ctx, struct error **e)
if (!ssl_cert || !ssl_key)
return false;
+ bool result = false;
+
char *cert_path = resolve_config_filename (ssl_cert);
char *key_path = resolve_config_filename (ssl_key);
if (!cert_path)
error_set (e, "%s: %s", "cannot open file", ssl_cert);
else if (!key_path)
error_set (e, "%s: %s", "cannot open file", ssl_key);
- if (!cert_path || !key_path)
- return false;
+ else
+ result = irc_initialize_ssl_ctx (ctx, cert_path, key_path, e);
- ctx->ssl_ctx = SSL_CTX_new (SSLv23_server_method ());
- if (!ctx->ssl_ctx)
- {
- // XXX: these error strings are really nasty; also there could be
- // multiple errors on the OpenSSL stack.
- error_set (e, "%s: %s", "could not initialize SSL",
- ERR_error_string (ERR_get_error (), NULL));
- goto error_ssl_1;
- }
- SSL_CTX_set_verify (ctx->ssl_ctx,
- SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, irc_ssl_verify_callback);
- // XXX: maybe we should call SSL_CTX_set_options() for some workarounds
-
- const unsigned char session_id_context[SSL_MAX_SSL_SESSION_ID_LENGTH]
- = PROGRAM_NAME;
- (void) SSL_CTX_set_session_id_context (ctx->ssl_ctx,
- session_id_context, sizeof session_id_context);
-
- // XXX: perhaps we should read the files ourselves for better messages
- if (!SSL_CTX_use_certificate_chain_file (ctx->ssl_ctx, cert_path))
- {
- error_set (e, "%s: %s", "setting the SSL client certificate failed",
- ERR_error_string (ERR_get_error (), NULL));
- goto error_ssl_2;
- }
- if (!SSL_CTX_use_PrivateKey_file (ctx->ssl_ctx, key_path, SSL_FILETYPE_PEM))
- {
- error_set (e, "%s: %s", "setting the SSL private key failed",
- ERR_error_string (ERR_get_error (), NULL));
- goto error_ssl_2;
- }
-
- // TODO: SSL_CTX_check_private_key()? It has probably already been checked
- // by SSL_CTX_use_PrivateKey_file() above.
-
- // Gah, spare me your awkward semantics, I just want to push data!
- // XXX: do we want SSL_MODE_AUTO_RETRY as well? I guess not.
- SSL_CTX_set_mode (ctx->ssl_ctx,
- SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER | SSL_MODE_ENABLE_PARTIAL_WRITE);
- return true;
-
-error_ssl_2:
- SSL_CTX_free (ctx->ssl_ctx);
- ctx->ssl_ctx = NULL;
-error_ssl_1:
- return false;
+ free (cert_path);
+ free (key_path);
+ return result;
}
static bool