fixed crash if crl fetching fails
[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 *my_virtual_ip;
157
158 /**
159 * virtual IP to use remotly
160 */
161 host_t *other_virtual_ip;
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_my_virtual_ip.
400 */
401 static host_t* get_my_virtual_ip(private_peer_cfg_t *this)
402 {
403 if (this->my_virtual_ip == NULL)
404 {
405 return NULL;
406 }
407 return this->my_virtual_ip->clone(this->my_virtual_ip);
408 }
409
410 /**
411 * Implementation of peer_cfg_t.get_other_virtual_ip.
412 */
413 static host_t* get_other_virtual_ip(private_peer_cfg_t *this, host_t *suggestion)
414 {
415 if (this->other_virtual_ip == NULL)
416 { /* disallow */
417 return NULL;
418 }
419 if (!this->other_virtual_ip->is_anyaddr(this->other_virtual_ip))
420 { /* force own configuration */
421 return this->other_virtual_ip->clone(this->other_virtual_ip);
422 }
423 if (suggestion == NULL || suggestion->is_anyaddr(suggestion))
424 {
425 return NULL;
426 }
427 return suggestion->clone(suggestion);
428 }
429
430 /**
431 * Implementation of peer_cfg_t.get_auth.
432 */
433 static auth_info_t* get_auth(private_peer_cfg_t *this)
434 {
435 return this->auth;
436 }
437
438 #ifdef ME
439 /**
440 * Implementation of peer_cfg_t.is_mediation.
441 */
442 static bool is_mediation(private_peer_cfg_t *this)
443 {
444 return this->mediation;
445 }
446
447 /**
448 * Implementation of peer_cfg_t.get_mediated_by.
449 */
450 static peer_cfg_t* get_mediated_by(private_peer_cfg_t *this)
451 {
452 if (this->mediated_by) {
453 this->mediated_by->get_ref(this->mediated_by);
454 return this->mediated_by;
455 }
456 return NULL;
457 }
458
459 /**
460 * Implementation of peer_cfg_t.get_peer_id.
461 */
462 static identification_t* get_peer_id(private_peer_cfg_t *this)
463 {
464 return this->peer_id;
465 }
466 #endif /* ME */
467
468 /**
469 * Implementation of peer_cfg_t.equals.
470 */
471 static bool equals(private_peer_cfg_t *this, private_peer_cfg_t *other)
472 {
473 if (this == other)
474 {
475 return TRUE;
476 }
477 if (this->public.equals != other->public.equals)
478 {
479 return FALSE;
480 }
481
482 return (
483 this->ike_version == other->ike_version &&
484 this->my_id->equals(this->my_id, other->my_id) &&
485 this->other_id->equals(this->other_id, other->other_id) &&
486 this->cert_policy == other->cert_policy &&
487 this->auth_method == other->auth_method &&
488 this->eap_type == other->eap_type &&
489 this->eap_vendor == other->eap_vendor &&
490 this->keyingtries == other->keyingtries &&
491 this->use_mobike == other->use_mobike &&
492 this->rekey_time == other->rekey_time &&
493 this->reauth_time == other->reauth_time &&
494 this->jitter_time == other->jitter_time &&
495 this->over_time == other->over_time &&
496 this->dpd_delay == other->dpd_delay &&
497 this->dpd_action == other->dpd_action &&
498 (this->my_virtual_ip == other->my_virtual_ip ||
499 (this->my_virtual_ip && other->my_virtual_ip &&
500 this->my_virtual_ip->equals(this->my_virtual_ip, other->my_virtual_ip))) &&
501 (this->other_virtual_ip == other->other_virtual_ip ||
502 (this->other_virtual_ip && other->other_virtual_ip &&
503 this->other_virtual_ip->equals(this->other_virtual_ip, other->other_virtual_ip))) &&
504 this->auth->equals(this->auth, other->auth)
505 #ifdef ME
506 && this->mediation == other->mediation &&
507 this->mediated_by == other->mediated_by &&
508 (this->peer_id == other->peer_id ||
509 (this->peer_id && other->peer_id &&
510 this->peer_id->equals(this->peer_id, other->peer_id)))
511 #endif /* ME */
512 );
513 }
514
515 /**
516 * Implements peer_cfg_t.get_ref.
517 */
518 static void get_ref(private_peer_cfg_t *this)
519 {
520 ref_get(&this->refcount);
521 }
522
523 /**
524 * Implements peer_cfg_t.destroy.
525 */
526 static void destroy(private_peer_cfg_t *this)
527 {
528 if (ref_put(&this->refcount))
529 {
530 this->ike_cfg->destroy(this->ike_cfg);
531 this->child_cfgs->destroy_offset(this->child_cfgs, offsetof(child_cfg_t, destroy));
532 this->my_id->destroy(this->my_id);
533 this->other_id->destroy(this->other_id);
534 DESTROY_IF(this->my_virtual_ip);
535 DESTROY_IF(this->other_virtual_ip);
536 this->auth->destroy(this->auth);
537 #ifdef ME
538 DESTROY_IF(this->mediated_by);
539 DESTROY_IF(this->peer_id);
540 #endif /* ME */
541 free(this->name);
542 free(this);
543 }
544 }
545
546 /*
547 * Described in header-file
548 */
549 peer_cfg_t *peer_cfg_create(char *name, u_int ike_version, ike_cfg_t *ike_cfg,
550 identification_t *my_id, identification_t *other_id,
551 cert_policy_t cert_policy,
552 auth_method_t auth_method, eap_type_t eap_type,
553 u_int32_t eap_vendor,
554 u_int32_t keyingtries, u_int32_t rekey_time,
555 u_int32_t reauth_time, u_int32_t jitter_time,
556 u_int32_t over_time, bool mobike,
557 u_int32_t dpd_delay, dpd_action_t dpd_action,
558 host_t *my_virtual_ip, host_t *other_virtual_ip,
559 bool mediation, peer_cfg_t *mediated_by,
560 identification_t *peer_id)
561 {
562 private_peer_cfg_t *this = malloc_thing(private_peer_cfg_t);
563
564 /* public functions */
565 this->public.get_name = (char* (*) (peer_cfg_t *))get_name;
566 this->public.get_ike_version = (u_int(*) (peer_cfg_t *))get_ike_version;
567 this->public.get_ike_cfg = (ike_cfg_t* (*) (peer_cfg_t *))get_ike_cfg;
568 this->public.add_child_cfg = (void (*) (peer_cfg_t *, child_cfg_t*))add_child_cfg;
569 this->public.remove_child_cfg = (void(*)(peer_cfg_t*, enumerator_t*))remove_child_cfg;
570 this->public.create_child_cfg_enumerator = (enumerator_t* (*) (peer_cfg_t *))create_child_cfg_enumerator;
571 this->public.select_child_cfg = (child_cfg_t* (*) (peer_cfg_t *,linked_list_t*,linked_list_t*,host_t*,host_t*))select_child_cfg;
572 this->public.get_my_id = (identification_t* (*)(peer_cfg_t*))get_my_id;
573 this->public.get_other_id = (identification_t* (*)(peer_cfg_t *))get_other_id;
574 this->public.get_cert_policy = (cert_policy_t (*) (peer_cfg_t *))get_cert_policy;
575 this->public.get_auth_method = (auth_method_t (*) (peer_cfg_t *))get_auth_method;
576 this->public.get_eap_type = (eap_type_t (*) (peer_cfg_t *,u_int32_t*))get_eap_type;
577 this->public.get_keyingtries = (u_int32_t (*) (peer_cfg_t *))get_keyingtries;
578 this->public.get_rekey_time = (u_int32_t(*)(peer_cfg_t*))get_rekey_time;
579 this->public.get_reauth_time = (u_int32_t(*)(peer_cfg_t*))get_reauth_time;
580 this->public.get_over_time = (u_int32_t(*)(peer_cfg_t*))get_over_time;
581 this->public.use_mobike = (bool (*) (peer_cfg_t *))use_mobike;
582 this->public.get_dpd_delay = (u_int32_t (*) (peer_cfg_t *))get_dpd_delay;
583 this->public.get_dpd_action = (dpd_action_t (*) (peer_cfg_t *))get_dpd_action;
584 this->public.get_my_virtual_ip = (host_t* (*) (peer_cfg_t *))get_my_virtual_ip;
585 this->public.get_other_virtual_ip = (host_t* (*) (peer_cfg_t *, host_t *))get_other_virtual_ip;
586 this->public.get_auth = (auth_info_t*(*)(peer_cfg_t*))get_auth;
587 this->public.equals = (bool(*)(peer_cfg_t*, peer_cfg_t *other))equals;
588 this->public.get_ref = (void(*)(peer_cfg_t *))get_ref;
589 this->public.destroy = (void(*)(peer_cfg_t *))destroy;
590 #ifdef ME
591 this->public.is_mediation = (bool (*) (peer_cfg_t *))is_mediation;
592 this->public.get_mediated_by = (peer_cfg_t* (*) (peer_cfg_t *))get_mediated_by;
593 this->public.get_peer_id = (identification_t* (*) (peer_cfg_t *))get_peer_id;
594 #endif /* ME */
595
596 /* apply init values */
597 this->name = strdup(name);
598 this->ike_version = ike_version;
599 this->ike_cfg = ike_cfg;
600 this->child_cfgs = linked_list_create();
601 pthread_mutex_init(&this->mutex, NULL);
602 this->my_id = my_id;
603 this->other_id = other_id;
604 this->cert_policy = cert_policy;
605 this->auth_method = auth_method;
606 this->eap_type = eap_type;
607 this->eap_vendor = eap_vendor;
608 this->keyingtries = keyingtries;
609 this->rekey_time = rekey_time;
610 this->reauth_time = reauth_time;
611 if (rekey_time && jitter_time > rekey_time)
612 {
613 jitter_time = rekey_time;
614 }
615 if (reauth_time && jitter_time > reauth_time)
616 {
617 jitter_time = reauth_time;
618 }
619 this->jitter_time = jitter_time;
620 this->over_time = over_time;
621 this->use_mobike = mobike;
622 this->dpd_delay = dpd_delay;
623 this->dpd_action = dpd_action;
624 this->my_virtual_ip = my_virtual_ip;
625 this->other_virtual_ip = other_virtual_ip;
626 this->auth = auth_info_create();
627 this->refcount = 1;
628 #ifdef ME
629 this->mediation = mediation;
630 this->mediated_by = mediated_by;
631 this->peer_id = peer_id;
632 #else /* ME */
633 DESTROY_IF(mediated_by);
634 DESTROY_IF(peer_id);
635 #endif /* ME */
636
637 return &this->public;
638 }