2 * @file configuration.c
4 * @brief Configuration class used to store IKE_SA-configurations.
6 * Object of this type represents the configuration for all IKE_SA's and their child_sa's.
11 * Copyright (C) 2005 Jan Hutter, Martin Willi
12 * Hochschule fuer Technik Rapperswil
14 * This program is free software; you can redistribute it and/or modify it
15 * under the terms of the GNU General Public License as published by the
16 * Free Software Foundation; either version 2 of the License, or (at your
17 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
19 * This program is distributed in the hope that it will be useful, but
20 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
21 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
27 #include "configuration_manager.h"
31 #include <utils/allocator.h>
33 typedef struct configuration_entry_t configuration_entry_t
;
35 /* A configuration entry combines a configuration name with a init and sa
36 * configuration represented as init_config_t and sa_config_t objects.
38 struct configuration_entry_t
{
47 * Configuration for IKE_SA_INIT exchange.
49 init_config_t
*init_config
;
52 * Configuration for all phases after IKE_SA_INIT exchange.
54 sa_config_t
*sa_config
;
57 * Destroys a configuration_entry_t
60 * @param this calling object
62 void (*destroy
) (configuration_entry_t
*this);
65 static void configuration_entry_destroy (configuration_entry_t
*this)
67 allocator_free(this->name
);
72 * Creates a configuration_entry_t object
74 * @param name name of the configuration entry (gets copied)
75 * @param init_config object of type init_config_t
76 * @param sa_config object of type sa_config_t
78 configuration_entry_t
* configuration_entry_create(char * name
, init_config_t
* init_config
, sa_config_t
* sa_config
)
80 configuration_entry_t
*entry
= allocator_alloc_thing(configuration_entry_t
);
83 entry
->destroy
= configuration_entry_destroy
;
86 entry
->init_config
= init_config
;
87 entry
->sa_config
= sa_config
;
88 entry
->name
= allocator_alloc(strlen(name
) + 1);
89 strcpy(entry
->name
,name
);
94 typedef struct private_configuration_manager_t private_configuration_manager_t
;
97 * Private data of an configuration_t object
99 struct private_configuration_manager_t
{
102 * Public part of configuration manager.
104 configuration_manager_t
public;
107 * Holding all configurations.
109 linked_list_t
*configurations
;
112 * Holding all init_configs.
114 linked_list_t
*init_configs
;
117 * Holding all init_configs.
119 linked_list_t
*sa_configs
;
123 * Assigned logger object.
128 * Load default configuration
131 * @param this calling object
132 * @param name name for the configuration
133 * @param init_config init_config_t object
134 * @param sa_config sa_config_t object
136 void (*add_new_configuration
) (private_configuration_manager_t
*this, char *name
, init_config_t
*init_config
, sa_config_t
*sa_config
);
139 * Load default configuration
142 * @param this calling object
144 void (*load_default_config
) (private_configuration_manager_t
*this);
148 * Implementation of private_configuration_manager_t.load_default_config.
150 static void load_default_config (private_configuration_manager_t
*this)
152 init_config_t
*init_config1
, *init_config2
, *init_config3
;
153 ike_proposal_t proposals
[2];
154 child_proposal_t child_proposals
[1];
155 sa_config_t
*sa_config1
, *sa_config2
;
156 traffic_selector_t
*ts
;
158 init_config1
= init_config_create("152.96.193.131","152.96.193.131",IKEV2_UDP_PORT
,500);
159 init_config2
= init_config_create("152.96.193.131","152.96.193.130",IKEV2_UDP_PORT
,IKEV2_UDP_PORT
);
160 init_config3
= init_config_create("0.0.0.0","127.0.0.1",IKEV2_UDP_PORT
,IKEV2_UDP_PORT
);
161 ts
= traffic_selector_create_from_string(1, TS_IPV4_ADDR_RANGE
, "0.0.0.0", 0, "255.255.255.255", 65535);
164 proposals
[0].encryption_algorithm
= ENCR_AES_CBC
;
165 proposals
[0].encryption_algorithm_key_length
= 16;
166 proposals
[0].integrity_algorithm
= AUTH_HMAC_MD5_96
;
167 proposals
[0].integrity_algorithm_key_length
= 16;
168 proposals
[0].pseudo_random_function
= PRF_HMAC_MD5
;
169 proposals
[0].pseudo_random_function_key_length
= 16;
170 proposals
[0].diffie_hellman_group
= MODP_1024_BIT
;
172 proposals
[1] = proposals
[0];
173 proposals
[1].integrity_algorithm
= AUTH_HMAC_SHA1_96
;
174 proposals
[1].integrity_algorithm_key_length
= 20;
175 proposals
[1].pseudo_random_function
= PRF_HMAC_SHA1
;
176 proposals
[1].pseudo_random_function_key_length
= 20;
178 init_config1
->add_proposal(init_config1
,1,proposals
[0]);
179 init_config1
->add_proposal(init_config1
,1,proposals
[1]);
180 init_config2
->add_proposal(init_config2
,1,proposals
[0]);
181 init_config2
->add_proposal(init_config2
,1,proposals
[1]);
182 init_config3
->add_proposal(init_config3
,1,proposals
[0]);
183 init_config3
->add_proposal(init_config3
,1,proposals
[1]);
185 sa_config1
= sa_config_create(ID_IPV4_ADDR
, "152.96.193.131",
186 ID_IPV4_ADDR
, "152.96.193.130",
187 SHARED_KEY_MESSAGE_INTEGRITY_CODE
);
189 sa_config1
->add_traffic_selector_initiator(sa_config1
,ts
);
190 sa_config1
->add_traffic_selector_responder(sa_config1
,ts
);
192 sa_config2
= sa_config_create(ID_IPV4_ADDR
, "152.96.193.130",
193 ID_IPV4_ADDR
, "152.96.193.131",
194 SHARED_KEY_MESSAGE_INTEGRITY_CODE
);
196 sa_config2
->add_traffic_selector_initiator(sa_config2
,ts
);
197 sa_config2
->add_traffic_selector_responder(sa_config2
,ts
);
201 /* ah and esp prop */
202 child_proposals
[0].ah
.is_set
= TRUE
;
203 child_proposals
[0].ah
.integrity_algorithm
= AUTH_HMAC_MD5_96
;
204 child_proposals
[0].ah
.integrity_algorithm_key_size
= 16;
205 child_proposals
[0].ah
.diffie_hellman_group
= MODP_1024_BIT
;
206 child_proposals
[0].ah
.extended_sequence_numbers
= NO_EXT_SEQ_NUMBERS
;
208 child_proposals
[0].esp
.is_set
= TRUE
;
209 child_proposals
[0].esp
.diffie_hellman_group
= MODP_1024_BIT
;
210 child_proposals
[0].esp
.encryption_algorithm
= ENCR_AES_CBC
;
211 child_proposals
[0].esp
.encryption_algorithm_key_size
= 16;
212 child_proposals
[0].esp
.integrity_algorithm
= AUTH_UNDEFINED
;
213 child_proposals
[0].esp
.spi
[0] = 2;
214 child_proposals
[0].esp
.spi
[1] = 2;
215 child_proposals
[0].esp
.spi
[2] = 2;
216 child_proposals
[0].esp
.spi
[3] = 2;
218 sa_config1
->add_proposal(sa_config1
, &child_proposals
[0]);
219 sa_config2
->add_proposal(sa_config2
, &child_proposals
[0]);
221 this->add_new_configuration(this,"pinflb31",init_config1
,sa_config2
);
222 this->add_new_configuration(this,"pinflb30",init_config2
,sa_config1
);
223 this->add_new_configuration(this,"localhost",init_config3
,sa_config1
);
228 * Implementation of configuration_manager_t.get_init_config_for_host.
230 static status_t
get_init_config_for_host (private_configuration_manager_t
*this, host_t
*my_host
, host_t
*other_host
,init_config_t
**init_config
)
232 iterator_t
*iterator
;
233 status_t status
= NOT_FOUND
;
235 iterator
= this->configurations
->create_iterator(this->configurations
,TRUE
);
237 while (iterator
->has_next(iterator
))
239 configuration_entry_t
*entry
;
240 host_t
*config_my_host
;
241 host_t
*config_other_host
;
243 iterator
->current(iterator
,(void **) &entry
);
245 config_my_host
= entry
->init_config
->get_my_host(entry
->init_config
);
246 config_other_host
= entry
->init_config
->get_other_host(entry
->init_config
);
248 /* first check if ip is equal */
249 if(config_other_host
->ip_is_equal(config_other_host
,other_host
))
251 /* could be right one, check my_host for default route*/
252 if (config_my_host
->is_default_route(config_my_host
))
254 *init_config
= entry
->init_config
;
258 /* check now if host informations are the same */
259 else if (config_my_host
->ip_is_equal(config_my_host
,my_host
))
261 *init_config
= entry
->init_config
;
267 /* Then check for wildcard hosts!
269 * actually its only checked if other host with default route can be found! */
270 else if (config_other_host
->is_default_route(config_other_host
))
272 /* could be right one, check my_host for default route*/
273 if (config_my_host
->is_default_route(config_my_host
))
275 *init_config
= entry
->init_config
;
279 /* check now if host informations are the same */
280 else if (config_my_host
->ip_is_equal(config_my_host
,my_host
))
282 *init_config
= entry
->init_config
;
289 iterator
->destroy(iterator
);
295 * Implementation of configuration_manager_t.get_init_config_for_name.
297 static status_t
get_init_config_for_name (private_configuration_manager_t
*this, char *name
, init_config_t
**init_config
)
299 iterator_t
*iterator
;
300 status_t status
= NOT_FOUND
;
302 iterator
= this->configurations
->create_iterator(this->configurations
,TRUE
);
304 while (iterator
->has_next(iterator
))
306 configuration_entry_t
*entry
;
307 iterator
->current(iterator
,(void **) &entry
);
309 if (strcmp(entry
->name
,name
) == 0)
312 /* found configuration */
313 *init_config
= entry
->init_config
;
319 iterator
->destroy(iterator
);
325 * Implementation of configuration_manager_t.get_sa_config_for_name.
327 static status_t
get_sa_config_for_name (private_configuration_manager_t
*this, char *name
, sa_config_t
**sa_config
)
329 iterator_t
*iterator
;
330 status_t status
= NOT_FOUND
;
332 iterator
= this->configurations
->create_iterator(this->configurations
,TRUE
);
334 while (iterator
->has_next(iterator
))
336 configuration_entry_t
*entry
;
337 iterator
->current(iterator
,(void **) &entry
);
339 if (strcmp(entry
->name
,name
) == 0)
341 /* found configuration */
342 *sa_config
= entry
->sa_config
;
348 iterator
->destroy(iterator
);
354 * Implementation of configuration_manager_t.get_sa_config_for_init_config_and_id.
356 static status_t
get_sa_config_for_init_config_and_id (private_configuration_manager_t
*this, init_config_t
*init_config
, identification_t
*other_id
, identification_t
*my_id
,sa_config_t
**sa_config
)
358 iterator_t
*iterator
;
359 status_t status
= NOT_FOUND
;
361 iterator
= this->configurations
->create_iterator(this->configurations
,TRUE
);
363 while (iterator
->has_next(iterator
))
365 configuration_entry_t
*entry
;
366 iterator
->current(iterator
,(void **) &entry
);
368 if (entry
->init_config
== init_config
)
370 identification_t
*config_my_id
= entry
->sa_config
->get_my_id(entry
->sa_config
);
371 identification_t
*config_other_id
= entry
->sa_config
->get_other_id(entry
->sa_config
);
373 /* host informations seem to be the same */
374 if (config_other_id
->equals(config_other_id
,other_id
))
376 /* other ids seems to match */
380 /* first matching one is selected */
382 /* TODO priorize found entries */
383 *sa_config
= entry
->sa_config
;
388 if (config_my_id
->equals(config_my_id
,my_id
))
390 *sa_config
= entry
->sa_config
;
399 iterator
->destroy(iterator
);
405 * Implementation of private_configuration_manager_t.add_new_configuration.
407 static void add_new_configuration (private_configuration_manager_t
*this, char *name
, init_config_t
*init_config
, sa_config_t
*sa_config
)
409 iterator_t
*iterator
;
412 iterator
= this->init_configs
->create_iterator(this->init_configs
,TRUE
);
414 while (iterator
->has_next(iterator
))
416 init_config_t
*found_init_config
;
417 iterator
->current(iterator
,(void **) &found_init_config
);
418 if (init_config
== found_init_config
)
424 iterator
->destroy(iterator
);
427 this->init_configs
->insert_first(this->init_configs
,init_config
);
430 iterator
= this->sa_configs
->create_iterator(this->sa_configs
,TRUE
);
432 while (iterator
->has_next(iterator
))
434 sa_config_t
*found_sa_config
;
435 iterator
->current(iterator
,(void **) &found_sa_config
);
436 if (sa_config
== found_sa_config
)
442 iterator
->destroy(iterator
);
445 this->sa_configs
->insert_first(this->sa_configs
,sa_config
);
448 this->configurations
->insert_first(this->configurations
,configuration_entry_create(name
,init_config
,sa_config
));
452 * Implementation of configuration_manager_t.destroy.
454 static void destroy(private_configuration_manager_t
*this)
456 this->logger
->log(this->logger
,CONTROL
| MORE
, "Going to destroy configuration manager ");
458 while (this->configurations
->get_count(this->configurations
) > 0)
460 configuration_entry_t
*entry
;
461 this->configurations
->remove_first(this->configurations
,(void **) &entry
);
462 entry
->destroy(entry
);
464 /* todo delete all config objects */
466 this->configurations
->destroy(this->configurations
);
468 while (this->sa_configs
->get_count(this->sa_configs
) > 0)
470 sa_config_t
*sa_config
;
471 this->sa_configs
->remove_first(this->sa_configs
,(void **) &sa_config
);
472 sa_config
->destroy(sa_config
);
475 this->sa_configs
->destroy(this->sa_configs
);
477 while (this->init_configs
->get_count(this->init_configs
) > 0)
479 init_config_t
*init_config
;
480 this->init_configs
->remove_first(this->init_configs
,(void **) &init_config
);
481 init_config
->destroy(init_config
);
483 this->init_configs
->destroy(this->init_configs
);
485 this->logger
->log(this->logger
,CONTROL
| MOST
, "Destroy assigned logger");
486 charon
->logger_manager
->destroy_logger(charon
->logger_manager
,this->logger
);
487 allocator_free(this);
491 * Described in header-file
493 configuration_manager_t
*configuration_manager_create()
495 private_configuration_manager_t
*this = allocator_alloc_thing(private_configuration_manager_t
);
497 /* public functions */
498 this->public.destroy
= (void(*)(configuration_manager_t
*))destroy
;
499 this->public.get_init_config_for_name
= (status_t (*) (configuration_manager_t
*, char *, init_config_t
**)) get_init_config_for_name
;
500 this->public.get_init_config_for_host
= (status_t (*) (configuration_manager_t
*, host_t
*, host_t
*,init_config_t
**)) get_init_config_for_host
;
501 this->public.get_sa_config_for_name
=(status_t (*) (configuration_manager_t
*, char *, sa_config_t
**)) get_sa_config_for_name
;
502 this->public.get_sa_config_for_init_config_and_id
=(status_t (*) (configuration_manager_t
*, init_config_t
*, identification_t
*, identification_t
*,sa_config_t
**)) get_sa_config_for_init_config_and_id
;
504 /* private functions */
505 this->load_default_config
= load_default_config
;
506 this->add_new_configuration
= add_new_configuration
;
508 /* private variables */
509 this->logger
= charon
->logger_manager
->create_logger(charon
->logger_manager
,CONFIGURATION_MANAGER
,NULL
);
510 this->configurations
= linked_list_create();
511 this->sa_configs
= linked_list_create();
512 this->init_configs
= linked_list_create();
514 this->load_default_config(this);
516 return (&this->public);