3737#include "../../lib/csv.h"
3838#include "tls_domain.h"
3939#include "tls_params.h"
40- #include "api.h"
4140#include <stdlib.h>
4241#include <fnmatch.h>
4342
4443
4544struct tls_domain * * tls_server_domains ;
4645struct tls_domain * * tls_client_domains ;
4746
48- map_t server_dom_matching ;
49- map_t client_dom_matching ;
47+ struct tls_domain * * script_srv_domains_template ;
48+ struct tls_domain * * script_cli_domains_template ;
5049
51- rw_lock_t * dom_lock ;
50+ map_t * server_dom_matching ;
51+ map_t * client_dom_matching ;
5252
53- extern struct openssl_binds openssl_api ;
54- extern struct wolfssl_binds wolfssl_api ;
53+ rw_lock_t * dom_lock ;
5554
5655void destroy_tls_dom (struct tls_domain * d );
5756
@@ -67,110 +66,50 @@ struct tls_domain *tls_find_domain_by_name(str *name, struct tls_domain **dom_li
6766 return NULL ;
6867}
6968
70- struct tls_domain * find_first_script_dom (struct tls_domain * dom )
71- {
72- struct tls_domain * d ;
73-
74- for (d = dom ; d && d -> flags & DOM_FLAG_DB ; d = d -> next ) ;
75-
76- return d ;
77- }
78-
7969void map_free_node (void * val )
8070{
8171 if (val )
8272 shm_free (val );
8373}
8474
85- void map_remove_tls_dom (struct tls_domain * dom )
86- {
87- map_t map = dom -> flags & DOM_FLAG_SRV ? server_dom_matching : client_dom_matching ;
88- map_iterator_t it , it_tmp ;
89- struct dom_filt_array * doms_array ;
90- void * * val ;
91- int i , j ;
92-
93- map_first (map , & it );
94- while (iterator_is_valid (& it )) {
95- it_tmp = it ;
96- iterator_next (& it );
97-
98- val = iterator_val (& it_tmp );
99- doms_array = (struct dom_filt_array * )* val ;
100- for (i = 0 ; i < doms_array -> size ;)
101- if (doms_array -> arr [i ].dom_link == dom ) {
102- for (j = i + 1 ; j < doms_array -> size ; j ++ )
103- doms_array -> arr [j - 1 ] = doms_array -> arr [j ];
104- doms_array -> size -- ;
105- }
106- else {
107- i ++ ;
108- }
109- if (doms_array -> size == 0 ) {
110- map_free_node (doms_array );
111- iterator_delete (& it_tmp );
112- }
113- }
114- }
115-
116- void tls_free_domain (struct tls_domain * dom )
75+ void tls_release_domain (struct tls_domain * dom )
11776{
11877 str_list * m_it , * m_tmp ;
78+ int free_it = 0 ;
11979
120- dom -> refs -- ;
121- if (dom -> refs == 0 ) {
122- LM_DBG ("Freeing domain: %.*s\n" ,
123- dom -> name .len , dom -> name .s );
124-
125- destroy_tls_dom (dom );
80+ if (!dom )
81+ return ;
12682
127- lock_destroy (dom -> lock );
128- lock_dealloc (dom -> lock );
83+ lock_get (dom -> lock );
84+ if (-- dom -> refs == 0 )
85+ free_it = 1 ;
86+ lock_release (dom -> lock );
12987
130- map_remove_tls_dom (dom );
88+ if (!free_it )
89+ return ;
13190
132- m_it = dom -> match_domains ;
133- while (m_it ) {
134- m_tmp = m_it ;
135- m_it = m_it -> next ;
136- shm_free (m_tmp );
137- }
138- m_it = dom -> match_addresses ;
139- while (m_it ) {
140- m_tmp = m_it ;
141- m_it = m_it -> next ;
142- shm_free (m_tmp );
143- }
91+ LM_DBG ("Freeing domain: %.*s\n" ,
92+ dom -> name .len , dom -> name .s );
14493
145- shm_free (dom );
146- }
147- }
94+ destroy_tls_dom (dom );
14895
149- /* frees the DB domains */
150- void tls_free_db_domains (struct tls_domain * dom )
151- {
152- struct tls_domain * tmp ;
96+ lock_destroy (dom -> lock );
97+ lock_dealloc (dom -> lock );
15398
154- while (dom && dom -> flags & DOM_FLAG_DB ) {
155- tmp = dom ;
156- dom = dom -> next ;
157- map_remove_tls_dom (tmp );
158- tls_free_domain (tmp );
99+ m_it = dom -> match_domains ;
100+ while (m_it ) {
101+ m_tmp = m_it ;
102+ m_it = m_it -> next ;
103+ shm_free (m_tmp );
104+ }
105+ m_it = dom -> match_addresses ;
106+ while (m_it ) {
107+ m_tmp = m_it ;
108+ m_it = m_it -> next ;
109+ shm_free (m_tmp );
159110 }
160- }
161-
162- void tls_release_domain (struct tls_domain * dom )
163- {
164- if (!dom || !(dom -> flags & DOM_FLAG_DB ))
165- return ;
166-
167- if (dom_lock )
168- lock_start_write (dom_lock );
169-
170- tls_free_domain (dom );
171111
172- if (dom_lock )
173- lock_stop_write (dom_lock );
112+ shm_free (dom );
174113}
175114
176115int set_all_domain_attr (struct tls_domain * * dom , char * * str_vals , int * int_vals ,
@@ -340,10 +279,10 @@ tls_find_server_domain(struct ip_addr *ip, unsigned short port)
340279 addr_s .s = addr_buf ;
341280 addr_s .len = strlen (addr_buf );
342281
343- val = map_find (server_dom_matching , addr_s );
282+ val = map_find (* server_dom_matching , addr_s );
344283 if (!val ) {
345284 /* try to find a domain which matches any address */
346- val = map_find (server_dom_matching , match_any_s );
285+ val = map_find (* server_dom_matching , match_any_s );
347286 if (!val ) {
348287 if (dom_lock )
349288 lock_stop_read (dom_lock );
@@ -384,11 +323,11 @@ tls_find_domain_by_filters(struct ip_addr *ip, unsigned short port,
384323 addr_s .len = strlen (addr_buf );
385324
386325 val = map_find (type == DOM_FLAG_SRV ?
387- server_dom_matching : client_dom_matching , addr_s );
326+ * server_dom_matching : * client_dom_matching , addr_s );
388327 if (!val ) {
389328 /* try to find domains which match any address */
390329 val = map_find (type == DOM_FLAG_SRV ?
391- server_dom_matching : client_dom_matching , match_any_s );
330+ * server_dom_matching : * client_dom_matching , match_any_s );
392331 if (!val ) {
393332 if (dom_lock )
394333 lock_stop_read (dom_lock );
@@ -554,6 +493,77 @@ int tls_new_domain(str *name, int type, struct tls_domain **dom)
554493 return 0 ;
555494}
556495
496+
497+ /*
498+ * Creates a deep-copy of a TLS domain. This is only appropriate for
499+ * script-defined domains that are instantiated from a template, as it
500+ * performs a mix of shallow and deep copying.
501+ */
502+ struct tls_domain * tls_copy_domain (struct tls_domain * d )
503+ {
504+ struct tls_domain * n ;
505+
506+ if (!d ) return NULL ;
507+
508+ /* Allocate space for the struct and the domain name, like tls_new_domain */
509+ n = shm_malloc (sizeof (struct tls_domain ) + d -> name .len );
510+ if (!n ) {
511+ LM_ERR ("No more shm mem\n" );
512+ return NULL ;
513+ }
514+ memset (n , 0 , sizeof (struct tls_domain ));
515+
516+ /* copy config fields */
517+ n -> flags = d -> flags ;
518+ n -> verify_cert = d -> verify_cert ;
519+ n -> require_client_cert = d -> require_client_cert ;
520+ n -> crl_check_all = d -> crl_check_all ;
521+ n -> cert = d -> cert ;
522+ n -> pkey = d -> pkey ;
523+ n -> crl_directory = d -> crl_directory ;
524+ n -> ca = d -> ca ;
525+ n -> dh_param = d -> dh_param ;
526+ n -> tls_ec_curve = d -> tls_ec_curve ;
527+ n -> ca_directory = d -> ca_directory ;
528+ n -> ciphers_list = d -> ciphers_list ;
529+ n -> method_str = d -> method_str ;
530+ n -> method = d -> method ;
531+ n -> method_max = d -> method_max ;
532+
533+ /* Fix the name pointer and copy the content from the template */
534+ n -> name .s = (char * )(n + 1 );
535+ n -> name .len = d -> name .len ;
536+ memcpy (n -> name .s , d -> name .s , d -> name .len );
537+
538+ /* Initialize runtime state that must not be shared from the template */
539+ n -> refs = 1 ;
540+ n -> lock = lock_alloc ();
541+ if (!n -> lock || lock_init (n -> lock ) == NULL ) {
542+ LM_ERR ("failed to init lock for domain clone\n" );
543+ if (n -> lock ) lock_dealloc (n -> lock );
544+ shm_free (n );
545+ return NULL ;
546+ }
547+
548+ /*
549+ * The matching lists are dynamically built in shm and freed by
550+ * tls_free_domain, so they need a deep copy. Other config strings
551+ * are pointers into the static config buffer and are correctly
552+ * shallow-copied.
553+ */
554+ if ((d -> match_domains && !(n -> match_domains = dup_shm_str_list (d -> match_domains ))) ||
555+ (d -> match_addresses && !(n -> match_addresses = dup_shm_str_list (d -> match_addresses )))
556+ ) {
557+ goto error ;
558+ }
559+
560+ return n ;
561+
562+ error :
563+ if (n ) tls_release_domain (n );
564+ return NULL ;
565+ }
566+
557567static int add_match_filt_to_dom (str * filter_s , str_list * * filter_list )
558568{
559569 str_list * match_filt ;
@@ -768,16 +778,15 @@ int db_add_domain(char **str_vals, int *int_vals, str* blob_vals,
768778 return 0 ;
769779}
770780
771- int update_matching_map (struct tls_domain * tls_dom )
781+ int update_matching_map (struct tls_domain * tls_dom , map_t matching_map )
772782{
773783 str_list * addrf_s , * domf_s ;
774784 struct dom_filt_array * doms_array ;
775785 void * * val ;
776786 int pos ;
777787
778788 for (addrf_s = tls_dom -> match_addresses ; addrf_s ; addrf_s = addrf_s -> next ) {
779- val = map_get (tls_dom -> flags & DOM_FLAG_SRV ?
780- server_dom_matching : client_dom_matching , addrf_s -> s );
789+ val = map_get (matching_map , addrf_s -> s );
781790 if (!val ) {
782791 LM_ERR ("No more shm memory!\n" );
783792 return -1 ;
0 commit comments