Browse code

tls: check tls domain cfg duplication after parsing all attributes

- allows definition of domain profiles with same address but different
server_name (SNI)

Daniel-Constantin Mierla authored on 06/09/2018 08:03:21
Showing 3 changed files
... ...
@@ -41,8 +41,8 @@
41 41
 #include <dirent.h>
42 42
 #include <sys/stat.h>
43 43
 
44
-static tls_domains_cfg_t* cfg = NULL;
45
-static tls_domain_t* domain = NULL;
44
+static tls_domains_cfg_t* _ksr_tls_cfg = NULL;
45
+static tls_domain_t* _ksr_tls_domain = NULL;
46 46
 
47 47
 static int parse_ipv6(struct ip_addr* ip, cfg_token_t* token,
48 48
 		cfg_parser_t* st)
... ...
@@ -180,24 +180,24 @@ static void update_opt_variables(void)
180 180
 {
181 181
 	int i;
182 182
 	for(i = 0; methods[i].name; i++) {
183
-		methods[i].param = &domain->method;
183
+		methods[i].param = &_ksr_tls_domain->method;
184 184
 	}
185
-	options[2].param = &domain->verify_cert;
186
-	options[3].param = &domain->verify_cert;
187
-	options[4].param = &domain->verify_depth;
188
-	options[5].param = &domain->require_cert;
189
-	options[6].param = &domain->require_cert;
190
-	options[7].param = &domain->pkey_file;
191
-	options[8].param = &domain->pkey_file;
192
-	options[9].param = &domain->ca_file;
193
-	options[10].param = &domain->cert_file;
194
-	options[11].param = &domain->cert_file;
195
-	options[12].param = &domain->cipher_list;
196
-	options[13].param = &domain->ca_file;
197
-	options[14].param = &domain->crl_file;
198
-	options[15].param = &domain->server_name;
199
-	options[16].param = &domain->server_name_mode;
200
-	options[17].param = &domain->server_id;
185
+	options[2].param = &_ksr_tls_domain->verify_cert;
186
+	options[3].param = &_ksr_tls_domain->verify_cert;
187
+	options[4].param = &_ksr_tls_domain->verify_depth;
188
+	options[5].param = &_ksr_tls_domain->require_cert;
189
+	options[6].param = &_ksr_tls_domain->require_cert;
190
+	options[7].param = &_ksr_tls_domain->pkey_file;
191
+	options[8].param = &_ksr_tls_domain->pkey_file;
192
+	options[9].param = &_ksr_tls_domain->ca_file;
193
+	options[10].param = &_ksr_tls_domain->cert_file;
194
+	options[11].param = &_ksr_tls_domain->cert_file;
195
+	options[12].param = &_ksr_tls_domain->cipher_list;
196
+	options[13].param = &_ksr_tls_domain->ca_file;
197
+	options[14].param = &_ksr_tls_domain->crl_file;
198
+	options[15].param = &_ksr_tls_domain->server_name;
199
+	options[16].param = &_ksr_tls_domain->server_name_mode;
200
+	options[17].param = &_ksr_tls_domain->server_id;
201 201
 }
202 202
 
203 203
 
... ...
@@ -273,7 +273,7 @@ static int ksr_tls_parse_hostport(int* type, struct ip_addr* ip, unsigned int* p
273 273
 }
274 274
 
275 275
 
