c54333178a04d713d424cd3d383f53e2beaad15f
[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 * Implementation of peer_cfg_t.remove_child_cfg.
202 */
203 static void remove_child_cfg(private_peer_cfg_t *this, enumerator_t *enumerator)
204 {
205 this->mutex->lock(this->mutex);
206 this->child_cfgs->remove_at(this->child_cfgs, enumerator);
207 this->mutex->unlock(this->mutex);
208 }
209
210 /**
211 * Implementation of peer_cfg_t.create_child_cfg_enumerator.
212 */
213 static enumerator_t* create_child_cfg_enumerator(private_peer_cfg_t *this)
214 {
215 enumerator_t *enumerator;
216
217 this->mutex->lock(this->mutex);
218 enumerator = this->child_cfgs->create_enumerator(this->child_cfgs);
219 return enumerator_create_cleaner(enumerator,
220 (void*)this->mutex->unlock, this->mutex);
221 }
222
223 /**
224 * Check if child_cfg contains traffic selectors
225 */
226 static int contains_ts(child_cfg_t *child, bool mine, linked_list_t *ts,
227 host_t *host)
228 {
229 linked_list_t *selected;
230 int prio;
231
232 if (child->equal_traffic_selectors(child, mine, ts, host))
233 {
234 return 2;
235 }
236 selected = child->get_traffic_selectors(child, mine, ts, host);
237 prio = selected->get_count(selected) ? 1 : 0;
238 selected->destroy_offset(selected, offsetof(traffic_selector_t, destroy));
239 return prio;
240 }
241
242 /**
243 * Implementation of peer_cfg_t.select_child_cfg
244 */
245 static child_cfg_t* select_child_cfg(private_peer_cfg_t *this,
246 linked_list_t *my_ts,
247 linked_list_t *other_ts,
248 host_t *my_host, host_t *other_host)
249 {
250 child_cfg_t *current, *found = NULL;
251 enumerator_t *enumerator;
252 int best = 0;
253
254 DBG2(DBG_CFG, "looking for a child config for %#R=== %#R", my_ts, other_ts);
255 enumerator = create_child_cfg_enumerator(this);
256 while (enumerator->enumerate(enumerator, &current))
257 {
258 int prio = contains_ts(current, TRUE, my_ts, my_host) +
259 contains_ts(current, FALSE, other_ts, other_host);
260
261 if (prio)
262 {
263 DBG2(DBG_CFG, " candidate \"%s\" with prio %d",
264 current->get_name(current), prio);
265 if (prio > best)
266 {
267 best = prio;
268 DESTROY_IF(found);
269 found = current->get_ref(current);
270 }
271 }
272 }
273 enumerator->destroy(enumerator);
274 if (found)
275 {
276 DBG2(DBG_CFG, "found matching child config \"%s\" with prio %d",
277 found->get_name(found), best);
278 }
279 return found;
280 }
281
282 /**
283 * Implementation of peer_cfg_t.get_cert_policy.
284 */
285 static cert_policy_t get_cert_policy(private_peer_cfg_t *this)
286 {
287 return this->cert_policy;
288 }
289
290 /**
291 * Implementation of peer_cfg_t.get_unique_policy.
292 */
293 static unique_policy_t get_unique_policy(private_peer_cfg_t *this)
294 {
295 return this->unique;
296 }
297
298 /**
299 * Implementation of peer_cfg_t.get_keyingtries.
300 */
301 static u_int32_t get_keyingtries(private_peer_cfg_t *this)
302 {
303 return this->keyingtries;
304 }
305
306 /**
307 * Implementation of peer_cfg_t.get_rekey_time.
308 */
309 static u_int32_t get_rekey_time(private_peer_cfg_t *this)
310 {
311 if (this->rekey_time == 0)
312 {
313 return 0;
314 }
315 if (this->jitter_time == 0)
316 {
317 return this->rekey_time;
318 }
319 return this->rekey_time - (random() % this->jitter_time);
320 }
321
322 /**
323 * Implementation of peer_cfg_t.get_reauth_time.
324 */
325 static u_int32_t get_reauth_time(private_peer_cfg_t *this)
326 {
327 if (this->reauth_time == 0)
328 {
329 return 0;
330 }
331 if (this->jitter_time == 0)
332 {
333 return this->reauth_time;
334 }
335 return this->reauth_time - (random() % this->jitter_time);
336 }
337
338 /**
339 * Implementation of peer_cfg_t.get_over_time.
340 */
341 static u_int32_t get_over_time(private_peer_cfg_t *this)
342 {
343 return this->over_time;
344 }
345
346 /**
347 * Implementation of peer_cfg_t.use_mobike.
348 */
349 static bool use_mobike(private_peer_cfg_t *this)
350 {
351 return this->use_mobike;
352 }
353
354 /**
355 * Implements peer_cfg_t.get_dpd
356 */
357 static u_int32_t get_dpd(private_peer_cfg_t *this)
358 {
359 return this->dpd;
360 }
361
362 /**
363 * Implementation of peer_cfg_t.get_virtual_ip.
364 */
365 static host_t* get_virtual_ip(private_peer_cfg_t *this)
366 {
367 return this->virtual_ip;
368 }
369
370 /**
371 * Implementation of peer_cfg_t.get_pool.
372 */
373 static char* get_pool(private_peer_cfg_t *this)
374 {
375 return this->pool;
376 }
377
378 /**
379 * Implementation of peer_cfg_t.add_auth_cfg
380 */
381 static void add_auth_cfg(private_peer_cfg_t *this,
382 auth_cfg_t *cfg, bool local)
383 {
384 if (local)
385 {
386 this->local_auth->insert_last(this->local_auth, cfg);
387 }
388 else
389 {
390 this->remote_auth->insert_last(this->remote_auth, cfg);
391 }
392 }
393
394 /**
395 * Implementation of peer_cfg_t.create_auth_cfg_enumerator
396 */
397 static enumerator_t* create_auth_cfg_enumerator(private_peer_cfg_t *this,
398 bool local)
399 {
400 if (local)
401 {
402 return this->local_auth->create_enumerator(this->local_auth);
403 }
404 return this->remote_auth->create_enumerator(this->remote_auth);
405 }
406
407 #ifdef ME
408 /**
409 * Implementation of peer_cfg_t.is_mediation.
410 */
411 static bool is_mediation(private_peer_cfg_t *this)
412 {
413 return this->mediation;
414 }
415
416 /**
417 * Implementation of peer_cfg_t.get_mediated_by.
418 */
419 static peer_cfg_t* get_mediated_by(private_peer_cfg_t *this)
420 {
421 return this->mediated_by;
422 }
423
424 /**
425 * Implementation of peer_cfg_t.get_peer_id.
426 */
427 static identification_t* get_peer_id(private_peer_cfg_t *this)
428 {
429 return this->peer_id;
430 }
431 #endif /* ME */
432
433 /**
434 * check auth configs for equality
435 */
436 static bool auth_cfg_equal(private_peer_cfg_t *this, private_peer_cfg_t *other)
437 {
438 enumerator_t *e1, *e2;
439 auth_cfg_t *cfg1, *cfg2;
440 bool equal = TRUE;
441
442 if (this->local_auth->get_count(this->local_auth) !=
443 other->local_auth->get_count(other->local_auth))
444 {
445 return FALSE;
446 }
447 if (this->remote_auth->get_count(this->remote_auth) !=
448 other->remote_auth->get_count(other->remote_auth))
449 {
450 return FALSE;
451 }
452
453 e1 = this->local_auth->create_enumerator(this->local_auth);
454 e2 = other->local_auth->create_enumerator(other->local_auth);
455 while (e1->enumerate(e1, &cfg1) && e2->enumerate(e2, &cfg2))
456 {
457 if (!cfg1->equals(cfg1, cfg2))
458 {
459 equal = FALSE;
460 break;
461 }
462 }
463 e1->destroy(e1);
464 e2->destroy(e2);
465
466 if (!equal)
467 {
468 return FALSE;
469 }
470
471 e1 = this->remote_auth->create_enumerator(this->remote_auth);
472 e2 = other->remote_auth->create_enumerator(other->remote_auth);
473 while (e1->enumerate(e1, &cfg1) && e2->enumerate(e2, &cfg2))
474 {
475 if (!cfg1->equals(cfg1, cfg2))
476 {
477 equal = FALSE;
478 break;
479 }
480 }
481 e1->destroy(e1);
482 e2->destroy(e2);
483
484 return equal;
485 }
486
487 /**
488 * Implementation of peer_cfg_t.equals.
489 */
490 static bool equals(private_peer_cfg_t *this, private_peer_cfg_t *other)
491 {
492 if (this == other)
493 {
494 return TRUE;
495 }
496 if (this->public.equals != other->public.equals)
497 {
498 return FALSE;
499 }
500
501 return (
502 this->ike_version == other->ike_version &&
503 this->cert_policy == other->cert_policy &&
504 this->unique == other->unique &&
505 this->keyingtries == other->keyingtries &&
506 this->use_mobike == other->use_mobike &&
507 this->rekey_time == other->rekey_time &&
508 this->reauth_time == other->reauth_time &&
509 this->jitter_time == other->jitter_time &&
510 this->over_time == other->over_time &&
511 this->dpd == other->dpd &&
512 (this->virtual_ip == other->virtual_ip ||
513 (this->virtual_ip && other->virtual_ip &&
514 this->virtual_ip->equals(this->virtual_ip, other->virtual_ip))) &&
515 (this->pool == other->pool ||
516 (this->pool && other->pool && streq(this->pool, other->pool))) &&
517 auth_cfg_equal(this, other)
518 #ifdef ME
519 && this->mediation == other->mediation &&
520 this->mediated_by == other->mediated_by &&
521 (this->peer_id == other->peer_id ||
522 (this->peer_id && other->peer_id &&
523 this->peer_id->equals(this->peer_id, other->peer_id)))
524 #endif /* ME */
525 );
526 }
527
528 /**
529 * Implements peer_cfg_t.get_ref.
530 */
531 static peer_cfg_t* get_ref(private_peer_cfg_t *this)
532 {
533 ref_get(&this->refcount);
534 return &this->public;
535 }
536
537 /**
538 * Implements peer_cfg_t.destroy.
539 */
540 static void destroy(private_peer_cfg_t *this)
541 {
542 if (ref_put(&this->refcount))
543 {
544 this->ike_cfg->destroy(this->ike_cfg);
545 this->child_cfgs->destroy_offset(this->child_cfgs,
546 offsetof(child_cfg_t, destroy));
547 DESTROY_IF(this->virtual_ip);
548 this->local_auth->destroy_offset(this->local_auth,
549 offsetof(auth_cfg_t, destroy));
550 this->remote_auth->destroy_offset(this->remote_auth,
551 offsetof(auth_cfg_t, destroy));
552 #ifdef ME
553 DESTROY_IF(this->mediated_by);
554 DESTROY_IF(this->peer_id);
555 #endif /* ME */
556 this->mutex->destroy(this->mutex);
557 free(this->name);
558 free(this->pool);
559 free(this);
560 }
561 }
562
563 /*
564 * Described in header-file
565 */
566 peer_cfg_t *peer_cfg_create(char *name, u_int ike_version, ike_cfg_t *ike_cfg,
567 cert_policy_t cert_policy, unique_policy_t unique,
568 u_int32_t keyingtries, u_int32_t rekey_time,
569 u_int32_t reauth_time, u_int32_t jitter_time,
570 u_int32_t over_time, bool mobike, u_int32_t dpd,
571 host_t *virtual_ip, char *pool,
572 bool mediation, peer_cfg_t *mediated_by,
573 identification_t *peer_id)
574 {
575 private_peer_cfg_t *this = malloc_thing(private_peer_cfg_t);
576
577 /* public functions */
578 this->public.get_name = (char* (*) (peer_cfg_t *))get_name;
579 this->public.get_ike_version = (u_int(*) (peer_cfg_t *))get_ike_version;
580 this->public.get_ike_cfg = (ike_cfg_t* (*) (peer_cfg_t *))get_ike_cfg;
581 this->public.add_child_cfg = (void (*) (peer_cfg_t *, child_cfg_t*))add_child_cfg;
582 this->public.remove_child_cfg = (void(*)(peer_cfg_t*, enumerator_t*))remove_child_cfg;
583 this->public.create_child_cfg_enumerator = (enumerator_t* (*) (peer_cfg_t *))create_child_cfg_enumerator;
584 this->public.select_child_cfg = (child_cfg_t* (*) (peer_cfg_t *,linked_list_t*,linked_list_t*,host_t*,host_t*))select_child_cfg;
585 this->public.get_cert_policy = (cert_policy_t (*) (peer_cfg_t *))get_cert_policy;
586 this->public.get_unique_policy = (unique_policy_t (*) (peer_cfg_t *))get_unique_policy;
587 this->public.get_keyingtries = (u_int32_t (*) (peer_cfg_t *))get_keyingtries;
588 this->public.get_rekey_time = (u_int32_t(*)(peer_cfg_t*))get_rekey_time;
589 this->public.get_reauth_time = (u_int32_t(*)(peer_cfg_t*))get_reauth_time;
590 this->public.get_over_time = (u_int32_t(*)(peer_cfg_t*))get_over_time;
591 this->public.use_mobike = (bool (*) (peer_cfg_t *))use_mobike;
592 this->public.get_dpd = (u_int32_t (*) (peer_cfg_t *))get_dpd;
593 this->public.get_virtual_ip = (host_t* (*) (peer_cfg_t *))get_virtual_ip;
594 this->public.get_pool = (char*(*)(peer_cfg_t*))get_pool;
595 this->public.add_auth_cfg = (void(*)(peer_cfg_t*, auth_cfg_t *cfg, bool local))add_auth_cfg;
596 this->public.create_auth_cfg_enumerator = (enumerator_t*(*)(peer_cfg_t*, bool local))create_auth_cfg_enumerator;
597 this->public.equals = (bool(*)(peer_cfg_t*, peer_cfg_t *other))equals;
598 this->public.get_ref = (peer_cfg_t*(*)(peer_cfg_t *))get_ref;
599 this->public.destroy = (void(*)(peer_cfg_t *))destroy;
600 #ifdef ME
601 this->public.is_mediation = (bool (*) (peer_cfg_t *))is_mediation;
602 this->public.get_mediated_by = (peer_cfg_t* (*) (peer_cfg_t *))get_mediated_by;
603 this->public.get_peer_id = (identification_t* (*) (peer_cfg_t *))get_peer_id;
604 #endif /* ME */
605
606 /* apply init values */
607 this->name = strdup(name);
608 this->ike_version = ike_version;
609 this->ike_cfg = ike_cfg;
610 this->child_cfgs = linked_list_create();
611 this->mutex = mutex_create(MUTEX_DEFAULT);
612 this->cert_policy = cert_policy;
613 this->unique = unique;
614 this->keyingtries = keyingtries;
615 this->rekey_time = rekey_time;
616 this->reauth_time = reauth_time;
617 if (rekey_time && jitter_time > rekey_time)
618 {
619 jitter_time = rekey_time;
620 }
621 if (reauth_time && jitter_time > reauth_time)
622 {
623 jitter_time = reauth_time;
624 }
625 this->jitter_time = jitter_time;
626 this->over_time = over_time;
627 this->use_mobike = mobike;
628 this->dpd = dpd;
629 this->virtual_ip = virtual_ip;
630 this->pool = pool ? strdup(pool) : NULL;
631 this->local_auth = linked_list_create();
632 this->remote_auth = linked_list_create();
633 this->refcount = 1;
634 #ifdef ME
635 this->mediation = mediation;
636 this->mediated_by = mediated_by;
637 this->peer_id = peer_id;
638 #else /* ME */
639 DESTROY_IF(mediated_by);
640 DESTROY_IF(peer_id);
641 #endif /* ME */
642
643 return &this->public;
644 }