diff --git a/modules/tls/tls_cfg.c b/modules/tls/tls_cfg.c index fd3b950bb4f..3ec4128e679 100644 --- a/modules/tls/tls_cfg.c +++ b/modules/tls/tls_cfg.c @@ -36,6 +36,7 @@ struct cfg_group_tls default_tls_cfg = { 0, /* tls_force_run */ STR_STATIC_INIT("TLSv1"), /* method */ STR_NULL, /* server name (sni) */ + STR_NULL, /* server id */ 0, /* verify_certificate */ 9, /* verify_depth */ 0, /* require_certificate */ @@ -142,6 +143,8 @@ cfg_def_t tls_cfg_def[] = { "TLS method used (TLSv1.2, TLSv1.1, TLSv1, SSLv3, SSLv2, SSLv23)"}, {"server_name", CFG_VAR_STR | CFG_READONLY, 0, 0, 0, 0, "Server name (SNI)"}, + {"server_id", CFG_VAR_STR | CFG_READONLY, 0, 0, 0, 0, + "Server id (match tls profile for outgoing connections)"}, {"verify_certificate", CFG_VAR_INT | CFG_READONLY, 0, 1, 0, 0, "if enabled the certificates will be verified" }, {"verify_depth", CFG_VAR_INT | CFG_READONLY, 0, 100, 0, 0, diff --git a/modules/tls/tls_cfg.h b/modules/tls/tls_cfg.h index 36cb6625227..2cb8d1cbcb5 100644 --- a/modules/tls/tls_cfg.h +++ b/modules/tls/tls_cfg.h @@ -42,6 +42,7 @@ struct cfg_group_tls { int force_run; str method; str server_name; + str server_id; int verify_cert; int verify_depth; int require_cert; diff --git a/modules/tls/tls_config.c b/modules/tls/tls_config.c index e1dca1bd564..af1d88a0324 100644 --- a/modules/tls/tls_config.c +++ b/modules/tls/tls_config.c @@ -164,6 +164,7 @@ static cfg_option_t options[] = { {"ca_list", .f = cfg_parse_str_opt, .flags = CFG_STR_SHMMEM}, {"crl", .f = cfg_parse_str_opt, .flags = CFG_STR_SHMMEM}, {"server_name", .f = cfg_parse_str_opt, .flags = CFG_STR_SHMMEM}, + {"server_id", .f = cfg_parse_str_opt, .flags = CFG_STR_SHMMEM}, {0} }; @@ -188,6 +189,7 @@ static void update_opt_variables(void) options[13].param = &domain->ca_file; options[14].param = &domain->crl_file; options[15].param = &domain->server_name; + options[16].param = &domain->server_id; } diff --git a/modules/tls/tls_domain.c b/modules/tls/tls_domain.c index 97b635614b7..e64e8bd1d3f 100644 --- a/modules/tls/tls_domain.c +++ b/modules/tls/tls_domain.c @@ -182,6 +182,8 @@ void tls_free_domain(tls_domain_t* d) if (d->crl_file.s) shm_free(d->crl_file.s); if (d->pkey_file.s) shm_free(d->pkey_file.s); if (d->cert_file.s) shm_free(d->cert_file.s); + if (d->server_name.s) shm_free(d->server_name.s); + if (d->server_id.s) shm_free(d->server_id.s); shm_free(d); } @@ -904,7 +906,7 @@ static int tls_server_name_cb(SSL *ssl, int *ad, void *private) server_name.len = strlen(server_name.s); new_domain = tls_lookup_cfg(*tls_domains_cfg, TLS_DOMAIN_SRV, - &orig_domain->ip, orig_domain->port, &server_name); + &orig_domain->ip, orig_domain->port, &server_name, 0); if (new_domain==NULL) { LM_DBG("TLS domain for socket [%s:%d] and server_name='%s' " "not found\n", ip_addr2a(&orig_domain->ip), @@ -1289,7 +1291,7 @@ tls_domains_cfg_t* tls_new_cfg(void) * @return found configuration or default, if not found */ tls_domain_t* tls_lookup_cfg(tls_domains_cfg_t* cfg, int type, - struct ip_addr* ip, unsigned short port, str *sname) + struct ip_addr* ip, unsigned short port, str *sname, str *srvid) { tls_domain_t *p; @@ -1302,6 +1304,18 @@ tls_domain_t* tls_lookup_cfg(tls_domains_cfg_t* cfg, int type, } while (p) { + if(srvid && srvid->len>0) { + LM_DBG("comparing addr: [%s:%d] [%s:%d] -- id: [%.*s] [%.*s]\n", + ip_addr2a(&p->ip), p->port, ip_addr2a(ip), port, + p->server_id.len, ZSW(p->server_id.s), + srvid->len, ZSW(srvid->s)); + if(p->server_id.s && p->server_id.len==srvid->len + && strncasecmp(p->server_name.s, srvid->s, srvid->len)==0) { + LM_DBG("TLS config found by server id\n"); + return 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, diff --git a/modules/tls/tls_domain.h b/modules/tls/tls_domain.h index d10c97ad273..3f4fd5085bb 100644 --- a/modules/tls/tls_domain.h +++ b/modules/tls/tls_domain.h @@ -106,6 +106,7 @@ typedef struct tls_domain { enum tls_method method; str crl_file; str server_name; + str server_id; struct tls_domain* next; } tls_domain_t; @@ -194,7 +195,7 @@ int tls_fix_domains_cfg(tls_domains_cfg_t* cfg, tls_domain_t* srv_defaults, * @return found configuration or default, if not found */ tls_domain_t* tls_lookup_cfg(tls_domains_cfg_t* cfg, int type, - struct ip_addr* ip, unsigned short port, str *sname); + struct ip_addr* ip, unsigned short port, str *sname, str *srvid); /** diff --git a/modules/tls/tls_server.c b/modules/tls/tls_server.c index 3f87fc8d470..e5f838d8491 100644 --- a/modules/tls/tls_server.c +++ b/modules/tls/tls_server.c @@ -130,6 +130,21 @@ int tls_run_event_routes(struct tcp_connection *c); extern str sr_tls_xavp_cfg; +static str *tls_get_connect_server_id(void) +{ + sr_xavp_t *vavp = NULL; + str sid = {"server_id", 9}; + if(sr_tls_xavp_cfg.s!=NULL) + vavp = xavp_get_child_with_sval(&sr_tls_xavp_cfg, &sid); + if(vavp==NULL || vavp->val.v.s.len<=0) { + LM_DBG("xavp with outbound server id not found\n"); + return NULL; + } + LM_DBG("found xavp with outbound server id: %s\n", vavp->val.v.s.s); + return &vavp->val.v.s; + +} + /** * get the server name (sni) for outbound connections from xavp */ @@ -167,6 +182,7 @@ static int tls_complete_init(struct tcp_connection* c) tls_domains_cfg_t* cfg; enum tls_conn_states state; str *sname = NULL; + str *srvid = NULL; if (LOW_MEM_NEW_CONNECTION_TEST()){ ERR("tls: ssl bug #1491 workaround: not enough memory for safe" @@ -192,12 +208,13 @@ static int tls_complete_init(struct tcp_connection* c) if (c->flags & F_CONN_PASSIVE) { state=S_TLS_ACCEPTING; dom = tls_lookup_cfg(cfg, TLS_DOMAIN_SRV, - &c->rcv.dst_ip, c->rcv.dst_port, 0); + &c->rcv.dst_ip, c->rcv.dst_port, 0, 0); } else { state=S_TLS_CONNECTING; sname = tls_get_connect_server_name(); + srvid = tls_get_connect_server_id(); dom = tls_lookup_cfg(cfg, TLS_DOMAIN_CLI, - &c->rcv.dst_ip, c->rcv.dst_port, sname); + &c->rcv.dst_ip, c->rcv.dst_port, sname, srvid); } if (unlikely(c->state<0)) { BUG("Invalid connection (state %d)\n", c->state);