4 * @brief Implementation of peer_cfg_t.
9 * Copyright (C) 2005-2007 Martin Willi
10 * Copyright (C) 2005 Jan Hutter
11 * Hochschule fuer Technik Rapperswil
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the
15 * Free Software Foundation; either version 2 of the License, or (at your
16 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
18 * This program is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
20 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
29 #include <utils/linked_list.h>
30 #include <utils/identification.h>
32 ENUM(cert_policy_names
, CERT_ALWAYS_SEND
, CERT_NEVER_SEND
,
38 ENUM(dpd_action_names
, DPD_NONE
, DPD_RESTART
,
45 typedef struct private_peer_cfg_t private_peer_cfg_t
;
48 * Private data of an peer_cfg_t object
50 struct private_peer_cfg_t
{
58 * Number of references hold by others to this peer_cfg
63 * Name of the peer_cfg, used to query it
68 * IKE version to use for initiation
73 * IKE config associated to this peer config
78 * list of child configs associated to this peer config
80 linked_list_t
*child_cfgs
;
83 * mutex to lock access to list of child_cfgs
85 pthread_mutex_t mutex
;
88 * id to use to identify us
90 identification_t
*my_id
;
93 * allowed id for other
95 identification_t
*other_id
;
98 * we have a cert issued by this CA
100 identification_t
*my_ca
;
103 * we require the other end to have a cert issued by this CA
105 identification_t
*other_ca
;
108 * should we send a certificate
110 cert_policy_t cert_policy
;
113 * Method to use for own authentication data
115 auth_method_t auth_method
;
118 * EAP type to use for peer authentication
123 * number of tries after giving up if peer does not respond
125 u_int32_t keyingtries
;
128 * user reauthentication instead of rekeying
133 * Time before an SA gets invalid
138 * Time before an SA gets rekeyed
143 * Time, which specifies the range of a random value
144 * substracted from lifetime.
149 * What to do with an SA when other peer seams to be dead?
154 * What to do with CHILDren when other peer seams to be dead?
159 * virtual IP to use locally
161 host_t
*my_virtual_ip
;
164 * virtual IP to use remotly
166 host_t
*other_virtual_ip
;
170 * Implementation of peer_cfg_t.get_name
172 static char *get_name(private_peer_cfg_t
*this)
178 * Implementation of peer_cfg_t.get_ike_version
180 static u_int
get_ike_version(private_peer_cfg_t
*this)
182 return this->ike_version
;
186 * Implementation of peer_cfg_t.get_ike_cfg
188 static ike_cfg_t
* get_ike_cfg(private_peer_cfg_t
*this)
190 return this->ike_cfg
;
194 * Implementation of peer_cfg_t.add_child_cfg.
196 static void add_child_cfg(private_peer_cfg_t
*this, child_cfg_t
*child_cfg
)
198 pthread_mutex_lock(&this->mutex
);
199 this->child_cfgs
->insert_last(this->child_cfgs
, child_cfg
);
200 pthread_mutex_unlock(&this->mutex
);
204 * Implementation of peer_cfg_t.create_child_cfg_iterator.
206 static iterator_t
* create_child_cfg_iterator(private_peer_cfg_t
*this)
208 return this->child_cfgs
->create_iterator_locked(this->child_cfgs
,
213 * Check if child_cfg contains traffic selectors
215 static bool contains_ts(child_cfg_t
*child
, bool mine
, linked_list_t
*ts
,
218 linked_list_t
*selected
;
219 bool contains
= FALSE
;
221 selected
= child
->get_traffic_selectors(child
, mine
, ts
, host
);
222 contains
= selected
->get_count(selected
);
223 selected
->destroy_offset(selected
, offsetof(traffic_selector_t
, destroy
));
228 * Implementation of peer_cfg_t.select_child_cfg
230 static child_cfg_t
* select_child_cfg(private_peer_cfg_t
*this,
231 linked_list_t
*my_ts
,
232 linked_list_t
*other_ts
,
233 host_t
*my_host
, host_t
*other_host
)
235 child_cfg_t
*current
, *found
= NULL
;
236 iterator_t
*iterator
;
238 iterator
= create_child_cfg_iterator(this);
239 while (iterator
->iterate(iterator
, (void**)¤t
))
241 if (contains_ts(current
, TRUE
, my_ts
, my_host
) &&
242 contains_ts(current
, FALSE
, other_ts
, other_host
))
245 found
->get_ref(found
);
249 iterator
->destroy(iterator
);
254 * Implementation of peer_cfg_t.get_my_id
256 static identification_t
*get_my_id(private_peer_cfg_t
*this)
262 * Implementation of peer_cfg_t.get_other_id
264 static identification_t
*get_other_id(private_peer_cfg_t
*this)
266 return this->other_id
;
270 * Implementation of peer_cfg_t.get_my_ca
272 static identification_t
*get_my_ca(private_peer_cfg_t
*this)
277 static identification_t
*get_other_ca(private_peer_cfg_t
*this)
279 return this->other_ca
;
283 * Implementation of peer_cfg_t.get_cert_policy.
285 static cert_policy_t
get_cert_policy(private_peer_cfg_t
*this)
287 return this->cert_policy
;
291 * Implementation of connection_t.auth_method_t.
293 static auth_method_t
get_auth_method(private_peer_cfg_t
*this)
295 return this->auth_method
;
299 * Implementation of connection_t.get_eap_type.
301 static eap_type_t
get_eap_type(private_peer_cfg_t
*this)
303 return this->eap_type
;
307 * Implementation of connection_t.get_keyingtries.
309 static u_int32_t
get_keyingtries(private_peer_cfg_t
*this)
311 return this->keyingtries
;
315 * Implementation of peer_cfg_t.get_soft_lifetime
317 static u_int32_t
get_lifetime(private_peer_cfg_t
*this, bool rekey
)
321 if (this->jitter
== 0)
323 return this->rekeytime
;
325 return this->rekeytime
- (random() % this->jitter
);
327 return this->lifetime
;
331 * Implementation of peer_cfg_t.use_reauth.
333 static bool use_reauth(private_peer_cfg_t
*this, bool rekey
)
335 return this->use_reauth
;
339 * Implements peer_cfg_t.get_dpd_delay
341 static u_int32_t
get_dpd_delay(private_peer_cfg_t
*this)
343 return this->dpd_delay
;
347 * Implements peer_cfg_t.get_dpd_action
349 static dpd_action_t
get_dpd_action(private_peer_cfg_t
*this)
351 return this->dpd_action
;
355 * Implementation of peer_cfg_t.get_virtual_ip.
357 static host_t
* get_virtual_ip(private_peer_cfg_t
*this, host_t
*suggestion
)
359 if (suggestion
== NULL
)
361 if (this->my_virtual_ip
)
363 return this->my_virtual_ip
->clone(this->my_virtual_ip
);
367 if (this->other_virtual_ip
)
369 return this->other_virtual_ip
->clone(this->other_virtual_ip
);
371 if (suggestion
->is_anyaddr(suggestion
))
375 return suggestion
->clone(suggestion
);
379 * Implements peer_cfg_t.get_ref.
381 static void get_ref(private_peer_cfg_t
*this)
383 ref_get(&this->refcount
);
387 * Implements peer_cfg_t.destroy.
389 static void destroy(private_peer_cfg_t
*this)
391 if (ref_put(&this->refcount
))
393 this->ike_cfg
->destroy(this->ike_cfg
);
394 this->child_cfgs
->destroy_offset(this->child_cfgs
, offsetof(child_cfg_t
, destroy
));
395 this->my_id
->destroy(this->my_id
);
396 this->other_id
->destroy(this->other_id
);
397 DESTROY_IF(this->my_ca
);
398 DESTROY_IF(this->other_ca
);
400 DESTROY_IF(this->my_virtual_ip
);
401 DESTROY_IF(this->other_virtual_ip
);
408 * Described in header-file
410 peer_cfg_t
*peer_cfg_create(char *name
, u_int ike_version
, ike_cfg_t
*ike_cfg
,
411 identification_t
*my_id
, identification_t
*other_id
,
412 identification_t
*my_ca
, identification_t
*other_ca
,
413 cert_policy_t cert_policy
, auth_method_t auth_method
,
414 eap_type_t eap_type
, u_int32_t keyingtries
,
415 u_int32_t lifetime
, u_int32_t rekeytime
,
416 u_int32_t jitter
, bool reauth
,
417 u_int32_t dpd_delay
, dpd_action_t dpd_action
,
418 host_t
*my_virtual_ip
, host_t
*other_virtual_ip
)
420 private_peer_cfg_t
*this = malloc_thing(private_peer_cfg_t
);
422 /* public functions */
423 this->public.get_name
= (char* (*) (peer_cfg_t
*))get_name
;
424 this->public.get_ike_version
= (u_int(*) (peer_cfg_t
*))get_ike_version
;
425 this->public.get_ike_cfg
= (ike_cfg_t
* (*) (peer_cfg_t
*))get_ike_cfg
;
426 this->public.add_child_cfg
= (void (*) (peer_cfg_t
*, child_cfg_t
*))add_child_cfg
;
427 this->public.create_child_cfg_iterator
= (iterator_t
* (*) (peer_cfg_t
*))create_child_cfg_iterator
;
428 this->public.select_child_cfg
= (child_cfg_t
* (*) (peer_cfg_t
*,linked_list_t
*,linked_list_t
*,host_t
*,host_t
*))select_child_cfg
;
429 this->public.get_my_id
= (identification_t
* (*)(peer_cfg_t
*))get_my_id
;
430 this->public.get_other_id
= (identification_t
* (*)(peer_cfg_t
*))get_other_id
;
431 this->public.get_my_ca
= (identification_t
* (*)(peer_cfg_t
*))get_my_ca
;
432 this->public.get_other_ca
= (identification_t
* (*)(peer_cfg_t
*))get_other_ca
;
433 this->public.get_cert_policy
= (cert_policy_t (*) (peer_cfg_t
*))get_cert_policy
;
434 this->public.get_auth_method
= (auth_method_t (*) (peer_cfg_t
*))get_auth_method
;
435 this->public.get_eap_type
= (eap_type_t (*) (peer_cfg_t
*))get_eap_type
;
436 this->public.get_keyingtries
= (u_int32_t (*) (peer_cfg_t
*))get_keyingtries
;
437 this->public.get_lifetime
= (u_int32_t (*) (peer_cfg_t
*, bool rekey
))get_lifetime
;
438 this->public.use_reauth
= (bool (*) (peer_cfg_t
*))use_reauth
;
439 this->public.get_dpd_delay
= (u_int32_t (*) (peer_cfg_t
*))get_dpd_delay
;
440 this->public.get_dpd_action
= (dpd_action_t (*) (peer_cfg_t
*))get_dpd_action
;
441 this->public.get_virtual_ip
= (host_t
* (*) (peer_cfg_t
*, host_t
*))get_virtual_ip
;
442 this->public.get_ref
= (void(*)(peer_cfg_t
*))get_ref
;
443 this->public.destroy
= (void(*)(peer_cfg_t
*))destroy
;
445 /* apply init values */
446 this->name
= strdup(name
);
447 this->ike_version
= ike_version
;
448 this->ike_cfg
= ike_cfg
;
449 this->child_cfgs
= linked_list_create();
450 pthread_mutex_init(&this->mutex
, NULL
);
452 this->other_id
= other_id
;
454 this->other_ca
= other_ca
;
455 this->cert_policy
= cert_policy
;
456 this->auth_method
= auth_method
;
457 this->eap_type
= eap_type
;
458 this->keyingtries
= keyingtries
;
459 this->lifetime
= lifetime
;
460 this->rekeytime
= rekeytime
;
461 this->jitter
= jitter
;
462 this->use_reauth
= reauth
;
463 this->dpd_delay
= dpd_delay
;
464 this->dpd_action
= dpd_action
;
465 this->my_virtual_ip
= my_virtual_ip
;
466 this->other_virtual_ip
= other_virtual_ip
;
469 return &this->public;