Annotation of embedaddon/strongswan/src/libstrongswan/credentials/sets/auth_cfg_wrapper.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (C) 2008-2009 Martin Willi
                      3:  * Copyright (C) 2008 Tobias Brunner
                      4:  * HSR Hochschule fuer Technik Rapperswil
                      5:  *
                      6:  * This program is free software; you can redistribute it and/or modify it
                      7:  * under the terms of the GNU General Public License as published by the
                      8:  * Free Software Foundation; either version 2 of the License, or (at your
                      9:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
                     10:  *
                     11:  * This program is distributed in the hope that it will be useful, but
                     12:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
                     13:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
                     14:  * for more details.
                     15:  */
                     16: 
                     17: #include <library.h>
                     18: #include <utils/debug.h>
                     19: 
                     20: #include "auth_cfg_wrapper.h"
                     21: 
                     22: typedef struct private_auth_cfg_wrapper_t private_auth_cfg_wrapper_t;
                     23: 
                     24: /**
                     25:  * private data of auth_cfg_wrapper
                     26:  */
                     27: struct private_auth_cfg_wrapper_t {
                     28: 
                     29:        /**
                     30:         * public functions
                     31:         */
                     32:        auth_cfg_wrapper_t public;
                     33: 
                     34:        /**
                     35:         * wrapped auth info
                     36:         */
                     37:        auth_cfg_t *auth;
                     38: };
                     39: 
                     40: /**
                     41:  * enumerator for auth_cfg_wrapper_t.create_cert_enumerator()
                     42:  */
                     43: typedef struct {
                     44:        /** implements enumerator_t */
                     45:        enumerator_t public;
                     46:        /** inner enumerator from auth_cfg */
                     47:        enumerator_t *inner;
                     48:        /** wrapped auth round */
                     49:        auth_cfg_t *auth;
                     50:        /** enumerated cert type */
                     51:        certificate_type_t cert;
                     52:        /** enumerated key type */
                     53:        key_type_t key;
                     54:        /** enumerated id */
                     55:        identification_t *id;
                     56: } wrapper_enumerator_t;
                     57: 
                     58: /**
                     59:  * Tries to fetch a certificate that was supplied as "Hash and URL"
                     60:  * (replaces rule type and value in place).
                     61:  */
                     62: static bool fetch_cert(wrapper_enumerator_t *enumerator,
                     63:                                           auth_rule_t *rule, void **value)
                     64: {
                     65:        char *url = (char*)*value;
                     66:        if (!url)
                     67:        {
                     68:                /* fetching the certificate previously failed */
                     69:                return FALSE;
                     70:        }
                     71: 
                     72:        chunk_t data;
                     73:        certificate_t *cert;
                     74: 
                     75:        DBG1(DBG_CFG, "  fetching certificate from '%s' ...", url);
                     76:        if (lib->fetcher->fetch(lib->fetcher, url, &data, FETCH_END) != SUCCESS)
                     77:        {
                     78:                DBG1(DBG_CFG, "  fetching certificate failed");
                     79:                /* we set the item to NULL, so we can skip it */
                     80:                enumerator->auth->replace(enumerator->auth, enumerator->inner,
                     81:                                                                  *rule, NULL);
                     82:                return FALSE;
                     83:        }
                     84: 
                     85:        cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
                     86:                                                          BUILD_BLOB_ASN1_DER, data, BUILD_END);
                     87:        free(data.ptr);
                     88: 
                     89:        if (!cert)
                     90:        {
                     91:                DBG1(DBG_CFG, "  parsing fetched certificate failed");
                     92:                /* we set the item to NULL, so we can skip it */
                     93:                enumerator->auth->replace(enumerator->auth, enumerator->inner,
                     94:                                                                  *rule, NULL);
                     95:                return FALSE;
                     96:        }
                     97: 
                     98:        DBG1(DBG_CFG, "  fetched certificate \"%Y\"", cert->get_subject(cert));
                     99:        lib->credmgr->cache_cert(lib->credmgr, cert);
                    100: 
                    101:        if (*rule == AUTH_HELPER_IM_HASH_URL)
                    102:        {
                    103:                *rule = AUTH_HELPER_IM_CERT;
                    104:        }
                    105:        else
                    106:        {
                    107:                *rule = AUTH_HELPER_SUBJECT_CERT;
                    108:        }
                    109:        *value = cert;
                    110:        enumerator->auth->replace(enumerator->auth, enumerator->inner,
                    111:                                                          *rule, cert);
                    112:        return TRUE;
                    113: }
                    114: 
                    115: METHOD(enumerator_t, enumerate, bool,
                    116:        wrapper_enumerator_t *this, va_list args)
                    117: {
                    118:        auth_rule_t rule;
                    119:        certificate_t *current, **cert;
                    120:        public_key_t *public;
                    121: 
                    122:        VA_ARGS_VGET(args, cert);
                    123: 
                    124:        while (this->inner->enumerate(this->inner, &rule, &current))
                    125:        {
                    126:                if (rule == AUTH_HELPER_IM_HASH_URL ||
                    127:                        rule == AUTH_HELPER_SUBJECT_HASH_URL)
                    128:                {       /* on-demand fetching of hash and url certificates */
                    129:                        if (!fetch_cert(this, &rule, (void**)&current))
                    130:                        {
                    131:                                continue;
                    132:                        }
                    133:                }
                    134:                else if (rule != AUTH_HELPER_SUBJECT_CERT &&
                    135:                                 rule != AUTH_HELPER_IM_CERT &&
                    136:                                 rule != AUTH_HELPER_REVOCATION_CERT &&
                    137:                                 rule != AUTH_HELPER_AC_CERT)
                    138:                {       /* handle only HELPER certificates */
                    139:                        continue;
                    140:                }
                    141:                if (this->cert != CERT_ANY && this->cert != current->get_type(current))
                    142:                {       /* CERT type requested, but does not match */
                    143:                        continue;
                    144:                }
                    145:                public = current->get_public_key(current);
                    146:                if (this->key != KEY_ANY && !public)
                    147:                {       /* key type requested, but no public key */
                    148:                        DESTROY_IF(public);
                    149:                        continue;
                    150:                }
                    151:                if (this->key != KEY_ANY && public && this->key != public->get_type(public))
                    152:                {       /* key type requested, but public key has another type */
                    153:                        DESTROY_IF(public);
                    154:                        continue;
                    155:                }
                    156:                DESTROY_IF(public);
                    157:                if (this->id && !current->has_subject(current, this->id))
                    158:                {       /* subject requested, but does not match */
                    159:                        continue;
                    160:                }
                    161:                *cert = current;
                    162:                return TRUE;
                    163:        }
                    164:        return FALSE;
                    165: }
                    166: 
                    167: METHOD(enumerator_t, wrapper_enumerator_destroy, void,
                    168:        wrapper_enumerator_t *this)
                    169: {
                    170:        this->inner->destroy(this->inner);
                    171:        free(this);
                    172: }
                    173: 
                    174: METHOD(credential_set_t, create_enumerator, enumerator_t*,
                    175:        private_auth_cfg_wrapper_t *this, certificate_type_t cert, key_type_t key,
                    176:        identification_t *id, bool trusted)
                    177: {
                    178:        wrapper_enumerator_t *enumerator;
                    179: 
                    180:        if (trusted)
                    181:        {
                    182:                return NULL;
                    183:        }
                    184:        INIT(enumerator,
                    185:                .public = {
                    186:                        .enumerate = enumerator_enumerate_default,
                    187:                        .venumerate = _enumerate,
                    188:                        .destroy = _wrapper_enumerator_destroy,
                    189:                },
                    190:                .auth = this->auth,
                    191:                .cert = cert,
                    192:                .key = key,
                    193:                .id = id,
                    194:                .inner = this->auth->create_enumerator(this->auth),
                    195:        );
                    196:        return &enumerator->public;
                    197: }
                    198: 
                    199: METHOD(auth_cfg_wrapper_t, destroy, void,
                    200:        private_auth_cfg_wrapper_t *this)
                    201: {
                    202:        free(this);
                    203: }
                    204: 
                    205: /*
                    206:  * see header file
                    207:  */
                    208: auth_cfg_wrapper_t *auth_cfg_wrapper_create(auth_cfg_t *auth)
                    209: {
                    210:        private_auth_cfg_wrapper_t *this;
                    211: 
                    212:        INIT(this,
                    213:                .public = {
                    214:                        .set = {
                    215:                                .create_cert_enumerator = _create_enumerator,
                    216:                                .create_shared_enumerator = (void*)return_null,
                    217:                                .create_cdp_enumerator = (void*)return_null,
                    218:                                .cache_cert = (void*)nop,
                    219:                        },
                    220:                        .destroy = _destroy,
                    221:                },
                    222:                .auth = auth,
                    223:        );
                    224: 
                    225:        return &this->public;
                    226: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>