using dpd actions to enforce connection state
[strongswan.git] / src / charon / config / peer_cfg.c
1 /*
2 * Copyright (C) 2007 Tobias Brunner
3 * Copyright (C) 2005-2007 Martin Willi
4 * Copyright (C) 2005 Jan Hutter
5 * Hochschule fuer Technik Rapperswil
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 * for more details.
16 *
17 * $Id$
18 */
19
20 #include <string.h>
21 #include <pthread.h>
22
23 #include "peer_cfg.h"
24
25 #include <utils/linked_list.h>
26 #include <utils/identification.h>
27
28 ENUM(cert_policy_names, CERT_ALWAYS_SEND, CERT_NEVER_SEND,
29 "CERT_ALWAYS_SEND",
30 "CERT_SEND_IF_ASKED",
31 "CERT_NEVER_SEND"
32 );
33
34 typedef struct private_peer_cfg_t private_peer_cfg_t;
35
36 /**
37 * Private data of an peer_cfg_t object
38 */
39 struct private_peer_cfg_t {
40
41 /**
42 * Public part
43 */
44 peer_cfg_t public;
45
46 /**
47 * Number of references hold by others to this peer_cfg
48 */
49 refcount_t refcount;
50
51 /**
52 * Name of the peer_cfg, used to query it
53 */
54 char *name;
55
56 /**
57 * IKE version to use for initiation
58 */
59 u_int ike_version;
60
61 /**
62 * IKE config associated to this peer config
63 */
64 ike_cfg_t *ike_cfg;
65
66 /**
67 * list of child configs associated to this peer config
68 */
69 linked_list_t *child_cfgs;
70
71 /**
72 * mutex to lock access to list of child_cfgs
73 */
74 pthread_mutex_t mutex;
75
76 /**
77 * id to use to identify us
78 */
79 identification_t *my_id;
80
81 /**
82 * allowed id for other
83 */
84 identification_t *other_id;
85
86 /**
87 * should we send a certificate
88 */
89 cert_policy_t cert_policy;
90
91 /**
92 * Method to use for own authentication data
93 */
94 auth_method_t auth_method;
95
96 /**
97 * EAP type to use for peer authentication
98 */
99 eap_type_t eap_type;
100
101 /**
102 * EAP vendor ID if vendor specific type is used
103 */
104 u_int32_t eap_vendor;
105
106 /**
107 * number of tries after giving up if peer does not respond
108 */
109 u_int32_t keyingtries;
110
111 /**
112 * enable support for MOBIKE
113 */
114 bool use_mobike;
115
116 /**
117 * Time before starting rekeying
118 */
119 u_int32_t rekey_time;
120
121 /**
122 * Time before starting reauthentication
123 */
124 u_int32_t reauth_time;
125
126 /**
127 * Time, which specifies the range of a random value substracted from above.
128 */
129 u_int32_t jitter_time;
130
131 /**
132 * Delay before deleting a rekeying/reauthenticating SA
133 */
134 u_int32_t over_time;
135
136 /**
137 * DPD check intervall
138 */
139 u_int32_t dpd;
140
141 /**
142 * virtual IP to use locally
143 */
144 host_t *virtual_ip;
145
146 /**
147 * pool to acquire configuration attributes from
148 */
149 char *pool;
150
151 /**
152 * required authorization constraints
153 */
154 auth_info_t *auth;
155
156 #ifdef ME
157 /**
158 * Is this a mediation connection?
159 */
160 bool mediation;
161
162 /**
163 * Name of the mediation connection to mediate through
164 */
165 peer_cfg_t *mediated_by;
166
167 /**
168 * ID of our peer at the mediation server (= leftid of the peer's conn with
169 * the mediation server)
170 */
171 identification_t *peer_id;
172 #endif /* ME */
173 };
174
175 /**
176 * Implementation of peer_cfg_t.get_name
177 */
178 static char *get_name(private_peer_cfg_t *this)
179 {
180 return this->name;
181 }
182
183 /**
184 * Implementation of peer_cfg_t.get_ike_version
185 */
186 static u_int get_ike_version(private_peer_cfg_t *this)
187 {
188 return this->ike_version;
189 }
190
191 /**
192 * Implementation of peer_cfg_t.get_ike_cfg
193 */
194 static ike_cfg_t* get_ike_cfg(private_peer_cfg_t *this)
195 {
196 return this->ike_cfg;
197 }
198
199 /**
200 * Implementation of peer_cfg_t.add_child_cfg.
201 */
202 static void add_child_cfg(private_peer_cfg_t *this, child_cfg_t *child_cfg)
203 {
204 pthread_mutex_lock(&this->mutex);
205 this->child_cfgs->insert_last(this->child_cfgs, child_cfg);
206 pthread_mutex_unlock(&this->mutex);
207 }
208
209 /**
210 * Implementation of peer_cfg_t.remove_child_cfg.
211 */
212 static void remove_child_cfg(private_peer_cfg_t *this, enumerator_t *enumerator)
213 {
214 pthread_mutex_lock(&this->mutex);
215 this->child_cfgs->remove_at(this->child_cfgs, enumerator);
216 pthread_mutex_unlock(&this->mutex);
217 }
218
219 /**
220 * Implementation of peer_cfg_t.create_child_cfg_enumerator.
221 */
222 static enumerator_t* create_child_cfg_enumerator(private_peer_cfg_t *this)
223 {
224 enumerator_t *enumerator;
225
226 pthread_mutex_lock(&this->mutex);
227 enumerator = this->child_cfgs->create_enumerator(this->child_cfgs);
228 return enumerator_create_cleaner(enumerator,
229 (void*)pthread_mutex_unlock, &this->mutex);
230 }
231
232 /**
233 * Check if child_cfg contains traffic selectors
234 */
235 static bool contains_ts(child_cfg_t *child, bool mine, linked_list_t *ts,
236 host_t *host)
237 {
238 linked_list_t *selected;
239 bool contains = FALSE;
240
241 selected = child->get_traffic_selectors(child, mine, ts, host);
242 contains = selected->get_count(selected);
243 selected->destroy_offset(selected, offsetof(traffic_selector_t, destroy));
244 return contains;
245 }
246
247 /**
248 * Implementation of peer_cfg_t.select_child_cfg
249 */
250 static child_cfg_t* select_child_cfg(private_peer_cfg_t *this,
251 linked_list_t *my_ts,
252 linked_list_t *other_ts,
253 host_t *my_host, host_t *other_host)
254 {
255 child_cfg_t *current, *found = NULL;
256 enumerator_t *enumerator;
257
258 enumerator = create_child_cfg_enumerator(this);
259 while (enumerator->enumerate(enumerator, &current))
260 {
261 if (contains_ts(current, TRUE, my_ts, my_host) &&
262 contains_ts(current, FALSE, other_ts, other_host))
263 {
264 found = current;
265 found->get_ref(found);
266 break;
267 }
268 }
269 enumerator->destroy(enumerator);
270 return found;
271 }
272
273 /**
274 * Implementation of peer_cfg_t.get_my_id
275 */
276 static identification_t *get_my_id(private_peer_cfg_t *this)
277 {
278 return this->my_id;
279 }
280
281 /**
282 * Implementation of peer_cfg_t.get_other_id
283 */
284 static identification_t *get_other_id(private_peer_cfg_t *this)
285 {
286 return this->other_id;
287 }
288
289 /**
290 * Implementation of peer_cfg_t.get_cert_policy.
291 */
292 static cert_policy_t get_cert_policy(private_peer_cfg_t *this)
293 {
294 return this->cert_policy;
295 }
296
297 /**
298 * Implementation of connection_t.auth_method_t.
299 */
300 static auth_method_t get_auth_method(private_peer_cfg_t *this)
301 {
302 return this->auth_method;
303 }
304
305 /**
306 * Implementation of connection_t.get_eap_type.
307 */
308 static eap_type_t get_eap_type(private_peer_cfg_t *this, u_int32_t *vendor)
309 {
310 *vendor = this->eap_vendor;
311 return this->eap_type;
312 }
313
314 /**
315 * Implementation of connection_t.get_keyingtries.
316 */
317 static u_int32_t get_keyingtries(private_peer_cfg_t *this)
318 {
319 return this->keyingtries;
320 }
321
322 /**
323 * Implementation of peer_cfg_t.get_rekey_time.
324 */
325 static u_int32_t get_rekey_time(private_peer_cfg_t *this)
326 {
327 if (this->rekey_time == 0)
328 {
329 return 0;
330 }
331 if (this->jitter_time == 0)
332 {
333 return this->rekey_time;
334 }
335 return this->rekey_time - (random() % this->jitter_time);
336 }
337
338 /**
339 * Implementation of peer_cfg_t.get_reauth_time.
340 */
341 static u_int32_t get_reauth_time(private_peer_cfg_t *this)
342 {
343 if (this->reauth_time == 0)
344 {
345 return 0;
346 }
347 if (this->jitter_time == 0)
348 {
349 return this->reauth_time;
350 }
351 return this->reauth_time - (random() % this->jitter_time);
352 }
353
354 /**
355 * Implementation of peer_cfg_t.get_over_time.
356 */
357 static u_int32_t get_over_time(private_peer_cfg_t *this)
358 {
359 return this->over_time;
360 }
361
362 /**
363 * Implementation of peer_cfg_t.use_mobike.
364 */
365 static bool use_mobike(private_peer_cfg_t *this)
366 {
367 return this->use_mobike;
368 }
369
370 /**
371 * Implements peer_cfg_t.get_dpd
372 */
373 static u_int32_t get_dpd(private_peer_cfg_t *this)
374 {
375 return this->dpd;
376 }
377
378 /**
379 * Implementation of peer_cfg_t.get_virtual_ip.
380 */
381 static host_t* get_virtual_ip(private_peer_cfg_t *this)
382 {
383 return this->virtual_ip;
384 }
385
386 /**
387 * Implementation of peer_cfg_t.get_pool.
388 */
389 static char* get_pool(private_peer_cfg_t *this)
390 {
391 return this->pool;
392 }
393
394 /**
395 * Implementation of peer_cfg_t.get_auth.
396 */
397 static auth_info_t* get_auth(private_peer_cfg_t *this)
398 {
399 return this->auth;
400 }
401
402 #ifdef ME
403 /**
404 * Implementation of peer_cfg_t.is_mediation.
405 */
406 static bool is_mediation(private_peer_cfg_t *this)
407 {
408 return this->mediation;
409 }
410
411 /**
412 * Implementation of peer_cfg_t.get_mediated_by.
413 */
414 static peer_cfg_t* get_mediated_by(private_peer_cfg_t *this)
415 {
416 return this->mediated_by;
417 }
418
419 /**
420 * Implementation of peer_cfg_t.get_peer_id.
421 */
422 static identification_t* get_peer_id(private_peer_cfg_t *this)
423 {
424 return this->peer_id;
425 }
426 #endif /* ME */
427
428 /**
429 * Implementation of peer_cfg_t.equals.
430 */
431 static bool equals(private_peer_cfg_t *this, private_peer_cfg_t *other)
432 {
433 if (this == other)
434 {
435 return TRUE;
436 }
437 if (this->public.equals != other->public.equals)
438 {
439 return FALSE;
440 }
441
442 return (
443 this->ike_version == other->ike_version &&
444 this->my_id->equals(this->my_id, other->my_id) &&
445 this->other_id->equals(this->other_id, other->other_id) &&
446 this->cert_policy == other->cert_policy &&
447 this->auth_method == other->auth_method &&
448 this->eap_type == other->eap_type &&
449 this->eap_vendor == other->eap_vendor &&
450 this->keyingtries == other->keyingtries &&
451 this->use_mobike == other->use_mobike &&
452 this->rekey_time == other->rekey_time &&
453 this->reauth_time == other->reauth_time &&
454 this->jitter_time == other->jitter_time &&
455 this->over_time == other->over_time &&
456 this->dpd == other->dpd &&
457 (this->virtual_ip == other->virtual_ip ||
458 (this->virtual_ip && other->virtual_ip &&
459 this->virtual_ip->equals(this->virtual_ip, other->virtual_ip))) &&
460 (this->pool == other->pool || streq(this->pool, other->pool)) &&
461 this->auth->equals(this->auth, other->auth)
462 #ifdef ME
463 && this->mediation == other->mediation &&
464 this->mediated_by == other->mediated_by &&
465 (this->peer_id == other->peer_id ||
466 (this->peer_id && other->peer_id &&
467 this->peer_id->equals(this->peer_id, other->peer_id)))
468 #endif /* ME */
469 );
470 }
471
472 /**
473 * Implements peer_cfg_t.get_ref.
474 */
475 static void get_ref(private_peer_cfg_t *this)
476 {
477 ref_get(&this->refcount);
478 }
479
480 /**
481 * Implements peer_cfg_t.destroy.
482 */
483 static void destroy(private_peer_cfg_t *this)
484 {
485 if (ref_put(&this->refcount))
486 {
487 this->ike_cfg->destroy(this->ike_cfg);
488 this->child_cfgs->destroy_offset(this->child_cfgs, offsetof(child_cfg_t, destroy));
489 this->my_id->destroy(this->my_id);
490 this->other_id->destroy(this->other_id);
491 DESTROY_IF(this->virtual_ip);
492 this->auth->destroy(this->auth);
493 #ifdef ME
494 DESTROY_IF(this->mediated_by);
495 DESTROY_IF(this->peer_id);
496 #endif /* ME */
497 free(this->name);
498 free(this->pool);
499 free(this);
500 }
501 }
502
503 /*
504 * Described in header-file
505 */
506 peer_cfg_t *peer_cfg_create(char *name, u_int ike_version, ike_cfg_t *ike_cfg,
507 identification_t *my_id, identification_t *other_id,
508 cert_policy_t cert_policy,
509 auth_method_t auth_method, eap_type_t eap_type,
510 u_int32_t eap_vendor,
511 u_int32_t keyingtries, u_int32_t rekey_time,
512 u_int32_t reauth_time, u_int32_t jitter_time,
513 u_int32_t over_time, bool mobike, u_int32_t dpd,
514 host_t *virtual_ip, char *pool,
515 bool mediation, peer_cfg_t *mediated_by,
516 identification_t *peer_id)
517 {
518 private_peer_cfg_t *this = malloc_thing(private_peer_cfg_t);
519
520 /* public functions */
521 this->public.get_name = (char* (*) (peer_cfg_t *))get_name;
522 this->public.get_ike_version = (u_int(*) (peer_cfg_t *))get_ike_version;
523 this->public.get_ike_cfg = (ike_cfg_t* (*) (peer_cfg_t *))get_ike_cfg;
524 this->public.add_child_cfg = (void (*) (peer_cfg_t *, child_cfg_t*))add_child_cfg;
525 this->public.remove_child_cfg = (void(*)(peer_cfg_t*, enumerator_t*))remove_child_cfg;
526 this->public.create_child_cfg_enumerator = (enumerator_t* (*) (peer_cfg_t *))create_child_cfg_enumerator;
527 this->public.select_child_cfg = (child_cfg_t* (*) (peer_cfg_t *,linked_list_t*,linked_list_t*,host_t*,host_t*))select_child_cfg;
528 this->public.get_my_id = (identification_t* (*)(peer_cfg_t*))get_my_id;
529 this->public.get_other_id = (identification_t* (*)(peer_cfg_t *))get_other_id;
530 this->public.get_cert_policy = (cert_policy_t (*) (peer_cfg_t *))get_cert_policy;
531 this->public.get_auth_method = (auth_method_t (*) (peer_cfg_t *))get_auth_method;
532 this->public.get_eap_type = (eap_type_t (*) (peer_cfg_t *,u_int32_t*))get_eap_type;
533 this->public.get_keyingtries = (u_int32_t (*) (peer_cfg_t *))get_keyingtries;
534 this->public.get_rekey_time = (u_int32_t(*)(peer_cfg_t*))get_rekey_time;
535 this->public.get_reauth_time = (u_int32_t(*)(peer_cfg_t*))get_reauth_time;
536 this->public.get_over_time = (u_int32_t(*)(peer_cfg_t*))get_over_time;
537 this->public.use_mobike = (bool (*) (peer_cfg_t *))use_mobike;
538 this->public.get_dpd = (u_int32_t (*) (peer_cfg_t *))get_dpd;
539 this->public.get_virtual_ip = (host_t* (*) (peer_cfg_t *))get_virtual_ip;
540 this->public.get_pool = (char*(*)(peer_cfg_t*))get_pool;
541 this->public.get_auth = (auth_info_t*(*)(peer_cfg_t*))get_auth;
542 this->public.equals = (bool(*)(peer_cfg_t*, peer_cfg_t *other))equals;
543 this->public.get_ref = (void(*)(peer_cfg_t *))get_ref;
544 this->public.destroy = (void(*)(peer_cfg_t *))destroy;
545 #ifdef ME
546 this->public.is_mediation = (bool (*) (peer_cfg_t *))is_mediation;
547 this->public.get_mediated_by = (peer_cfg_t* (*) (peer_cfg_t *))get_mediated_by;
548 this->public.get_peer_id = (identification_t* (*) (peer_cfg_t *))get_peer_id;
549 #endif /* ME */
550
551 /* apply init values */
552 this->name = strdup(name);
553 this->ike_version = ike_version;
554 this->ike_cfg = ike_cfg;
555 this->child_cfgs = linked_list_create();
556 pthread_mutex_init(&this->mutex, NULL);
557 this->my_id = my_id;
558 this->other_id = other_id;
559 this->cert_policy = cert_policy;
560 this->auth_method = auth_method;
561 this->eap_type = eap_type;
562 this->eap_vendor = eap_vendor;
563 this->keyingtries = keyingtries;
564 this->rekey_time = rekey_time;
565 this->reauth_time = reauth_time;
566 if (rekey_time && jitter_time > rekey_time)
567 {
568 jitter_time = rekey_time;
569 }
570 if (reauth_time && jitter_time > reauth_time)
571 {
572 jitter_time = reauth_time;
573 }
574 this->jitter_time = jitter_time;
575 this->over_time = over_time;
576 this->use_mobike = mobike;
577 this->dpd = dpd;
578 this->virtual_ip = virtual_ip;
579 this->pool = pool ? strdup(pool) : NULL;
580 this->auth = auth_info_create();
581 this->refcount = 1;
582 #ifdef ME
583 this->mediation = mediation;
584 this->mediated_by = mediated_by;
585 this->peer_id = peer_id;
586 #else /* ME */
587 DESTROY_IF(mediated_by);
588 DESTROY_IF(peer_id);
589 #endif /* ME */
590
591 return &this->public;
592 }