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