9bde66d161077df899b81dbe1fda66aab442e0b9
[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 cert_validation_t validated, required;
370
371 required = (uintptr_t)value;
372 validated = (uintptr_t)get(this, t1);
373 switch (required)
374 {
375 case VALIDATION_FAILED:
376 /* no constraint */
377 break;
378 case VALIDATION_SKIPPED:
379 if (validated == VALIDATION_SKIPPED)
380 {
381 break;
382 }
383 /* FALL */
384 case VALIDATION_GOOD:
385 if (validated == VALIDATION_GOOD)
386 {
387 break;
388 }
389 /* FALL */
390 default:
391 success = FALSE;
392 if (log_error)
393 {
394 DBG1(DBG_CFG, "constraint check failed: %N is %N, "
395 "but requires at least %N", auth_rule_names,
396 t1, cert_validation_names, validated,
397 cert_validation_names, required);
398 }
399 break;
400 }
401 break;
402 }
403 case AUTH_RULE_IDENTITY:
404 case AUTH_RULE_EAP_IDENTITY:
405 case AUTH_RULE_AAA_IDENTITY:
406 {
407 identification_t *id1, *id2;
408
409 id1 = (identification_t*)value;
410 id2 = get(this, t1);
411 if (!id2 || !id2->matches(id2, id1))
412 {
413 success = FALSE;
414 if (log_error)
415 {
416 DBG1(DBG_CFG, "constraint check failed: %sidentity '%Y'"
417 " required ", t1 == AUTH_RULE_IDENTITY ? "" :
418 "EAP ", id1);
419 }
420 }
421 break;
422 }
423 case AUTH_RULE_AUTH_CLASS:
424 {
425 if ((uintptr_t)value != AUTH_CLASS_ANY &&
426 (uintptr_t)value != (uintptr_t)get(this, t1))
427 {
428 success = FALSE;
429 if (log_error)
430 {
431 DBG1(DBG_CFG, "constraint requires %N authentication, "
432 "but %N was used", auth_class_names, (uintptr_t)value,
433 auth_class_names, (uintptr_t)get(this, t1));
434 }
435 }
436 break;
437 }
438 case AUTH_RULE_EAP_TYPE:
439 {
440 if ((uintptr_t)value != (uintptr_t)get(this, t1))
441 {
442 success = FALSE;
443 if (log_error)
444 {
445 DBG1(DBG_CFG, "constraint requires %N, "
446 "but %N was used", eap_type_names, (uintptr_t)value,
447 eap_type_names, (uintptr_t)get(this, t1));
448 }
449 }
450 break;
451 }
452 case AUTH_RULE_EAP_VENDOR:
453 {
454 if ((uintptr_t)value != (uintptr_t)get(this, t1))
455 {
456 success = FALSE;
457 if (log_error)
458 {
459 DBG1(DBG_CFG, "constraint requires EAP vendor %d, "
460 "but %d was used", (uintptr_t)value,
461 (uintptr_t)get(this, t1));
462 }
463 }
464 break;
465 }
466 case AUTH_RULE_GROUP:
467 {
468 identification_t *id1, *id2;
469
470 /* for groups, a match of a single group is sufficient */
471 has_group = TRUE;
472 id1 = (identification_t*)value;
473 e2 = create_enumerator(this);
474 while (e2->enumerate(e2, &t2, &id2))
475 {
476 if (t2 == AUTH_RULE_GROUP && id2->matches(id2, id1))
477 {
478 group_match = TRUE;
479 }
480 }
481 e2->destroy(e2);
482 break;
483 }
484 case AUTH_RULE_RSA_STRENGTH:
485 case AUTH_RULE_ECDSA_STRENGTH:
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 %d bit public key "
493 "strength", value);
494 }
495 }
496 break;
497 }
498 case AUTH_HELPER_IM_CERT:
499 case AUTH_HELPER_SUBJECT_CERT:
500 case AUTH_HELPER_IM_HASH_URL:
501 case AUTH_HELPER_SUBJECT_HASH_URL:
502 /* skip helpers */
503 continue;
504 }
505 if (!success)
506 {
507 break;
508 }
509 }
510 e1->destroy(e1);
511
512 if (has_group && !group_match)
513 {
514 if (log_error)
515 {
516 DBG1(DBG_CFG, "constraint check failed: group membership required");
517 }
518 return FALSE;
519 }
520 return success;
521 }
522
523 /**
524 * Implementation of auth_cfg_t.merge.
525 */
526 static void merge(private_auth_cfg_t *this, private_auth_cfg_t *other, bool copy)
527 {
528 if (!other)
529 { /* nothing to merge */
530 return;
531 }
532 if (copy)
533 {
534 enumerator_t *enumerator;
535 auth_rule_t type;
536 void *value;
537
538 enumerator = create_enumerator(other);
539 while (enumerator->enumerate(enumerator, &type, &value))
540 {
541 switch (type)
542 {
543 case AUTH_RULE_CA_CERT:
544 case AUTH_RULE_IM_CERT:
545 case AUTH_RULE_SUBJECT_CERT:
546 case AUTH_HELPER_IM_CERT:
547 case AUTH_HELPER_SUBJECT_CERT:
548 {
549 certificate_t *cert = (certificate_t*)value;
550
551 add(this, type, cert->get_ref(cert));
552 break;
553 }
554 case AUTH_RULE_CRL_VALIDATION:
555 case AUTH_RULE_OCSP_VALIDATION:
556 case AUTH_RULE_AUTH_CLASS:
557 case AUTH_RULE_EAP_TYPE:
558 case AUTH_RULE_EAP_VENDOR:
559 case AUTH_RULE_RSA_STRENGTH:
560 case AUTH_RULE_ECDSA_STRENGTH:
561 {
562 add(this, type, (uintptr_t)value);
563 break;
564 }
565 case AUTH_RULE_IDENTITY:
566 case AUTH_RULE_EAP_IDENTITY:
567 case AUTH_RULE_AAA_IDENTITY:
568 case AUTH_RULE_GROUP:
569 {
570 identification_t *id = (identification_t*)value;
571
572 add(this, type, id->clone(id));
573 break;
574 }
575 case AUTH_HELPER_IM_HASH_URL:
576 case AUTH_HELPER_SUBJECT_HASH_URL:
577 {
578 add(this, type, strdup((char*)value));
579 break;
580 }
581 }
582 }
583 enumerator->destroy(enumerator);
584 }
585 else
586 {
587 entry_t *entry;
588
589 while (other->entries->remove_first(other->entries,
590 (void**)&entry) == SUCCESS)
591 {
592 this->entries->insert_last(this->entries, entry);
593 }
594 }
595 }
596
597 /**
598 * Implementation of auth_cfg_t.equals.
599 */
600 static bool equals(private_auth_cfg_t *this, private_auth_cfg_t *other)
601 {
602 enumerator_t *e1, *e2;
603 entry_t *i1, *i2;
604 bool equal = TRUE, found;
605
606 if (this->entries->get_count(this->entries) !=
607 other->entries->get_count(other->entries))
608 {
609 return FALSE;
610 }
611 e1 = this->entries->create_enumerator(this->entries);
612 while (e1->enumerate(e1, &i1))
613 {
614 found = FALSE;
615 e2 = other->entries->create_enumerator(other->entries);
616 while (e2->enumerate(e2, &i2))
617 {
618 if (i1->type == i2->type)
619 {
620 switch (i1->type)
621 {
622 case AUTH_RULE_AUTH_CLASS:
623 case AUTH_RULE_EAP_TYPE:
624 case AUTH_RULE_EAP_VENDOR:
625 case AUTH_RULE_CRL_VALIDATION:
626 case AUTH_RULE_OCSP_VALIDATION:
627 case AUTH_RULE_RSA_STRENGTH:
628 case AUTH_RULE_ECDSA_STRENGTH:
629 {
630 if (i1->value == i2->value)
631 {
632 found = TRUE;
633 break;
634 }
635 continue;
636 }
637 case AUTH_RULE_CA_CERT:
638 case AUTH_RULE_IM_CERT:
639 case AUTH_RULE_SUBJECT_CERT:
640 case AUTH_HELPER_IM_CERT:
641 case AUTH_HELPER_SUBJECT_CERT:
642 {
643 certificate_t *c1, *c2;
644
645 c1 = (certificate_t*)i1->value;
646 c2 = (certificate_t*)i2->value;
647
648 if (c1->equals(c1, c2))
649 {
650 found = TRUE;
651 break;
652 }
653 continue;
654 }
655 case AUTH_RULE_IDENTITY:
656 case AUTH_RULE_EAP_IDENTITY:
657 case AUTH_RULE_AAA_IDENTITY:
658 case AUTH_RULE_GROUP:
659 {
660 identification_t *id1, *id2;
661
662 id1 = (identification_t*)i1->value;
663 id2 = (identification_t*)i2->value;
664
665 if (id1->equals(id1, id2))
666 {
667 found = TRUE;
668 break;
669 }
670 continue;
671 }
672 case AUTH_HELPER_IM_HASH_URL:
673 case AUTH_HELPER_SUBJECT_HASH_URL:
674 {
675 if (streq(i1->value, i2->value))
676 {
677 found = TRUE;
678 break;
679 }
680 continue;
681 }
682 }
683 break;
684 }
685 }
686 e2->destroy(e2);
687 if (!found)
688 {
689 equal = FALSE;
690 break;
691 }
692 }
693 e1->destroy(e1);
694 return equal;
695 }
696
697 /**
698 * Implementation of auth_cfg_t.purge
699 */
700 static void purge(private_auth_cfg_t *this, bool keep_ca)
701 {
702 entry_t *entry;
703 linked_list_t *cas;
704
705 cas = linked_list_create();
706 while (this->entries->remove_last(this->entries, (void**)&entry) == SUCCESS)
707 {
708 if (keep_ca && entry->type == AUTH_RULE_CA_CERT)
709 {
710 cas->insert_first(cas, entry);
711 }
712 else
713 {
714 destroy_entry_value(entry);
715 free(entry);
716 }
717 }
718 while (cas->remove_last(cas, (void**)&entry) == SUCCESS)
719 {
720 this->entries->insert_first(this->entries, entry);
721 }
722 cas->destroy(cas);
723 }
724
725 /**
726 * Implementation of auth_cfg_t.clone
727 */
728 static auth_cfg_t* clone_(private_auth_cfg_t *this)
729 {
730 enumerator_t *enumerator;
731 auth_cfg_t *clone;
732 entry_t *entry;
733
734 clone = auth_cfg_create();
735 enumerator = this->entries->create_enumerator(this->entries);
736 while (enumerator->enumerate(enumerator, &entry))
737 {
738 switch (entry->type)
739 {
740 case AUTH_RULE_IDENTITY:
741 case AUTH_RULE_EAP_IDENTITY:
742 case AUTH_RULE_AAA_IDENTITY:
743 case AUTH_RULE_GROUP:
744 {
745 identification_t *id = (identification_t*)entry->value;
746 clone->add(clone, entry->type, id->clone(id));
747 break;
748 }
749 case AUTH_RULE_CA_CERT:
750 case AUTH_RULE_IM_CERT:
751 case AUTH_RULE_SUBJECT_CERT:
752 case AUTH_HELPER_IM_CERT:
753 case AUTH_HELPER_SUBJECT_CERT:
754 {
755 certificate_t *cert = (certificate_t*)entry->value;
756 clone->add(clone, entry->type, cert->get_ref(cert));
757 break;
758 }
759 case AUTH_HELPER_IM_HASH_URL:
760 case AUTH_HELPER_SUBJECT_HASH_URL:
761 {
762 clone->add(clone, entry->type, strdup(entry->value));
763 break;
764 }
765 case AUTH_RULE_AUTH_CLASS:
766 case AUTH_RULE_EAP_TYPE:
767 case AUTH_RULE_EAP_VENDOR:
768 case AUTH_RULE_CRL_VALIDATION:
769 case AUTH_RULE_OCSP_VALIDATION:
770 case AUTH_RULE_RSA_STRENGTH:
771 case AUTH_RULE_ECDSA_STRENGTH:
772 clone->add(clone, entry->type, (uintptr_t)entry->value);
773 break;
774 }
775 }
776 enumerator->destroy(enumerator);
777 return clone;
778 }
779
780 /**
781 * Implementation of auth_cfg_t.destroy
782 */
783 static void destroy(private_auth_cfg_t *this)
784 {
785 purge(this, FALSE);
786 this->entries->destroy(this->entries);
787 free(this);
788 }
789
790 /*
791 * see header file
792 */
793 auth_cfg_t *auth_cfg_create()
794 {
795 private_auth_cfg_t *this = malloc_thing(private_auth_cfg_t);
796
797 this->public.add = (void(*)(auth_cfg_t*, auth_rule_t type, ...))add;
798 this->public.get = (void*(*)(auth_cfg_t*, auth_rule_t type))get;
799 this->public.create_enumerator = (enumerator_t*(*)(auth_cfg_t*))create_enumerator;
800 this->public.replace = (void(*)(auth_cfg_t*,enumerator_t*,auth_rule_t,...))replace;
801 this->public.complies = (bool(*)(auth_cfg_t*, auth_cfg_t *,bool))complies;
802 this->public.merge = (void(*)(auth_cfg_t*, auth_cfg_t *other,bool))merge;
803 this->public.purge = (void(*)(auth_cfg_t*,bool))purge;
804 this->public.equals = (bool(*)(auth_cfg_t*, auth_cfg_t *other))equals;
805 this->public.clone = (auth_cfg_t*(*)(auth_cfg_t*))clone_;
806 this->public.destroy = (void(*)(auth_cfg_t*))destroy;
807
808 this->entries = linked_list_create();
809
810 return &this->public;
811 }