276
-static int parse_domain(void* param, cfg_parser_t* st, unsigned int flags)
276
+static int ksr_tls_parse_domain(void* param, cfg_parser_t* st, unsigned int flags)
277 277
 {
278 278
 	cfg_token_t t;
279 279
 	int ret;
... ...
@@ -283,6 +283,13 @@ static int parse_domain(void* param, cfg_parser_t* st, unsigned int flags)
283 283
 	struct ip_addr ip;
284 284
 	unsigned int port;
285 285
 
286
+	if(_ksr_tls_cfg!=NULL && _ksr_tls_domain!=NULL) {
287
+		/* Make sure the previous domain is not a duplicate */
288
+		if (ksr_tls_domain_duplicated(_ksr_tls_cfg, _ksr_tls_domain)) {
289
+			return -1;
290
+		}
291
+	}
292
+
286 293
 	memset(&ip, 0, sizeof(struct ip_addr));
287 294
 
288 295
 	ret = cfg_get_token(&t, st, 0);
... ...
@@ -331,26 +338,29 @@ static int parse_domain(void* param, cfg_parser_t* st, unsigned int flags)
331 338
 
332 339
 	if (cfg_eat_eol(st, flags)) return -1;
333 340
 
334
-	if ((domain = tls_new_domain(opt->val | type, &ip, port)) == NULL) {
341
+	if ((_ksr_tls_domain = tls_new_domain(opt->val | type, &ip, port)) == NULL) {
335 342
 		LM_ERR("%s:%d: Cannot create TLS domain structure\n", st->file, st->line);
336 343
 		return -1;
337 344
 	}
338 345
 
339
-	ret = tls_add_domain(cfg, domain);
346
+	ret = tls_add_domain(_ksr_tls_cfg, _ksr_tls_domain);
340 347
 	if (ret < 0) {
341 348
 		LM_ERR("%s:%d: Error while creating TLS domain structure\n", st->file,
342 349
 				st->line);
343
-		tls_free_domain(domain);
350
+		tls_free_domain(_ksr_tls_domain);
351
+		_ksr_tls_domain = NULL;
344 352
 		return -1;
345 353
 	} else if (ret == 1) {
346 354
 		LM_ERR("%s:%d: Duplicate TLS domain (appears earlier in the config file)\n",
347 355
 				st->file, st->line);
348
-		tls_free_domain(domain);
356
+		tls_free_domain(_ksr_tls_domain);
357
+		_ksr_tls_domain = NULL;
349 358
 		return -1;
350 359
 	}
351 360
 
352 361
 	update_opt_variables();
353 362
 	cfg_set_options(st, options);
363
+
354 364
 	return 0;
355 365
 }
356 366
 
... ...
@@ -376,7 +386,7 @@ tls_domains_cfg_t* tls_load_config(str* filename)
376 386
 	in_fd = out_fd = filename_is_directory = 0;
377 387
 	file_path = (char *)0;
378 388
 
379
-	if ((cfg = tls_new_cfg()) == NULL) goto error;
389
+	if ((_ksr_tls_cfg = tls_new_cfg()) == NULL) goto error;
380 390
 
381 391
 	if (stat(filename->s, &file_status) != 0) {
382 392
 		LM_ERR("cannot stat config file %s\n", filename->s);
... ...
@@ -451,11 +461,11 @@ tls_domains_cfg_t* tls_load_config(str* filename)
451 461
 		}
452 462
 	}
453 463
 
454
-	cfg_section_parser(parser, parse_domain, NULL);
464
+	cfg_section_parser(parser, ksr_tls_parse_domain, NULL);
455 465
 	if (sr_cfg_parse(parser)) goto error;
456 466
 	cfg_parser_close(parser);
457 467
 	if (file_path) pkg_free(file_path);
458
-	return cfg;
468
+	return _ksr_tls_cfg;
459 469
 
460 470
 error:
461 471
 	if (dir) closedir(dir);
... ...
@@ -465,7 +475,10 @@ error:
465 475
 	}
466 476
 	if (file_path) pkg_free(file_path);
467 477
 	if (parser) cfg_parser_close(parser);
468
-	if (cfg) tls_free_cfg(cfg);
478
+	if (_ksr_tls_cfg) {
479
+		tls_free_cfg(_ksr_tls_cfg);
480
+		_ksr_tls_cfg = NULL;
481
+	}
469 482
 	return 0;
470 483
 }
471 484
 
... ...
@@ -272,6 +272,12 @@ char* tls_domain_str(tls_domain_t* d)
272 272
 	p = strcat(p, d->type & TLS_DOMAIN_SRV ? "TLSs<" : "TLSc<");
