Module: kamailio
Branch: master
Commit: 9a36fb7aae0adc39efb17a967a88db2eebfd8c36
URL:
https://github.com/kamailio/kamailio/commit/9a36fb7aae0adc39efb17a967a88db2…
Author: Daniel-Constantin Mierla <miconda(a)gmail.com>
Committer: Daniel-Constantin Mierla <miconda(a)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/9a36fb7aae0adc39efb17a967a88db2…
Patch:
https://github.com/kamailio/kamailio/commit/9a36fb7aae0adc39efb17a967a88db2…
---
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: