summaryrefslogtreecommitdiff
path: root/src/libstrongswan/plugins/plugin_feature.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstrongswan/plugins/plugin_feature.c')
-rw-r--r--src/libstrongswan/plugins/plugin_feature.c383
1 files changed, 383 insertions, 0 deletions
diff --git a/src/libstrongswan/plugins/plugin_feature.c b/src/libstrongswan/plugins/plugin_feature.c
new file mode 100644
index 000000000..2a97205bb
--- /dev/null
+++ b/src/libstrongswan/plugins/plugin_feature.c
@@ -0,0 +1,383 @@
+/*
+ * Copyright (C) 2011 Martin Willi
+ * Copyright (C) 2011 revosec AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+
+#include "plugin_feature.h"
+
+#include <debug.h>
+
+ENUM(plugin_feature_names, FEATURE_NONE, FEATURE_CUSTOM,
+ "NONE",
+ "CRYPTER",
+ "AEAD",
+ "SIGNER",
+ "HASHER",
+ "PRF",
+ "DH",
+ "RNG",
+ "PRIVKEY",
+ "PRIVKEY_GEN",
+ "PRIVKEY_SIGN",
+ "PRIVKEY_DECRYPT",
+ "PUBKEY",
+ "PUBKEY_VERIFY",
+ "PUBKEY_ENCRYPT",
+ "CERT_DECODE",
+ "CERT_ENCODE",
+ "EAP_SERVER",
+ "EAP_CLIENT",
+ "DATABASE",
+ "FETCHER",
+ "CUSTOM",
+);
+
+/**
+ * See header.
+ */
+bool plugin_feature_matches(plugin_feature_t *a, plugin_feature_t *b)
+{
+ if (a->type == b->type)
+ {
+ switch (a->type)
+ {
+ case FEATURE_NONE:
+ return FALSE;
+ case FEATURE_CRYPTER:
+ return a->arg.crypter.alg == b->arg.crypter.alg &&
+ a->arg.crypter.key_size == b->arg.crypter.key_size;
+ case FEATURE_AEAD:
+ return a->arg.aead.alg == b->arg.aead.alg &&
+ a->arg.aead.key_size == b->arg.aead.key_size;
+ case FEATURE_SIGNER:
+ return a->arg.signer == b->arg.signer;
+ case FEATURE_HASHER:
+ return a->arg.hasher == b->arg.hasher;
+ case FEATURE_PRF:
+ return a->arg.prf == b->arg.prf;
+ case FEATURE_DH:
+ return a->arg.dh_group == b->arg.dh_group;
+ case FEATURE_RNG:
+ return a->arg.rng_quality <= b->arg.rng_quality;
+ case FEATURE_PRIVKEY:
+ case FEATURE_PRIVKEY_GEN:
+ case FEATURE_PUBKEY:
+ return a->arg.privkey == b->arg.privkey;
+ case FEATURE_PRIVKEY_SIGN:
+ case FEATURE_PUBKEY_VERIFY:
+ return a->arg.privkey_sign == b->arg.privkey_sign;
+ case FEATURE_PRIVKEY_DECRYPT:
+ case FEATURE_PUBKEY_ENCRYPT:
+ return a->arg.privkey_decrypt == b->arg.privkey_decrypt;
+ case FEATURE_CERT_DECODE:
+ case FEATURE_CERT_ENCODE:
+ return a->arg.cert == b->arg.cert;
+ case FEATURE_EAP_SERVER:
+ case FEATURE_EAP_PEER:
+ return a->arg.eap == b->arg.eap;
+ case FEATURE_DATABASE:
+ return a->arg.database == DB_ANY ||
+ a->arg.database == b->arg.database;
+ case FEATURE_FETCHER:
+ return a->arg.fetcher == NULL ||
+ streq(a->arg.fetcher, b->arg.fetcher);
+ case FEATURE_CUSTOM:
+ return streq(a->arg.custom, b->arg.custom);
+ }
+ }
+ return FALSE;
+}
+
+/**
+ * See header.
+ */
+char* plugin_feature_get_string(plugin_feature_t *feature)
+{
+ char *str = NULL;
+
+ if (feature->kind == FEATURE_REGISTER)
+ {
+ return strdup("(register function)");
+ }
+ switch (feature->type)
+ {
+ case FEATURE_NONE:
+ return strdup("NONE");
+ case FEATURE_CRYPTER:
+ if (asprintf(&str, "%N:%N-%d", plugin_feature_names, feature->type,
+ encryption_algorithm_names, feature->arg.crypter.alg,
+ feature->arg.crypter.key_size) > 0)
+ {
+ return str;
+ }
+ break;
+ case FEATURE_AEAD:
+ if (asprintf(&str, "%N:%N-%d", plugin_feature_names, feature->type,
+ encryption_algorithm_names, feature->arg.aead.alg,
+ feature->arg.aead.key_size) > 0)
+ {
+ return str;
+ }
+ break;
+ case FEATURE_SIGNER:
+ if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type,
+ integrity_algorithm_names, feature->arg.signer) > 0)
+ {
+ return str;
+ }
+ break;
+ case FEATURE_HASHER:
+ if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type,
+ hash_algorithm_names, feature->arg.hasher) > 0)
+ {
+ return str;
+ }
+ break;
+ case FEATURE_PRF:
+ if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type,
+ pseudo_random_function_names, feature->arg.prf) > 0)
+ {
+ return str;
+ }
+ break;
+ case FEATURE_DH:
+ if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type,
+ diffie_hellman_group_names, feature->arg.dh_group) > 0)
+ {
+ return str;
+ }
+ break;
+ case FEATURE_RNG:
+ if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type,
+ rng_quality_names, feature->arg.rng_quality) > 0)
+ {
+ return str;
+ }
+ break;
+ case FEATURE_PRIVKEY:
+ case FEATURE_PRIVKEY_GEN:
+ case FEATURE_PUBKEY:
+ if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type,
+ key_type_names, feature->arg.privkey) > 0)
+ {
+ return str;
+ }
+ break;
+ case FEATURE_PRIVKEY_SIGN:
+ case FEATURE_PUBKEY_VERIFY:
+ if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type,
+ signature_scheme_names, feature->arg.privkey_sign) > 0)
+ {
+ return str;
+ }
+ break;
+ case FEATURE_PRIVKEY_DECRYPT:
+ case FEATURE_PUBKEY_ENCRYPT:
+ if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type,
+ encryption_scheme_names, feature->arg.privkey_decrypt) > 0)
+ {
+ return str;
+ }
+ break;
+ case FEATURE_CERT_DECODE:
+ case FEATURE_CERT_ENCODE:
+ if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type,
+ certificate_type_names, feature->arg.cert) > 0)
+ {
+ return str;
+ }
+ break;
+ case FEATURE_EAP_SERVER:
+ case FEATURE_EAP_PEER:
+ if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type,
+ eap_type_short_names, feature->arg.eap) > 0)
+ {
+ return str;
+ }
+ break;
+ case FEATURE_DATABASE:
+ if (asprintf(&str, "%N:%N", plugin_feature_names, feature->type,
+ db_driver_names, feature->arg.database) > 0)
+ {
+ return str;
+ }
+ break;
+ case FEATURE_FETCHER:
+ if (asprintf(&str, "%N:%s", plugin_feature_names, feature->type,
+ feature->arg.fetcher) > 0)
+ {
+ return str;
+ }
+ break;
+ case FEATURE_CUSTOM:
+ if (asprintf(&str, "%N:%s", plugin_feature_names, feature->type,
+ feature->arg.custom) > 0)
+ {
+ return str;
+ }
+ break;
+ }
+ if (!str)
+ {
+ str = strdup("(invalid)");
+ }
+ return str;
+}
+
+/**
+ * See header.
+ */
+bool plugin_feature_load(plugin_t *plugin, plugin_feature_t *feature,
+ plugin_feature_t *reg)
+{
+ char *name;
+
+ if (!reg)
+ { /* noting to do for this feature */
+ return TRUE;
+ }
+ if (reg->kind == FEATURE_CALLBACK)
+ {
+ if (reg->arg.cb.f(plugin, feature, TRUE, reg->arg.cb.data))
+ {
+ return TRUE;
+ }
+ return FALSE;
+ }
+ name = plugin->get_name(plugin);
+ switch (feature->type)
+ {
+ case FEATURE_CRYPTER:
+ lib->crypto->add_crypter(lib->crypto, feature->arg.crypter.alg,
+ name, reg->arg.reg.f);
+ break;
+ case FEATURE_AEAD:
+ lib->crypto->add_aead(lib->crypto, feature->arg.aead.alg,
+ name, reg->arg.reg.f);
+ break;
+ case FEATURE_SIGNER:
+ lib->crypto->add_signer(lib->crypto, feature->arg.signer,
+ name, reg->arg.reg.f);
+ break;
+ case FEATURE_HASHER:
+ lib->crypto->add_hasher(lib->crypto, feature->arg.hasher,
+ name, reg->arg.reg.f);
+ break;
+ case FEATURE_PRF:
+ lib->crypto->add_prf(lib->crypto, feature->arg.prf,
+ name, reg->arg.reg.f);
+ break;
+ case FEATURE_DH:
+ lib->crypto->add_dh(lib->crypto, feature->arg.dh_group,
+ name, reg->arg.reg.f);
+ break;
+ case FEATURE_RNG:
+ lib->crypto->add_rng(lib->crypto, feature->arg.rng_quality,
+ name, reg->arg.reg.f);
+ break;
+ case FEATURE_PRIVKEY:
+ case FEATURE_PRIVKEY_GEN:
+ lib->creds->add_builder(lib->creds, CRED_PRIVATE_KEY,
+ feature->arg.privkey, reg->arg.reg.final,
+ reg->arg.reg.f);
+ break;
+ case FEATURE_PUBKEY:
+ lib->creds->add_builder(lib->creds, CRED_PUBLIC_KEY,
+ feature->arg.pubkey, reg->arg.reg.final,
+ reg->arg.reg.f);
+ break;
+ case FEATURE_CERT_DECODE:
+ case FEATURE_CERT_ENCODE:
+ lib->creds->add_builder(lib->creds, CRED_CERTIFICATE,
+ feature->arg.cert, reg->arg.reg.final,
+ reg->arg.reg.f);
+ break;
+ case FEATURE_DATABASE:
+ lib->db->add_database(lib->db, reg->arg.reg.f);
+ break;
+ case FEATURE_FETCHER:
+ lib->fetcher->add_fetcher(lib->fetcher, reg->arg.reg.f,
+ feature->arg.fetcher);
+ break;
+ default:
+ break;
+ }
+ return TRUE;
+}
+
+/**
+ * See header.
+ */
+bool plugin_feature_unload(plugin_t *plugin, plugin_feature_t *feature,
+ plugin_feature_t *reg)
+{
+ if (!reg)
+ { /* noting to do for this feature */
+ return TRUE;
+ }
+ if (reg->kind == FEATURE_CALLBACK)
+ {
+ if (reg->arg.cb.f(plugin, feature, FALSE, reg->arg.cb.data))
+ {
+ return TRUE;
+ }
+ return FALSE;
+ }
+ switch (feature->type)
+ {
+ case FEATURE_CRYPTER:
+ lib->crypto->remove_crypter(lib->crypto, reg->arg.reg.f);
+ break;
+ case FEATURE_AEAD:
+ lib->crypto->remove_aead(lib->crypto, reg->arg.reg.f);
+ break;
+ case FEATURE_SIGNER:
+ lib->crypto->remove_signer(lib->crypto, reg->arg.reg.f);
+ break;
+ case FEATURE_HASHER:
+ lib->crypto->remove_hasher(lib->crypto, reg->arg.reg.f);
+ break;
+ case FEATURE_PRF:
+ lib->crypto->remove_prf(lib->crypto, reg->arg.reg.f);
+ break;
+ case FEATURE_DH:
+ lib->crypto->remove_dh(lib->crypto, reg->arg.reg.f);
+ break;
+ case FEATURE_RNG:
+ lib->crypto->remove_rng(lib->crypto, reg->arg.reg.f);
+ break;
+ case FEATURE_PRIVKEY:
+ case FEATURE_PRIVKEY_GEN:
+ lib->creds->remove_builder(lib->creds, reg->arg.reg.f);
+ break;
+ case FEATURE_PUBKEY:
+ lib->creds->remove_builder(lib->creds, reg->arg.reg.f);
+ break;
+ case FEATURE_CERT_DECODE:
+ case FEATURE_CERT_ENCODE:
+ lib->creds->remove_builder(lib->creds, reg->arg.reg.f);
+ break;
+ case FEATURE_DATABASE:
+ lib->db->remove_database(lib->db, reg->arg.reg.f);
+ break;
+ case FEATURE_FETCHER:
+ lib->fetcher->remove_fetcher(lib->fetcher, reg->arg.reg.f);
+ break;
+ default:
+ break;
+ }
+ return TRUE;
+}