Annotation of embedaddon/strongswan/src/libstrongswan/credentials/credential_factory.c, revision 1.1
1.1 ! misho 1: /*
! 2: * Copyright (C) 2008 Martin Willi
! 3: * HSR Hochschule fuer Technik Rapperswil
! 4: *
! 5: * This program is free software; you can redistribute it and/or modify it
! 6: * under the terms of the GNU General Public License as published by the
! 7: * Free Software Foundation; either version 2 of the License, or (at your
! 8: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
! 9: *
! 10: * This program is distributed in the hope that it will be useful, but
! 11: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
! 12: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
! 13: * for more details.
! 14: */
! 15:
! 16: #include <stdint.h>
! 17:
! 18: #include "credential_factory.h"
! 19:
! 20: #include <utils/debug.h>
! 21: #include <collections/linked_list.h>
! 22: #include <threading/thread_value.h>
! 23: #include <threading/rwlock.h>
! 24: #include <credentials/certificates/x509.h>
! 25: #include <credentials/containers/container.h>
! 26:
! 27: ENUM(credential_type_names, CRED_PRIVATE_KEY, CRED_CONTAINER,
! 28: "CRED_PRIVATE_KEY",
! 29: "CRED_PUBLIC_KEY",
! 30: "CRED_CERTIFICATE",
! 31: "CRED_CONTAINER",
! 32: );
! 33:
! 34: typedef struct private_credential_factory_t private_credential_factory_t;
! 35:
! 36: /**
! 37: * private data of credential_factory
! 38: */
! 39: struct private_credential_factory_t {
! 40:
! 41: /**
! 42: * public functions
! 43: */
! 44: credential_factory_t public;
! 45:
! 46: /**
! 47: * list with entry_t
! 48: */
! 49: linked_list_t *constructors;
! 50:
! 51: /**
! 52: * Thread specific recursiveness counter
! 53: */
! 54: thread_value_t *recursive;
! 55:
! 56: /**
! 57: * lock access to builders
! 58: */
! 59: rwlock_t *lock;
! 60: };
! 61:
! 62: typedef struct entry_t entry_t;
! 63: struct entry_t {
! 64: /** kind of credential builder */
! 65: credential_type_t type;
! 66: /** subtype of credential, e.g. certificate_type_t */
! 67: int subtype;
! 68: /** registered with final flag? */
! 69: bool final;
! 70: /** builder function */
! 71: builder_function_t constructor;
! 72: };
! 73:
! 74: METHOD(credential_factory_t, add_builder, void,
! 75: private_credential_factory_t *this, credential_type_t type, int subtype,
! 76: bool final, builder_function_t constructor)
! 77: {
! 78: entry_t *entry = malloc_thing(entry_t);
! 79:
! 80: entry->type = type;
! 81: entry->subtype = subtype;
! 82: entry->final = final;
! 83: entry->constructor = constructor;
! 84: this->lock->write_lock(this->lock);
! 85: this->constructors->insert_last(this->constructors, entry);
! 86: this->lock->unlock(this->lock);
! 87: }
! 88:
! 89: METHOD(credential_factory_t, remove_builder, void,
! 90: private_credential_factory_t *this, builder_function_t constructor)
! 91: {
! 92: enumerator_t *enumerator;
! 93: entry_t *entry;
! 94:
! 95: this->lock->write_lock(this->lock);
! 96: enumerator = this->constructors->create_enumerator(this->constructors);
! 97: while (enumerator->enumerate(enumerator, &entry))
! 98: {
! 99: if (entry->constructor == constructor)
! 100: {
! 101: this->constructors->remove_at(this->constructors, enumerator);
! 102: free(entry);
! 103: }
! 104: }
! 105: enumerator->destroy(enumerator);
! 106: this->lock->unlock(this->lock);
! 107: }
! 108:
! 109: METHOD(credential_factory_t, create, void*,
! 110: private_credential_factory_t *this, credential_type_t type, int subtype, ...)
! 111: {
! 112: enumerator_t *enumerator;
! 113: entry_t *entry;
! 114: va_list args;
! 115: void *construct = NULL;
! 116: int failures = 0;
! 117: uintptr_t level;
! 118:
! 119: level = (uintptr_t)this->recursive->get(this->recursive);
! 120: this->recursive->set(this->recursive, (void*)level + 1);
! 121:
! 122: this->lock->read_lock(this->lock);
! 123: enumerator = this->constructors->create_enumerator(this->constructors);
! 124: while (enumerator->enumerate(enumerator, &entry))
! 125: {
! 126: if (entry->type == type && entry->subtype == subtype)
! 127: {
! 128: va_start(args, subtype);
! 129: construct = entry->constructor(subtype, args);
! 130: va_end(args);
! 131: if (construct)
! 132: {
! 133: break;
! 134: }
! 135: failures++;
! 136: }
! 137: }
! 138: enumerator->destroy(enumerator);
! 139: this->lock->unlock(this->lock);
! 140:
! 141: if (!construct && !level)
! 142: {
! 143: enum_name_t *names;
! 144:
! 145: switch (type)
! 146: {
! 147: case CRED_CERTIFICATE:
! 148: names = certificate_type_names;
! 149: break;
! 150: case CRED_CONTAINER:
! 151: names = container_type_names;
! 152: break;
! 153: case CRED_PRIVATE_KEY:
! 154: case CRED_PUBLIC_KEY:
! 155: default:
! 156: names = key_type_names;
! 157: break;
! 158: }
! 159: DBG1(DBG_LIB, "building %N - %N failed, tried %d builders",
! 160: credential_type_names, type, names, subtype, failures);
! 161: }
! 162: this->recursive->set(this->recursive, (void*)level);
! 163: return construct;
! 164: }
! 165:
! 166: CALLBACK(builder_filter, bool,
! 167: void *null, enumerator_t *orig, va_list args)
! 168: {
! 169: entry_t *entry;
! 170: credential_type_t *type;
! 171: int *subtype;
! 172:
! 173: VA_ARGS_VGET(args, type, subtype);
! 174:
! 175: while (orig->enumerate(orig, &entry))
! 176: {
! 177: if (entry->final)
! 178: {
! 179: *type = entry->type;
! 180: *subtype = entry->subtype;
! 181: return TRUE;
! 182: }
! 183: }
! 184: return FALSE;
! 185: }
! 186:
! 187: METHOD(credential_factory_t, create_builder_enumerator, enumerator_t*,
! 188: private_credential_factory_t *this)
! 189: {
! 190: this->lock->read_lock(this->lock);
! 191: return enumerator_create_filter(
! 192: this->constructors->create_enumerator(this->constructors),
! 193: builder_filter, this->lock, (void*)this->lock->unlock);
! 194: }
! 195:
! 196: METHOD(credential_factory_t, destroy, void,
! 197: private_credential_factory_t *this)
! 198: {
! 199: this->constructors->destroy_function(this->constructors, free);
! 200: this->recursive->destroy(this->recursive);
! 201: this->lock->destroy(this->lock);
! 202: free(this);
! 203: }
! 204:
! 205: /*
! 206: * see header file
! 207: */
! 208: credential_factory_t *credential_factory_create()
! 209: {
! 210: private_credential_factory_t *this;
! 211:
! 212: INIT(this,
! 213: .public = {
! 214: .create = _create,
! 215: .create_builder_enumerator = _create_builder_enumerator,
! 216: .add_builder = _add_builder,
! 217: .remove_builder = _remove_builder,
! 218: .destroy = _destroy,
! 219: },
! 220: .constructors = linked_list_create(),
! 221: .recursive = thread_value_create(NULL),
! 222: .lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
! 223: );
! 224:
! 225: return &this->public;
! 226: }
! 227:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>