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