Browse code

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

Daniel-Constantin Mierla authored on 17/02/2015 13:05:53
Showing 3 changed files
... ...
@@ -1302,6 +1302,12 @@ tls_domain_t* tls_lookup_cfg(tls_domains_cfg_t* cfg, int type,
1302 1302
 	}
1303 1303
 
1304 1304
 	while (p) {
1305
+		if(sname) {
1306
+			LM_DBG("comparing addr: [%s:%d]  [%s:%d] -- sni: [%.*s] [%.*s]\n",
1307
+				ip_addr2a(&p->ip), p->port, ip_addr2a(ip), port,
1308
+				p->server_name.len, ZSW(p->server_name.s),
1309
+				sname->len, ZSW(sname->s));
1310
+		}
1305 1311
 		if ((p->port == port) && ip_addr_cmp(&p->ip, ip)) {
1306 1312
 			if(sname && sname->len>0) {
1307 1313
 				if(p->server_name.len==sname->len
... ...
@@ -82,6 +82,7 @@ static int is_peer_verified(struct sip_msg* msg, char* foo, char* foo2);
82 82
 MODULE_VERSION
83 83
 
84 84
 
85
+str sr_tls_xavp_cfg = {0, 0};
85 86
 /*
86 87
  * Default settings when modparams are used 
87 88
  */
... ...
@@ -203,6 +204,7 @@ static param_export_t params[] = {
203 204
 	{"low_mem_threshold1",  PARAM_INT,    &default_tls_cfg.low_mem_threshold1},
204 205
 	{"low_mem_threshold2",  PARAM_INT,    &default_tls_cfg.low_mem_threshold2},
205 206
 	{"renegotiation",       PARAM_INT,    &sr_tls_renegotiation},
207
+	{"xavp_cfg",            PARAM_STR,    &sr_tls_xavp_cfg},
206 208
 	{0, 0, 0}
207 209
 };
208 210
 
... ...
@@ -42,6 +42,7 @@
42 42
 #include "../../route.h"
43 43
 #include "../../forward.h"
44 44
 #include "../../onsend.h"
45
+#include "../../xavp.h"
45 46
 
46 47
 #include "tls_init.h"
47 48
 #include "tls_domain.h"
... ...
@@ -127,6 +128,30 @@ int tls_run_event_routes(struct tcp_connection *c);
127 128
 #endif /* TLS_RD_DEBUG */
128 129
 
129 130
 
131
+extern str sr_tls_xavp_cfg;
132
+
133
+/**
134
+ * get the server name (sni) for outbound connections from xavp
135
+ */
136
+static str *tls_get_connect_server_name(void)
137
+{
138
+#ifndef OPENSSL_NO_TLSEXT
139
+	sr_xavp_t *vavp = NULL;
140
+	str sname = {"server_name", 11};
141
+
142
+	if(sr_tls_xavp_cfg.s!=NULL)
143
+		vavp = xavp_get_child_with_sval(&sr_tls_xavp_cfg, &sname);
144
+	if(vavp==NULL || vavp->val.v.s.len<=0) {
145
+		LM_DBG("xavp with outbound server name not found\n");
146
+		return NULL;
147
+	}
148
+	LM_DBG("found xavp with outbound server name: %s\n", vavp->val.v.s.s);
149
+	return &vavp->val.v.s;
150
+#else
151
+	return NULL;
152
+#endif
153
+}
154
+
130 155
 /** finish the ssl init.
131 156
  * Creates the SSL context + internal tls_extra_data and sets
132 157
  * extra_data to it.
... ...
@@ -141,6 +166,7 @@ static int tls_complete_init(struct tcp_connection* c)
141 166
 	struct tls_extra_data* data = 0;
142 167
 	tls_domains_cfg_t* cfg;
143 168
 	enum tls_conn_states state;
169
+	str *sname = NULL;
144 170
 
145 171
 	if (LOW_MEM_NEW_CONNECTION_TEST()){
146 172
 		ERR("tls: ssl bug #1491 workaround: not enough memory for safe"
... ...
@@ -169,8 +195,9 @@ static int tls_complete_init(struct tcp_connection* c)
169 195
 								&c->rcv.dst_ip, c->rcv.dst_port, 0);
170 196
 	} else {
171 197
 		state=S_TLS_CONNECTING;
198
+		sname = tls_get_connect_server_name();
172 199
 		dom = tls_lookup_cfg(cfg, TLS_DOMAIN_CLI,
173
-								&c->rcv.dst_ip, c->rcv.dst_port, 0);
200
+								&c->rcv.dst_ip, c->rcv.dst_port, sname);
174 201
 	}
175 202
 	if (unlikely(c->state<0)) {
176 203
 		BUG("Invalid connection (state %d)\n", c->state);
... ...
@@ -199,6 +226,20 @@ static int tls_complete_init(struct tcp_connection* c)
199 226
 			BIO_free(data->rwbio);
200 227
 		goto error;
201 228
 	}
229
+
230
+#ifndef OPENSSL_NO_TLSEXT
231
+	if (sname!=NULL) {
232
+		if(!SSL_set_tlsext_host_name(data->ssl, sname->s)) {
233
+			if (data->ssl)
234
+				SSL_free(data->ssl);
235
+			if (data->rwbio)
236
+				BIO_free(data->rwbio);
237
+			goto error;
238
+		}
239
+		LM_DBG("outbound TLS server name set to: %s\n", sname->s);
240
+	}
241
+#endif
242
+
202 243
 #ifdef TLS_KSSL_WORKARROUND
203 244
 	 /* if needed apply workaround for openssl bug #1467 */
204 245
 	if (data->ssl->kssl_ctx && openssl_kssl_malloc_bug){
... ...
@@ -211,7 +252,6 @@ static int tls_complete_init(struct tcp_connection* c)
211 252
 
212 253
 	/* link the extra data struct inside ssl connection*/
213 254
 	SSL_set_app_data(data->ssl, data);
214
-
215 255
 	return 0;
216 256
 
217 257
  error: