summaryrefslogtreecommitdiff
path: root/src/libstrongswan/credentials/credential_factory.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstrongswan/credentials/credential_factory.c')
-rw-r--r--src/libstrongswan/credentials/credential_factory.c159
1 files changed, 54 insertions, 105 deletions
diff --git a/src/libstrongswan/credentials/credential_factory.c b/src/libstrongswan/credentials/credential_factory.c
index e55df0398..5139ad504 100644
--- a/src/libstrongswan/credentials/credential_factory.c
+++ b/src/libstrongswan/credentials/credential_factory.c
@@ -13,17 +13,21 @@
* for more details.
*/
+#include <stdint.h>
+
#include "credential_factory.h"
#include <debug.h>
#include <utils/linked_list.h>
-#include <utils/mutex.h>
+#include <threading/thread_value.h>
+#include <threading/rwlock.h>
#include <credentials/certificates/x509.h>
ENUM(credential_type_names, CRED_PRIVATE_KEY, CRED_CERTIFICATE,
"CRED_PRIVATE_KEY",
"CRED_PUBLIC_KEY",
"CRED_CERTIFICATE",
+ "CRED_PLUTO_CERT",
);
typedef struct private_credential_factory_t private_credential_factory_t;
@@ -37,12 +41,17 @@ struct private_credential_factory_t {
* public functions
*/
credential_factory_t public;
-
+
/**
* list with entry_t
*/
linked_list_t *constructors;
-
+
+ /**
+ * Thread specific recursiveness counter
+ */
+ thread_value_t *recursive;
+
/**
* lock access to builders
*/
@@ -55,52 +64,19 @@ struct entry_t {
credential_type_t type;
/** subtype of credential, e.g. certificate_type_t */
int subtype;
- /** builder construction function */
- builder_constructor_t constructor;
+ /** builder function */
+ builder_function_t constructor;
};
/**
- * type/subtype filter function for builder_enumerator
- */
-static bool builder_filter(entry_t *data, entry_t **in, builder_t **out)
-{
- if (data->type == (*in)->type &&
- data->subtype == (*in)->subtype)
- {
- *out = (*in)->constructor(data->subtype);
- return TRUE;
- }
- return FALSE;
-}
-
-/**
- * Implementation of credential_factory_t.create_builder_enumerator.
- */
-static enumerator_t* create_builder_enumerator(
- private_credential_factory_t *this, credential_type_t type, int subtype)
-{
- entry_t *data = malloc_thing(entry_t);
-
- data->type = type;
- data->subtype = subtype;
-
- this->lock->read_lock(this->lock);
- return enumerator_create_cleaner(
- enumerator_create_filter(
- this->constructors->create_enumerator(this->constructors),
- (void*)builder_filter, data, free),
- (void*)this->lock->unlock, this->lock);
-}
-
-/**
* Implementation of credential_factory_t.add_builder_constructor.
*/
static void add_builder(private_credential_factory_t *this,
credential_type_t type, int subtype,
- builder_constructor_t constructor)
+ builder_function_t constructor)
{
entry_t *entry = malloc_thing(entry_t);
-
+
entry->type = type;
entry->subtype = subtype;
entry->constructor = constructor;
@@ -113,11 +89,11 @@ static void add_builder(private_credential_factory_t *this,
* Implementation of credential_factory_t.remove_builder.
*/
static void remove_builder(private_credential_factory_t *this,
- builder_constructor_t constructor)
+ builder_function_t constructor)
{
enumerator_t *enumerator;
entry_t *entry;
-
+
this->lock->write_lock(this->lock);
enumerator = this->constructors->create_enumerator(this->constructors);
while (enumerator->enumerate(enumerator, &entry))
@@ -139,73 +115,46 @@ static void* create(private_credential_factory_t *this, credential_type_t type,
int subtype, ...)
{
enumerator_t *enumerator;
- builder_t *builder;
- builder_part_t part;
+ entry_t *entry;
va_list args;
- void* construct = NULL;
-
- enumerator = create_builder_enumerator(this, type, subtype);
- while (enumerator->enumerate(enumerator, &builder))
+ void *construct = NULL;
+ int failures = 0;
+ uintptr_t level;
+
+ level = (uintptr_t)this->recursive->get(this->recursive);
+ this->recursive->set(this->recursive, (void*)level + 1);
+
+ this->lock->read_lock(this->lock);
+ enumerator = this->constructors->create_enumerator(this->constructors);
+ while (enumerator->enumerate(enumerator, &entry))
{
- va_start(args, subtype);
- while (TRUE)
+ if (entry->type == type && entry->subtype == subtype)
{
- part = va_arg(args, builder_part_t);
- switch (part)
+ va_start(args, subtype);
+ construct = entry->constructor(subtype, args);
+ va_end(args);
+ if (construct)
{
- case BUILD_END:
- break;
- case BUILD_BLOB_ASN1_DER:
- case BUILD_BLOB_PGP:
- case BUILD_BLOB_RFC_3110:
- case BUILD_SERIAL:
- builder->add(builder, part, va_arg(args, chunk_t));
- continue;
- case BUILD_X509_FLAG:
- builder->add(builder, part, va_arg(args, x509_flag_t));
- continue;
- case BUILD_KEY_SIZE:
- builder->add(builder, part, va_arg(args, u_int));
- continue;
- case BUILD_NOT_BEFORE_TIME:
- case BUILD_NOT_AFTER_TIME:
- builder->add(builder, part, va_arg(args, time_t));
- continue;
- case BUILD_BLOB_ASN1_PEM:
- case BUILD_FROM_FILE:
- case BUILD_AGENT_SOCKET:
- case BUILD_SIGNING_KEY:
- case BUILD_PUBLIC_KEY:
- case BUILD_SUBJECT:
- case BUILD_SUBJECT_ALTNAME:
- case BUILD_ISSUER:
- case BUILD_ISSUER_ALTNAME:
- case BUILD_SIGNING_CERT:
- case BUILD_CA_CERT:
- case BUILD_CERT:
- case BUILD_IETF_GROUP_ATTR:
- case BUILD_SMARTCARD_KEYID:
- case BUILD_SMARTCARD_PIN:
- builder->add(builder, part, va_arg(args, void*));
- continue;
- /* no default to get a compiler warning */
+ break;
}
- break;
- }
- va_end(args);
-
- construct = builder->build(builder);
- if (construct)
- {
- break;
+ failures++;
}
}
enumerator->destroy(enumerator);
- if (!construct)
+ this->lock->unlock(this->lock);
+
+ if (!construct && !level)
{
- DBG1("failed to create a builder for credential type %N,"
- " subtype (%d)", credential_type_names, type, subtype);
+ enum_name_t *names = key_type_names;
+
+ if (type == CRED_CERTIFICATE)
+ {
+ names = certificate_type_names;
+ }
+ DBG1("building %N - %N failed, tried %d builders",
+ credential_type_names, type, names, subtype, failures);
}
+ this->recursive->set(this->recursive, (void*)level);
return construct;
}
@@ -215,6 +164,7 @@ static void* create(private_credential_factory_t *this, credential_type_t type,
static void destroy(private_credential_factory_t *this)
{
this->constructors->destroy_function(this->constructors, free);
+ this->recursive->destroy(this->recursive);
this->lock->destroy(this->lock);
free(this);
}
@@ -227,15 +177,14 @@ credential_factory_t *credential_factory_create()
private_credential_factory_t *this = malloc_thing(private_credential_factory_t);
this->public.create = (void*(*)(credential_factory_t*, credential_type_t type, int subtype, ...))create;
- this->public.create_builder_enumerator = (enumerator_t*(*)(credential_factory_t*, credential_type_t type, int subtype))create_builder_enumerator;
- this->public.add_builder = (void(*)(credential_factory_t*,credential_type_t type, int subtype, builder_constructor_t constructor))add_builder;
- this->public.remove_builder = (void(*)(credential_factory_t*,builder_constructor_t constructor))remove_builder;
+ this->public.add_builder = (void(*)(credential_factory_t*,credential_type_t type, int subtype, builder_function_t constructor))add_builder;
+ this->public.remove_builder = (void(*)(credential_factory_t*,builder_function_t constructor))remove_builder;
this->public.destroy = (void(*)(credential_factory_t*))destroy;
-
+
this->constructors = linked_list_create();
-
+ this->recursive = thread_value_create(NULL);
this->lock = rwlock_create(RWLOCK_TYPE_DEFAULT);
-
+
return &this->public;
}