Module: kamailio Branch: master Commit: 9a36fb7aae0adc39efb17a967a88db2eebfd8c36 URL: https://github.com/kamailio/kamailio/commit/9a36fb7aae0adc39efb17a967a88db2e...
Author: Daniel-Constantin Mierla miconda@gmail.com Committer: Daniel-Constantin Mierla miconda@gmail.com Date: 2015-02-17T14:11:07+01:00
tls: set SNI for outbound connections via xavp
- new parameter: xavp_cfg to set the name of the xavp that holds attributes for tls connections - server_name attribute can be used to specify SNI for outbound connections:
modparam("tls", "xavp_cfg", "tls") ... $xavp(tls=>server_name) = "kamailio.org"; $du = "sip:kamailio.org:5061;transport=tls"; route(RELAY);
- note: kamailio tries to identify the client context from tls.cfg by ip, port and server_name, but many OSes allocate a local random port when initiating TCP/TLS connection, so it is hard to add such contexts, in this case the client:default being used
---
Modified: modules/tls/tls_domain.c Modified: modules/tls/tls_mod.c Modified: modules/tls/tls_server.c
---
Diff: https://github.com/kamailio/kamailio/commit/9a36fb7aae0adc39efb17a967a88db2e... Patch: https://github.com/kamailio/kamailio/commit/9a36fb7aae0adc39efb17a967a88db2e...
---
diff --git a/modules/tls/tls_domain.c b/modules/tls/tls_domain.c index 260522f..e31a4fe 100644 --- a/modules/tls/tls_domain.c +++ b/modules/tls/tls_domain.c @@ -1302,6 +1302,12 @@ tls_domain_t* tls_lookup_cfg(tls_domains_cfg_t* cfg, int type, }
while (p) { + if(sname) { + LM_DBG("comparing addr: [%s:%d] [%s:%d] -- sni: [%.*s] [%.*s]\n", + ip_addr2a(&p->ip), p->port, ip_addr2a(ip), port, + p->server_name.len, ZSW(p->server_name.s), + sname->len, ZSW(sname->s)); + } if ((p->port == port) && ip_addr_cmp(&p->ip, ip)) { if(sname && sname->len>0) { if(p->server_name.len==sname->len diff --git a/modules/tls/tls_mod.c b/modules/tls/tls_mod.c index ed8ac01..2d085d0 100644 --- a/modules/tls/tls_mod.c +++ b/modules/tls/tls_mod.c @@ -82,6 +82,7 @@ static int is_peer_verified(struct sip_msg* msg, char* foo, char* foo2); MODULE_VERSION
+str sr_tls_xavp_cfg = {0, 0}; /* * Default settings when modparams are used */ @@ -203,6 +204,7 @@ static param_export_t params[] = { {"low_mem_threshold1", PARAM_INT, &default_tls_cfg.low_mem_threshold1}, {"low_mem_threshold2", PARAM_INT, &default_tls_cfg.low_mem_threshold2}, {"renegotiation", PARAM_INT, &sr_tls_renegotiation}, + {"xavp_cfg", PARAM_STR, &sr_tls_xavp_cfg}, {0, 0, 0} };
diff --git a/modules/tls/tls_server.c b/modules/tls/tls_server.c index f8abb5b..b7e3207 100644 --- a/modules/tls/tls_server.c +++ b/modules/tls/tls_server.c @@ -42,6 +42,7 @@ #include "../../route.h" #include "../../forward.h" #include "../../onsend.h" +#include "../../xavp.h"
#include "tls_init.h" #include "tls_domain.h" @@ -127,6 +128,30 @@ int tls_run_event_routes(struct tcp_connection *c); #endif /* TLS_RD_DEBUG */
+extern str sr_tls_xavp_cfg; + +/** + * get the server name (sni) for outbound connections from xavp + */ +static str *tls_get_connect_server_name(void) +{ +#ifndef OPENSSL_NO_TLSEXT + sr_xavp_t *vavp = NULL; + str sname = {"server_name", 11}; + + if(sr_tls_xavp_cfg.s!=NULL) + vavp = xavp_get_child_with_sval(&sr_tls_xavp_cfg, &sname); + if(vavp==NULL || vavp->val.v.s.len<=0) { + LM_DBG("xavp with outbound server name not found\n"); + return NULL; + } + LM_DBG("found xavp with outbound server name: %s\n", vavp->val.v.s.s); + return &vavp->val.v.s; +#else + return NULL; +#endif +} + /** finish the ssl init. * Creates the SSL context + internal tls_extra_data and sets * extra_data to it. @@ -141,6 +166,7 @@ static int tls_complete_init(struct tcp_connection* c) struct tls_extra_data* data = 0; tls_domains_cfg_t* cfg; enum tls_conn_states state; + str *sname = NULL;
if (LOW_MEM_NEW_CONNECTION_TEST()){ ERR("tls: ssl bug #1491 workaround: not enough memory for safe" @@ -169,8 +195,9 @@ static int tls_complete_init(struct tcp_connection* c) &c->rcv.dst_ip, c->rcv.dst_port, 0); } else { state=S_TLS_CONNECTING; + sname = tls_get_connect_server_name(); dom = tls_lookup_cfg(cfg, TLS_DOMAIN_CLI, - &c->rcv.dst_ip, c->rcv.dst_port, 0); + &c->rcv.dst_ip, c->rcv.dst_port, sname); } if (unlikely(c->state<0)) { BUG("Invalid connection (state %d)\n", c->state); @@ -199,6 +226,20 @@ static int tls_complete_init(struct tcp_connection* c) BIO_free(data->rwbio); goto error; } + +#ifndef OPENSSL_NO_TLSEXT + if (sname!=NULL) { + if(!SSL_set_tlsext_host_name(data->ssl, sname->s)) { + if (data->ssl) + SSL_free(data->ssl); + if (data->rwbio) + BIO_free(data->rwbio); + goto error; + } + LM_DBG("outbound TLS server name set to: %s\n", sname->s); + } +#endif + #ifdef TLS_KSSL_WORKARROUND /* if needed apply workaround for openssl bug #1467 */ if (data->ssl->kssl_ctx && openssl_kssl_malloc_bug){ @@ -211,7 +252,6 @@ static int tls_complete_init(struct tcp_connection* c)
/* link the extra data struct inside ssl connection*/ SSL_set_app_data(data->ssl, data); - return 0;
error: