소스 검색

tls: allow defining a tls profile (domain) for any address

- 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)
Daniel-Constantin Mierla 7 년 전
부모
커밋
6cfc608750
3개의 변경된 파일40개의 추가작업 그리고 11개의 파일을 삭제
  1. 16 3
      src/modules/tls/tls_config.c
  2. 22 7
      src/modules/tls/tls_domain.c
  3. 2 1
      src/modules/tls/tls_domain.h

+ 16 - 3
src/modules/tls/tls_config.c

@@ -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;

+ 22 - 7
src/modules/tls/tls_domain.c

@@ -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;
 			}

+ 2 - 1
src/modules/tls/tls_domain.h

@@ -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 */
 };