9b3078f06cd31b8ac77111c35b7926a9c35b2b09
[strongswan.git] / src / libstrongswan / credentials / auth_cfg.c
1 /*
2 * Copyright (C) 2007-2009 Martin Willi
3 * Copyright (C) 2008 Tobias Brunner
4 * Hochschule fuer Technik Rapperswil
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * for more details.
15 */
16
17 #include "auth_cfg.h"
18
19 #include <library.h>
20 #include <debug.h>
21 #include <utils/linked_list.h>
22 #include <utils/identification.h>
23 #include <credentials/certificates/certificate.h>
24
25 ENUM(auth_class_names, AUTH_CLASS_ANY, AUTH_CLASS_EAP,
26 "any",
27 "public key",
28 "pre-shared key",
29 "EAP",
30 );
31
32 ENUM_BEGIN(eap_type_names, EAP_IDENTITY, EAP_GTC,
33 "EAP_IDENTITY",
34 "EAP_NOTIFICATION",
35 "EAP_NAK",
36 "EAP_MD5",
37 "EAP_OTP",
38 "EAP_GTC");
39 ENUM_NEXT(eap_type_names, EAP_TLS, EAP_TLS, EAP_GTC,
40 "EAP_TLS");
41 ENUM_NEXT(eap_type_names, EAP_SIM, EAP_SIM, EAP_TLS,
42 "EAP_SIM");
43 ENUM_NEXT(eap_type_names, EAP_TTLS, EAP_TTLS, EAP_SIM,
44 "EAP_TTLS");
45 ENUM_NEXT(eap_type_names, EAP_AKA, EAP_AKA, EAP_TTLS,
46 "EAP_AKA");
47 ENUM_NEXT(eap_type_names, EAP_MSCHAPV2, EAP_MSCHAPV2, EAP_AKA,
48 "EAP_MSCHAPV2");
49 ENUM_NEXT(eap_type_names, EAP_RADIUS, EAP_EXPERIMENTAL, EAP_MSCHAPV2,
50 "EAP_RADIUS",
51 "EAP_EXPANDED",
52 "EAP_EXPERIMENTAL");
53 ENUM_END(eap_type_names, EAP_EXPERIMENTAL);
54
55 ENUM_BEGIN(eap_type_short_names, EAP_IDENTITY, EAP_GTC,
56 "ID",
57 "NTF",
58 "NAK",
59 "MD5",
60 "OTP",
61 "GTC");
62 ENUM_NEXT(eap_type_short_names, EAP_TLS, EAP_TLS, EAP_GTC,
63 "TLS");
64 ENUM_NEXT(eap_type_short_names, EAP_SIM, EAP_SIM, EAP_TLS,
65 "SIM");
66 ENUM_NEXT(eap_type_short_names, EAP_TTLS, EAP_TTLS, EAP_SIM,
67 "TTLS");
68 ENUM_NEXT(eap_type_short_names, EAP_AKA, EAP_AKA, EAP_TTLS,
69 "AKA");
70 ENUM_NEXT(eap_type_short_names, EAP_MSCHAPV2, EAP_MSCHAPV2, EAP_AKA,
71 "MSCHAPV2");
72 ENUM_NEXT(eap_type_short_names, EAP_RADIUS, EAP_EXPERIMENTAL, EAP_MSCHAPV2,
73 "RAD",
74 "EXP",
75 "XP");
76 ENUM_END(eap_type_short_names, EAP_EXPERIMENTAL);
77
78 ENUM(auth_rule_names, AUTH_RULE_IDENTITY, AUTH_HELPER_SUBJECT_HASH_URL,
79 "RULE_IDENTITY",
80 "RULE_AUTH_CLASS",
81 "RULE_EAP_IDENTITY",
82 "RULE_EAP_TYPE",
83 "RULE_EAP_VENDOR",
84 "RULE_CA_CERT",
85 "RULE_IM_CERT",
86 "RULE_SUBJECT_CERT",
87 "RULE_CRL_VALIDATION",
88 "RULE_OCSP_VALIDATION",
89 "RULE_GROUP",
90 "HELPER_IM_CERT",
91 "HELPER_SUBJECT_CERT",
92 "HELPER_IM_HASH_URL",
93 "HELPER_SUBJECT_HASH_URL",
94 );
95
96 typedef struct private_auth_cfg_t private_auth_cfg_t;
97
98 /**
99 * private data of item_set
100 */
101 struct private_auth_cfg_t {
102
103 /**
104 * public functions
105 */
106 auth_cfg_t public;
107
108 /**
109 * list of entry_t
110 */
111 linked_list_t *entries;
112 };
113
114 typedef struct entry_t entry_t;
115
116 struct entry_t {
117 /** rule type */
118 auth_rule_t type;
119 /** associated value */
120 void *value;
121 };
122
123 /**
124 * enumerator for auth_cfg_t.create_enumerator()
125 */
126 typedef struct {
127 /** implements enumerator_t */
128 enumerator_t public;
129 /** inner enumerator from linked_list_t */
130 enumerator_t *inner;
131 /** current entry */
132 entry_t *current;
133 } entry_enumerator_t;
134
135 /**
136 * enumerate function for item_enumerator_t
137 */
138 static bool enumerate(entry_enumerator_t *this, auth_rule_t *type, void **value)
139 {
140 entry_t *entry;
141
142 if (this->inner->enumerate(this->inner, &entry))
143 {
144 this->current = entry;
145 *type = entry->type;
146 *value = entry->value;
147 return TRUE;
148 }
149 return FALSE;
150 }
151
152 /**
153 * destroy function for item_enumerator_t
154 */
155 static void entry_enumerator_destroy(entry_enumerator_t *this)
156 {
157 this->inner->destroy(this->inner);
158 free(this);
159 }
160
161 /**
162 * Implementation of auth_cfg_t.create_enumerator.
163 */
164 static enumerator_t* create_enumerator(private_auth_cfg_t *this)
165 {
166 entry_enumerator_t *enumerator;
167
168 enumerator = malloc_thing(entry_enumerator_t);
169 enumerator->inner = this->entries->create_enumerator(this->entries);
170 enumerator->public.enumerate = (void*)enumerate;
171 enumerator->public.destroy = (void*)entry_enumerator_destroy;
172 enumerator->current = NULL;
173 return &enumerator->public;
174 }
175
176 /**
177 * Destroy the value associated with an entry
178 */
179 static void destroy_entry_value(entry_t *entry)
180 {
181 switch (entry->type)
182 {
183 case AUTH_RULE_IDENTITY:
184 case AUTH_RULE_EAP_IDENTITY:
185 case AUTH_RULE_GROUP:
186 {
187 identification_t *id = (identification_t*)entry->value;
188 id->destroy(id);
189 break;
190 }
191 case AUTH_RULE_CA_CERT:
192 case AUTH_RULE_IM_CERT:
193 case AUTH_RULE_SUBJECT_CERT:
194 case AUTH_HELPER_IM_CERT:
195 case AUTH_HELPER_SUBJECT_CERT:
196 {
197 certificate_t *cert = (certificate_t*)entry->value;
198 cert->destroy(cert);
199 break;
200 }
201 case AUTH_HELPER_IM_HASH_URL:
202 case AUTH_HELPER_SUBJECT_HASH_URL:
203 {
204 free(entry->value);
205 break;
206 }
207 case AUTH_RULE_AUTH_CLASS:
208 case AUTH_RULE_EAP_TYPE:
209 case AUTH_RULE_EAP_VENDOR:
210 case AUTH_RULE_CRL_VALIDATION:
211 case AUTH_RULE_OCSP_VALIDATION:
212 break;
213 }
214 }
215
216 /**
217 * Implementation of auth_cfg_t.replace.
218 */
219 static void replace(auth_cfg_t *this, entry_enumerator_t *enumerator,
220 auth_rule_t type, ...)
221 {
222 if (enumerator->current)
223 {
224 va_list args;
225
226 va_start(args, type);
227
228 destroy_entry_value(enumerator->current);
229 enumerator->current->type = type;
230 switch (type)
231 {
232 case AUTH_RULE_AUTH_CLASS:
233 case AUTH_RULE_EAP_TYPE:
234 case AUTH_RULE_EAP_VENDOR:
235 case AUTH_RULE_CRL_VALIDATION:
236 case AUTH_RULE_OCSP_VALIDATION:
237 /* integer type */
238 enumerator->current->value = (void*)(uintptr_t)va_arg(args, u_int);
239 break;
240 case AUTH_RULE_IDENTITY:
241 case AUTH_RULE_EAP_IDENTITY:
242 case AUTH_RULE_GROUP:
243 case AUTH_RULE_CA_CERT:
244 case AUTH_RULE_IM_CERT:
245 case AUTH_RULE_SUBJECT_CERT:
246 case AUTH_HELPER_IM_CERT:
247 case AUTH_HELPER_SUBJECT_CERT:
248 case AUTH_HELPER_IM_HASH_URL:
249 case AUTH_HELPER_SUBJECT_HASH_URL:
250 /* pointer type */
251 enumerator->current->value = va_arg(args, void*);
252 break;
253 }
254 va_end(args);
255 }
256 }
257
258 /**
259 * Implementation of auth_cfg_t.get.
260 */
261 static void* get(private_auth_cfg_t *this, auth_rule_t type)
262 {
263 enumerator_t *enumerator;
264 void *current_value, *best_value = NULL;
265 auth_rule_t current_type;
266 bool found = FALSE;
267
268 enumerator = create_enumerator(this);
269 while (enumerator->enumerate(enumerator, &current_type, &current_value))
270 {
271 if (type == current_type)
272 {
273 if (type == AUTH_RULE_CRL_VALIDATION ||
274 type == AUTH_RULE_OCSP_VALIDATION)
275 { /* for CRL/OCSP validation, always get() the highest value */
276 if (!found || current_value > best_value)
277 {
278 best_value = current_value;
279 }
280 found = TRUE;
281 continue;
282 }
283 best_value = current_value;
284 found = TRUE;
285 break;
286 }
287 }
288 enumerator->destroy(enumerator);
289 if (found)
290 {
291 return best_value;
292 }
293 switch (type)
294 {
295 /* use some sane defaults if we don't find an entry */
296 case AUTH_RULE_AUTH_CLASS:
297 return (void*)AUTH_CLASS_ANY;
298 case AUTH_RULE_EAP_TYPE:
299 return (void*)EAP_NAK;
300 case AUTH_RULE_EAP_VENDOR:
301 return (void*)0;
302 case AUTH_RULE_CRL_VALIDATION:
303 case AUTH_RULE_OCSP_VALIDATION:
304 return (void*)VALIDATION_FAILED;
305 case AUTH_RULE_IDENTITY:
306 case AUTH_RULE_EAP_IDENTITY:
307 case AUTH_RULE_GROUP:
308 case AUTH_RULE_CA_CERT:
309 case AUTH_RULE_IM_CERT:
310 case AUTH_RULE_SUBJECT_CERT:
311 case AUTH_HELPER_IM_CERT:
312 case AUTH_HELPER_SUBJECT_CERT:
313 case AUTH_HELPER_IM_HASH_URL:
314 case AUTH_HELPER_SUBJECT_HASH_URL:
315 default:
316 return NULL;
317 }
318 }
319
320 /**
321 * Implementation of auth_cfg_t.add.
322 */
323 static void add(private_auth_cfg_t *this, auth_rule_t type, ...)
324 {
325 entry_t *entry = malloc_thing(entry_t);
326 va_list args;
327
328 va_start(args, type);
329 entry->type = type;
330 switch (type)
331 {
332 case AUTH_RULE_AUTH_CLASS:
333 case AUTH_RULE_EAP_TYPE:
334 case AUTH_RULE_EAP_VENDOR:
335 case AUTH_RULE_CRL_VALIDATION:
336 case AUTH_RULE_OCSP_VALIDATION:
337 /* integer type */
338 entry->value = (void*)(uintptr_t)va_arg(args, u_int);
339 break;
340 case AUTH_RULE_IDENTITY:
341 case AUTH_RULE_EAP_IDENTITY:
342 case AUTH_RULE_GROUP:
343 case AUTH_RULE_CA_CERT:
344 case AUTH_RULE_IM_CERT:
345 case AUTH_RULE_SUBJECT_CERT:
346 case AUTH_HELPER_IM_CERT:
347 case AUTH_HELPER_SUBJECT_CERT:
348 case AUTH_HELPER_IM_HASH_URL:
349 case AUTH_HELPER_SUBJECT_HASH_URL:
350 /* pointer type */
351 entry->value = va_arg(args, void*);
352 break;
353 }
354 va_end(args);
355 this->entries->insert_last(this->entries, entry);
356 }
357
358 /**
359 * Implementation of auth_cfg_t.complies.
360 */
361 static bool complies(private_auth_cfg_t *this, auth_cfg_t *constraints,
362 bool log_error)
363 {
364 enumerator_t *e1, *e2;
365 bool success = TRUE, has_group = FALSE, group_match = FALSE;
366 auth_rule_t t1, t2;
367 void *value;
368
369 e1 = constraints->create_enumerator(constraints);
370 while (e1->enumerate(e1, &t1, &value))
371 {
372 switch (t1)
373 {
374 case AUTH_RULE_CA_CERT:
375 case AUTH_RULE_IM_CERT:
376 {
377 certificate_t *c1, *c2;
378
379 c1 = (certificate_t*)value;
380
381 success = FALSE;
382 e2 = create_enumerator(this);
383 while (e2->enumerate(e2, &t2, &c2))
384 {
385 if ((t2 == AUTH_RULE_CA_CERT || t2 == AUTH_RULE_IM_CERT) &&
386 c1->equals(c1, c2))
387 {
388 success = TRUE;
389 }
390 }
391 e2->destroy(e2);
392 if (!success && log_error)
393 {
394 DBG1(DBG_CFG, "constraint check failed: peer not "
395 "authenticated by CA '%Y'.", c1->get_subject(c1));
396 }
397 break;
398 }
399 case AUTH_RULE_SUBJECT_CERT:
400 {
401 certificate_t *c1, *c2;
402
403 c1 = (certificate_t*)value;
404 c2 = get(this, AUTH_RULE_SUBJECT_CERT);
405 if (!c2 || !c1->equals(c1, c2))
406 {
407 success = FALSE;
408 if (log_error)
409 {
410 DBG1(DBG_CFG, "constraint check failed: peer not "
411 "authenticated with peer cert '%Y'.",
412 c1->get_subject(c1));
413 }
414 }
415 break;
416 }
417 case AUTH_RULE_CRL_VALIDATION:
418 case AUTH_RULE_OCSP_VALIDATION:
419 {
420 cert_validation_t validated, required;
421
422 required = (uintptr_t)value;
423 validated = (uintptr_t)get(this, t1);
424 switch (required)
425 {
426 case VALIDATION_FAILED:
427 /* no constraint */
428 break;
429 case VALIDATION_SKIPPED:
430 if (validated == VALIDATION_SKIPPED)
431 {
432 break;
433 }
434 /* FALL */
435 case VALIDATION_GOOD:
436 if (validated == VALIDATION_GOOD)
437 {
438 break;
439 }
440 /* FALL */
441 default:
442 success = FALSE;
443 if (log_error)
444 {
445 DBG1(DBG_CFG, "constraint check failed: %N is %N, "
446 "but requires at least %N", auth_rule_names,
447 t1, cert_validation_names, validated,
448 cert_validation_names, required);
449 }
450 break;
451 }
452 break;
453 }
454 case AUTH_RULE_IDENTITY:
455 case AUTH_RULE_EAP_IDENTITY:
456 {
457 identification_t *id1, *id2;
458
459 id1 = (identification_t*)value;
460 id2 = get(this, t1);
461 if (!id2 || !id2->matches(id2, id1))
462 {
463 success = FALSE;
464 if (log_error)
465 {
466 DBG1(DBG_CFG, "constraint check failed: %sidentity '%Y'"
467 " required ", t1 == AUTH_RULE_IDENTITY ? "" :
468 "EAP ", id1);
469 }
470 }
471 break;
472 }
473 case AUTH_RULE_AUTH_CLASS:
474 {
475 if ((uintptr_t)value != AUTH_CLASS_ANY &&
476 (uintptr_t)value != (uintptr_t)get(this, t1))
477 {
478 success = FALSE;
479 if (log_error)
480 {
481 DBG1(DBG_CFG, "constraint requires %N authentication, "
482 "but %N was used", auth_class_names, (uintptr_t)value,
483 auth_class_names, (uintptr_t)get(this, t1));
484 }
485 }
486 break;
487 }
488 case AUTH_RULE_EAP_TYPE:
489 {
490 if ((uintptr_t)value != (uintptr_t)get(this, t1))
491 {
492 success = FALSE;
493 if (log_error)
494 {
495 DBG1(DBG_CFG, "constraint requires %N, "
496 "but %N was used", eap_type_names, (uintptr_t)value,
497 eap_type_names, (uintptr_t)get(this, t1));
498 }
499 }
500 break;
501 }
502 case AUTH_RULE_EAP_VENDOR:
503 {
504 if ((uintptr_t)value != (uintptr_t)get(this, t1))
505 {
506 success = FALSE;
507 if (log_error)
508 {
509 DBG1(DBG_CFG, "constraint requires EAP vendor %d, "
510 "but %d was used", (uintptr_t)value,
511 (uintptr_t)get(this, t1));
512 }
513 }
514 break;
515 }
516 case AUTH_RULE_GROUP:
517 {
518 identification_t *id1, *id2;
519
520 /* for groups, a match of a single group is sufficient */
521 has_group = TRUE;
522 id1 = (identification_t*)value;
523 e2 = create_enumerator(this);
524 while (e2->enumerate(e2, &t2, &id2))
525 {
526 if (t2 == AUTH_RULE_GROUP && id2->matches(id2, id1))
527 {
528 group_match = TRUE;
529 }
530 }
531 e2->destroy(e2);
532 break;
533 }
534 case AUTH_HELPER_IM_CERT:
535 case AUTH_HELPER_SUBJECT_CERT:
536 case AUTH_HELPER_IM_HASH_URL:
537 case AUTH_HELPER_SUBJECT_HASH_URL:
538 /* skip helpers */
539 continue;
540 }
541 if (!success)
542 {
543 break;
544 }
545 }
546 e1->destroy(e1);
547
548 if (has_group && !group_match)
549 {
550 if (log_error)
551 {
552 DBG1(DBG_CFG, "constraint check failed: group membership required");
553 }
554 return FALSE;
555 }
556 return success;
557 }
558
559 /**
560 * Implementation of auth_cfg_t.merge.
561 */
562 static void merge(private_auth_cfg_t *this, private_auth_cfg_t *other, bool copy)
563 {
564 if (!other)
565 { /* nothing to merge */
566 return;
567 }
568 if (copy)
569 {
570 enumerator_t *enumerator;
571 auth_rule_t type;
572 void *value;
573
574 enumerator = create_enumerator(other);
575 while (enumerator->enumerate(enumerator, &type, &value))
576 {
577 switch (type)
578 {
579 case AUTH_RULE_CA_CERT:
580 case AUTH_RULE_IM_CERT:
581 case AUTH_RULE_SUBJECT_CERT:
582 case AUTH_HELPER_IM_CERT:
583 case AUTH_HELPER_SUBJECT_CERT:
584 {
585 certificate_t *cert = (certificate_t*)value;
586
587 add(this, type, cert->get_ref(cert));
588 break;
589 }
590 case AUTH_RULE_CRL_VALIDATION:
591 case AUTH_RULE_OCSP_VALIDATION:
592 case AUTH_RULE_AUTH_CLASS:
593 case AUTH_RULE_EAP_TYPE:
594 case AUTH_RULE_EAP_VENDOR:
595 {
596 add(this, type, (uintptr_t)value);
597 break;
598 }
599 case AUTH_RULE_IDENTITY:
600 case AUTH_RULE_EAP_IDENTITY:
601 case AUTH_RULE_GROUP:
602 {
603 identification_t *id = (identification_t*)value;
604
605 add(this, type, id->clone(id));
606 break;
607 }
608 case AUTH_HELPER_IM_HASH_URL:
609 case AUTH_HELPER_SUBJECT_HASH_URL:
610 {
611 add(this, type, strdup((char*)value));
612 break;
613 }
614 }
615 }
616 enumerator->destroy(enumerator);
617 }
618 else
619 {
620 entry_t *entry;
621
622 while (other->entries->remove_first(other->entries,
623 (void**)&entry) == SUCCESS)
624 {
625 this->entries->insert_last(this->entries, entry);
626 }
627 }
628 }
629
630 /**
631 * Implementation of auth_cfg_t.equals.
632 */
633 static bool equals(private_auth_cfg_t *this, private_auth_cfg_t *other)
634 {
635 enumerator_t *e1, *e2;
636 entry_t *i1, *i2;
637 bool equal = TRUE, found;
638
639 if (this->entries->get_count(this->entries) !=
640 other->entries->get_count(other->entries))
641 {
642 return FALSE;
643 }
644 e1 = this->entries->create_enumerator(this->entries);
645 while (e1->enumerate(e1, &i1))
646 {
647 found = FALSE;
648 e2 = other->entries->create_enumerator(other->entries);
649 while (e2->enumerate(e2, &i2))
650 {
651 if (i1->type == i2->type)
652 {
653 switch (i1->type)
654 {
655 case AUTH_RULE_AUTH_CLASS:
656 case AUTH_RULE_EAP_TYPE:
657 case AUTH_RULE_EAP_VENDOR:
658 case AUTH_RULE_CRL_VALIDATION:
659 case AUTH_RULE_OCSP_VALIDATION:
660 {
661 if (i1->value == i2->value)
662 {
663 found = TRUE;
664 break;
665 }
666 continue;
667 }
668 case AUTH_RULE_CA_CERT:
669 case AUTH_RULE_IM_CERT:
670 case AUTH_RULE_SUBJECT_CERT:
671 case AUTH_HELPER_IM_CERT:
672 case AUTH_HELPER_SUBJECT_CERT:
673 {
674 certificate_t *c1, *c2;
675
676 c1 = (certificate_t*)i1->value;
677 c2 = (certificate_t*)i2->value;
678
679 if (c1->equals(c1, c2))
680 {
681 found = TRUE;
682 break;
683 }
684 continue;
685 }
686 case AUTH_RULE_IDENTITY:
687 case AUTH_RULE_EAP_IDENTITY:
688 case AUTH_RULE_GROUP:
689 {
690 identification_t *id1, *id2;
691
692 id1 = (identification_t*)i1->value;
693 id2 = (identification_t*)i2->value;
694
695 if (id1->equals(id1, id2))
696 {
697 found = TRUE;
698 break;
699 }
700 continue;
701 }
702 case AUTH_HELPER_IM_HASH_URL:
703 case AUTH_HELPER_SUBJECT_HASH_URL:
704 {
705 if (streq(i1->value, i2->value))
706 {
707 found = TRUE;
708 break;
709 }
710 continue;
711 }
712 }
713 break;
714 }
715 }
716 e2->destroy(e2);
717 if (!found)
718 {
719 equal = FALSE;
720 break;
721 }
722 }
723 e1->destroy(e1);
724 return equal;
725 }
726
727 /**
728 * Implementation of auth_cfg_t.purge
729 */
730 static void purge(private_auth_cfg_t *this, bool keep_ca)
731 {
732 entry_t *entry;
733 linked_list_t *cas;
734
735 cas = linked_list_create();
736 while (this->entries->remove_last(this->entries, (void**)&entry) == SUCCESS)
737 {
738 if (keep_ca && entry->type == AUTH_RULE_CA_CERT)
739 {
740 cas->insert_first(cas, entry);
741 }
742 else
743 {
744 destroy_entry_value(entry);
745 free(entry);
746 }
747 }
748 while (cas->remove_last(cas, (void**)&entry) == SUCCESS)
749 {
750 this->entries->insert_first(this->entries, entry);
751 }
752 cas->destroy(cas);
753 }
754
755 /**
756 * Implementation of auth_cfg_t.clone
757 */
758 static auth_cfg_t* clone_(private_auth_cfg_t *this)
759 {
760 enumerator_t *enumerator;
761 auth_cfg_t *clone;
762 entry_t *entry;
763
764 clone = auth_cfg_create();
765 enumerator = this->entries->create_enumerator(this->entries);
766 while (enumerator->enumerate(enumerator, &entry))
767 {
768 switch (entry->type)
769 {
770 case AUTH_RULE_IDENTITY:
771 case AUTH_RULE_EAP_IDENTITY:
772 case AUTH_RULE_GROUP:
773 {
774 identification_t *id = (identification_t*)entry->value;
775 clone->add(clone, entry->type, id->clone(id));
776 break;
777 }
778 case AUTH_RULE_CA_CERT:
779 case AUTH_RULE_IM_CERT:
780 case AUTH_RULE_SUBJECT_CERT:
781 case AUTH_HELPER_IM_CERT:
782 case AUTH_HELPER_SUBJECT_CERT:
783 {
784 certificate_t *cert = (certificate_t*)entry->value;
785 clone->add(clone, entry->type, cert->get_ref(cert));
786 break;
787 }
788 case AUTH_HELPER_IM_HASH_URL:
789 case AUTH_HELPER_SUBJECT_HASH_URL:
790 {
791 clone->add(clone, entry->type, strdup(entry->value));
792 break;
793 }
794 case AUTH_RULE_AUTH_CLASS:
795 case AUTH_RULE_EAP_TYPE:
796 case AUTH_RULE_EAP_VENDOR:
797 case AUTH_RULE_CRL_VALIDATION:
798 case AUTH_RULE_OCSP_VALIDATION:
799 clone->add(clone, entry->type, (uintptr_t)entry->value);
800 break;
801 }
802 }
803 enumerator->destroy(enumerator);
804 return clone;
805 }
806
807 /**
808 * Implementation of auth_cfg_t.destroy
809 */
810 static void destroy(private_auth_cfg_t *this)
811 {
812 purge(this, FALSE);
813 this->entries->destroy(this->entries);
814 free(this);
815 }
816
817 /*
818 * see header file
819 */
820 auth_cfg_t *auth_cfg_create()
821 {
822 private_auth_cfg_t *this = malloc_thing(private_auth_cfg_t);
823
824 this->public.add = (void(*)(auth_cfg_t*, auth_rule_t type, ...))add;
825 this->public.get = (void*(*)(auth_cfg_t*, auth_rule_t type))get;
826 this->public.create_enumerator = (enumerator_t*(*)(auth_cfg_t*))create_enumerator;
827 this->public.replace = (void(*)(auth_cfg_t*,enumerator_t*,auth_rule_t,...))replace;
828 this->public.complies = (bool(*)(auth_cfg_t*, auth_cfg_t *,bool))complies;
829 this->public.merge = (void(*)(auth_cfg_t*, auth_cfg_t *other,bool))merge;
830 this->public.purge = (void(*)(auth_cfg_t*,bool))purge;
831 this->public.equals = (bool(*)(auth_cfg_t*, auth_cfg_t *other))equals;
832 this->public.clone = (auth_cfg_t*(*)(auth_cfg_t*))clone_;
833 this->public.destroy = (void(*)(auth_cfg_t*))destroy;
834
835 this->entries = linked_list_create();
836
837 return &this->public;
838 }