2 * Copyright (C) 2008 Martin Willi
4 * Copyright (C) secunet Security Networks AG
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>.
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
19 #include "credential_factory.h"
21 #include <utils/debug.h>
22 #include <collections/linked_list.h>
23 #include <threading/thread_value.h>
24 #include <threading/rwlock.h>
25 #include <credentials/certificates/x509.h>
26 #include <credentials/containers/container.h>
28 ENUM(credential_type_names
, CRED_PRIVATE_KEY
, CRED_CONTAINER
,
35 typedef struct private_credential_factory_t private_credential_factory_t
;
38 * private data of credential_factory
40 struct private_credential_factory_t
{
45 credential_factory_t
public;
50 linked_list_t
*constructors
;
53 * Thread specific recursiveness counter
55 thread_value_t
*recursive
;
58 * lock access to builders
63 typedef struct entry_t entry_t
;
65 /** kind of credential builder */
66 credential_type_t type
;
67 /** subtype of credential, e.g. certificate_type_t */
69 /** registered with final flag? */
71 /** plugin that registered this algorithm */
72 const char *plugin_name
;
73 /** builder function */
74 builder_function_t constructor
;
77 METHOD(credential_factory_t
, add_builder
, void,
78 private_credential_factory_t
*this, credential_type_t type
, int subtype
,
79 bool final
, const char *plugin_name
, builder_function_t constructor
)
81 entry_t
*entry
= malloc_thing(entry_t
);
84 entry
->subtype
= subtype
;
86 entry
->plugin_name
= plugin_name
;
87 entry
->constructor
= constructor
;
88 this->lock
->write_lock(this->lock
);
89 this->constructors
->insert_last(this->constructors
, entry
);
90 this->lock
->unlock(this->lock
);
93 METHOD(credential_factory_t
, remove_builder
, void,
94 private_credential_factory_t
*this, builder_function_t constructor
)
96 enumerator_t
*enumerator
;
99 this->lock
->write_lock(this->lock
);
100 enumerator
= this->constructors
->create_enumerator(this->constructors
);
101 while (enumerator
->enumerate(enumerator
, &entry
))
103 if (entry
->constructor
== constructor
)
105 this->constructors
->remove_at(this->constructors
, enumerator
);
109 enumerator
->destroy(enumerator
);
110 this->lock
->unlock(this->lock
);
113 METHOD(credential_factory_t
, create
, void*,
114 private_credential_factory_t
*this, credential_type_t type
, int subtype
, ...)
116 enumerator_t
*enumerator
;
119 void *construct
= NULL
;
126 case CRED_CERTIFICATE
:
127 names
= certificate_type_names
;
130 names
= container_type_names
;
132 case CRED_PRIVATE_KEY
:
133 case CRED_PUBLIC_KEY
:
135 names
= key_type_names
;
139 level
= (uintptr_t)this->recursive
->get(this->recursive
);
140 this->recursive
->set(this->recursive
, (void*)level
+ 1);
142 this->lock
->read_lock(this->lock
);
143 enumerator
= this->constructors
->create_enumerator(this->constructors
);
144 while (enumerator
->enumerate(enumerator
, &entry
))
146 if (entry
->type
== type
&& entry
->subtype
== subtype
)
148 DBG2(DBG_LIB
, "builder L%d %N - %N of plugin '%s'",
149 (int)level
, credential_type_names
, type
, names
, subtype
,
151 va_start(args
, subtype
);
152 construct
= entry
->constructor(subtype
, args
);
161 enumerator
->destroy(enumerator
);
162 this->lock
->unlock(this->lock
);
164 if (!construct
&& !level
)
166 DBG1(DBG_LIB
, "building %N - %N failed, tried %d builders",
167 credential_type_names
, type
, names
, subtype
, failures
);
169 this->recursive
->set(this->recursive
, (void*)level
);
173 CALLBACK(builder_filter
, bool,
174 void *null
, enumerator_t
*orig
, va_list args
)
177 credential_type_t
*type
;
180 VA_ARGS_VGET(args
, type
, subtype
);
182 while (orig
->enumerate(orig
, &entry
))
187 *subtype
= entry
->subtype
;
194 METHOD(credential_factory_t
, create_builder_enumerator
, enumerator_t
*,
195 private_credential_factory_t
*this)
197 this->lock
->read_lock(this->lock
);
198 return enumerator_create_filter(
199 this->constructors
->create_enumerator(this->constructors
),
200 builder_filter
, this->lock
, (void*)this->lock
->unlock
);
203 METHOD(credential_factory_t
, destroy
, void,
204 private_credential_factory_t
*this)
206 this->constructors
->destroy_function(this->constructors
, free
);
207 this->recursive
->destroy(this->recursive
);
208 this->lock
->destroy(this->lock
);
215 credential_factory_t
*credential_factory_create()
217 private_credential_factory_t
*this;
222 .create_builder_enumerator
= _create_builder_enumerator
,
223 .add_builder
= _add_builder
,
224 .remove_builder
= _remove_builder
,
227 .constructors
= linked_list_create(),
228 .recursive
= thread_value_create(NULL
),
229 .lock
= rwlock_create(RWLOCK_TYPE_DEFAULT
),
232 return &this->public;