tls: allow defining a tls profile (domain) for any address
authorDaniel-Constantin Mierla <miconda@gmail.com>
Wed, 5 Sep 2018 11:01:19 +0000 (13:01 +0200)
committerDaniel-Constantin Mierla <miconda@gmail.com>
Wed, 5 Sep 2018 11:01:19 +0000 (13:01 +0200)
- token 'any' or 'all' can be used instead of the address
  [server:any] or [client:any]
- useful when the IP address/port to listen on is not known upfront or
  many addresses are used to listen on
- such profiles can be defined many times and must have server_name attribute
  (for SNI)

src/modules/tls/tls_config.c
src/modules/tls/tls_domain.c
src/modules/tls/tls_domain.h

index fceba47..a2cade2 100644 (file)
@@ -146,6 +146,12 @@ static cfg_option_t token_default[] = {
        {0}
 };
 
+static cfg_option_t ksr_tls_token_any[] = {
+       {"any"},
+       {"all"},
+       {0}
+};
+
 
 static cfg_option_t options[] = {
        {"method",              .param = methods, .f = cfg_parse_enum_opt},
@@ -193,7 +199,7 @@ static void update_opt_variables(void)
 }
 
 
-static int parse_hostport(int* type, struct ip_addr* ip, unsigned int* port,
+static int ksr_tls_parse_hostport(int* type, struct ip_addr* ip, unsigned int* port,
                cfg_token_t* token, cfg_parser_t* st)
 {
        int ret;
@@ -217,7 +223,14 @@ static int parse_hostport(int* type, struct ip_addr* ip, unsigned int* port,
                        /* Default domain */
                        return 0;
                } else {
-                       if (parse_ipv4(ip, &t, st) < 0) return -1;
+                       opt = cfg_lookup_token(ksr_tls_token_any, &t.val);
+                       if (opt) {
+                               *type = TLS_DOMAIN_ANY;
+                               /* Default domain */
+                               return 0;
+                       } else {
+                               if (parse_ipv4(ip, &t, st) < 0) return -1;
+                       }
                }
        } else {
                LM_ERR("%s:%d:%d: Syntax error, IP address expected\n",
@@ -299,7 +312,7 @@ static int parse_domain(void* param, cfg_parser_t* st, unsigned int flags)
        }
 
        port = 0;
-       if (parse_hostport(&type, &ip, &port, &t, st) < 0) return -1;
+       if (ksr_tls_parse_hostport(&type, &ip, &port, &t, st) < 0) return -1;
 
        ret = cfg_get_token(&t, st, 0);
        if (ret < 0) return -1;
index 161d0d0..dcafcdf 100644 (file)
@@ -1521,12 +1521,14 @@ tls_domain_t* tls_lookup_cfg(tls_domains_cfg_t* cfg, int type,
 
                }
                if(sname) {
-                       LM_DBG("comparing addr: [%s:%d]  [%s:%d] -- sni: [%.*s] [%.*s]\n",
+                       LM_DBG("comparing addr: [%s:%d]  [%s:%d] -- sni: [%.*s] [%.*s] -- %d\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));
+                               sname->len, ZSW(sname->s), p->type);
                }
-               if ((p->port==0 || p->port == port) && ip_addr_cmp(&p->ip, ip)) {
+               if ((p->type & TLS_DOMAIN_ANY)
+                               || ((p->port==0 || p->port == port)
+                                               && ip_addr_cmp(&p->ip, ip))) {
                        if(sname && sname->len>0) {
                                if(p->server_name.s && p->server_name.len==sname->len
                                        && strncasecmp(p->server_name.s, sname->s, sname->len)==0) {
@@ -1534,13 +1536,15 @@ tls_domain_t* tls_lookup_cfg(tls_domains_cfg_t* cfg, int type,
                                        return p;
                                }
                        } else {
-                               return p;
+                               if (!(p->type & TLS_DOMAIN_ANY)) {
+                                       return p;
+                               }
                        }
                }
                p = p->next;
        }
 
-            /* No matching domain found, return default */
+       /* No matching domain found, return default */
        if (type & TLS_DOMAIN_SRV) return cfg->srv_default;
        else return cfg->cli_default;
 }
@@ -1564,10 +1568,21 @@ static int domain_exists(tls_domains_cfg_t* cfg, tls_domain_t* d)
                else p = cfg->cli_list;
        }
 
+       if(d->type & TLS_DOMAIN_ANY) {
+               /* any address, it must have server_name for SNI */
+               if(d->server_name.len==0) {
+                       LM_WARN("duplicate definition for a tls profile (same address)"
+                                       " and no server name provided\n");
+                       return 1;
+               }
+       } else {
+               return 0;
+       }
+
        while (p) {
                if ((p->port == d->port) && ip_addr_cmp(&p->ip, &d->ip)) {
-                       if(p->server_name.len==0) {
-                               LM_WARN("another tls domain with same address was defined"
+                       if(d->server_name.len==0 || p->server_name.len==0) {
+                               LM_WARN("duplicate definition for a tls profile (same address)"
                                                " and no server name provided\n");
                                return 1;
                        }
index a0e4d7b..a34a84a 100644 (file)
@@ -84,7 +84,8 @@ enum tls_method {
 enum tls_domain_type {
        TLS_DOMAIN_DEF = (1 << 0), /**< Default domain */
        TLS_DOMAIN_SRV = (1 << 1), /**< Server domain */
-       TLS_DOMAIN_CLI = (1 << 2)  /**< Client domain */
+       TLS_DOMAIN_CLI = (1 << 2), /**< Client domain */
+       TLS_DOMAIN_ANY = (1 << 3)  /**< Any address */
 };