diff options
-rw-r--r-- | channels/chan_sip.c | 1 | ||||
-rw-r--r-- | include/asterisk/tcptls.h | 17 | ||||
-rw-r--r-- | main/tcptls.c | 34 |
3 files changed, 50 insertions, 2 deletions
diff --git a/channels/chan_sip.c b/channels/chan_sip.c index e2d2daf5e..a84adeb75 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -31884,6 +31884,7 @@ static int unload_module(void) if (sip_tls_desc.master) { ast_tcptls_server_stop(&sip_tls_desc); } + ast_ssl_teardown(sip_tls_desc.tls_cfg); /* Kill all existing TCP/TLS threads */ i = ao2_iterator_init(threadt, 0); diff --git a/include/asterisk/tcptls.h b/include/asterisk/tcptls.h index ba6ac12d9..6d8d14993 100644 --- a/include/asterisk/tcptls.h +++ b/include/asterisk/tcptls.h @@ -196,9 +196,26 @@ void ast_tcptls_server_start(struct ast_tcptls_session_args *desc); * \version 1.6.1 changed desc parameter to be of ast_tcptls_session_args type */ void ast_tcptls_server_stop(struct ast_tcptls_session_args *desc); + +/*! + * \brief Set up an SSL server + * + * \param cfg Configuration for the SSL server + * \retval 1 Success + * \retval 0 Failure + */ int ast_ssl_setup(struct ast_tls_config *cfg); /*! + * \brief free resources used by an SSL server + * + * \note This only needs to be called if ast_ssl_setup() was + * directly called first. + * \param cfg Configuration for the SSL server + */ +void ast_ssl_teardown(struct ast_tls_config *cfg); + +/*! * \brief Used to parse conf files containing tls/ssl options. */ int ast_tls_read_conf(struct ast_tls_config *tls_cfg, struct ast_tcptls_session_args *tls_desc, const char *varname, const char *value); diff --git a/main/tcptls.c b/main/tcptls.c index 7b1772287..a96fb55ed 100644 --- a/main/tcptls.c +++ b/main/tcptls.c @@ -131,6 +131,14 @@ HOOK_T ast_tcptls_server_write(struct ast_tcptls_session_instance *tcptls_sessio return write(tcptls_session->fd, buf, count); } +static void session_instance_destructor(void *obj) +{ + struct ast_tcptls_session_instance *i = obj; + if (i->parent && i->parent->tls_cfg) { + ast_ssl_teardown(i->parent->tls_cfg); + } +} + /*! \brief * creates a FILE * from the fd passed by the accept thread. * This operation is potentially expensive (certificate verification), @@ -279,7 +287,7 @@ void *ast_tcptls_server_root(void *data) } continue; } - tcptls_session = ao2_alloc(sizeof(*tcptls_session), NULL); + tcptls_session = ao2_alloc(sizeof(*tcptls_session), session_instance_destructor); if (!tcptls_session) { ast_log(LOG_WARNING, "No memory for new session: %s\n", strerror(errno)); if (close(fd)) { @@ -319,6 +327,14 @@ static int __ssl_setup(struct ast_tls_config *cfg, int client) SSL_load_error_strings(); SSLeay_add_ssl_algorithms(); + /* Get rid of an old SSL_CTX since we're about to + * allocate a new one + */ + if (cfg->ssl_ctx) { + SSL_CTX_free(cfg->ssl_ctx); + cfg->ssl_ctx = NULL; + } + if (client) { #ifndef OPENSSL_NO_SSL2 if (ast_test_flag(&cfg->flags, AST_SSL_SSLV2_CLIENT)) { @@ -354,6 +370,8 @@ static int __ssl_setup(struct ast_tls_config *cfg, int client) ast_verb(0, "SSL error loading cert file. <%s>\n", cfg->certfile); sleep(2); cfg->enabled = 0; + SSL_CTX_free(cfg->ssl_ctx); + cfg->ssl_ctx = NULL; return 0; } } @@ -363,6 +381,8 @@ static int __ssl_setup(struct ast_tls_config *cfg, int client) ast_verb(0, "SSL error loading private key file. <%s>\n", tmpprivate); sleep(2); cfg->enabled = 0; + SSL_CTX_free(cfg->ssl_ctx); + cfg->ssl_ctx = NULL; return 0; } } @@ -373,6 +393,8 @@ static int __ssl_setup(struct ast_tls_config *cfg, int client) ast_verb(0, "SSL cipher error <%s>\n", cfg->cipher); sleep(2); cfg->enabled = 0; + SSL_CTX_free(cfg->ssl_ctx); + cfg->ssl_ctx = NULL; return 0; } } @@ -393,6 +415,14 @@ int ast_ssl_setup(struct ast_tls_config *cfg) return __ssl_setup(cfg, 0); } +void ast_ssl_teardown(struct ast_tls_config *cfg) +{ + if (cfg->ssl_ctx) { + SSL_CTX_free(cfg->ssl_ctx); + cfg->ssl_ctx = NULL; + } +} + struct ast_tcptls_session_instance *ast_tcptls_client_start(struct ast_tcptls_session_instance *tcptls_session) { struct ast_tcptls_session_args *desc; @@ -471,7 +501,7 @@ struct ast_tcptls_session_instance *ast_tcptls_client_create(struct ast_tcptls_s } } - if (!(tcptls_session = ao2_alloc(sizeof(*tcptls_session), NULL))) { + if (!(tcptls_session = ao2_alloc(sizeof(*tcptls_session), session_instance_destructor))) { goto error; } |