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