summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--channels/chan_sip.c1
-rw-r--r--include/asterisk/tcptls.h17
-rw-r--r--main/tcptls.c34
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;
}