273 273
 	if (d->type & TLS_DOMAIN_DEF) {
274 274
 		p = strcat(p, "default>");
275
+	} else if (d->type & TLS_DOMAIN_ANY) {
276
+		p = strcat(p, "any:");
277
+		if(d->server_name.s && d->server_name.len>0) {
278
+			p = strncat(p, d->server_name.s, d->server_name.len);
279
+		}
280
+		p = strcat(p, ">");
275 281
 	} else {
276 282
 		p = strcat(p, ip_addr2a(&d->ip));
277 283
 		p = strcat(p, ":");
... ...
@@ -291,7 +297,7 @@ char* tls_domain_str(tls_domain_t* d)
291 297
  * @param parent parent domain
292 298
  * @return 0 on success, -1 on error
293 299
  */
294
-static int fill_missing(tls_domain_t* d, tls_domain_t* parent)
300
+static int ksr_tls_fill_missing(tls_domain_t* d, tls_domain_t* parent)
295 301
 {
296 302
 	if (d->method == TLS_METHOD_UNSPEC) d->method = parent->method;
297 303
 	LOG(L_INFO, "%s: tls_method=%d\n", tls_domain_str(d), d->method);
... ...
@@ -983,12 +989,20 @@ static int tls_server_name_cb(SSL *ssl, int *ad, void *private)
983 989
  * @param d initialized TLS domain
984 990
  * @param def default TLS domains
985 991
  */
986
-static int fix_domain(tls_domain_t* d, tls_domain_t* def)
992
+static int ksr_tls_fix_domain(tls_domain_t* d, tls_domain_t* def)
987 993
 {
988 994
 	int i;
989 995
 	int procs_no;
990 996
 
991
-	if (fill_missing(d, def) < 0) return -1;
997
+	if (ksr_tls_fill_missing(d, def) < 0) return -1;
998
+
999
+	if(d->type & TLS_DOMAIN_ANY) {
1000
+		if(d->server_name.s==NULL || d->server_name.len<0) {
1001
+			LM_ERR("%s: tls domain for any address but no server name\n",
1002
+					tls_domain_str(d));
1003
+			return -1;
1004
+		}
1005
+	}
992 1006
 
993 1007
 	procs_no=get_max_procs();
994 1008
 	d->ctx = (SSL_CTX**)shm_malloc(sizeof(SSL_CTX*) * procs_no);
... ...
@@ -1354,18 +1368,18 @@ int tls_fix_domains_cfg(tls_domains_cfg_t* cfg, tls_domain_t* srv_defaults,
1354 1368
 											0, 0);
1355 1369
 	}
1356 1370
 
1357
-	if (fix_domain(cfg->srv_default, srv_defaults) < 0) return -1;
1358
-	if (fix_domain(cfg->cli_default, cli_defaults) < 0) return -1;
1371
+	if (ksr_tls_fix_domain(cfg->srv_default, srv_defaults) < 0) return -1;
1372
+	if (ksr_tls_fix_domain(cfg->cli_default, cli_defaults) < 0) return -1;
1359 1373
 
1360 1374
 	d = cfg->srv_list;
1361 1375
 	while (d) {
1362
-		if (fix_domain(d, srv_defaults) < 0) return -1;
1376
+		if (ksr_tls_fix_domain(d, srv_defaults) < 0) return -1;
1363 1377
 		d = d->next;
1364 1378
 	}
1365 1379
 
1366 1380
 	d = cfg->cli_list;
1367 1381
 	while (d) {
1368
-		if (fix_domain(d, cli_defaults) < 0) return -1;
1382
+		if (ksr_tls_fix_domain(d, cli_defaults) < 0) return -1;
1369 1383
 		d = d->next;
1370 1384
 	}
1371 1385
 
... ...
@@ -1571,18 +1585,27 @@ tls_domain_t* tls_lookup_cfg(tls_domains_cfg_t* cfg, int type,
1571 1585
 
1572 1586
 
1573 1587
 /**
1574
- * @brief Check whether configuration domain exists
1588
+ * @brief Check whether configuration domain is duplicated
1575 1589
  * @param cfg configuration set
1576 1590
  * @param d checked domain
1577
- * @return 1 if domain exists, 0 if its not exists
1591
+ * @return 1 if domain is duplicated, 0 if it's not
1578 1592
  */
1579
-static int domain_exists(tls_domains_cfg_t* cfg, tls_domain_t* d)
1593
+int ksr_tls_domain_duplicated(tls_domains_cfg_t* cfg, tls_domain_t* d)
1580 1594
 {
1581 1595
 	tls_domain_t *p;
1582 1596
 
1583 1597
 	if (d->type & TLS_DOMAIN_DEF) {
1584
-		if (d->type & TLS_DOMAIN_SRV) return cfg->srv_default != NULL;
1585
-		else return cfg->cli_default != NULL;
1598
+		if (d->type & TLS_DOMAIN_SRV) {
1599
+			if(cfg->srv_default==d) {
1600
+				return 0;
1601
+			}
1602
+			return cfg->srv_default != NULL;
1603
+		} else {
1604
+			if(cfg->cli_default==d) {
1605
+				return 0;
1606
+			}
1607
+			return cfg->cli_default != NULL;
1608
+		}
1586 1609
 	} else {
1587 1610
 		if (d->type & TLS_DOMAIN_SRV) p = cfg->srv_list;
1588 1611
 		else p = cfg->cli_list;
... ...
@@ -1594,17 +1617,19 @@ static int domain_exists(tls_domains_cfg_t* cfg, tls_domain_t* d)
1594 1617
 			LM_WARN("duplicate definition for a tls profile (same address)"
1595 1618
 					" and no server name provided\n");
1596 1619
 			return 1;
1620
+		} else {
1621
+			return 0;
1597 1622
 		}
1598
-	} else {
1599
-		return 0;
1600 1623
 	}
1601 1624
 
1602 1625
 	while (p) {
1603
-		if ((p->port == d->port) && ip_addr_cmp(&p->ip, &d->ip)) {
1604
-			if(d->server_name.len==0 || p->server_name.len==0) {
1605
-				LM_WARN("duplicate definition for a tls profile (same address)"
1606
-						" and no server name provided\n");
1607
-				return 1;
1626
+		if(p!=d) {
1627
+			if ((p->port == d->port) && ip_addr_cmp(&p->ip, &d->ip)) {
1628
+				if(d->server_name.len==0 || p->server_name.len==0) {
1629
+					LM_WARN("duplicate definition for a tls profile (same address)"
1630
+							" and no server name provided\n");
1631
+					return 1;
1632
+				}
1608 1633
 			}
1609 1634
 		}
1610 1635
 		p = p->next;
... ...
@@ -1627,9 +1652,6 @@ int tls_add_domain(tls_domains_cfg_t* cfg, tls_domain_t* d)
1627 1652
 		return -1;
1628 1653
 	}
1629 1654
 
1630
-	     /* Make sure the domain does not exist */
1631
-	if (domain_exists(cfg, d)) return 1;
1632
-
1633 1655
 	if (d->type & TLS_DOMAIN_DEF) {
1634 1656
 		if (d->type & TLS_DOMAIN_CLI) {
1635 1657
 			cfg->cli_default = d;
... ...
@@ -214,4 +214,9 @@ void tls_free_cfg(tls_domains_cfg_t* cfg);
214 214
  */
215 215
 void tls_destroy_cfg(void);
216 216
 
217
+/**
218
+ * @brief Check if a TLS configuration domain exists
219
+ */
220
+int ksr_tls_domain_duplicated(tls_domains_cfg_t* cfg, tls_domain_t* d);
221
+
217 222
 #endif /* _TLS_DOMAIN_H */