Return to auth_cfg_wrapper.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libstrongswan / credentials / sets |
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, ¤t)) 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**)¤t)) 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: }