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