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