moved eap_from_string() fomr libcharon to libstrongswan to make it available in starter
[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 /*
97 * See header
98 */
99 eap_type_t eap_type_from_string(char *name)
100 {
101 int i;
102 static struct {
103 char *name;
104 eap_type_t type;
105 } types[] = {
106 {"identity", EAP_IDENTITY},
107 {"md5", EAP_MD5},
108 {"otp", EAP_OTP},
109 {"gtc", EAP_GTC},
110 {"tls", EAP_TLS},
111 {"ttls", EAP_TTLS},
112 {"sim", EAP_SIM},
113 {"aka", EAP_AKA},
114 {"mschapv2", EAP_MSCHAPV2},
115 {"radius", EAP_RADIUS},
116 };
117
118 for (i = 0; i < countof(types); i++)
119 {
120 if (strcaseeq(name, types[i].name))
121 {
122 return types[i].type;
123 }
124 }
125 return 0;
126 }
127
128 typedef struct private_auth_cfg_t private_auth_cfg_t;
129
130 /**
131 * private data of item_set
132 */
133 struct private_auth_cfg_t {
134
135 /**
136 * public functions
137 */
138 auth_cfg_t public;
139
140 /**
141 * list of entry_t
142 */
143 linked_list_t *entries;
144 };
145
146 typedef struct entry_t entry_t;
147
148 struct entry_t {
149 /** rule type */
150 auth_rule_t type;
151 /** associated value */
152 void *value;
153 };
154
155 /**
156 * enumerator for auth_cfg_t.create_enumerator()
157 */
158 typedef struct {
159 /** implements enumerator_t */
160 enumerator_t public;
161 /** inner enumerator from linked_list_t */
162 enumerator_t *inner;
163 /** current entry */
164 entry_t *current;
165 } entry_enumerator_t;
166
167 /**
168 * enumerate function for item_enumerator_t
169 */
170 static bool enumerate(entry_enumerator_t *this, auth_rule_t *type, void **value)
171 {
172 entry_t *entry;
173
174 if (this->inner->enumerate(this->inner, &entry))
175 {
176 this->current = entry;
177 *type = entry->type;
178 *value = entry->value;
179 return TRUE;
180 }
181 return FALSE;
182 }
183
184 /**
185 * destroy function for item_enumerator_t
186 */
187 static void entry_enumerator_destroy(entry_enumerator_t *this)
188 {
189 this->inner->destroy(this->inner);
190 free(this);
191 }
192
193 /**
194 * Implementation of auth_cfg_t.create_enumerator.
195 */
196 static enumerator_t* create_enumerator(private_auth_cfg_t *this)
197 {
198 entry_enumerator_t *enumerator;
199
200 enumerator = malloc_thing(entry_enumerator_t);
201 enumerator->inner = this->entries->create_enumerator(this->entries);
202 enumerator->public.enumerate = (void*)enumerate;
203 enumerator->public.destroy = (void*)entry_enumerator_destroy;
204 enumerator->current = NULL;
205 return &enumerator->public;
206 }
207
208 /**
209 * Destroy the value associated with an entry
210 */
211 static void destroy_entry_value(entry_t *entry)
212 {
213 switch (entry->type)
214 {
215 case AUTH_RULE_IDENTITY:
216 case AUTH_RULE_EAP_IDENTITY:
217 case AUTH_RULE_GROUP:
218 {
219 identification_t *id = (identification_t*)entry->value;
220 id->destroy(id);
221 break;
222 }
223 case AUTH_RULE_CA_CERT:
224 case AUTH_RULE_IM_CERT:
225 case AUTH_RULE_SUBJECT_CERT:
226 case AUTH_HELPER_IM_CERT:
227 case AUTH_HELPER_SUBJECT_CERT:
228 {
229 certificate_t *cert = (certificate_t*)entry->value;
230 cert->destroy(cert);
231 break;
232 }
233 case AUTH_HELPER_IM_HASH_URL:
234 case AUTH_HELPER_SUBJECT_HASH_URL:
235 {
236 free(entry->value);
237 break;
238 }
239 case AUTH_RULE_AUTH_CLASS:
240 case AUTH_RULE_EAP_TYPE:
241 case AUTH_RULE_EAP_VENDOR:
242 case AUTH_RULE_CRL_VALIDATION:
243 case AUTH_RULE_OCSP_VALIDATION:
244 break;
245 }
246 }
247
248 /**
249 * Implementation of auth_cfg_t.replace.
250 */
251 static void replace(auth_cfg_t *this, entry_enumerator_t *enumerator,
252 auth_rule_t type, ...)
253 {
254 if (enumerator->current)
255 {
256 va_list args;
257
258 va_start(args, type);
259
260 destroy_entry_value(enumerator->current);
261 enumerator->current->type = type;
262 switch (type)
263 {
264 case AUTH_RULE_AUTH_CLASS:
265 case AUTH_RULE_EAP_TYPE:
266 case AUTH_RULE_EAP_VENDOR:
267 case AUTH_RULE_CRL_VALIDATION:
268 case AUTH_RULE_OCSP_VALIDATION:
269 /* integer type */
270 enumerator->current->value = (void*)(uintptr_t)va_arg(args, u_int);
271 break;
272 case AUTH_RULE_IDENTITY:
273 case AUTH_RULE_EAP_IDENTITY:
274 case AUTH_RULE_GROUP:
275 case AUTH_RULE_CA_CERT:
276 case AUTH_RULE_IM_CERT:
277 case AUTH_RULE_SUBJECT_CERT:
278 case AUTH_HELPER_IM_CERT:
279 case AUTH_HELPER_SUBJECT_CERT:
280 case AUTH_HELPER_IM_HASH_URL:
281 case AUTH_HELPER_SUBJECT_HASH_URL:
282 /* pointer type */
283 enumerator->current->value = va_arg(args, void*);
284 break;
285 }
286 va_end(args);
287 }
288 }
289
290 /**
291 * Implementation of auth_cfg_t.get.
292 */
293 static void* get(private_auth_cfg_t *this, auth_rule_t type)
294 {
295 enumerator_t *enumerator;
296 void *current_value, *best_value = NULL;
297 auth_rule_t current_type;
298 bool found = FALSE;
299
300 enumerator = create_enumerator(this);
301 while (enumerator->enumerate(enumerator, &current_type, &current_value))
302 {
303 if (type == current_type)
304 {
305 if (type == AUTH_RULE_CRL_VALIDATION ||
306 type == AUTH_RULE_OCSP_VALIDATION)
307 { /* for CRL/OCSP validation, always get() the highest value */
308 if (!found || current_value > best_value)
309 {
310 best_value = current_value;
311 }
312 found = TRUE;
313 continue;
314 }
315 best_value = current_value;
316 found = TRUE;
317 break;
318 }
319 }
320 enumerator->destroy(enumerator);
321 if (found)
322 {
323 return best_value;
324 }
325 switch (type)
326 {
327 /* use some sane defaults if we don't find an entry */
328 case AUTH_RULE_AUTH_CLASS:
329 return (void*)AUTH_CLASS_ANY;
330 case AUTH_RULE_EAP_TYPE:
331 return (void*)EAP_NAK;
332 case AUTH_RULE_EAP_VENDOR:
333 return (void*)0;
334 case AUTH_RULE_CRL_VALIDATION:
335 case AUTH_RULE_OCSP_VALIDATION:
336 return (void*)VALIDATION_FAILED;
337 case AUTH_RULE_IDENTITY:
338 case AUTH_RULE_EAP_IDENTITY:
339 case AUTH_RULE_GROUP:
340 case AUTH_RULE_CA_CERT:
341 case AUTH_RULE_IM_CERT:
342 case AUTH_RULE_SUBJECT_CERT:
343 case AUTH_HELPER_IM_CERT:
344 case AUTH_HELPER_SUBJECT_CERT:
345 case AUTH_HELPER_IM_HASH_URL:
346 case AUTH_HELPER_SUBJECT_HASH_URL:
347 default:
348 return NULL;
349 }
350 }
351
352 /**
353 * Implementation of auth_cfg_t.add.
354 */
355 static void add(private_auth_cfg_t *this, auth_rule_t type, ...)
356 {
357 entry_t *entry = malloc_thing(entry_t);
358 va_list args;
359
360 va_start(args, type);
361 entry->type = type;
362 switch (type)
363 {
364 case AUTH_RULE_AUTH_CLASS:
365 case AUTH_RULE_EAP_TYPE:
366 case AUTH_RULE_EAP_VENDOR:
367 case AUTH_RULE_CRL_VALIDATION:
368 case AUTH_RULE_OCSP_VALIDATION:
369 /* integer type */
370 entry->value = (void*)(uintptr_t)va_arg(args, u_int);
371 break;
372 case AUTH_RULE_IDENTITY:
373 case AUTH_RULE_EAP_IDENTITY:
374 case AUTH_RULE_GROUP:
375 case AUTH_RULE_CA_CERT:
376 case AUTH_RULE_IM_CERT:
377 case AUTH_RULE_SUBJECT_CERT:
378 case AUTH_HELPER_IM_CERT:
379 case AUTH_HELPER_SUBJECT_CERT:
380 case AUTH_HELPER_IM_HASH_URL:
381 case AUTH_HELPER_SUBJECT_HASH_URL:
382 /* pointer type */
383 entry->value = va_arg(args, void*);
384 break;
385 }
386 va_end(args);
387 this->entries->insert_last(this->entries, entry);
388 }
389
390 /**
391 * Implementation of auth_cfg_t.complies.
392 */
393 static bool complies(private_auth_cfg_t *this, auth_cfg_t *constraints,
394 bool log_error)
395 {
396 enumerator_t *e1, *e2;
397 bool success = TRUE, has_group = FALSE, group_match = FALSE;
398 auth_rule_t t1, t2;
399 void *value;
400
401 e1 = constraints->create_enumerator(constraints);
402 while (e1->enumerate(e1, &t1, &value))
403 {
404 switch (t1)
405 {
406 case AUTH_RULE_CA_CERT:
407 case AUTH_RULE_IM_CERT:
408 {
409 certificate_t *c1, *c2;
410
411 c1 = (certificate_t*)value;
412
413 success = FALSE;
414 e2 = create_enumerator(this);
415 while (e2->enumerate(e2, &t2, &c2))
416 {
417 if ((t2 == AUTH_RULE_CA_CERT || t2 == AUTH_RULE_IM_CERT) &&
418 c1->equals(c1, c2))
419 {
420 success = TRUE;
421 }
422 }
423 e2->destroy(e2);
424 if (!success && log_error)
425 {
426 DBG1(DBG_CFG, "constraint check failed: peer not "
427 "authenticated by CA '%Y'.", c1->get_subject(c1));
428 }
429 break;
430 }
431 case AUTH_RULE_SUBJECT_CERT:
432 {
433 certificate_t *c1, *c2;
434
435 c1 = (certificate_t*)value;
436 c2 = get(this, AUTH_RULE_SUBJECT_CERT);
437 if (!c2 || !c1->equals(c1, c2))
438 {
439 success = FALSE;
440 if (log_error)
441 {
442 DBG1(DBG_CFG, "constraint check failed: peer not "
443 "authenticated with peer cert '%Y'.",
444 c1->get_subject(c1));
445 }
446 }
447 break;
448 }
449 case AUTH_RULE_CRL_VALIDATION:
450 case AUTH_RULE_OCSP_VALIDATION:
451 {
452 cert_validation_t validated, required;
453
454 required = (uintptr_t)value;
455 validated = (uintptr_t)get(this, t1);
456 switch (required)
457 {
458 case VALIDATION_FAILED:
459 /* no constraint */
460 break;
461 case VALIDATION_SKIPPED:
462 if (validated == VALIDATION_SKIPPED)
463 {
464 break;
465 }
466 /* FALL */
467 case VALIDATION_GOOD:
468 if (validated == VALIDATION_GOOD)
469 {
470 break;
471 }
472 /* FALL */
473 default:
474 success = FALSE;
475 if (log_error)
476 {
477 DBG1(DBG_CFG, "constraint check failed: %N is %N, "
478 "but requires at least %N", auth_rule_names,
479 t1, cert_validation_names, validated,
480 cert_validation_names, required);
481 }
482 break;
483 }
484 break;
485 }
486 case AUTH_RULE_IDENTITY:
487 case AUTH_RULE_EAP_IDENTITY:
488 {
489 identification_t *id1, *id2;
490
491 id1 = (identification_t*)value;
492 id2 = get(this, t1);
493 if (!id2 || !id2->matches(id2, id1))
494 {
495 success = FALSE;
496 if (log_error)
497 {
498 DBG1(DBG_CFG, "constraint check failed: %sidentity '%Y'"
499 " required ", t1 == AUTH_RULE_IDENTITY ? "" :
500 "EAP ", id1);
501 }
502 }
503 break;
504 }
505 case AUTH_RULE_AUTH_CLASS:
506 {
507 if ((uintptr_t)value != AUTH_CLASS_ANY &&
508 (uintptr_t)value != (uintptr_t)get(this, t1))
509 {
510 success = FALSE;
511 if (log_error)
512 {
513 DBG1(DBG_CFG, "constraint requires %N authentication, "
514 "but %N was used", auth_class_names, (uintptr_t)value,
515 auth_class_names, (uintptr_t)get(this, t1));
516 }
517 }
518 break;
519 }
520 case AUTH_RULE_EAP_TYPE:
521 {
522 if ((uintptr_t)value != (uintptr_t)get(this, t1))
523 {
524 success = FALSE;
525 if (log_error)
526 {
527 DBG1(DBG_CFG, "constraint requires %N, "
528 "but %N was used", eap_type_names, (uintptr_t)value,
529 eap_type_names, (uintptr_t)get(this, t1));
530 }
531 }
532 break;
533 }
534 case AUTH_RULE_EAP_VENDOR:
535 {
536 if ((uintptr_t)value != (uintptr_t)get(this, t1))
537 {
538 success = FALSE;
539 if (log_error)
540 {
541 DBG1(DBG_CFG, "constraint requires EAP vendor %d, "
542 "but %d was used", (uintptr_t)value,
543 (uintptr_t)get(this, t1));
544 }
545 }
546 break;
547 }
548 case AUTH_RULE_GROUP:
549 {
550 identification_t *id1, *id2;
551
552 /* for groups, a match of a single group is sufficient */
553 has_group = TRUE;
554 id1 = (identification_t*)value;
555 e2 = create_enumerator(this);
556 while (e2->enumerate(e2, &t2, &id2))
557 {
558 if (t2 == AUTH_RULE_GROUP && id2->matches(id2, id1))
559 {
560 group_match = TRUE;
561 }
562 }
563 e2->destroy(e2);
564 break;
565 }
566 case AUTH_HELPER_IM_CERT:
567 case AUTH_HELPER_SUBJECT_CERT:
568 case AUTH_HELPER_IM_HASH_URL:
569 case AUTH_HELPER_SUBJECT_HASH_URL:
570 /* skip helpers */
571 continue;
572 }
573 if (!success)
574 {
575 break;
576 }
577 }
578 e1->destroy(e1);
579
580 if (has_group && !group_match)
581 {
582 if (log_error)
583 {
584 DBG1(DBG_CFG, "constraint check failed: group membership required");
585 }
586 return FALSE;
587 }
588 return success;
589 }
590
591 /**
592 * Implementation of auth_cfg_t.merge.
593 */
594 static void merge(private_auth_cfg_t *this, private_auth_cfg_t *other, bool copy)
595 {
596 if (!other)
597 { /* nothing to merge */
598 return;
599 }
600 if (copy)
601 {
602 enumerator_t *enumerator;
603 auth_rule_t type;
604 void *value;
605
606 enumerator = create_enumerator(other);
607 while (enumerator->enumerate(enumerator, &type, &value))
608 {
609 switch (type)
610 {
611 case AUTH_RULE_CA_CERT:
612 case AUTH_RULE_IM_CERT:
613 case AUTH_RULE_SUBJECT_CERT:
614 case AUTH_HELPER_IM_CERT:
615 case AUTH_HELPER_SUBJECT_CERT:
616 {
617 certificate_t *cert = (certificate_t*)value;
618
619 add(this, type, cert->get_ref(cert));
620 break;
621 }
622 case AUTH_RULE_CRL_VALIDATION:
623 case AUTH_RULE_OCSP_VALIDATION:
624 case AUTH_RULE_AUTH_CLASS:
625 case AUTH_RULE_EAP_TYPE:
626 case AUTH_RULE_EAP_VENDOR:
627 {
628 add(this, type, (uintptr_t)value);
629 break;
630 }
631 case AUTH_RULE_IDENTITY:
632 case AUTH_RULE_EAP_IDENTITY:
633 case AUTH_RULE_GROUP:
634 {
635 identification_t *id = (identification_t*)value;
636
637 add(this, type, id->clone(id));
638 break;
639 }
640 case AUTH_HELPER_IM_HASH_URL:
641 case AUTH_HELPER_SUBJECT_HASH_URL:
642 {
643 add(this, type, strdup((char*)value));
644 break;
645 }
646 }
647 }
648 enumerator->destroy(enumerator);
649 }
650 else
651 {
652 entry_t *entry;
653
654 while (other->entries->remove_first(other->entries,
655 (void**)&entry) == SUCCESS)
656 {
657 this->entries->insert_last(this->entries, entry);
658 }
659 }
660 }
661
662 /**
663 * Implementation of auth_cfg_t.equals.
664 */
665 static bool equals(private_auth_cfg_t *this, private_auth_cfg_t *other)
666 {
667 enumerator_t *e1, *e2;
668 entry_t *i1, *i2;
669 bool equal = TRUE, found;
670
671 if (this->entries->get_count(this->entries) !=
672 other->entries->get_count(other->entries))
673 {
674 return FALSE;
675 }
676 e1 = this->entries->create_enumerator(this->entries);
677 while (e1->enumerate(e1, &i1))
678 {
679 found = FALSE;
680 e2 = other->entries->create_enumerator(other->entries);
681 while (e2->enumerate(e2, &i2))
682 {
683 if (i1->type == i2->type)
684 {
685 switch (i1->type)
686 {
687 case AUTH_RULE_AUTH_CLASS:
688 case AUTH_RULE_EAP_TYPE:
689 case AUTH_RULE_EAP_VENDOR:
690 case AUTH_RULE_CRL_VALIDATION:
691 case AUTH_RULE_OCSP_VALIDATION:
692 {
693 if (i1->value == i2->value)
694 {
695 found = TRUE;
696 break;
697 }
698 continue;
699 }
700 case AUTH_RULE_CA_CERT:
701 case AUTH_RULE_IM_CERT:
702 case AUTH_RULE_SUBJECT_CERT:
703 case AUTH_HELPER_IM_CERT:
704 case AUTH_HELPER_SUBJECT_CERT:
705 {
706 certificate_t *c1, *c2;
707
708 c1 = (certificate_t*)i1->value;
709 c2 = (certificate_t*)i2->value;
710
711 if (c1->equals(c1, c2))
712 {
713 found = TRUE;
714 break;
715 }
716 continue;
717 }
718 case AUTH_RULE_IDENTITY:
719 case AUTH_RULE_EAP_IDENTITY:
720 case AUTH_RULE_GROUP:
721 {
722 identification_t *id1, *id2;
723
724 id1 = (identification_t*)i1->value;
725 id2 = (identification_t*)i2->value;
726
727 if (id1->equals(id1, id2))
728 {
729 found = TRUE;
730 break;
731 }
732 continue;
733 }
734 case AUTH_HELPER_IM_HASH_URL:
735 case AUTH_HELPER_SUBJECT_HASH_URL:
736 {
737 if (streq(i1->value, i2->value))
738 {
739 found = TRUE;
740 break;
741 }
742 continue;
743 }
744 }
745 break;
746 }
747 }
748 e2->destroy(e2);
749 if (!found)
750 {
751 equal = FALSE;
752 break;
753 }
754 }
755 e1->destroy(e1);
756 return equal;
757 }
758
759 /**
760 * Implementation of auth_cfg_t.purge
761 */
762 static void purge(private_auth_cfg_t *this, bool keep_ca)
763 {
764 entry_t *entry;
765 linked_list_t *cas;
766
767 cas = linked_list_create();
768 while (this->entries->remove_last(this->entries, (void**)&entry) == SUCCESS)
769 {
770 if (keep_ca && entry->type == AUTH_RULE_CA_CERT)
771 {
772 cas->insert_first(cas, entry);
773 }
774 else
775 {
776 destroy_entry_value(entry);
777 free(entry);
778 }
779 }
780 while (cas->remove_last(cas, (void**)&entry) == SUCCESS)
781 {
782 this->entries->insert_first(this->entries, entry);
783 }
784 cas->destroy(cas);
785 }
786
787 /**
788 * Implementation of auth_cfg_t.clone
789 */
790 static auth_cfg_t* clone_(private_auth_cfg_t *this)
791 {
792 enumerator_t *enumerator;
793 auth_cfg_t *clone;
794 entry_t *entry;
795
796 clone = auth_cfg_create();
797 enumerator = this->entries->create_enumerator(this->entries);
798 while (enumerator->enumerate(enumerator, &entry))
799 {
800 switch (entry->type)
801 {
802 case AUTH_RULE_IDENTITY:
803 case AUTH_RULE_EAP_IDENTITY:
804 case AUTH_RULE_GROUP:
805 {
806 identification_t *id = (identification_t*)entry->value;
807 clone->add(clone, entry->type, id->clone(id));
808 break;
809 }
810 case AUTH_RULE_CA_CERT:
811 case AUTH_RULE_IM_CERT:
812 case AUTH_RULE_SUBJECT_CERT:
813 case AUTH_HELPER_IM_CERT:
814 case AUTH_HELPER_SUBJECT_CERT:
815 {
816 certificate_t *cert = (certificate_t*)entry->value;
817 clone->add(clone, entry->type, cert->get_ref(cert));
818 break;
819 }
820 case AUTH_HELPER_IM_HASH_URL:
821 case AUTH_HELPER_SUBJECT_HASH_URL:
822 {
823 clone->add(clone, entry->type, strdup(entry->value));
824 break;
825 }
826 case AUTH_RULE_AUTH_CLASS:
827 case AUTH_RULE_EAP_TYPE:
828 case AUTH_RULE_EAP_VENDOR:
829 case AUTH_RULE_CRL_VALIDATION:
830 case AUTH_RULE_OCSP_VALIDATION:
831 clone->add(clone, entry->type, (uintptr_t)entry->value);
832 break;
833 }
834 }
835 enumerator->destroy(enumerator);
836 return clone;
837 }
838
839 /**
840 * Implementation of auth_cfg_t.destroy
841 */
842 static void destroy(private_auth_cfg_t *this)
843 {
844 purge(this, FALSE);
845 this->entries->destroy(this->entries);
846 free(this);
847 }
848
849 /*
850 * see header file
851 */
852 auth_cfg_t *auth_cfg_create()
853 {
854 private_auth_cfg_t *this = malloc_thing(private_auth_cfg_t);
855
856 this->public.add = (void(*)(auth_cfg_t*, auth_rule_t type, ...))add;
857 this->public.get = (void*(*)(auth_cfg_t*, auth_rule_t type))get;
858 this->public.create_enumerator = (enumerator_t*(*)(auth_cfg_t*))create_enumerator;
859 this->public.replace = (void(*)(auth_cfg_t*,enumerator_t*,auth_rule_t,...))replace;
860 this->public.complies = (bool(*)(auth_cfg_t*, auth_cfg_t *,bool))complies;
861 this->public.merge = (void(*)(auth_cfg_t*, auth_cfg_t *other,bool))merge;
862 this->public.purge = (void(*)(auth_cfg_t*,bool))purge;
863 this->public.equals = (bool(*)(auth_cfg_t*, auth_cfg_t *other))equals;
864 this->public.clone = (auth_cfg_t*(*)(auth_cfg_t*))clone_;
865 this->public.destroy = (void(*)(auth_cfg_t*))destroy;
866
867 this->entries = linked_list_create();
868
869 return &this->public;
870 }