Annotation of embedaddon/strongswan/src/libstrongswan/credentials/auth_cfg.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (C) 2008-2017 Tobias Brunner
3: * Copyright (C) 2007-2009 Martin Willi
4: * Copyright (C) 2016 Andreas Steffen
5: * HSR Hochschule fuer Technik Rapperswil
6: *
7: * This program is free software; you can redistribute it and/or modify it
8: * under the terms of the GNU General Public License as published by the
9: * Free Software Foundation; either version 2 of the License, or (at your
10: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
11: *
12: * This program is distributed in the hope that it will be useful, but
13: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15: * for more details.
16: */
17:
18: #include "auth_cfg.h"
19:
20: #include <library.h>
21: #include <utils/debug.h>
22: #include <collections/array.h>
23: #include <utils/identification.h>
24: #include <eap/eap.h>
25: #include <credentials/certificates/certificate.h>
26:
27: ENUM(auth_class_names, AUTH_CLASS_ANY, AUTH_CLASS_XAUTH,
28: "any",
29: "public key",
30: "pre-shared key",
31: "EAP",
32: "XAuth",
33: );
34:
35: ENUM(auth_rule_names, AUTH_RULE_IDENTITY, AUTH_HELPER_AC_CERT,
36: "RULE_IDENTITY",
37: "RULE_IDENTITY_LOOSE",
38: "RULE_AUTH_CLASS",
39: "RULE_AAA_IDENTITY",
40: "RULE_EAP_IDENTITY",
41: "RULE_EAP_TYPE",
42: "RULE_EAP_VENDOR",
43: "RULE_XAUTH_BACKEND",
44: "RULE_XAUTH_IDENTITY",
45: "AUTH_RULE_CA_IDENTITY",
46: "RULE_CA_CERT",
47: "RULE_IM_CERT",
48: "RULE_SUBJECT_CERT",
49: "RULE_CRL_VALIDATION",
50: "RULE_OCSP_VALIDATION",
51: "RULE_CERT_VALIDATION_SUSPENDED",
52: "RULE_GROUP",
53: "RULE_RSA_STRENGTH",
54: "RULE_ECDSA_STRENGTH",
55: "RULE_BLISS_STRENGTH",
56: "RULE_SIGNATURE_SCHEME",
57: "RULE_IKE_SIGNATURE_SCHEME",
58: "RULE_CERT_POLICY",
59: "HELPER_IM_CERT",
60: "HELPER_SUBJECT_CERT",
61: "HELPER_IM_HASH_URL",
62: "HELPER_SUBJECT_HASH_URL",
63: "HELPER_REVOCATION_CERT",
64: "HELPER_AC_CERT",
65: );
66:
67: /**
68: * Check if the given rule is a rule for which there may be multiple values.
69: */
70: static inline bool is_multi_value_rule(auth_rule_t type)
71: {
72: switch (type)
73: {
74: case AUTH_RULE_AUTH_CLASS:
75: case AUTH_RULE_EAP_TYPE:
76: case AUTH_RULE_EAP_VENDOR:
77: case AUTH_RULE_IDENTITY:
78: case AUTH_RULE_IDENTITY_LOOSE:
79: case AUTH_RULE_EAP_IDENTITY:
80: case AUTH_RULE_AAA_IDENTITY:
81: case AUTH_RULE_XAUTH_IDENTITY:
82: case AUTH_RULE_XAUTH_BACKEND:
83: case AUTH_RULE_CERT_VALIDATION_SUSPENDED:
84: case AUTH_HELPER_SUBJECT_CERT:
85: case AUTH_HELPER_SUBJECT_HASH_URL:
86: case AUTH_RULE_MAX:
87: return FALSE;
88: case AUTH_RULE_OCSP_VALIDATION:
89: case AUTH_RULE_CRL_VALIDATION:
90: case AUTH_RULE_GROUP:
91: case AUTH_RULE_SUBJECT_CERT:
92: case AUTH_RULE_CA_IDENTITY:
93: case AUTH_RULE_CA_CERT:
94: case AUTH_RULE_IM_CERT:
95: case AUTH_RULE_CERT_POLICY:
96: case AUTH_RULE_RSA_STRENGTH:
97: case AUTH_RULE_ECDSA_STRENGTH:
98: case AUTH_RULE_BLISS_STRENGTH:
99: case AUTH_RULE_SIGNATURE_SCHEME:
100: case AUTH_RULE_IKE_SIGNATURE_SCHEME:
101: case AUTH_HELPER_IM_CERT:
102: case AUTH_HELPER_IM_HASH_URL:
103: case AUTH_HELPER_REVOCATION_CERT:
104: case AUTH_HELPER_AC_CERT:
105: return TRUE;
106: }
107: return FALSE;
108: }
109:
110: typedef struct private_auth_cfg_t private_auth_cfg_t;
111:
112: /**
113: * private data of item_set
114: */
115: struct private_auth_cfg_t {
116:
117: /**
118: * public functions
119: */
120: auth_cfg_t public;
121:
122: /**
123: * Array of entry_t
124: */
125: array_t *entries;
126: };
127:
128: typedef struct entry_t entry_t;
129:
130: struct entry_t {
131: /** rule type */
132: auth_rule_t type;
133: /** associated value */
134: void *value;
135: };
136:
137: /**
138: * enumerator for auth_cfg_t.create_enumerator()
139: */
140: typedef struct {
141: /** implements enumerator_t */
142: enumerator_t public;
143: /** inner enumerator from linked_list_t */
144: enumerator_t *inner;
145: /** current entry */
146: entry_t *current;
147: /** types we have already enumerated */
148: bool enumerated[AUTH_RULE_MAX];
149: } entry_enumerator_t;
150:
151: METHOD(enumerator_t, enumerate, bool,
152: entry_enumerator_t *this, va_list args)
153: {
154: auth_rule_t *type;
155: entry_t *entry;
156: void **value;
157:
158: VA_ARGS_VGET(args, type, value);
159:
160: while (this->inner->enumerate(this->inner, &entry))
161: {
162: if (!is_multi_value_rule(entry->type) && this->enumerated[entry->type])
163: {
164: continue;
165: }
166: this->enumerated[entry->type] = TRUE;
167: this->current = entry;
168: if (type)
169: {
170: *type = entry->type;
171: }
172: if (value)
173: {
174: *value = entry->value;
175: }
176: return TRUE;
177: }
178: return FALSE;
179: }
180:
181: METHOD(enumerator_t, entry_enumerator_destroy, void,
182: entry_enumerator_t *this)
183: {
184: this->inner->destroy(this->inner);
185: free(this);
186: }
187:
188: METHOD(auth_cfg_t, create_enumerator, enumerator_t*,
189: private_auth_cfg_t *this)
190: {
191: entry_enumerator_t *enumerator;
192:
193: INIT(enumerator,
194: .public = {
195: .enumerate = enumerator_enumerate_default,
196: .venumerate = _enumerate,
197: .destroy = _entry_enumerator_destroy,
198: },
199: .inner = array_create_enumerator(this->entries),
200: );
201: return &enumerator->public;
202: }
203:
204: /**
205: * Initialize an entry.
206: */
207: static void init_entry(entry_t *this, auth_rule_t type, va_list args)
208: {
209: this->type = type;
210: switch (type)
211: {
212: case AUTH_RULE_IDENTITY_LOOSE:
213: case AUTH_RULE_AUTH_CLASS:
214: case AUTH_RULE_EAP_TYPE:
215: case AUTH_RULE_EAP_VENDOR:
216: case AUTH_RULE_CRL_VALIDATION:
217: case AUTH_RULE_OCSP_VALIDATION:
218: case AUTH_RULE_RSA_STRENGTH:
219: case AUTH_RULE_ECDSA_STRENGTH:
220: case AUTH_RULE_BLISS_STRENGTH:
221: case AUTH_RULE_CERT_VALIDATION_SUSPENDED:
222: /* integer type */
223: this->value = (void*)(uintptr_t)va_arg(args, u_int);
224: break;
225: case AUTH_RULE_IDENTITY:
226: case AUTH_RULE_EAP_IDENTITY:
227: case AUTH_RULE_AAA_IDENTITY:
228: case AUTH_RULE_XAUTH_BACKEND:
229: case AUTH_RULE_XAUTH_IDENTITY:
230: case AUTH_RULE_GROUP:
231: case AUTH_RULE_CA_IDENTITY:
232: case AUTH_RULE_CA_CERT:
233: case AUTH_RULE_IM_CERT:
234: case AUTH_RULE_SUBJECT_CERT:
235: case AUTH_RULE_CERT_POLICY:
236: case AUTH_RULE_SIGNATURE_SCHEME:
237: case AUTH_RULE_IKE_SIGNATURE_SCHEME:
238: case AUTH_HELPER_IM_CERT:
239: case AUTH_HELPER_SUBJECT_CERT:
240: case AUTH_HELPER_IM_HASH_URL:
241: case AUTH_HELPER_SUBJECT_HASH_URL:
242: case AUTH_HELPER_REVOCATION_CERT:
243: case AUTH_HELPER_AC_CERT:
244: /* pointer type */
245: this->value = va_arg(args, void*);
246: break;
247: case AUTH_RULE_MAX:
248: this->value = NULL;
249: break;
250: }
251: }
252:
253: /**
254: * Compare two entries for equality.
255: */
256: static bool entry_equals(entry_t *e1, entry_t *e2)
257: {
258: if (e1->type != e2->type)
259: {
260: return FALSE;
261: }
262: switch (e1->type)
263: {
264: case AUTH_RULE_IDENTITY_LOOSE:
265: case AUTH_RULE_AUTH_CLASS:
266: case AUTH_RULE_EAP_TYPE:
267: case AUTH_RULE_EAP_VENDOR:
268: case AUTH_RULE_CRL_VALIDATION:
269: case AUTH_RULE_OCSP_VALIDATION:
270: case AUTH_RULE_RSA_STRENGTH:
271: case AUTH_RULE_ECDSA_STRENGTH:
272: case AUTH_RULE_BLISS_STRENGTH:
273: case AUTH_RULE_CERT_VALIDATION_SUSPENDED:
274: {
275: return e1->value == e2->value;
276: }
277: case AUTH_RULE_CA_CERT:
278: case AUTH_RULE_IM_CERT:
279: case AUTH_RULE_SUBJECT_CERT:
280: case AUTH_HELPER_IM_CERT:
281: case AUTH_HELPER_SUBJECT_CERT:
282: case AUTH_HELPER_REVOCATION_CERT:
283: case AUTH_HELPER_AC_CERT:
284: {
285: certificate_t *c1, *c2;
286:
287: c1 = (certificate_t*)e1->value;
288: c2 = (certificate_t*)e2->value;
289:
290: return c1->equals(c1, c2);
291: }
292: case AUTH_RULE_IDENTITY:
293: case AUTH_RULE_CA_IDENTITY:
294: case AUTH_RULE_EAP_IDENTITY:
295: case AUTH_RULE_AAA_IDENTITY:
296: case AUTH_RULE_XAUTH_IDENTITY:
297: case AUTH_RULE_GROUP:
298: {
299: identification_t *id1, *id2;
300:
301: id1 = (identification_t*)e1->value;
302: id2 = (identification_t*)e2->value;
303:
304: return id1->equals(id1, id2);
305: }
306: case AUTH_RULE_SIGNATURE_SCHEME:
307: case AUTH_RULE_IKE_SIGNATURE_SCHEME:
308: {
309: return signature_params_equal(e1->value, e2->value);
310: }
311: case AUTH_RULE_CERT_POLICY:
312: case AUTH_RULE_XAUTH_BACKEND:
313: case AUTH_HELPER_IM_HASH_URL:
314: case AUTH_HELPER_SUBJECT_HASH_URL:
315: {
316: return streq(e1->value, e2->value);
317: }
318: case AUTH_RULE_MAX:
319: break;
320: }
321: return FALSE;
322: }
323:
324: /**
325: * Destroy the value associated with an entry
326: */
327: static void destroy_entry_value(entry_t *entry)
328: {
329: switch (entry->type)
330: {
331: case AUTH_RULE_IDENTITY:
332: case AUTH_RULE_CA_IDENTITY:
333: case AUTH_RULE_EAP_IDENTITY:
334: case AUTH_RULE_AAA_IDENTITY:
335: case AUTH_RULE_GROUP:
336: case AUTH_RULE_XAUTH_IDENTITY:
337: {
338: identification_t *id = (identification_t*)entry->value;
339: id->destroy(id);
340: break;
341: }
342: case AUTH_RULE_CA_CERT:
343: case AUTH_RULE_IM_CERT:
344: case AUTH_RULE_SUBJECT_CERT:
345: case AUTH_HELPER_IM_CERT:
346: case AUTH_HELPER_SUBJECT_CERT:
347: case AUTH_HELPER_REVOCATION_CERT:
348: case AUTH_HELPER_AC_CERT:
349: {
350: certificate_t *cert = (certificate_t*)entry->value;
351: cert->destroy(cert);
352: break;
353: }
354: case AUTH_RULE_CERT_POLICY:
355: case AUTH_RULE_XAUTH_BACKEND:
356: case AUTH_HELPER_IM_HASH_URL:
357: case AUTH_HELPER_SUBJECT_HASH_URL:
358: {
359: free(entry->value);
360: break;
361: }
362: case AUTH_RULE_SIGNATURE_SCHEME:
363: case AUTH_RULE_IKE_SIGNATURE_SCHEME:
364: {
365: signature_params_destroy(entry->value);
366: break;
367: }
368: case AUTH_RULE_IDENTITY_LOOSE:
369: case AUTH_RULE_AUTH_CLASS:
370: case AUTH_RULE_EAP_TYPE:
371: case AUTH_RULE_EAP_VENDOR:
372: case AUTH_RULE_CRL_VALIDATION:
373: case AUTH_RULE_OCSP_VALIDATION:
374: case AUTH_RULE_RSA_STRENGTH:
375: case AUTH_RULE_ECDSA_STRENGTH:
376: case AUTH_RULE_BLISS_STRENGTH:
377: case AUTH_RULE_CERT_VALIDATION_SUSPENDED:
378: case AUTH_RULE_MAX:
379: break;
380: }
381: }
382:
383: /**
384: * Implementation of auth_cfg_t.replace.
385: */
386: static void replace(private_auth_cfg_t *this, entry_enumerator_t *enumerator,
387: auth_rule_t type, ...)
388: {
389: if (enumerator->current)
390: {
391: entry_t *entry;
392: va_list args;
393:
394: va_start(args, type);
395: entry = enumerator->current;
396: destroy_entry_value(entry);
397: entry->type = type;
398: switch (type)
399: {
400: case AUTH_RULE_IDENTITY_LOOSE:
401: case AUTH_RULE_AUTH_CLASS:
402: case AUTH_RULE_EAP_TYPE:
403: case AUTH_RULE_EAP_VENDOR:
404: case AUTH_RULE_CRL_VALIDATION:
405: case AUTH_RULE_OCSP_VALIDATION:
406: case AUTH_RULE_RSA_STRENGTH:
407: case AUTH_RULE_ECDSA_STRENGTH:
408: case AUTH_RULE_BLISS_STRENGTH:
409: case AUTH_RULE_CERT_VALIDATION_SUSPENDED:
410: /* integer type */
411: entry->value = (void*)(uintptr_t)va_arg(args, u_int);
412: break;
413: case AUTH_RULE_IDENTITY:
414: case AUTH_RULE_CA_IDENTITY:
415: case AUTH_RULE_EAP_IDENTITY:
416: case AUTH_RULE_AAA_IDENTITY:
417: case AUTH_RULE_XAUTH_BACKEND:
418: case AUTH_RULE_XAUTH_IDENTITY:
419: case AUTH_RULE_GROUP:
420: case AUTH_RULE_CA_CERT:
421: case AUTH_RULE_IM_CERT:
422: case AUTH_RULE_SUBJECT_CERT:
423: case AUTH_RULE_CERT_POLICY:
424: case AUTH_RULE_SIGNATURE_SCHEME:
425: case AUTH_RULE_IKE_SIGNATURE_SCHEME:
426: case AUTH_HELPER_IM_CERT:
427: case AUTH_HELPER_SUBJECT_CERT:
428: case AUTH_HELPER_IM_HASH_URL:
429: case AUTH_HELPER_SUBJECT_HASH_URL:
430: case AUTH_HELPER_REVOCATION_CERT:
431: case AUTH_HELPER_AC_CERT:
432: /* pointer type */
433: entry->value = va_arg(args, void*);
434: break;
435: case AUTH_RULE_MAX:
436: entry->value = NULL;
437: break;
438: }
439: va_end(args);
440: }
441: }
442:
443: METHOD(auth_cfg_t, get, void*,
444: private_auth_cfg_t *this, auth_rule_t type)
445: {
446: enumerator_t *enumerator;
447: void *current_value, *best_value = NULL;
448: auth_rule_t current_type;
449: bool found = FALSE;
450:
451: enumerator = create_enumerator(this);
452: while (enumerator->enumerate(enumerator, ¤t_type, ¤t_value))
453: {
454: if (type == current_type)
455: {
456: if (type == AUTH_RULE_CRL_VALIDATION ||
457: type == AUTH_RULE_OCSP_VALIDATION)
458: { /* for CRL/OCSP validation, always get() the highest value */
459: if (!found || current_value > best_value)
460: {
461: best_value = current_value;
462: }
463: found = TRUE;
464: continue;
465: }
466: best_value = current_value;
467: found = TRUE;
468: break;
469: }
470: }
471: enumerator->destroy(enumerator);
472: if (found)
473: {
474: return best_value;
475: }
476: switch (type)
477: {
478: /* use some sane defaults if we don't find an entry */
479: case AUTH_RULE_AUTH_CLASS:
480: return (void*)AUTH_CLASS_ANY;
481: case AUTH_RULE_EAP_TYPE:
482: return (void*)EAP_NAK;
483: case AUTH_RULE_EAP_VENDOR:
484: case AUTH_RULE_RSA_STRENGTH:
485: case AUTH_RULE_ECDSA_STRENGTH:
486: case AUTH_RULE_BLISS_STRENGTH:
487: return (void*)0;
488: case AUTH_RULE_CRL_VALIDATION:
489: case AUTH_RULE_OCSP_VALIDATION:
490: return (void*)VALIDATION_FAILED;
491: case AUTH_RULE_IDENTITY_LOOSE:
492: case AUTH_RULE_CERT_VALIDATION_SUSPENDED:
493: return (void*)FALSE;
494: case AUTH_RULE_IDENTITY:
495: case AUTH_RULE_CA_IDENTITY:
496: case AUTH_RULE_EAP_IDENTITY:
497: case AUTH_RULE_AAA_IDENTITY:
498: case AUTH_RULE_XAUTH_BACKEND:
499: case AUTH_RULE_XAUTH_IDENTITY:
500: case AUTH_RULE_GROUP:
501: case AUTH_RULE_CA_CERT:
502: case AUTH_RULE_IM_CERT:
503: case AUTH_RULE_SUBJECT_CERT:
504: case AUTH_RULE_CERT_POLICY:
505: case AUTH_RULE_SIGNATURE_SCHEME:
506: case AUTH_RULE_IKE_SIGNATURE_SCHEME:
507: case AUTH_HELPER_IM_CERT:
508: case AUTH_HELPER_SUBJECT_CERT:
509: case AUTH_HELPER_IM_HASH_URL:
510: case AUTH_HELPER_SUBJECT_HASH_URL:
511: case AUTH_HELPER_REVOCATION_CERT:
512: case AUTH_HELPER_AC_CERT:
513: case AUTH_RULE_MAX:
514: break;
515: }
516: return NULL;
517: }
518:
519: /**
520: * Implementation of auth_cfg_t.add.
521: */
522: static void add(private_auth_cfg_t *this, auth_rule_t type, ...)
523: {
524: entry_t entry;
525: va_list args;
526:
527: va_start(args, type);
528: init_entry(&entry, type, args);
529: va_end(args);
530:
531: if (is_multi_value_rule(type))
532: { /* insert rules that may occur multiple times at the end */
533: array_insert(this->entries, ARRAY_TAIL, &entry);
534: }
535: else
536: { /* insert rules we expect only once at the front (get() will return
537: * the latest value) */
538: array_insert(this->entries, ARRAY_HEAD, &entry);
539: }
540: }
541:
542: /**
543: * Create a constraint for RSA/PSS signatures
544: */
545: static signature_params_t *create_rsa_pss_constraint(char *token)
546: {
547: signature_params_t *params = NULL;
548: hash_algorithm_t hash;
549:
550: if (enum_from_name(hash_algorithm_short_names, token, &hash))
551: {
552: rsa_pss_params_t pss = {
553: .hash = hash,
554: .mgf1_hash = hash,
555: .salt_len = RSA_PSS_SALT_LEN_DEFAULT,
556: };
557: signature_params_t pss_params = {
558: .scheme = SIGN_RSA_EMSA_PSS,
559: .params = &pss,
560: };
561: rsa_pss_params_set_salt_len(&pss, 0);
562: params = signature_params_clone(&pss_params);
563: }
564: return params;
565: }
566:
567: METHOD(auth_cfg_t, add_pubkey_constraints, void,
568: private_auth_cfg_t *this, char* constraints, bool ike)
569: {
570: enumerator_t *enumerator;
571: bool ike_added = FALSE, rsa_pss;
572: key_type_t expected_type = -1;
573: auth_rule_t expected_strength = AUTH_RULE_MAX;
574: signature_params_t *params;
575: int strength;
576: char *token, *key_token = NULL;
577: auth_rule_t type;
578: void *value;
579:
580: rsa_pss = lib->settings->get_bool(lib->settings, "%s.rsa_pss", FALSE,
581: lib->ns);
582:
583: enumerator = enumerator_create_token(constraints, "-", "");
584: while (enumerator->enumerate(enumerator, &token))
585: {
586: bool found = FALSE;
587: int i;
588: struct {
589: char *name;
590: signature_scheme_t scheme;
591: key_type_t key;
592: } schemes[] = {
593: { "md5", SIGN_RSA_EMSA_PKCS1_MD5, KEY_RSA, },
594: { "sha1", SIGN_RSA_EMSA_PKCS1_SHA1, KEY_RSA, },
595: { "sha224", SIGN_RSA_EMSA_PKCS1_SHA2_224, KEY_RSA, },
596: { "sha256", SIGN_RSA_EMSA_PKCS1_SHA2_256, KEY_RSA, },
597: { "sha384", SIGN_RSA_EMSA_PKCS1_SHA2_384, KEY_RSA, },
598: { "sha512", SIGN_RSA_EMSA_PKCS1_SHA2_512, KEY_RSA, },
599: { "sha1", SIGN_ECDSA_WITH_SHA1_DER, KEY_ECDSA, },
600: { "sha256", SIGN_ECDSA_WITH_SHA256_DER, KEY_ECDSA, },
601: { "sha384", SIGN_ECDSA_WITH_SHA384_DER, KEY_ECDSA, },
602: { "sha512", SIGN_ECDSA_WITH_SHA512_DER, KEY_ECDSA, },
603: { "sha256", SIGN_ECDSA_256, KEY_ECDSA, },
604: { "sha384", SIGN_ECDSA_384, KEY_ECDSA, },
605: { "sha512", SIGN_ECDSA_521, KEY_ECDSA, },
606: { "sha256", SIGN_BLISS_WITH_SHA2_256, KEY_BLISS, },
607: { "sha384", SIGN_BLISS_WITH_SHA2_384, KEY_BLISS, },
608: { "sha512", SIGN_BLISS_WITH_SHA2_512, KEY_BLISS, },
609: { "identity", SIGN_ED25519, KEY_ED25519, },
610: { "identity", SIGN_ED448, KEY_ED448, },
611: };
612:
613: if (expected_strength != AUTH_RULE_MAX)
614: { /* expecting a key strength token */
615: strength = atoi(token);
616: if (strength)
617: {
618: add(this, expected_strength, (uintptr_t)strength);
619: }
620: expected_strength = AUTH_RULE_MAX;
621: if (strength)
622: {
623: continue;
624: }
625: }
626: if (streq(token, "rsa") || streq(token, "ike:rsa"))
627: {
628: key_token = token;
629: expected_type = KEY_RSA;
630: expected_strength = AUTH_RULE_RSA_STRENGTH;
631: continue;
632: }
633: if (streq(token, "rsa/pss") || streq(token, "ike:rsa/pss"))
634: {
635: key_token = token;
636: expected_type = KEY_RSA;
637: expected_strength = AUTH_RULE_RSA_STRENGTH;
638: continue;
639: }
640: if (streq(token, "ecdsa") || streq(token, "ike:ecdsa"))
641: {
642: key_token = token;
643: expected_type = KEY_ECDSA;
644: expected_strength = AUTH_RULE_ECDSA_STRENGTH;
645: continue;
646: }
647: if (streq(token, "ed25519") || streq(token, "ike:ed25519"))
648: {
649: key_token = token;
650: expected_type = KEY_ED25519;
651: continue;
652: }
653: if (streq(token, "ed448") || streq(token, "ike:ed448"))
654: {
655: key_token = token;
656: expected_type = KEY_ED448;
657: continue;
658: }
659: if (streq(token, "bliss") || streq(token, "ike:bliss"))
660: {
661: key_token = token;
662: expected_type = KEY_BLISS;
663: expected_strength = AUTH_RULE_BLISS_STRENGTH;
664: continue;
665: }
666: if (streq(token, "pubkey") || streq(token, "ike:pubkey"))
667: {
668: key_token = token;
669: expected_type = KEY_ANY;
670: continue;
671: }
672: if (key_token && strpfx(key_token, "ike:") && !ike)
673: {
674: continue;
675: }
676:
677: if (key_token && streq(key_token + strlen(key_token) - 3, "pss"))
678: {
679: params = create_rsa_pss_constraint(token);
680: if (params)
681: {
682: if (strpfx(key_token, "ike:"))
683: {
684: add(this, AUTH_RULE_IKE_SIGNATURE_SCHEME, params);
685: ike_added = TRUE;
686: }
687: else
688: {
689: add(this, AUTH_RULE_SIGNATURE_SCHEME, params);
690: }
691: found = TRUE;
692: }
693: }
694: else
695: {
696: if (rsa_pss)
697: {
698: if (expected_type == KEY_ANY ||
699: expected_type == KEY_RSA)
700: {
701: params = create_rsa_pss_constraint(token);
702: if (params)
703: {
704: if (strpfx(key_token, "ike:"))
705: {
706: add(this, AUTH_RULE_IKE_SIGNATURE_SCHEME, params);
707: ike_added = TRUE;
708: }
709: else
710: {
711: add(this, AUTH_RULE_SIGNATURE_SCHEME, params);
712: }
713: found = TRUE;
714: }
715: }
716: }
717: for (i = 0; i < countof(schemes); i++)
718: {
719: if (streq(schemes[i].name, token))
720: {
721: if (expected_type == KEY_ANY ||
722: expected_type == schemes[i].key)
723: {
724: INIT(params,
725: .scheme = schemes[i].scheme,
726: );
727: if (strpfx(key_token, "ike:"))
728: {
729: add(this, AUTH_RULE_IKE_SIGNATURE_SCHEME, params);
730: ike_added = TRUE;
731: }
732: else
733: {
734: add(this, AUTH_RULE_SIGNATURE_SCHEME, params);
735: }
736: }
737: found = TRUE;
738: }
739: }
740: }
741: if (!found)
742: {
743: DBG1(DBG_CFG, "ignoring invalid auth token: '%s'", token);
744: }
745: }
746: enumerator->destroy(enumerator);
747:
748: /* if no explicit IKE signature constraints were added we add them for all
749: * configured signature constraints */
750: if (ike && !ike_added &&
751: lib->settings->get_bool(lib->settings,
752: "%s.signature_authentication_constraints", TRUE,
753: lib->ns))
754: {
755: enumerator = create_enumerator(this);
756: while (enumerator->enumerate(enumerator, &type, &value))
757: {
758: if (type == AUTH_RULE_SIGNATURE_SCHEME)
759: {
760: add(this, AUTH_RULE_IKE_SIGNATURE_SCHEME,
761: signature_params_clone(value));
762: }
763: }
764: enumerator->destroy(enumerator);
765: }
766: }
767:
768: /**
769: * Check if signature schemes of a specific type are compliant
770: */
771: static bool complies_scheme(private_auth_cfg_t *this, auth_cfg_t *constraints,
772: auth_rule_t type, bool log_error)
773: {
774: enumerator_t *e1, *e2;
775: auth_rule_t t1, t2;
776: signature_params_t *params, *constraint;
777: bool success = TRUE;
778:
779: e2 = create_enumerator(this);
780: while (e2->enumerate(e2, &t2, ¶ms))
781: {
782: if (t2 == type)
783: {
784: success = FALSE;
785: e1 = constraints->create_enumerator(constraints);
786: while (e1->enumerate(e1, &t1, &constraint))
787: {
788: if (t1 == type &&
789: signature_params_comply(constraint, params))
790: {
791: success = TRUE;
792: break;
793: }
794: }
795: e1->destroy(e1);
796: if (!success)
797: {
798: if (log_error)
799: {
800: DBG1(DBG_CFG, "%s signature scheme %N not acceptable",
801: AUTH_RULE_SIGNATURE_SCHEME == type ? "X.509" : "IKE",
802: signature_scheme_names, params->scheme);
803: }
804: break;
805: }
806: }
807: }
808: e2->destroy(e2);
809: return success;
810: }
811:
812: METHOD(auth_cfg_t, complies, bool,
813: private_auth_cfg_t *this, auth_cfg_t *constraints, bool log_error)
814: {
815: enumerator_t *e1, *e2;
816: bool success = TRUE, group_match = FALSE;
817: bool ca_match = FALSE, cert_match = FALSE;
818: identification_t *require_group = NULL, *require_ca = NULL;
819: certificate_t *require_cert = NULL;
820: signature_params_t *ike_scheme = NULL, *scheme = NULL;
821: u_int strength = 0;
822: auth_rule_t t1, t2;
823: char *key_type;
824: void *value;
825:
826: e1 = constraints->create_enumerator(constraints);
827: while (e1->enumerate(e1, &t1, &value))
828: {
829: switch (t1)
830: {
831: case AUTH_RULE_CA_CERT:
832: case AUTH_RULE_IM_CERT:
833: {
834: certificate_t *cert, *ca;
835:
836: /* for CA certs, a match of a single cert is sufficient */
837: ca = (certificate_t*)value;
838: require_ca = ca->get_subject(ca);
839:
840: e2 = create_enumerator(this);
841: while (e2->enumerate(e2, &t2, &cert))
842: {
843: if ((t2 == AUTH_RULE_CA_CERT || t2 == AUTH_RULE_IM_CERT) &&
844: cert->equals(cert, ca))
845: {
846: ca_match = TRUE;
847: }
848: }
849: e2->destroy(e2);
850: break;
851: }
852: case AUTH_RULE_CA_IDENTITY:
853: {
854: certificate_t *cert;
855:
856: require_ca = (identification_t*)value;
857:
858: e2 = create_enumerator(this);
859: while (e2->enumerate(e2, &t2, &cert))
860: {
861: if ((t2 == AUTH_RULE_CA_CERT || t2 == AUTH_RULE_IM_CERT) &&
862: cert->has_subject(cert, require_ca))
863: {
864: ca_match = TRUE;
865: }
866: }
867: e2->destroy(e2);
868: break;
869: }
870: case AUTH_RULE_SUBJECT_CERT:
871: {
872: certificate_t *cert;
873:
874: /* for certs, a match of a single cert is sufficient */
875: require_cert = (certificate_t*)value;
876:
877: e2 = create_enumerator(this);
878: while (e2->enumerate(e2, &t2, &cert))
879: {
880: if (t2 == AUTH_RULE_SUBJECT_CERT &&
881: cert->equals(cert, require_cert))
882: {
883: cert_match = TRUE;
884: }
885: }
886: e2->destroy(e2);
887: break;
888: }
889: case AUTH_RULE_CRL_VALIDATION:
890: case AUTH_RULE_OCSP_VALIDATION:
891: {
892: uintptr_t validated;
893:
894: if (get(this, AUTH_RULE_CERT_VALIDATION_SUSPENDED))
895: { /* skip validation, may happen later */
896: break;
897: }
898:
899: e2 = create_enumerator(this);
900: while (e2->enumerate(e2, &t2, &validated))
901: {
902: if (t2 == t1)
903: {
904: switch ((uintptr_t)value)
905: {
906: case VALIDATION_FAILED:
907: /* no constraint */
908: break;
909: case VALIDATION_SKIPPED:
910: if (validated == VALIDATION_SKIPPED)
911: {
912: break;
913: }
914: /* FALL */
915: case VALIDATION_GOOD:
916: if (validated == VALIDATION_GOOD)
917: {
918: break;
919: }
920: /* FALL */
921: default:
922: success = FALSE;
923: if (log_error)
924: {
925: DBG1(DBG_CFG, "constraint check failed: "
926: "%N is %N, but requires at least %N",
927: auth_rule_names, t1,
928: cert_validation_names, validated,
929: cert_validation_names, (uintptr_t)value);
930: }
931: break;
932: }
933: }
934: }
935: e2->destroy(e2);
936: break;
937: }
938: case AUTH_RULE_IDENTITY:
939: case AUTH_RULE_EAP_IDENTITY:
940: case AUTH_RULE_AAA_IDENTITY:
941: case AUTH_RULE_XAUTH_IDENTITY:
942: {
943: identification_t *id1, *id2;
944:
945: id1 = (identification_t*)value;
946: id2 = get(this, t1);
947: if (!id2 || !id2->matches(id2, id1))
948: {
949: if (t1 == AUTH_RULE_IDENTITY &&
950: constraints->get(constraints, AUTH_RULE_IDENTITY_LOOSE))
951: { /* also verify identity against subjectAltNames */
952: certificate_t *cert;
953:
954: cert = get(this, AUTH_RULE_SUBJECT_CERT);
955: if (cert && cert->has_subject(cert, id1))
956: {
957: break;
958: }
959: }
960: success = FALSE;
961: if (log_error)
962: {
963: DBG1(DBG_CFG, "constraint check failed: %sidentity '%Y'"
964: " required ", t1 == AUTH_RULE_IDENTITY ? "" :
965: "EAP ", id1);
966: }
967: }
968: break;
969: }
970: case AUTH_RULE_AUTH_CLASS:
971: {
972: if ((uintptr_t)value != AUTH_CLASS_ANY &&
973: (uintptr_t)value != (uintptr_t)get(this, t1))
974: {
975: success = FALSE;
976: if (log_error)
977: {
978: DBG1(DBG_CFG, "constraint requires %N authentication, "
979: "but %N was used", auth_class_names, (uintptr_t)value,
980: auth_class_names, (uintptr_t)get(this, t1));
981: }
982: }
983: break;
984: }
985: case AUTH_RULE_EAP_TYPE:
986: {
987: if ((uintptr_t)value != (uintptr_t)get(this, t1) &&
988: (uintptr_t)value != EAP_DYNAMIC &&
989: (uintptr_t)value != EAP_RADIUS)
990: {
991: success = FALSE;
992: if (log_error)
993: {
994: DBG1(DBG_CFG, "constraint requires %N, "
995: "but %N was used", eap_type_names, (uintptr_t)value,
996: eap_type_names, (uintptr_t)get(this, t1));
997: }
998: }
999: break;
1000: }
1001: case AUTH_RULE_EAP_VENDOR:
1002: {
1003: if ((uintptr_t)value != (uintptr_t)get(this, t1))
1004: {
1005: success = FALSE;
1006: if (log_error)
1007: {
1008: DBG1(DBG_CFG, "constraint requires EAP vendor %d, "
1009: "but %d was used", (uintptr_t)value,
1010: (uintptr_t)get(this, t1));
1011: }
1012: }
1013: break;
1014: }
1015: case AUTH_RULE_GROUP:
1016: {
1017: identification_t *group;
1018:
1019: /* for groups, a match of a single group is sufficient */
1020: require_group = (identification_t*)value;
1021: e2 = create_enumerator(this);
1022: while (e2->enumerate(e2, &t2, &group))
1023: {
1024: if (t2 == AUTH_RULE_GROUP &&
1025: group->matches(group, require_group))
1026: {
1027: group_match = TRUE;
1028: }
1029: }
1030: e2->destroy(e2);
1031: break;
1032: }
1033: case AUTH_RULE_RSA_STRENGTH:
1034: case AUTH_RULE_ECDSA_STRENGTH:
1035: case AUTH_RULE_BLISS_STRENGTH:
1036: {
1037: strength = (uintptr_t)value;
1038: break;
1039: }
1040: case AUTH_RULE_IKE_SIGNATURE_SCHEME:
1041: {
1042: ike_scheme = value;
1043: break;
1044: }
1045: case AUTH_RULE_SIGNATURE_SCHEME:
1046: {
1047: scheme = value;
1048: break;
1049: }
1050: case AUTH_RULE_CERT_POLICY:
1051: {
1052: char *oid1, *oid2;
1053:
1054: oid1 = (char*)value;
1055: success = FALSE;
1056: e2 = create_enumerator(this);
1057: while (e2->enumerate(e2, &t2, &oid2))
1058: {
1059: if (t2 == t1 && streq(oid1, oid2))
1060: {
1061: success = TRUE;
1062: break;
1063: }
1064: }
1065: e2->destroy(e2);
1066: if (!success && log_error)
1067: {
1068: DBG1(DBG_CFG, "constraint requires cert policy %s", oid1);
1069: }
1070: break;
1071: }
1072: case AUTH_RULE_IDENTITY_LOOSE:
1073: /* just an indication when verifying AUTH_RULE_IDENTITY */
1074: case AUTH_RULE_XAUTH_BACKEND:
1075: /* not enforced, just a hint for local authentication */
1076: case AUTH_RULE_CERT_VALIDATION_SUSPENDED:
1077: /* not a constraint */
1078: case AUTH_HELPER_IM_CERT:
1079: case AUTH_HELPER_SUBJECT_CERT:
1080: case AUTH_HELPER_IM_HASH_URL:
1081: case AUTH_HELPER_SUBJECT_HASH_URL:
1082: case AUTH_HELPER_REVOCATION_CERT:
1083: case AUTH_HELPER_AC_CERT:
1084: case AUTH_RULE_MAX:
1085: /* skip helpers */
1086: continue;
1087: }
1088: if (!success)
1089: {
1090: break;
1091: }
1092: }
1093: e1->destroy(e1);
1094:
1095: /* Check if we have a matching constraint (or none at all) for used
1096: * signature schemes. */
1097: if (success && scheme)
1098: {
1099: success = complies_scheme(this, constraints,
1100: AUTH_RULE_SIGNATURE_SCHEME, log_error);
1101: }
1102: if (success && ike_scheme)
1103: {
1104: success = complies_scheme(this, constraints,
1105: AUTH_RULE_IKE_SIGNATURE_SCHEME, log_error);
1106: }
1107:
1108: /* Check if we have a matching constraint (or none at all) for used
1109: * public key strength */
1110: if (success && strength)
1111: {
1112: e2 = create_enumerator(this);
1113: while (e2->enumerate(e2, &t2, &strength))
1114: {
1115: switch (t2)
1116: {
1117: default:
1118: continue;
1119: case AUTH_RULE_RSA_STRENGTH:
1120: key_type = "RSA";
1121: break;
1122: case AUTH_RULE_ECDSA_STRENGTH:
1123: key_type = "ECDSA";
1124: break;
1125: case AUTH_RULE_BLISS_STRENGTH:
1126: key_type = "BLISS";
1127: break;
1128: }
1129: success = FALSE;
1130: e1 = constraints->create_enumerator(constraints);
1131: while (e1->enumerate(e1, &t1, &value))
1132: {
1133: if (t1 == t2 && (uintptr_t)value <= strength)
1134: {
1135: success = TRUE;
1136: break;
1137: }
1138: }
1139: e1->destroy(e1);
1140: if (!success)
1141: {
1142: if (log_error)
1143: {
1144: DBG1(DBG_CFG, "%s-%d signatures not acceptable",
1145: key_type, strength);
1146: }
1147: break;
1148: }
1149: }
1150: e2->destroy(e2);
1151: }
1152:
1153: if (require_group && !group_match)
1154: {
1155: if (log_error)
1156: {
1157: DBG1(DBG_CFG, "constraint check failed: group membership to "
1158: "'%Y' required", require_group);
1159: }
1160: return FALSE;
1161: }
1162: if (require_ca && !ca_match)
1163: {
1164: if (log_error)
1165: {
1166: DBG1(DBG_CFG, "constraint check failed: peer not "
1167: "authenticated by CA '%Y'", require_ca);
1168: }
1169: return FALSE;
1170: }
1171: if (require_cert && !cert_match)
1172: {
1173: if (log_error)
1174: {
1175: DBG1(DBG_CFG, "constraint check failed: peer not "
1176: "authenticated with peer cert '%Y'",
1177: require_cert->get_subject(require_cert));
1178: }
1179: return FALSE;
1180: }
1181: return success;
1182: }
1183:
1184: /**
1185: * Implementation of auth_cfg_t.merge.
1186: */
1187: static void merge(private_auth_cfg_t *this, private_auth_cfg_t *other, bool copy)
1188: {
1189: if (!other)
1190: { /* nothing to merge */
1191: return;
1192: }
1193: if (copy)
1194: {
1195: enumerator_t *enumerator;
1196: auth_rule_t type;
1197: void *value;
1198:
1199: /* this enumerator skips duplicates for rules we expect only once */
1200: enumerator = create_enumerator(other);
1201: while (enumerator->enumerate(enumerator, &type, &value))
1202: {
1203: switch (type)
1204: {
1205: case AUTH_RULE_CA_CERT:
1206: case AUTH_RULE_IM_CERT:
1207: case AUTH_RULE_SUBJECT_CERT:
1208: case AUTH_HELPER_IM_CERT:
1209: case AUTH_HELPER_SUBJECT_CERT:
1210: case AUTH_HELPER_REVOCATION_CERT:
1211: case AUTH_HELPER_AC_CERT:
1212: {
1213: certificate_t *cert = (certificate_t*)value;
1214:
1215: add(this, type, cert->get_ref(cert));
1216: break;
1217: }
1218: case AUTH_RULE_IDENTITY_LOOSE:
1219: case AUTH_RULE_CRL_VALIDATION:
1220: case AUTH_RULE_OCSP_VALIDATION:
1221: case AUTH_RULE_AUTH_CLASS:
1222: case AUTH_RULE_EAP_TYPE:
1223: case AUTH_RULE_EAP_VENDOR:
1224: case AUTH_RULE_RSA_STRENGTH:
1225: case AUTH_RULE_ECDSA_STRENGTH:
1226: case AUTH_RULE_BLISS_STRENGTH:
1227: case AUTH_RULE_CERT_VALIDATION_SUSPENDED:
1228: {
1229: add(this, type, (uintptr_t)value);
1230: break;
1231: }
1232: case AUTH_RULE_IDENTITY:
1233: case AUTH_RULE_CA_IDENTITY:
1234: case AUTH_RULE_EAP_IDENTITY:
1235: case AUTH_RULE_AAA_IDENTITY:
1236: case AUTH_RULE_GROUP:
1237: case AUTH_RULE_XAUTH_IDENTITY:
1238: {
1239: identification_t *id = (identification_t*)value;
1240:
1241: add(this, type, id->clone(id));
1242: break;
1243: }
1244: case AUTH_RULE_SIGNATURE_SCHEME:
1245: case AUTH_RULE_IKE_SIGNATURE_SCHEME:
1246: {
1247: add(this, type, signature_params_clone(value));
1248: break;
1249: }
1250: case AUTH_RULE_XAUTH_BACKEND:
1251: case AUTH_RULE_CERT_POLICY:
1252: case AUTH_HELPER_IM_HASH_URL:
1253: case AUTH_HELPER_SUBJECT_HASH_URL:
1254: {
1255: add(this, type, strdup((char*)value));
1256: break;
1257: }
1258: case AUTH_RULE_MAX:
1259: break;
1260: }
1261: }
1262: enumerator->destroy(enumerator);
1263: }
1264: else
1265: {
1266: entry_t entry;
1267:
1268: while (array_remove(other->entries, ARRAY_TAIL, &entry))
1269: { /* keep order but prefer new values (esp. for single valued ones) */
1270: array_insert(this->entries, ARRAY_HEAD, &entry);
1271: }
1272: array_compress(other->entries);
1273: }
1274: }
1275:
1276: /**
1277: * Compare two auth_cfg_t objects for equality.
1278: */
1279: static bool auth_cfg_equals(private_auth_cfg_t *this, private_auth_cfg_t *other)
1280: {
1281: enumerator_t *e1, *e2;
1282: entry_t *i1, *i2;
1283: bool equal = TRUE, found;
1284:
1285: /* the rule count does not have to be equal for the two, as we only compare
1286: * the first value found for some rules */
1287: e1 = array_create_enumerator(this->entries);
1288: while (e1->enumerate(e1, &i1))
1289: {
1290: found = FALSE;
1291:
1292: e2 = array_create_enumerator(other->entries);
1293: while (e2->enumerate(e2, &i2))
1294: {
1295: if (entry_equals(i1, i2))
1296: {
1297: found = TRUE;
1298: break;
1299: }
1300: else if (i1->type == i2->type && !is_multi_value_rule(i1->type))
1301: { /* we continue our search, only for multi valued rules */
1302: break;
1303: }
1304: }
1305: e2->destroy(e2);
1306: if (!found)
1307: {
1308: equal = FALSE;
1309: break;
1310: }
1311: }
1312: e1->destroy(e1);
1313: return equal;
1314: }
1315:
1316: /**
1317: * Implementation of auth_cfg_t.equals.
1318: */
1319: static bool equals(private_auth_cfg_t *this, private_auth_cfg_t *other)
1320: {
1321: if (auth_cfg_equals(this, other))
1322: {
1323: /* as 'other' might contain entries that 'this' doesn't we also check
1324: * the other way around */
1325: return auth_cfg_equals(other, this);
1326: }
1327: return FALSE;
1328: }
1329:
1330: METHOD(auth_cfg_t, purge, void,
1331: private_auth_cfg_t *this, bool keep_ca)
1332: {
1333: enumerator_t *enumerator;
1334: entry_t *entry;
1335:
1336: enumerator = array_create_enumerator(this->entries);
1337: while (enumerator->enumerate(enumerator, &entry))
1338: {
1339: if (!keep_ca || entry->type != AUTH_RULE_CA_CERT)
1340: {
1341: destroy_entry_value(entry);
1342: array_remove_at(this->entries, enumerator);
1343: }
1344: }
1345: enumerator->destroy(enumerator);
1346:
1347: array_compress(this->entries);
1348: }
1349:
1350: METHOD(auth_cfg_t, clone_, auth_cfg_t*,
1351: private_auth_cfg_t *this)
1352: {
1353: enumerator_t *enumerator;
1354: auth_cfg_t *clone;
1355: auth_rule_t type;
1356: void *value;
1357:
1358: clone = auth_cfg_create();
1359: /* this enumerator skips duplicates for rules we expect only once */
1360: enumerator = create_enumerator(this);
1361: while (enumerator->enumerate(enumerator, &type, &value))
1362: {
1363: switch (type)
1364: {
1365: case AUTH_RULE_IDENTITY:
1366: case AUTH_RULE_CA_IDENTITY:
1367: case AUTH_RULE_EAP_IDENTITY:
1368: case AUTH_RULE_AAA_IDENTITY:
1369: case AUTH_RULE_GROUP:
1370: case AUTH_RULE_XAUTH_IDENTITY:
1371: {
1372: identification_t *id = (identification_t*)value;
1373: clone->add(clone, type, id->clone(id));
1374: break;
1375: }
1376: case AUTH_RULE_CA_CERT:
1377: case AUTH_RULE_IM_CERT:
1378: case AUTH_RULE_SUBJECT_CERT:
1379: case AUTH_HELPER_IM_CERT:
1380: case AUTH_HELPER_SUBJECT_CERT:
1381: case AUTH_HELPER_REVOCATION_CERT:
1382: case AUTH_HELPER_AC_CERT:
1383: {
1384: certificate_t *cert = (certificate_t*)value;
1385: clone->add(clone, type, cert->get_ref(cert));
1386: break;
1387: }
1388: case AUTH_RULE_XAUTH_BACKEND:
1389: case AUTH_RULE_CERT_POLICY:
1390: case AUTH_HELPER_IM_HASH_URL:
1391: case AUTH_HELPER_SUBJECT_HASH_URL:
1392: {
1393: clone->add(clone, type, strdup(value));
1394: break;
1395: }
1396: case AUTH_RULE_IDENTITY_LOOSE:
1397: case AUTH_RULE_AUTH_CLASS:
1398: case AUTH_RULE_EAP_TYPE:
1399: case AUTH_RULE_EAP_VENDOR:
1400: case AUTH_RULE_CRL_VALIDATION:
1401: case AUTH_RULE_OCSP_VALIDATION:
1402: case AUTH_RULE_RSA_STRENGTH:
1403: case AUTH_RULE_ECDSA_STRENGTH:
1404: case AUTH_RULE_BLISS_STRENGTH:
1405: case AUTH_RULE_CERT_VALIDATION_SUSPENDED:
1406: clone->add(clone, type, (uintptr_t)value);
1407: break;
1408: case AUTH_RULE_SIGNATURE_SCHEME:
1409: case AUTH_RULE_IKE_SIGNATURE_SCHEME:
1410: {
1411: clone->add(clone, type, signature_params_clone(value));
1412: break;
1413: }
1414: case AUTH_RULE_MAX:
1415: break;
1416: }
1417: }
1418: enumerator->destroy(enumerator);
1419: return clone;
1420: }
1421:
1422: METHOD(auth_cfg_t, destroy, void,
1423: private_auth_cfg_t *this)
1424: {
1425: purge(this, FALSE);
1426: array_destroy(this->entries);
1427: free(this);
1428: }
1429:
1430: /*
1431: * see header file
1432: */
1433: auth_cfg_t *auth_cfg_create()
1434: {
1435: private_auth_cfg_t *this;
1436:
1437: INIT(this,
1438: .public = {
1439: .add = (void(*)(auth_cfg_t*, auth_rule_t type, ...))add,
1440: .add_pubkey_constraints = _add_pubkey_constraints,
1441: .get = _get,
1442: .create_enumerator = _create_enumerator,
1443: .replace = (void(*)(auth_cfg_t*,enumerator_t*,auth_rule_t,...))replace,
1444: .complies = _complies,
1445: .merge = (void(*)(auth_cfg_t*,auth_cfg_t*,bool))merge,
1446: .purge = _purge,
1447: .equals = (bool(*)(auth_cfg_t*,auth_cfg_t*))equals,
1448: .clone = _clone_,
1449: .destroy = _destroy,
1450: },
1451: .entries = array_create(sizeof(entry_t), 0),
1452: );
1453:
1454: return &this->public;
1455: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>