fixed remove_child_cfg(), use correct enumerator for remove_at
[strongswan.git] / src / charon / config / peer_cfg.c
1 /*
2 * Copyright (C) 2007-2008 Tobias Brunner
3 * Copyright (C) 2005-2009 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
18 #include <string.h>
19
20 #include "peer_cfg.h"
21
22 #include <daemon.h>
23
24 #include <utils/mutex.h>
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 ENUM(unique_policy_names, UNIQUE_NO, UNIQUE_KEEP,
35 "UNIQUE_NO",
36 "UNIQUE_REPLACE",
37 "UNIQUE_KEEP",
38 );
39
40 typedef struct private_peer_cfg_t private_peer_cfg_t;
41
42 /**
43 * Private data of an peer_cfg_t object
44 */
45 struct private_peer_cfg_t {
46
47 /**
48 * Public part
49 */
50 peer_cfg_t public;
51
52 /**
53 * Number of references hold by others to this peer_cfg
54 */
55 refcount_t refcount;
56
57 /**
58 * Name of the peer_cfg, used to query it
59 */
60 char *name;
61
62 /**
63 * IKE version to use for initiation
64 */
65 u_int ike_version;
66
67 /**
68 * IKE config associated to this peer config
69 */
70 ike_cfg_t *ike_cfg;
71
72 /**
73 * list of child configs associated to this peer config
74 */
75 linked_list_t *child_cfgs;
76
77 /**
78 * mutex to lock access to list of child_cfgs
79 */
80 mutex_t *mutex;
81
82 /**
83 * should we send a certificate
84 */
85 cert_policy_t cert_policy;
86
87 /**
88 * uniqueness of an IKE_SA
89 */
90 unique_policy_t unique;
91
92 /**
93 * number of tries after giving up if peer does not respond
94 */
95 u_int32_t keyingtries;
96
97 /**
98 * enable support for MOBIKE
99 */
100 bool use_mobike;
101
102 /**
103 * Time before starting rekeying
104 */
105 u_int32_t rekey_time;
106
107 /**
108 * Time before starting reauthentication
109 */
110 u_int32_t reauth_time;
111
112 /**
113 * Time, which specifies the range of a random value substracted from above.
114 */
115 u_int32_t jitter_time;
116
117 /**
118 * Delay before deleting a rekeying/reauthenticating SA
119 */
120 u_int32_t over_time;
121
122 /**
123 * DPD check intervall
124 */
125 u_int32_t dpd;
126
127 /**
128 * virtual IP to use locally
129 */
130 host_t *virtual_ip;
131
132 /**
133 * pool to acquire configuration attributes from
134 */
135 char *pool;
136
137 /**
138 * local authentication configs (rulesets)
139 */
140 linked_list_t *local_auth;
141
142 /**
143 * remote authentication configs (constraints)
144 */
145 linked_list_t *remote_auth;
146
147 #ifdef ME
148 /**
149 * Is this a mediation connection?
150 */
151 bool mediation;
152
153 /**
154 * Name of the mediation connection to mediate through
155 */
156 peer_cfg_t *mediated_by;
157
158 /**
159 * ID of our peer at the mediation server (= leftid of the peer's conn with
160 * the mediation server)
161 */
162 identification_t *peer_id;
163 #endif /* ME */
164 };
165
166 /**
167 * Implementation of peer_cfg_t.get_name
168 */
169 static char *get_name(private_peer_cfg_t *this)
170 {
171 return this->name;
172 }
173
174 /**
175 * Implementation of peer_cfg_t.get_ike_version
176 */
177 static u_int get_ike_version(private_peer_cfg_t *this)
178 {
179 return this->ike_version;
180 }
181
182 /**
183 * Implementation of peer_cfg_t.get_ike_cfg
184 */
185 static ike_cfg_t* get_ike_cfg(private_peer_cfg_t *this)
186 {
187 return this->ike_cfg;
188 }
189
190 /**
191 * Implementation of peer_cfg_t.add_child_cfg.
192 */
193 static void add_child_cfg(private_peer_cfg_t *this, child_cfg_t *child_cfg)
194 {
195 this->mutex->lock(this->mutex);
196 this->child_cfgs->insert_last(this->child_cfgs, child_cfg);
197 this->mutex->unlock(this->mutex);
198 }
199
200 /**
201 * child_cfg enumerator
202 */
203 typedef struct {
204 enumerator_t public;
205 enumerator_t *wrapped;
206 mutex_t *mutex;
207 } child_cfg_enumerator_t;
208
209 /**
210 * Implementation of peer_cfg_t.remove_child_cfg.
211 */
212 static void remove_child_cfg(private_peer_cfg_t *this,
213 child_cfg_enumerator_t *enumerator)
214 {
215 this->child_cfgs->remove_at(this->child_cfgs, enumerator->wrapped);
216 }
217
218 /**
219 * Implementation of child_cfg_enumerator_t.destroy
220 */
221 static void child_cfg_enumerator_destroy(child_cfg_enumerator_t *this)
222 {
223 this->mutex->unlock(this->mutex);
224 this->wrapped->destroy(this->wrapped);
225 free(this);
226 }
227
228 /**
229 * Implementation of child_cfg_enumerator_t.enumerate
230 */
231 static bool child_cfg_enumerate(child_cfg_enumerator_t *this, child_cfg_t **chd)
232 {
233 return this->wrapped->enumerate(this->wrapped, chd);
234 }
235
236 /**
237 * Implementation of peer_cfg_t.create_child_cfg_enumerator.
238 */
239 static enumerator_t* create_child_cfg_enumerator(private_peer_cfg_t *this)
240 {
241 child_cfg_enumerator_t *enumerator = malloc_thing(child_cfg_enumerator_t);
242
243 enumerator->public.enumerate = (void*)child_cfg_enumerate;
244 enumerator->public.destroy = (void*)child_cfg_enumerator_destroy;
245 enumerator->mutex = this->mutex;
246 enumerator->wrapped = this->child_cfgs->create_enumerator(this->child_cfgs);
247
248 this->mutex->lock(this->mutex);
249 return &enumerator->public;
250 }
251
252 /**
253 * Check if child_cfg contains traffic selectors
254 */
255 static int contains_ts(child_cfg_t *child, bool mine, linked_list_t *ts,
256 host_t *host)
257 {
258 linked_list_t *selected;
259 int prio;
260
261 if (child->equal_traffic_selectors(child, mine, ts, host))
262 {
263 return 2;
264 }
265 selected = child->get_traffic_selectors(child, mine, ts, host);
266 prio = selected->get_count(selected) ? 1 : 0;
267 selected->destroy_offset(selected, offsetof(traffic_selector_t, destroy));
268 return prio;
269 }
270
271 /**
272 * Implementation of peer_cfg_t.select_child_cfg
273 */
274 static child_cfg_t* select_child_cfg(private_peer_cfg_t *this,
275 linked_list_t *my_ts,
276 linked_list_t *other_ts,
277 host_t *my_host, host_t *other_host)
278 {
279 child_cfg_t *current, *found = NULL;
280 enumerator_t *enumerator;
281 int best = 0;
282
283 DBG2(DBG_CFG, "looking for a child config for %#R=== %#R", my_ts, other_ts);
284 enumerator = create_child_cfg_enumerator(this);
285 while (enumerator->enumerate(enumerator, &current))
286 {
287 int prio = contains_ts(current, TRUE, my_ts, my_host) +
288 contains_ts(current, FALSE, other_ts, other_host);
289
290 if (prio)
291 {
292 DBG2(DBG_CFG, " candidate \"%s\" with prio %d",
293 current->get_name(current), prio);
294 if (prio > best)
295 {
296 best = prio;
297 DESTROY_IF(found);
298 found = current->get_ref(current);
299 }
300 }
301 }
302 enumerator->destroy(enumerator);
303 if (found)
304 {
305 DBG2(DBG_CFG, "found matching child config \"%s\" with prio %d",
306 found->get_name(found), best);
307 }
308 return found;
309 }
310
311 /**
312 * Implementation of peer_cfg_t.get_cert_policy.
313 */
314 static cert_policy_t get_cert_policy(private_peer_cfg_t *this)
315 {
316 return this->cert_policy;
317 }
318
319 /**
320 * Implementation of peer_cfg_t.get_unique_policy.
321 */
322 static unique_policy_t get_unique_policy(private_peer_cfg_t *this)
323 {
324 return this->unique;
325 }
326
327 /**
328 * Implementation of peer_cfg_t.get_keyingtries.
329 */
330 static u_int32_t get_keyingtries(private_peer_cfg_t *this)
331 {
332 return this->keyingtries;
333 }
334
335 /**
336 * Implementation of peer_cfg_t.get_rekey_time.
337 */
338 static u_int32_t get_rekey_time(private_peer_cfg_t *this)
339 {
340 if (this->rekey_time == 0)
341 {
342 return 0;
343 }
344 if (this->jitter_time == 0)
345 {
346 return this->rekey_time;
347 }
348 return this->rekey_time - (random() % this->jitter_time);
349 }
350
351 /**
352 * Implementation of peer_cfg_t.get_reauth_time.
353 */
354 static u_int32_t get_reauth_time(private_peer_cfg_t *this)
355 {
356 if (this->reauth_time == 0)
357 {
358 return 0;
359 }
360 if (this->jitter_time == 0)
361 {
362 return this->reauth_time;
363 }
364 return this->reauth_time - (random() % this->jitter_time);
365 }
366
367 /**
368 * Implementation of peer_cfg_t.get_over_time.
369 */
370 static u_int32_t get_over_time(private_peer_cfg_t *this)
371 {
372 return this->over_time;
373 }
374
375 /**
376 * Implementation of peer_cfg_t.use_mobike.
377 */
378 static bool use_mobike(private_peer_cfg_t *this)
379 {
380 return this->use_mobike;
381 }
382
383 /**
384 * Implements peer_cfg_t.get_dpd
385 */
386 static u_int32_t get_dpd(private_peer_cfg_t *this)
387 {
388 return this->dpd;
389 }
390
391 /**
392 * Implementation of peer_cfg_t.get_virtual_ip.
393 */
394 static host_t* get_virtual_ip(private_peer_cfg_t *this)
395 {
396 return this->virtual_ip;
397 }
398
399 /**
400 * Implementation of peer_cfg_t.get_pool.
401 */
402 static char* get_pool(private_peer_cfg_t *this)
403 {
404 return this->pool;
405 }
406
407 /**
408 * Implementation of peer_cfg_t.add_auth_cfg
409 */
410 static void add_auth_cfg(private_peer_cfg_t *this,
411 auth_cfg_t *cfg, bool local)
412 {
413 if (local)
414 {
415 this->local_auth->insert_last(this->local_auth, cfg);
416 }
417 else
418 {
419 this->remote_auth->insert_last(this->remote_auth, cfg);
420 }
421 }
422
423 /**
424 * Implementation of peer_cfg_t.create_auth_cfg_enumerator
425 */
426 static enumerator_t* create_auth_cfg_enumerator(private_peer_cfg_t *this,
427 bool local)
428 {
429 if (local)
430 {
431 return this->local_auth->create_enumerator(this->local_auth);
432 }
433 return this->remote_auth->create_enumerator(this->remote_auth);
434 }
435
436 #ifdef ME
437 /**
438 * Implementation of peer_cfg_t.is_mediation.
439 */
440 static bool is_mediation(private_peer_cfg_t *this)
441 {
442 return this->mediation;
443 }
444
445 /**
446 * Implementation of peer_cfg_t.get_mediated_by.
447 */
448 static peer_cfg_t* get_mediated_by(private_peer_cfg_t *this)
449 {
450 return this->mediated_by;
451 }
452
453 /**
454 * Implementation of peer_cfg_t.get_peer_id.
455 */
456 static identification_t* get_peer_id(private_peer_cfg_t *this)
457 {
458 return this->peer_id;
459 }
460 #endif /* ME */
461
462 /**
463 * check auth configs for equality
464 */
465 static bool auth_cfg_equal(private_peer_cfg_t *this, private_peer_cfg_t *other)
466 {
467 enumerator_t *e1, *e2;
468 auth_cfg_t *cfg1, *cfg2;
469 bool equal = TRUE;
470
471 if (this->local_auth->get_count(this->local_auth) !=
472 other->local_auth->get_count(other->local_auth))
473 {
474 return FALSE;
475 }
476 if (this->remote_auth->get_count(this->remote_auth) !=
477 other->remote_auth->get_count(other->remote_auth))
478 {
479 return FALSE;
480 }
481
482 e1 = this->local_auth->create_enumerator(this->local_auth);
483 e2 = other->local_auth->create_enumerator(other->local_auth);
484 while (e1->enumerate(e1, &cfg1) && e2->enumerate(e2, &cfg2))
485 {
486 if (!cfg1->equals(cfg1, cfg2))
487 {
488 equal = FALSE;
489 break;
490 }
491 }
492 e1->destroy(e1);
493 e2->destroy(e2);
494
495 if (!equal)
496 {
497 return FALSE;
498 }
499
500 e1 = this->remote_auth->create_enumerator(this->remote_auth);
501 e2 = other->remote_auth->create_enumerator(other->remote_auth);
502 while (e1->enumerate(e1, &cfg1) && e2->enumerate(e2, &cfg2))
503 {
504 if (!cfg1->equals(cfg1, cfg2))
505 {
506 equal = FALSE;
507 break;
508 }
509 }
510 e1->destroy(e1);
511 e2->destroy(e2);
512
513 return equal;
514 }
515
516 /**
517 * Implementation of peer_cfg_t.equals.
518 */
519 static bool equals(private_peer_cfg_t *this, private_peer_cfg_t *other)
520 {
521 if (this == other)
522 {
523 return TRUE;
524 }
525 if (this->public.equals != other->public.equals)
526 {
527 return FALSE;
528 }
529
530 return (
531 this->ike_version == other->ike_version &&
532 this->cert_policy == other->cert_policy &&
533 this->unique == other->unique &&
534 this->keyingtries == other->keyingtries &&
535 this->use_mobike == other->use_mobike &&
536 this->rekey_time == other->rekey_time &&
537 this->reauth_time == other->reauth_time &&
538 this->jitter_time == other->jitter_time &&
539 this->over_time == other->over_time &&
540 this->dpd == other->dpd &&
541 (this->virtual_ip == other->virtual_ip ||
542 (this->virtual_ip && other->virtual_ip &&
543 this->virtual_ip->equals(this->virtual_ip, other->virtual_ip))) &&
544 (this->pool == other->pool ||
545 (this->pool && other->pool && streq(this->pool, other->pool))) &&
546 auth_cfg_equal(this, other)
547 #ifdef ME
548 && this->mediation == other->mediation &&
549 this->mediated_by == other->mediated_by &&
550 (this->peer_id == other->peer_id ||
551 (this->peer_id && other->peer_id &&
552 this->peer_id->equals(this->peer_id, other->peer_id)))
553 #endif /* ME */
554 );
555 }
556
557 /**
558 * Implements peer_cfg_t.get_ref.
559 */
560 static peer_cfg_t* get_ref(private_peer_cfg_t *this)
561 {
562 ref_get(&this->refcount);
563 return &this->public;
564 }
565
566 /**
567 * Implements peer_cfg_t.destroy.
568 */
569 static void destroy(private_peer_cfg_t *this)
570 {
571 if (ref_put(&this->refcount))
572 {
573 this->ike_cfg->destroy(this->ike_cfg);
574 this->child_cfgs->destroy_offset(this->child_cfgs,
575 offsetof(child_cfg_t, destroy));
576 DESTROY_IF(this->virtual_ip);
577 this->local_auth->destroy_offset(this->local_auth,
578 offsetof(auth_cfg_t, destroy));
579 this->remote_auth->destroy_offset(this->remote_auth,
580 offsetof(auth_cfg_t, destroy));
581 #ifdef ME
582 DESTROY_IF(this->mediated_by);
583 DESTROY_IF(this->peer_id);
584 #endif /* ME */
585 this->mutex->destroy(this->mutex);
586 free(this->name);
587 free(this->pool);
588 free(this);
589 }
590 }
591
592 /*
593 * Described in header-file
594 */
595 peer_cfg_t *peer_cfg_create(char *name, u_int ike_version, ike_cfg_t *ike_cfg,
596 cert_policy_t cert_policy, unique_policy_t unique,
597 u_int32_t keyingtries, u_int32_t rekey_time,
598 u_int32_t reauth_time, u_int32_t jitter_time,
599 u_int32_t over_time, bool mobike, u_int32_t dpd,
600 host_t *virtual_ip, char *pool,
601 bool mediation, peer_cfg_t *mediated_by,
602 identification_t *peer_id)
603 {
604 private_peer_cfg_t *this = malloc_thing(private_peer_cfg_t);
605
606 /* public functions */
607 this->public.get_name = (char* (*) (peer_cfg_t *))get_name;
608 this->public.get_ike_version = (u_int(*) (peer_cfg_t *))get_ike_version;
609 this->public.get_ike_cfg = (ike_cfg_t* (*) (peer_cfg_t *))get_ike_cfg;
610 this->public.add_child_cfg = (void (*) (peer_cfg_t *, child_cfg_t*))add_child_cfg;
611 this->public.remove_child_cfg = (void(*)(peer_cfg_t*, enumerator_t*))remove_child_cfg;
612 this->public.create_child_cfg_enumerator = (enumerator_t* (*) (peer_cfg_t *))create_child_cfg_enumerator;
613 this->public.select_child_cfg = (child_cfg_t* (*) (peer_cfg_t *,linked_list_t*,linked_list_t*,host_t*,host_t*))select_child_cfg;
614 this->public.get_cert_policy = (cert_policy_t (*) (peer_cfg_t *))get_cert_policy;
615 this->public.get_unique_policy = (unique_policy_t (*) (peer_cfg_t *))get_unique_policy;
616 this->public.get_keyingtries = (u_int32_t (*) (peer_cfg_t *))get_keyingtries;
617 this->public.get_rekey_time = (u_int32_t(*)(peer_cfg_t*))get_rekey_time;
618 this->public.get_reauth_time = (u_int32_t(*)(peer_cfg_t*))get_reauth_time;
619 this->public.get_over_time = (u_int32_t(*)(peer_cfg_t*))get_over_time;
620 this->public.use_mobike = (bool (*) (peer_cfg_t *))use_mobike;
621 this->public.get_dpd = (u_int32_t (*) (peer_cfg_t *))get_dpd;
622 this->public.get_virtual_ip = (host_t* (*) (peer_cfg_t *))get_virtual_ip;
623 this->public.get_pool = (char*(*)(peer_cfg_t*))get_pool;
624 this->public.add_auth_cfg = (void(*)(peer_cfg_t*, auth_cfg_t *cfg, bool local))add_auth_cfg;
625 this->public.create_auth_cfg_enumerator = (enumerator_t*(*)(peer_cfg_t*, bool local))create_auth_cfg_enumerator;
626 this->public.equals = (bool(*)(peer_cfg_t*, peer_cfg_t *other))equals;
627 this->public.get_ref = (peer_cfg_t*(*)(peer_cfg_t *))get_ref;
628 this->public.destroy = (void(*)(peer_cfg_t *))destroy;
629 #ifdef ME
630 this->public.is_mediation = (bool (*) (peer_cfg_t *))is_mediation;
631 this->public.get_mediated_by = (peer_cfg_t* (*) (peer_cfg_t *))get_mediated_by;
632 this->public.get_peer_id = (identification_t* (*) (peer_cfg_t *))get_peer_id;
633 #endif /* ME */
634
635 /* apply init values */
636 this->name = strdup(name);
637 this->ike_version = ike_version;
638 this->ike_cfg = ike_cfg;
639 this->child_cfgs = linked_list_create();
640 this->mutex = mutex_create(MUTEX_DEFAULT);
641 this->cert_policy = cert_policy;
642 this->unique = unique;
643 this->keyingtries = keyingtries;
644 this->rekey_time = rekey_time;
645 this->reauth_time = reauth_time;
646 if (rekey_time && jitter_time > rekey_time)
647 {
648 jitter_time = rekey_time;
649 }
650 if (reauth_time && jitter_time > reauth_time)
651 {
652 jitter_time = reauth_time;
653 }
654 this->jitter_time = jitter_time;
655 this->over_time = over_time;
656 this->use_mobike = mobike;
657 this->dpd = dpd;
658 this->virtual_ip = virtual_ip;
659 this->pool = pool ? strdup(pool) : NULL;
660 this->local_auth = linked_list_create();
661 this->remote_auth = linked_list_create();
662 this->refcount = 1;
663 #ifdef ME
664 this->mediation = mediation;
665 this->mediated_by = mediated_by;
666 this->peer_id = peer_id;
667 #else /* ME */
668 DESTROY_IF(mediated_by);
669 DESTROY_IF(peer_id);
670 #endif /* ME */
671
672 return &this->public;
673 }