7935b9703ae8a8af201a61953a24730cd537edf3
[strongswan.git] / src / charon / config / peer_cfg.c
1 /**
2 * @file peer_cfg.c
3 *
4 * @brief Implementation of peer_cfg_t.
5 *
6 */
7
8 /*
9 * Copyright (C) 2005-2007 Martin Willi
10 * Copyright (C) 2005 Jan Hutter
11 * Hochschule fuer Technik Rapperswil
12 *
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the
15 * Free Software Foundation; either version 2 of the License, or (at your
16 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
17 *
18 * This program is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
20 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 * for more details.
22 */
23
24 #include <string.h>
25 #include <pthread.h>
26
27 #include "peer_cfg.h"
28
29 #include <utils/linked_list.h>
30 #include <utils/identification.h>
31 #include <crypto/ietf_attr_list.h>
32
33 ENUM(cert_policy_names, CERT_ALWAYS_SEND, CERT_NEVER_SEND,
34 "CERT_ALWAYS_SEND",
35 "CERT_SEND_IF_ASKED",
36 "CERT_NEVER_SEND"
37 );
38
39 ENUM(dpd_action_names, DPD_NONE, DPD_RESTART,
40 "DPD_NONE",
41 "DPD_CLEAR",
42 "DPD_ROUTE",
43 "DPD_RESTART"
44 );
45
46 typedef struct private_peer_cfg_t private_peer_cfg_t;
47
48 /**
49 * Private data of an peer_cfg_t object
50 */
51 struct private_peer_cfg_t {
52
53 /**
54 * Public part
55 */
56 peer_cfg_t public;
57
58 /**
59 * Number of references hold by others to this peer_cfg
60 */
61 refcount_t refcount;
62
63 /**
64 * Name of the peer_cfg, used to query it
65 */
66 char *name;
67
68 /**
69 * IKE version to use for initiation
70 */
71 u_int ike_version;
72
73 /**
74 * IKE config associated to this peer config
75 */
76 ike_cfg_t *ike_cfg;
77
78 /**
79 * list of child configs associated to this peer config
80 */
81 linked_list_t *child_cfgs;
82
83 /**
84 * mutex to lock access to list of child_cfgs
85 */
86 pthread_mutex_t mutex;
87
88 /**
89 * id to use to identify us
90 */
91 identification_t *my_id;
92
93 /**
94 * allowed id for other
95 */
96 identification_t *other_id;
97
98 /**
99 * we have a cert issued by this CA
100 */
101 identification_t *my_ca;
102
103 /**
104 * we require the other end to have a cert issued by this CA
105 */
106 identification_t *other_ca;
107
108 /**
109 * we require the other end to belong to at least one group
110 */
111 linked_list_t *groups;
112
113 /**
114 * should we send a certificate
115 */
116 cert_policy_t cert_policy;
117
118 /**
119 * Method to use for own authentication data
120 */
121 auth_method_t auth_method;
122
123 /**
124 * EAP type to use for peer authentication
125 */
126 eap_type_t eap_type;
127
128 /**
129 * number of tries after giving up if peer does not respond
130 */
131 u_int32_t keyingtries;
132
133 /**
134 * user reauthentication instead of rekeying
135 */
136 bool use_reauth;
137
138 /**
139 * enable support for MOBIKE
140 */
141 bool use_mobike;
142
143 /**
144 * enforce UDP encapsulation
145 */
146 bool force_encap;
147
148 /**
149 * Time before an SA gets invalid
150 */
151 u_int32_t lifetime;
152
153 /**
154 * Time before an SA gets rekeyed
155 */
156 u_int32_t rekeytime;
157
158 /**
159 * Time, which specifies the range of a random value
160 * substracted from lifetime.
161 */
162 u_int32_t jitter;
163
164 /**
165 * What to do with an SA when other peer seams to be dead?
166 */
167 bool dpd_delay;
168
169 /**
170 * What to do with CHILDren when other peer seams to be dead?
171 */
172 bool dpd_action;
173
174 /**
175 * virtual IP to use locally
176 */
177 host_t *my_virtual_ip;
178
179 /**
180 * virtual IP to use remotly
181 */
182 host_t *other_virtual_ip;
183 };
184
185 /**
186 * Implementation of peer_cfg_t.get_name
187 */
188 static char *get_name(private_peer_cfg_t *this)
189 {
190 return this->name;
191 }
192
193 /**
194 * Implementation of peer_cfg_t.get_ike_version
195 */
196 static u_int get_ike_version(private_peer_cfg_t *this)
197 {
198 return this->ike_version;
199 }
200
201 /**
202 * Implementation of peer_cfg_t.get_ike_cfg
203 */
204 static ike_cfg_t* get_ike_cfg(private_peer_cfg_t *this)
205 {
206 return this->ike_cfg;
207 }
208
209 /**
210 * Implementation of peer_cfg_t.add_child_cfg.
211 */
212 static void add_child_cfg(private_peer_cfg_t *this, child_cfg_t *child_cfg)
213 {
214 pthread_mutex_lock(&this->mutex);
215 this->child_cfgs->insert_last(this->child_cfgs, child_cfg);
216 pthread_mutex_unlock(&this->mutex);
217 }
218
219 /**
220 * Implementation of peer_cfg_t.create_child_cfg_iterator.
221 */
222 static iterator_t* create_child_cfg_iterator(private_peer_cfg_t *this)
223 {
224 return this->child_cfgs->create_iterator_locked(this->child_cfgs,
225 &this->mutex);
226 }
227
228 /**
229 * Check if child_cfg contains traffic selectors
230 */
231 static bool contains_ts(child_cfg_t *child, bool mine, linked_list_t *ts,
232 host_t *host)
233 {
234 linked_list_t *selected;
235 bool contains = FALSE;
236
237 selected = child->get_traffic_selectors(child, mine, ts, host);
238 contains = selected->get_count(selected);
239 selected->destroy_offset(selected, offsetof(traffic_selector_t, destroy));
240 return contains;
241 }
242
243 /**
244 * Implementation of peer_cfg_t.select_child_cfg
245 */
246 static child_cfg_t* select_child_cfg(private_peer_cfg_t *this,
247 linked_list_t *my_ts,
248 linked_list_t *other_ts,
249 host_t *my_host, host_t *other_host)
250 {
251 child_cfg_t *current, *found = NULL;
252 iterator_t *iterator;
253
254 iterator = create_child_cfg_iterator(this);
255 while (iterator->iterate(iterator, (void**)&current))
256 {
257 if (contains_ts(current, TRUE, my_ts, my_host) &&
258 contains_ts(current, FALSE, other_ts, other_host))
259 {
260 found = current;
261 found->get_ref(found);
262 break;
263 }
264 }
265 iterator->destroy(iterator);
266 return found;
267 }
268
269 /**
270 * Implementation of peer_cfg_t.get_my_id
271 */
272 static identification_t *get_my_id(private_peer_cfg_t *this)
273 {
274 return this->my_id;
275 }
276
277 /**
278 * Implementation of peer_cfg_t.get_other_id
279 */
280 static identification_t *get_other_id(private_peer_cfg_t *this)
281 {
282 return this->other_id;
283 }
284
285 /**
286 * Implementation of peer_cfg_t.get_my_ca
287 */
288 static identification_t *get_my_ca(private_peer_cfg_t *this)
289 {
290 return this->my_ca;
291 }
292
293 /**
294 * Implementation of peer_cfg_t.get_other_ca
295 */
296 static identification_t *get_other_ca(private_peer_cfg_t *this)
297 {
298 return this->other_ca;
299 }
300
301 /**
302 * Implementation of peer_cfg_t.get_groups
303 */
304 static linked_list_t *get_groups(private_peer_cfg_t *this)
305 {
306 return this->groups;
307 }
308
309 /**
310 * Implementation of peer_cfg_t.get_cert_policy.
311 */
312 static cert_policy_t get_cert_policy(private_peer_cfg_t *this)
313 {
314 return this->cert_policy;
315 }
316
317 /**
318 * Implementation of connection_t.auth_method_t.
319 */
320 static auth_method_t get_auth_method(private_peer_cfg_t *this)
321 {
322 return this->auth_method;
323 }
324
325 /**
326 * Implementation of connection_t.get_eap_type.
327 */
328 static eap_type_t get_eap_type(private_peer_cfg_t *this)
329 {
330 return this->eap_type;
331 }
332
333 /**
334 * Implementation of connection_t.get_keyingtries.
335 */
336 static u_int32_t get_keyingtries(private_peer_cfg_t *this)
337 {
338 return this->keyingtries;
339 }
340
341 /**
342 * Implementation of peer_cfg_t.get_soft_lifetime
343 */
344 static u_int32_t get_lifetime(private_peer_cfg_t *this, bool rekey)
345 {
346 if (rekey)
347 {
348 if (this->jitter == 0)
349 {
350 return this->rekeytime;
351 }
352 return this->rekeytime - (random() % this->jitter);
353 }
354 return this->lifetime;
355 }
356
357 /**
358 * Implementation of peer_cfg_t.use_reauth.
359 */
360 static bool use_reauth(private_peer_cfg_t *this)
361 {
362 return this->use_reauth;
363 }
364
365 /**
366 * Implementation of peer_cfg_t.use_mobike.
367 */
368 static bool use_mobike(private_peer_cfg_t *this)
369 {
370 return this->use_mobike;
371 }
372
373 /**
374 * Implementation of peer_cfg_t.force_encap.
375 */
376 static bool force_encap_meth(private_peer_cfg_t *this)
377 {
378 return this->force_encap;
379 }
380
381 /**
382 * Implements peer_cfg_t.get_dpd_delay
383 */
384 static u_int32_t get_dpd_delay(private_peer_cfg_t *this)
385 {
386 return this->dpd_delay;
387 }
388
389 /**
390 * Implements peer_cfg_t.get_dpd_action
391 */
392 static dpd_action_t get_dpd_action(private_peer_cfg_t *this)
393 {
394 return this->dpd_action;
395 }
396
397 /**
398 * Implementation of peer_cfg_t.get_my_virtual_ip.
399 */
400 static host_t* get_my_virtual_ip(private_peer_cfg_t *this)
401 {
402 if (this->my_virtual_ip == NULL)
403 {
404 return NULL;
405 }
406 return this->my_virtual_ip->clone(this->my_virtual_ip);
407 }
408
409 /**
410 * Implementation of peer_cfg_t.get_other_virtual_ip.
411 */
412 static host_t* get_other_virtual_ip(private_peer_cfg_t *this, host_t *suggestion)
413 {
414 if (this->other_virtual_ip == NULL)
415 { /* disallow */
416 return NULL;
417 }
418 if (!this->other_virtual_ip->is_anyaddr(this->other_virtual_ip))
419 { /* force own configuration */
420 return this->other_virtual_ip->clone(this->other_virtual_ip);
421 }
422 if (suggestion == NULL || suggestion->is_anyaddr(suggestion))
423 {
424 return NULL;
425 }
426 return suggestion->clone(suggestion);
427 }
428
429 /**
430 * Implements peer_cfg_t.get_ref.
431 */
432 static void get_ref(private_peer_cfg_t *this)
433 {
434 ref_get(&this->refcount);
435 }
436
437 /**
438 * Implements peer_cfg_t.destroy.
439 */
440 static void destroy(private_peer_cfg_t *this)
441 {
442 if (ref_put(&this->refcount))
443 {
444 this->ike_cfg->destroy(this->ike_cfg);
445 this->child_cfgs->destroy_offset(this->child_cfgs, offsetof(child_cfg_t, destroy));
446 this->my_id->destroy(this->my_id);
447 this->other_id->destroy(this->other_id);
448 DESTROY_IF(this->my_ca);
449 DESTROY_IF(this->other_ca);
450 DESTROY_IF(this->my_virtual_ip);
451 DESTROY_IF(this->other_virtual_ip);
452 ietfAttr_list_destroy(this->groups);
453 free(this->name);
454 free(this);
455 }
456 }
457
458 /*
459 * Described in header-file
460 */
461 peer_cfg_t *peer_cfg_create(char *name, u_int ike_version, ike_cfg_t *ike_cfg,
462 identification_t *my_id, identification_t *other_id,
463 identification_t *my_ca, identification_t *other_ca,
464 linked_list_t *groups, cert_policy_t cert_policy,
465 auth_method_t auth_method, eap_type_t eap_type,
466 u_int32_t keyingtries, u_int32_t lifetime,
467 u_int32_t rekeytime, u_int32_t jitter,
468 bool reauth, bool mobike, bool force_encap,
469 u_int32_t dpd_delay, dpd_action_t dpd_action,
470 host_t *my_virtual_ip, host_t *other_virtual_ip)
471 {
472 private_peer_cfg_t *this = malloc_thing(private_peer_cfg_t);
473
474 /* public functions */
475 this->public.get_name = (char* (*) (peer_cfg_t *))get_name;
476 this->public.get_ike_version = (u_int(*) (peer_cfg_t *))get_ike_version;
477 this->public.get_ike_cfg = (ike_cfg_t* (*) (peer_cfg_t *))get_ike_cfg;
478 this->public.add_child_cfg = (void (*) (peer_cfg_t *, child_cfg_t*))add_child_cfg;
479 this->public.create_child_cfg_iterator = (iterator_t* (*) (peer_cfg_t *))create_child_cfg_iterator;
480 this->public.select_child_cfg = (child_cfg_t* (*) (peer_cfg_t *,linked_list_t*,linked_list_t*,host_t*,host_t*))select_child_cfg;
481 this->public.get_my_id = (identification_t* (*)(peer_cfg_t*))get_my_id;
482 this->public.get_other_id = (identification_t* (*)(peer_cfg_t *))get_other_id;
483 this->public.get_my_ca = (identification_t* (*)(peer_cfg_t *))get_my_ca;
484 this->public.get_other_ca = (identification_t* (*)(peer_cfg_t *))get_other_ca;
485 this->public.get_groups = (linked_list_t* (*)(peer_cfg_t *))get_groups;
486 this->public.get_cert_policy = (cert_policy_t (*) (peer_cfg_t *))get_cert_policy;
487 this->public.get_auth_method = (auth_method_t (*) (peer_cfg_t *))get_auth_method;
488 this->public.get_eap_type = (eap_type_t (*) (peer_cfg_t *))get_eap_type;
489 this->public.get_keyingtries = (u_int32_t (*) (peer_cfg_t *))get_keyingtries;
490 this->public.get_lifetime = (u_int32_t (*) (peer_cfg_t *, bool rekey))get_lifetime;
491 this->public.use_reauth = (bool (*) (peer_cfg_t *))use_reauth;
492 this->public.use_mobike = (bool (*) (peer_cfg_t *))use_mobike;
493 this->public.force_encap = (bool (*) (peer_cfg_t *))force_encap_meth;
494 this->public.get_dpd_delay = (u_int32_t (*) (peer_cfg_t *))get_dpd_delay;
495 this->public.get_dpd_action = (dpd_action_t (*) (peer_cfg_t *))get_dpd_action;
496 this->public.get_my_virtual_ip = (host_t* (*) (peer_cfg_t *))get_my_virtual_ip;
497 this->public.get_other_virtual_ip = (host_t* (*) (peer_cfg_t *, host_t *))get_other_virtual_ip;
498 this->public.get_ref = (void(*)(peer_cfg_t *))get_ref;
499 this->public.destroy = (void(*)(peer_cfg_t *))destroy;
500
501 /* apply init values */
502 this->name = strdup(name);
503 this->ike_version = ike_version;
504 this->ike_cfg = ike_cfg;
505 this->child_cfgs = linked_list_create();
506 pthread_mutex_init(&this->mutex, NULL);
507 this->my_id = my_id;
508 this->other_id = other_id;
509 this->my_ca = my_ca;
510 this->other_ca = other_ca;
511 this->groups = groups;
512 this->cert_policy = cert_policy;
513 this->auth_method = auth_method;
514 this->eap_type = eap_type;
515 this->keyingtries = keyingtries;
516 this->lifetime = lifetime;
517 this->rekeytime = rekeytime;
518 this->jitter = jitter;
519 this->use_reauth = reauth;
520 this->use_mobike = mobike;
521 this->force_encap = force_encap;
522 this->dpd_delay = dpd_delay;
523 this->dpd_action = dpd_action;
524 this->my_virtual_ip = my_virtual_ip;
525 this->other_virtual_ip = other_virtual_ip;
526 this->refcount = 1;
527
528 return &this->public;
529 }