summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Kuron <m.kuron@gmx.de>2016-11-15 20:44:13 +0100
committerMichael Kuron <m.kuron@gmx.de>2016-11-22 20:05:29 +0100
commit8e77d6f52039e3ba20374c8a0083ad73bcce9e98 (patch)
treec098219c28b39211ab8d5474937a1d350c9abf27
parentee73af1d88c9ff6db90f70f934f5ea57b8ab0625 (diff)
tcptls: Use new certificate upon sip reload
Previously, a TLS server socket would only be restarted upon sip reload if the bind address had changed. This commit adds checking for changes to TLS parameters like certificate, ciphers, etc. so they get picked up without requiring a reload of the entire chan_sip module. This does not affect open connections in any way, but new connections will use the new TLS parameters. The changes also apply to HTTP and Manager. ASTERISK-26604 #close Change-Id: I169e86cefc6dcd627c915134015a6a1ab1aadbe6
-rw-r--r--include/asterisk/tcptls.h4
-rw-r--r--main/tcptls.c86
2 files changed, 89 insertions, 1 deletions
diff --git a/include/asterisk/tcptls.h b/include/asterisk/tcptls.h
index e1a632cca..8a18a8fe7 100644
--- a/include/asterisk/tcptls.h
+++ b/include/asterisk/tcptls.h
@@ -106,6 +106,9 @@ struct ast_tls_config {
char *capath;
struct ast_flags flags;
SSL_CTX *ssl_ctx;
+ char certhash[41];
+ char pvthash[41];
+ char cahash[41];
};
/*! \page AstTlsOverview TLS Implementation Overview
@@ -150,6 +153,7 @@ struct ast_tcptls_session_args {
void (*periodic_fn)(void *);/*!< something we may want to run before after select on the accept socket */
void *(*worker_fn)(void *); /*!< the function in charge of doing the actual work */
const char *name;
+ struct ast_tls_config *old_tls_cfg; /*!< copy of the SSL configuration to determine whether changes have been made */
};
struct ast_tcptls_stream;
diff --git a/main/tcptls.c b/main/tcptls.c
index 34baf9a0e..19012e1e0 100644
--- a/main/tcptls.c
+++ b/main/tcptls.c
@@ -39,6 +39,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include <signal.h>
#include <sys/signal.h>
+#include <sys/stat.h>
#include "asterisk/compat.h"
#include "asterisk/tcptls.h"
@@ -49,6 +50,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/manager.h"
#include "asterisk/astobj2.h"
#include "asterisk/pbx.h"
+#include "asterisk/app.h"
/*! ao2 object used for the FILE stream fopencookie()/funopen() cookie. */
struct ast_tcptls_stream {
@@ -1037,9 +1039,64 @@ void ast_tcptls_server_start(struct ast_tcptls_session_args *desc)
{
int flags;
int x = 1;
+ int tls_changed = 0;
+
+ if (desc->tls_cfg) {
+ char hash[41];
+ char *str = NULL;
+ struct stat st;
+
+ /* Store the hashes of the TLS certificate etc. */
+ if (stat(desc->tls_cfg->certfile, &st) || NULL == (str = ast_read_textfile(desc->tls_cfg->certfile))) {
+ memset(hash, 0, 41);
+ } else {
+ ast_sha1_hash(hash, str);
+ }
+ ast_free(str);
+ str = NULL;
+ memcpy(desc->tls_cfg->certhash, hash, 41);
+ if (stat(desc->tls_cfg->pvtfile, &st) || NULL == (str = ast_read_textfile(desc->tls_cfg->pvtfile))) {
+ memset(hash, 0, 41);
+ } else {
+ ast_sha1_hash(hash, str);
+ }
+ ast_free(str);
+ str = NULL;
+ memcpy(desc->tls_cfg->pvthash, hash, 41);
+ if (stat(desc->tls_cfg->cafile, &st) || NULL == (str = ast_read_textfile(desc->tls_cfg->cafile))) {
+ memset(hash, 0, 41);
+ } else {
+ ast_sha1_hash(hash, str);
+ }
+ ast_free(str);
+ str = NULL;
+ memcpy(desc->tls_cfg->cahash, hash, 41);
+
+ /* Check whether TLS configuration has changed */
+ if (!desc->old_tls_cfg) { /* No previous configuration */
+ tls_changed = 1;
+ desc->old_tls_cfg = ast_calloc(1, sizeof(*desc->old_tls_cfg));
+ } else if (memcmp(desc->tls_cfg->certhash, desc->old_tls_cfg->certhash, 41)) {
+ tls_changed = 1;
+ } else if (memcmp(desc->tls_cfg->pvthash, desc->old_tls_cfg->pvthash, 41)) {
+ tls_changed = 1;
+ } else if (strcmp(desc->tls_cfg->cipher, desc->old_tls_cfg->cipher)) {
+ tls_changed = 1;
+ } else if (memcmp(desc->tls_cfg->cahash, desc->old_tls_cfg->cahash, 41)) {
+ tls_changed = 1;
+ } else if (strcmp(desc->tls_cfg->capath, desc->old_tls_cfg->capath)) {
+ tls_changed = 1;
+ } else if (memcmp(&desc->tls_cfg->flags, &desc->old_tls_cfg->flags, sizeof(desc->tls_cfg->flags))) {
+ tls_changed = 1;
+ }
+
+ if (tls_changed) {
+ ast_debug(1, "Changed parameters for %s found\n", desc->name);
+ }
+ }
/* Do nothing if nothing has changed */
- if (!ast_sockaddr_cmp(&desc->old_address, &desc->local_address)) {
+ if (!tls_changed && !ast_sockaddr_cmp(&desc->old_address, &desc->local_address)) {
ast_debug(1, "Nothing changed in %s\n", desc->name);
return;
}
@@ -1095,6 +1152,22 @@ void ast_tcptls_server_start(struct ast_tcptls_session_args *desc)
/* Set current info */
ast_sockaddr_copy(&desc->old_address, &desc->local_address);
+ if (desc->old_tls_cfg) {
+ ast_free(desc->old_tls_cfg->certfile);
+ ast_free(desc->old_tls_cfg->pvtfile);
+ ast_free(desc->old_tls_cfg->cipher);
+ ast_free(desc->old_tls_cfg->cafile);
+ ast_free(desc->old_tls_cfg->capath);
+ desc->old_tls_cfg->certfile = ast_strdup(desc->tls_cfg->certfile);
+ desc->old_tls_cfg->pvtfile = ast_strdup(desc->tls_cfg->pvtfile);
+ desc->old_tls_cfg->cipher = ast_strdup(desc->tls_cfg->cipher);
+ desc->old_tls_cfg->cafile = ast_strdup(desc->tls_cfg->cafile);
+ desc->old_tls_cfg->capath = ast_strdup(desc->tls_cfg->capath);
+ memcpy(desc->old_tls_cfg->certhash, desc->tls_cfg->certhash, 41);
+ memcpy(desc->old_tls_cfg->pvthash, desc->tls_cfg->pvthash, 41);
+ memcpy(desc->old_tls_cfg->cahash, desc->tls_cfg->cahash, 41);
+ memcpy(&desc->old_tls_cfg->flags, &desc->tls_cfg->flags, sizeof(desc->old_tls_cfg->flags));
+ }
return;
@@ -1140,6 +1213,17 @@ void ast_tcptls_server_stop(struct ast_tcptls_session_args *desc)
close(desc->accept_fd);
}
desc->accept_fd = -1;
+
+ if (desc->old_tls_cfg) {
+ ast_free(desc->old_tls_cfg->certfile);
+ ast_free(desc->old_tls_cfg->pvtfile);
+ ast_free(desc->old_tls_cfg->cipher);
+ ast_free(desc->old_tls_cfg->cafile);
+ ast_free(desc->old_tls_cfg->capath);
+ ast_free(desc->old_tls_cfg);
+ desc->old_tls_cfg = NULL;
+ }
+
ast_debug(2, "Stopped server :: %s\n", desc->name);
}