From 05f5cfe02b197873c5eb6c09e978a787b4bda4bd Mon Sep 17 00:00:00 2001 From: Bram Matthys Date: Sun, 20 Aug 2006 23:05:55 +0000 Subject: [PATCH] - The server SSL certificate and private key can now be reloaded without requiring a server restart, simply use: /REHASH -ssl --- Changes | 2 + src/s_serv.c | 6 +++ src/ssl.c | 106 ++++++++++++++++++++++++++++++++++++++++----------- 3 files changed, 91 insertions(+), 23 deletions(-) diff --git a/Changes b/Changes index a98ba2199..e9f6f0c14 100644 --- a/Changes +++ b/Changes @@ -1285,3 +1285,5 @@ a server connects, just like HOOTYPE_SERVER_CONNECT but this is actually called *after* all clients and channels are synched. Obviously needed for some modules which must synch data that refers to clients/channels that would otherwise not exist yet on the other side. +- The server SSL certificate and private key can now be reloaded without requiring a server + restart, simply use: /REHASH -ssl diff --git a/src/s_serv.c b/src/s_serv.c index d7b2f50a8..096450a53 100644 --- a/src/s_serv.c +++ b/src/s_serv.c @@ -672,6 +672,12 @@ CMD_FUNC(m_rehash) reinit_resolver(sptr); return 0; } + if (!_match("-ssl*", parv[1])) + { + extern void reinit_ssl(aClient *); + reinit_ssl(sptr); + return 0; + } if (!_match("-o*motd", parv[1])) { sendto_ops diff --git a/src/ssl.c b/src/ssl.c index 6f40920f8..da165dbc3 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -174,14 +174,27 @@ static int ssl_verify_callback(int preverify_ok, X509_STORE_CTX *ctx) return 1; } - -void init_ctx_server(void) +static void mylog(char *fmt, ...) { +va_list vl; +static char buf[2048]; + + va_start(vl, fmt); + ircvsprintf(buf, fmt, vl); + va_end(vl); + sendto_realops("[SSL rehash] %s", buf); + ircd_log(LOG_ERROR, "%s", buf); +} + +SSL_CTX *init_ctx_server(void) +{ +SSL_CTX *ctx_server; + ctx_server = SSL_CTX_new(SSLv23_server_method()); if (!ctx_server) { - ircd_log(LOG_ERROR, "Failed to do SSL CTX new"); - exit(2); + mylog("Failed to do SSL CTX new"); + return NULL; } SSL_CTX_set_default_passwd_cb(ctx_server, ssl_pem_passwd_cb); SSL_CTX_set_options(ctx_server, SSL_OP_NO_SSLv2); @@ -191,57 +204,67 @@ void init_ctx_server(void) if (SSL_CTX_use_certificate_chain_file(ctx_server, SSL_SERVER_CERT_PEM) <= 0) { - ircd_log(LOG_ERROR, "Failed to load SSL certificate %s", SSL_SERVER_CERT_PEM); - exit(3); + mylog("Failed to load SSL certificate %s", SSL_SERVER_CERT_PEM); + goto fail; } if (SSL_CTX_use_PrivateKey_file(ctx_server, SSL_SERVER_KEY_PEM, SSL_FILETYPE_PEM) <= 0) { - ircd_log(LOG_ERROR, "Failed to load SSL private key %s", SSL_SERVER_KEY_PEM); - exit(4); + mylog("Failed to load SSL private key %s", SSL_SERVER_KEY_PEM); + goto fail; } if (!SSL_CTX_check_private_key(ctx_server)) { - ircd_log(LOG_ERROR, "Failed to check SSL private key"); - exit(5); + mylog("Failed to check SSL private key"); + goto fail; } if (iConf.trusted_ca_file) { if (!SSL_CTX_load_verify_locations(ctx_server, iConf.trusted_ca_file, NULL)) { - ircd_log(LOG_ERROR, "Failed to load Trusted CA's from %s", iConf.trusted_ca_file); - exit(6); + mylog("Failed to load Trusted CA's from %s", iConf.trusted_ca_file); + goto fail; } } + return ctx_server; +fail: + SSL_CTX_free(ctx_server); + return NULL; } -void init_ctx_client(void) +SSL_CTX *init_ctx_client(void) { +SSL_CTX *ctx_client; + ctx_client = SSL_CTX_new(SSLv3_client_method()); if (!ctx_client) { - ircd_log(LOG_ERROR, "Failed to do SSL CTX new client"); - exit(2); + mylog("Failed to do SSL CTX new client"); + return NULL; } SSL_CTX_set_default_passwd_cb(ctx_client, ssl_pem_passwd_cb); SSL_CTX_set_session_cache_mode(ctx_client, SSL_SESS_CACHE_OFF); if (SSL_CTX_use_certificate_file(ctx_client, SSL_SERVER_CERT_PEM, SSL_FILETYPE_PEM) <= 0) { - ircd_log(LOG_ERROR, "Failed to load SSL certificate %s (client)", SSL_SERVER_CERT_PEM); - exit(3); + mylog("Failed to load SSL certificate %s (client)", SSL_SERVER_CERT_PEM); + goto fail; } if (SSL_CTX_use_PrivateKey_file(ctx_client, SSL_SERVER_KEY_PEM, SSL_FILETYPE_PEM) <= 0) { - ircd_log(LOG_ERROR, "Failed to load SSL private key %s (client)", SSL_SERVER_KEY_PEM); - exit(4); + mylog("Failed to load SSL private key %s (client)", SSL_SERVER_KEY_PEM); + goto fail; } if (!SSL_CTX_check_private_key(ctx_client)) { - ircd_log(LOG_ERROR, "Failed to check SSL private key (client)"); - exit(5); + mylog("Failed to check SSL private key (client)"); + goto fail; } + return ctx_client; +fail: + SSL_CTX_free(ctx_client); + return NULL; } void init_ssl(void) @@ -261,8 +284,45 @@ void init_ssl(void) #endif RAND_egd(EGD_PATH); } - init_ctx_server(); - init_ctx_client(); + ctx_server = init_ctx_server(); + if (!ctx_server) + exit(7); + if (!init_ctx_client()) + exit(8); +} + +void reinit_ssl(aClient *acptr) +{ +SSL_CTX *tmp; + + if (IsPerson(acptr)) + mylog("%s (%s@%s) requested a reload of all SSL related data (/rehash -ssl)", + acptr->name, acptr->user->username, acptr->user->realhost); + else + mylog("%s requested a reload of all SSL related data (/rehash -ssl)", + acptr->name); + + tmp = init_ctx_server(); + if (!tmp) + { + mylog("SSL Reload failed."); + return; + } + /* free and do it for real */ + SSL_CTX_free(tmp); + SSL_CTX_free(ctx_server); + ctx_server = init_ctx_server(); + + tmp = init_ctx_client(); + if (!tmp) + { + mylog("SSL Reload partially failed. Server context is reloaded, client context failed"); + return; + } + /* free and do it for real */ + SSL_CTX_free(tmp); + SSL_CTX_free(ctx_client); + ctx_client = init_ctx_client(); } #define CHK_NULL(x) if ((x)==NULL) {\