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