Annotation of embedaddon/strongswan/src/libstrongswan/credentials/auth_cfg.c, revision 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, &current_type, &current_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, &params))
        !           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>