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