diff options
-rw-r--r-- | CHANGES | 7 | ||||
-rw-r--r-- | channels/chan_sip.c | 11 | ||||
-rw-r--r-- | configs/http.conf.sample | 12 | ||||
-rw-r--r-- | configs/manager.conf.sample | 4 | ||||
-rw-r--r-- | configs/sip.conf.sample | 10 | ||||
-rw-r--r-- | include/asterisk/tcptls.h | 1 | ||||
-rw-r--r-- | main/http.c | 9 | ||||
-rw-r--r-- | main/manager.c | 7 | ||||
-rw-r--r-- | main/tcptls.c | 16 |
9 files changed, 61 insertions, 16 deletions
@@ -20,6 +20,9 @@ SIP Changes * Added SIP_CODEC_OUTBOUND dialplan variable which can be used to set the codec to be used for the outgoing call. It must be one of the codecs configured for the device. + * Added tlsprivatekey option to sip.conf. This allows a separate .pem file + to be used for holding a private key. If tlsprivatekey is not specified, + tlscertfile is searched for both public and private key. Applications ------------ @@ -96,7 +99,9 @@ Asterisk Manager Interface -------------------------- * The Hangup action now accepts a Cause header which may be used to set the channel's hangup cause. - + * sslprivatekey option added to manager.conf and http.conf. Adds the ability + to specify a separate .pem file to hold a private key. By default sslcert + is used to hold both the public and private key. ------------------------------------------------------------------------------ --- Functionality changes from Asterisk 1.6.1 to Asterisk 1.6.2 ------------- ------------------------------------------------------------------------------ diff --git a/channels/chan_sip.c b/channels/chan_sip.c index c20ca70f5..e904b27cb 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -23785,7 +23785,6 @@ static int reload_config(enum channelreloadreason reason) /* iterator->call = sip_destroy(iterator->call); */ } ASTOBJ_UNLOCK(iterator); - } while(0)); /* Then, actually destroy users and registry */ @@ -23793,20 +23792,21 @@ static int reload_config(enum channelreloadreason reason) ast_debug(4, "--------------- Done destroying registry list\n"); ao2_t_callback(peers, OBJ_NODATA, peer_markall_func, NULL, "callback to mark all peers"); } - + /* Reset certificate handling for TLS sessions */ if (reason != CHANNEL_MODULE_LOAD) { ast_free(default_tls_cfg.certfile); + ast_free(default_tls_cfg.pvtfile); ast_free(default_tls_cfg.cipher); ast_free(default_tls_cfg.cafile); ast_free(default_tls_cfg.capath); } default_tls_cfg.certfile = ast_strdup(AST_CERTFILE); /*XXX Not sure if this is useful */ + default_tls_cfg.pvtfile = ast_strdup(""); default_tls_cfg.cipher = ast_strdup(""); default_tls_cfg.cafile = ast_strdup(""); default_tls_cfg.capath = ast_strdup(""); - /* Initialize copy of current global_regcontext for later use in removing stale contexts */ ast_copy_string(oldcontexts, global_regcontext, sizeof(oldcontexts)); oldregcontext = oldcontexts; @@ -24017,6 +24017,9 @@ static int reload_config(enum channelreloadreason reason) } else if (!strcasecmp(v->name, "tlscertfile")) { ast_free(default_tls_cfg.certfile); default_tls_cfg.certfile = ast_strdup(v->value); + } else if (!strcasecmp(v->name, "tlsprivatekey")) { + ast_free(default_tls_cfg.pvtfile); + default_tls_cfg.pvtfile = ast_strdup(v->value); } else if (!strcasecmp(v->name, "tlscipher")) { ast_free(default_tls_cfg.cipher); default_tls_cfg.cipher = ast_strdup(v->value); @@ -25367,6 +25370,8 @@ static int unload_module(void) if (default_tls_cfg.certfile) ast_free(default_tls_cfg.certfile); + if (default_tls_cfg.pvtfile) + ast_free(default_tls_cfg.pvtfile); if (default_tls_cfg.cipher) ast_free(default_tls_cfg.cipher); if (default_tls_cfg.cafile) diff --git a/configs/http.conf.sample b/configs/http.conf.sample index f15c9cf72..9d3769712 100644 --- a/configs/http.conf.sample +++ b/configs/http.conf.sample @@ -52,12 +52,16 @@ bindaddr=127.0.0.1 ; sslbindport=4433 ; port to use - default is 8089 ; sslbindaddr=0.0.0.0 ; address to bind to - default is bindaddr. ; -; sslcert=/tmp/foo.pem ; path to the certificate ; -; To produce a certificate you can e.g. use openssl -; openssl req -new -x509 -days 365 -nodes -out /tmp/foo.pem -keyout /tmp/foo.pem +; sslcert=</path/to/certificate.pem> ; path to the certificate file (*.pem) only. +; sslprivatekey=</path/to/private.pem> ; path to private key file (*.pem) only. +; If no path is given for sslcert or sslprivatekey, default is to look in current +; directory. If no sslprivatekey is given, default is to search sslcert for private key. +; +; To produce a certificate you can e.g. use openssl. This places both the cert and +; private in same .pem file. +; openssl req -new -x509 -days 365 -nodes -out /tmp/foo.pem -keyout /tmp/foo.pem ; - ; The post_mappings section maps URLs to real paths on the filesystem. If a ; POST is done from within an authenticated manager session to one of the ; configured POST mappings, then any files in the POST will be placed in the diff --git a/configs/manager.conf.sample b/configs/manager.conf.sample index 0fd4ccbaa..39585c1de 100644 --- a/configs/manager.conf.sample +++ b/configs/manager.conf.sample @@ -43,9 +43,11 @@ bindaddr = 0.0.0.0 ; sslbindport=5039 ; the port to bind to ; sslbindaddr=0.0.0.0 ; address to bind to, default to bindaddr ; sslcert=/tmp/asterisk.pem ; path to the certificate. +; sslprivatekey=/tmp/private.pem ; path to the private key, if no private given, + ; if no sslprivatekey is given, default is to search + ; sslcert for private key. ; sslcipher=<cipher string> ; string specifying which SSL ciphers to use or not use - ; ;allowmultiplelogin = yes ; IF set to no, rejects manager logins that are already in use. ; ; The default is yes. diff --git a/configs/sip.conf.sample b/configs/sip.conf.sample index 46ac6e903..a9288817c 100644 --- a/configs/sip.conf.sample +++ b/configs/sip.conf.sample @@ -117,12 +117,16 @@ tcpbindaddr=0.0.0.0 ; IP address for TCP server to bind to (0.0.0.0 ; Remember that the IP address must match the common name (hostname) in the ; certificate, so you don't want to bind a TLS socket to multiple IP addresses. -;tlscertfile=asterisk.pem ; Certificate file (*.pem only) to use for TLS connections - ; default is to look for "asterisk.pem" in current directory +;tlscertfile=</path/to/certificate.pem> ; Certificate file (*.pem only) to use for TLS connections + ; default is to look for "asterisk.pem" in current directory + +;tlsprivatekey=</path/to/private.pem> ; Private key file (*.pem only) for TLS connections. + ; If no tlsprivatekey is specified, tlscertfile is searched for + ; for both public and private key. ;tlscafile=</path/to/certificate> ; If the server your connecting to uses a self signed certificate -; you should have their certificate installed here so the code can +; you should have their certificate installed here so the code can ; verify the authenticity of their certificate. ;tlscadir=</path/to/ca/dir> diff --git a/include/asterisk/tcptls.h b/include/asterisk/tcptls.h index 8e6fd4b4e..e811ab290 100644 --- a/include/asterisk/tcptls.h +++ b/include/asterisk/tcptls.h @@ -78,6 +78,7 @@ enum ast_ssl_flags { struct ast_tls_config { int enabled; char *certfile; + char *pvtfile; char *cipher; char *cafile; char *capath; diff --git a/main/http.c b/main/http.c index 399e5140c..595d6cbab 100644 --- a/main/http.c +++ b/main/http.c @@ -1004,6 +1004,12 @@ static int __ast_http_load(int reload) ast_free(http_tls_cfg.certfile); } http_tls_cfg.certfile = ast_strdup(AST_CERTFILE); + + if (http_tls_cfg.pvtfile) { + ast_free(http_tls_cfg.pvtfile); + } + http_tls_cfg.pvtfile = ast_strdup(""); + if (http_tls_cfg.cipher) { ast_free(http_tls_cfg.cipher); } @@ -1027,6 +1033,9 @@ static int __ast_http_load(int reload) } else if (!strcasecmp(v->name, "sslcert")) { ast_free(http_tls_cfg.certfile); http_tls_cfg.certfile = ast_strdup(v->value); + } else if (!strcasecmp(v->name, "sslprivatekey")) { + ast_free(http_tls_cfg.pvtfile); + http_tls_cfg.pvtfile = ast_strdup(v->value); } else if (!strcasecmp(v->name, "sslcipher")) { ast_free(http_tls_cfg.cipher); http_tls_cfg.cipher = ast_strdup(v->value); diff --git a/main/manager.c b/main/manager.c index 8a054b89b..09e3c764c 100644 --- a/main/manager.c +++ b/main/manager.c @@ -4791,6 +4791,10 @@ static int __init_manager(int reload) ast_free(ami_tls_cfg.certfile); } ami_tls_cfg.certfile = ast_strdup(AST_CERTFILE); + if (ami_tls_cfg.pvtfile) { + ast_free(ami_tls_cfg.pvtfile); + } + ami_tls_cfg.pvtfile = ast_strdup(""); if (ami_tls_cfg.cipher) { ast_free(ami_tls_cfg.cipher); } @@ -4812,6 +4816,9 @@ static int __init_manager(int reload) } else if (!strcasecmp(var->name, "sslcert")) { ast_free(ami_tls_cfg.certfile); ami_tls_cfg.certfile = ast_strdup(val); + } else if (!strcasecmp(var->name, "sslprivatekey")) { + ast_free(ami_tls_cfg.pvtfile); + ami_tls_cfg.pvtfile = ast_strdup(val); } else if (!strcasecmp(var->name, "sslcipher")) { ast_free(ami_tls_cfg.cipher); ami_tls_cfg.cipher = ast_strdup(val); diff --git a/main/tcptls.c b/main/tcptls.c index edf2fe97e..5837668de 100644 --- a/main/tcptls.c +++ b/main/tcptls.c @@ -289,12 +289,20 @@ static int __ssl_setup(struct ast_tls_config *cfg, int client) return 0; } if (!ast_strlen_zero(cfg->certfile)) { - if (SSL_CTX_use_certificate_file(cfg->ssl_ctx, cfg->certfile, SSL_FILETYPE_PEM) == 0 || - SSL_CTX_use_PrivateKey_file(cfg->ssl_ctx, cfg->certfile, SSL_FILETYPE_PEM) == 0 || - SSL_CTX_check_private_key(cfg->ssl_ctx) == 0 ) { + char *tmpprivate = ast_strlen_zero(cfg->pvtfile) ? cfg->certfile : cfg->pvtfile; + if (SSL_CTX_use_certificate_file(cfg->ssl_ctx, cfg->certfile, SSL_FILETYPE_PEM) == 0) { if (!client) { /* Clients don't need a certificate, but if its setup we can use it */ - ast_verb(0, "SSL cert error <%s>", cfg->certfile); + ast_verb(0, "SSL error loading cert file. <%s>", cfg->certfile); + sleep(2); + cfg->enabled = 0; + return 0; + } + } + if ((SSL_CTX_use_PrivateKey_file(cfg->ssl_ctx, tmpprivate, SSL_FILETYPE_PEM) == 0) || (SSL_CTX_check_private_key(cfg->ssl_ctx) == 0 )) { + if (!client) { + /* Clients don't need a private key, but if its setup we can use it */ + ast_verb(0, "SSL error loading private key file. <%s>", tmpprivate); sleep(2); cfg->enabled = 0; return 0; |