Merge branch 'plugin-loader'
Improves how plugin loader resolves dependencies between plugins. The old loader had problems if plugins had dependencies on features provided by plugins listed later in the plugin list. For instance, it was not possible to use the X.509 implementation provided by the x509 plugin while using all the crypto primitives provided by the openssl plugin. Because the x509 plugin has a dependency on SHA1, the old loader skipped that plugin until it loaded a SHA1 implementation. Because the loader also loaded all features with resolved dependencies provided by a specific plugin it would, while loading the openssl plugin's SHA1 implementation, also load its X.509 implementation. So to use the x509 plugin it was necessary to load the sha1 plugin before it so that its dependencies could be properly resolved. With the new implementation the plugins don't have to be in a specific order to resolve dependencies. But the order still matters if two plugins provide the same feature. Also, support for the get_features() interface was added to all plugins.
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
#include "addrblock_plugin.h"
|
||||
|
||||
#include <daemon.h>
|
||||
#include <plugins/plugin_feature.h>
|
||||
|
||||
#include "addrblock_validator.h"
|
||||
#include "addrblock_narrow.h"
|
||||
@@ -49,11 +50,41 @@ METHOD(plugin_t, get_name, char*,
|
||||
return "addrblock";
|
||||
}
|
||||
|
||||
/**
|
||||
* Register listener
|
||||
*/
|
||||
static bool plugin_cb(private_addrblock_plugin_t *this,
|
||||
plugin_feature_t *feature, bool reg, void *cb_data)
|
||||
{
|
||||
if (reg)
|
||||
{
|
||||
lib->credmgr->add_validator(lib->credmgr, &this->validator->validator);
|
||||
charon->bus->add_listener(charon->bus, &this->narrower->listener);
|
||||
}
|
||||
else
|
||||
{
|
||||
charon->bus->remove_listener(charon->bus, &this->narrower->listener);
|
||||
lib->credmgr->remove_validator(lib->credmgr,
|
||||
&this->validator->validator);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(plugin_t, get_features, int,
|
||||
private_addrblock_plugin_t *this, plugin_feature_t *features[])
|
||||
{
|
||||
static plugin_feature_t f[] = {
|
||||
PLUGIN_CALLBACK((plugin_feature_callback_t)plugin_cb, NULL),
|
||||
PLUGIN_PROVIDE(CUSTOM, "addrblock"),
|
||||
PLUGIN_SDEPEND(CERT_DECODE, CERT_X509),
|
||||
};
|
||||
*features = f;
|
||||
return countof(f);
|
||||
}
|
||||
|
||||
METHOD(plugin_t, destroy, void,
|
||||
private_addrblock_plugin_t *this)
|
||||
{
|
||||
charon->bus->remove_listener(charon->bus, &this->narrower->listener);
|
||||
lib->credmgr->remove_validator(lib->credmgr, &this->validator->validator);
|
||||
this->narrower->destroy(this->narrower);
|
||||
this->validator->destroy(this->validator);
|
||||
free(this);
|
||||
@@ -70,15 +101,13 @@ plugin_t *addrblock_plugin_create()
|
||||
.public = {
|
||||
.plugin = {
|
||||
.get_name = _get_name,
|
||||
.reload = (void*)return_false,
|
||||
.get_features = _get_features,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
},
|
||||
.validator = addrblock_validator_create(),
|
||||
.narrower = addrblock_narrow_create(),
|
||||
);
|
||||
lib->credmgr->add_validator(lib->credmgr, &this->validator->validator);
|
||||
charon->bus->add_listener(charon->bus, &this->narrower->listener);
|
||||
|
||||
return &this->public.plugin;
|
||||
}
|
||||
|
||||
@@ -43,11 +43,39 @@ METHOD(plugin_t, get_name, char*,
|
||||
return "android-dns";
|
||||
}
|
||||
|
||||
/**
|
||||
* Register handler
|
||||
*/
|
||||
static bool plugin_cb(private_android_dns_plugin_t *this,
|
||||
plugin_feature_t *feature, bool reg, void *cb_data)
|
||||
{
|
||||
if (reg)
|
||||
{
|
||||
hydra->attributes->add_handler(hydra->attributes,
|
||||
&this->handler->handler);
|
||||
}
|
||||
else
|
||||
{
|
||||
hydra->attributes->remove_handler(hydra->attributes,
|
||||
&this->handler->handler);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(plugin_t, get_features, int,
|
||||
private_android_dns_plugin_t *this, plugin_feature_t *features[])
|
||||
{
|
||||
static plugin_feature_t f[] = {
|
||||
PLUGIN_CALLBACK((plugin_feature_callback_t)plugin_cb, NULL),
|
||||
PLUGIN_PROVIDE(CUSTOM, "android-dns"),
|
||||
};
|
||||
*features = f;
|
||||
return countof(f);
|
||||
}
|
||||
|
||||
METHOD(plugin_t, destroy, void,
|
||||
private_android_dns_plugin_t *this)
|
||||
{
|
||||
hydra->attributes->remove_handler(hydra->attributes,
|
||||
&this->handler->handler);
|
||||
this->handler->destroy(this->handler);
|
||||
free(this);
|
||||
}
|
||||
@@ -63,14 +91,12 @@ plugin_t *android_dns_plugin_create()
|
||||
.public = {
|
||||
.plugin = {
|
||||
.get_name = _get_name,
|
||||
.reload = (void*)return_false,
|
||||
.get_features = _get_features,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
},
|
||||
.handler = android_dns_handler_create(),
|
||||
);
|
||||
|
||||
hydra->attributes->add_handler(hydra->attributes, &this->handler->handler);
|
||||
|
||||
return &this->public.plugin;
|
||||
}
|
||||
|
||||
@@ -43,6 +43,17 @@ METHOD(plugin_t, get_name, char*,
|
||||
return "android-log";
|
||||
}
|
||||
|
||||
METHOD(plugin_t, get_features, int,
|
||||
private_android_log_plugin_t *this, plugin_feature_t *features[])
|
||||
{
|
||||
static plugin_feature_t f[] = {
|
||||
PLUGIN_NOOP,
|
||||
PLUGIN_PROVIDE(CUSTOM, "android-log"),
|
||||
};
|
||||
*features = f;
|
||||
return countof(f);
|
||||
}
|
||||
|
||||
METHOD(plugin_t, destroy, void,
|
||||
private_android_log_plugin_t *this)
|
||||
{
|
||||
@@ -62,7 +73,7 @@ plugin_t *android_log_plugin_create()
|
||||
.public = {
|
||||
.plugin = {
|
||||
.get_name = _get_name,
|
||||
.reload = (void*)return_false,
|
||||
.get_features = _get_features,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
},
|
||||
@@ -73,4 +84,3 @@ plugin_t *android_log_plugin_create()
|
||||
|
||||
return &this->public.plugin;
|
||||
}
|
||||
|
||||
|
||||
@@ -49,10 +49,37 @@ METHOD(plugin_t, get_name, char*,
|
||||
return "certexpire";
|
||||
}
|
||||
|
||||
/**
|
||||
* Register listener
|
||||
*/
|
||||
static bool plugin_cb(private_certexpire_plugin_t *this,
|
||||
plugin_feature_t *feature, bool reg, void *cb_data)
|
||||
{
|
||||
if (reg)
|
||||
{
|
||||
charon->bus->add_listener(charon->bus, &this->listener->listener);
|
||||
}
|
||||
else
|
||||
{
|
||||
charon->bus->remove_listener(charon->bus, &this->listener->listener);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(plugin_t, get_features, int,
|
||||
private_certexpire_plugin_t *this, plugin_feature_t *features[])
|
||||
{
|
||||
static plugin_feature_t f[] = {
|
||||
PLUGIN_CALLBACK((plugin_feature_callback_t)plugin_cb, NULL),
|
||||
PLUGIN_PROVIDE(CUSTOM, "certexpire"),
|
||||
};
|
||||
*features = f;
|
||||
return countof(f);
|
||||
}
|
||||
|
||||
METHOD(plugin_t, destroy, void,
|
||||
private_certexpire_plugin_t *this)
|
||||
{
|
||||
charon->bus->remove_listener(charon->bus, &this->listener->listener);
|
||||
this->listener->destroy(this->listener);
|
||||
this->export->destroy(this->export);
|
||||
free(this);
|
||||
@@ -69,14 +96,13 @@ plugin_t *certexpire_plugin_create()
|
||||
.public = {
|
||||
.plugin = {
|
||||
.get_name = _get_name,
|
||||
.reload = (void*)return_false,
|
||||
.get_features = _get_features,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
},
|
||||
.export = certexpire_export_create(),
|
||||
);
|
||||
this->listener = certexpire_listener_create(this->export),
|
||||
charon->bus->add_listener(charon->bus, &this->listener->listener);
|
||||
this->listener = certexpire_listener_create(this->export);
|
||||
|
||||
return &this->public.plugin;
|
||||
}
|
||||
|
||||
@@ -43,11 +43,48 @@ METHOD(plugin_t, get_name, char*,
|
||||
return "coupling";
|
||||
}
|
||||
|
||||
/**
|
||||
* Since the validator instantiates a hasher we create it as plugin feature.
|
||||
* The default is SHA1 which we soft depend but depending on the plugin order
|
||||
* there is no guarantee that the configured algorithm is registered.
|
||||
*/
|
||||
static bool plugin_cb(private_coupling_plugin_t *this,
|
||||
plugin_feature_t *feature, bool reg, void *cb_data)
|
||||
{
|
||||
if (reg)
|
||||
{
|
||||
this->validator = coupling_validator_create();
|
||||
|
||||
if (!this->validator)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
lib->credmgr->add_validator(lib->credmgr, &this->validator->validator);
|
||||
}
|
||||
else
|
||||
{
|
||||
lib->credmgr->remove_validator(lib->credmgr,
|
||||
&this->validator->validator);
|
||||
this->validator->destroy(this->validator);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(plugin_t, get_features, int,
|
||||
private_coupling_plugin_t *this, plugin_feature_t *features[])
|
||||
{
|
||||
static plugin_feature_t f[] = {
|
||||
PLUGIN_CALLBACK((plugin_feature_callback_t)plugin_cb, NULL),
|
||||
PLUGIN_PROVIDE(CUSTOM, "coupling"),
|
||||
PLUGIN_SDEPEND(HASHER, HASH_SHA1),
|
||||
};
|
||||
*features = f;
|
||||
return countof(f);
|
||||
}
|
||||
|
||||
METHOD(plugin_t, destroy, void,
|
||||
private_coupling_plugin_t *this)
|
||||
{
|
||||
lib->credmgr->remove_validator(lib->credmgr, &this->validator->validator);
|
||||
this->validator->destroy(this->validator);
|
||||
free(this);
|
||||
}
|
||||
|
||||
@@ -62,20 +99,11 @@ plugin_t *coupling_plugin_create()
|
||||
.public = {
|
||||
.plugin = {
|
||||
.get_name = _get_name,
|
||||
.reload = (void*)return_false,
|
||||
.get_features = _get_features,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
},
|
||||
.validator = coupling_validator_create(),
|
||||
);
|
||||
|
||||
if (!this->validator)
|
||||
{
|
||||
free(this);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lib->credmgr->add_validator(lib->credmgr, &this->validator->validator);
|
||||
|
||||
return &this->public.plugin;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Tobias Brunner
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* Copyright (C) 2010 Martin Willi
|
||||
* Copyright (C) 2010 revosec AG
|
||||
*
|
||||
@@ -17,6 +20,7 @@
|
||||
|
||||
#include <hydra.h>
|
||||
#include <daemon.h>
|
||||
#include <plugins/plugin_feature.h>
|
||||
|
||||
#include "dhcp_socket.h"
|
||||
#include "dhcp_provider.h"
|
||||
@@ -50,13 +54,49 @@ METHOD(plugin_t, get_name, char*,
|
||||
return "dhcp";
|
||||
}
|
||||
|
||||
/**
|
||||
* Register listener
|
||||
*/
|
||||
static bool plugin_cb(private_dhcp_plugin_t *this,
|
||||
plugin_feature_t *feature, bool reg, void *cb_data)
|
||||
{
|
||||
if (reg)
|
||||
{
|
||||
this->socket = dhcp_socket_create();
|
||||
|
||||
if (!this->socket)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
this->provider = dhcp_provider_create(this->socket);
|
||||
hydra->attributes->add_provider(hydra->attributes,
|
||||
&this->provider->provider);
|
||||
}
|
||||
else
|
||||
{
|
||||
hydra->attributes->remove_provider(hydra->attributes,
|
||||
&this->provider->provider);
|
||||
this->provider->destroy(this->provider);
|
||||
this->socket->destroy(this->socket);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(plugin_t, get_features, int,
|
||||
private_dhcp_plugin_t *this, plugin_feature_t *features[])
|
||||
{
|
||||
static plugin_feature_t f[] = {
|
||||
PLUGIN_CALLBACK((plugin_feature_callback_t)plugin_cb, NULL),
|
||||
PLUGIN_PROVIDE(CUSTOM, "dhcp"),
|
||||
PLUGIN_DEPENDS(RNG, RNG_WEAK),
|
||||
};
|
||||
*features = f;
|
||||
return countof(f);
|
||||
}
|
||||
|
||||
METHOD(plugin_t, destroy, void,
|
||||
private_dhcp_plugin_t *this)
|
||||
{
|
||||
hydra->attributes->remove_provider(hydra->attributes,
|
||||
&this->provider->provider);
|
||||
this->provider->destroy(this->provider);
|
||||
this->socket->destroy(this->socket);
|
||||
free(this);
|
||||
}
|
||||
|
||||
@@ -71,23 +111,11 @@ plugin_t *dhcp_plugin_create()
|
||||
.public = {
|
||||
.plugin = {
|
||||
.get_name = _get_name,
|
||||
.reload = (void*)return_false,
|
||||
.get_features = _get_features,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
},
|
||||
.socket = dhcp_socket_create(),
|
||||
);
|
||||
|
||||
if (!this->socket)
|
||||
{
|
||||
free(this);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
this->provider = dhcp_provider_create(this->socket);
|
||||
hydra->attributes->add_provider(hydra->attributes,
|
||||
&this->provider->provider);
|
||||
|
||||
return &this->public.plugin;
|
||||
}
|
||||
|
||||
|
||||
@@ -49,10 +49,37 @@ METHOD(plugin_t, get_name, char*,
|
||||
return "duplicheck";
|
||||
}
|
||||
|
||||
/**
|
||||
* Register listener
|
||||
*/
|
||||
static bool plugin_cb(private_duplicheck_plugin_t *this,
|
||||
plugin_feature_t *feature, bool reg, void *cb_data)
|
||||
{
|
||||
if (reg)
|
||||
{
|
||||
charon->bus->add_listener(charon->bus, &this->listener->listener);
|
||||
}
|
||||
else
|
||||
{
|
||||
charon->bus->remove_listener(charon->bus, &this->listener->listener);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(plugin_t, get_features, int,
|
||||
private_duplicheck_plugin_t *this, plugin_feature_t *features[])
|
||||
{
|
||||
static plugin_feature_t f[] = {
|
||||
PLUGIN_CALLBACK((plugin_feature_callback_t)plugin_cb, NULL),
|
||||
PLUGIN_PROVIDE(CUSTOM, "duplicheck"),
|
||||
};
|
||||
*features = f;
|
||||
return countof(f);
|
||||
}
|
||||
|
||||
METHOD(plugin_t, destroy, void,
|
||||
private_duplicheck_plugin_t *this)
|
||||
{
|
||||
charon->bus->remove_listener(charon->bus, &this->listener->listener);
|
||||
this->notify->destroy(this->notify);
|
||||
this->listener->destroy(this->listener);
|
||||
free(this);
|
||||
@@ -75,7 +102,7 @@ plugin_t *duplicheck_plugin_create()
|
||||
.public = {
|
||||
.plugin = {
|
||||
.get_name = _get_name,
|
||||
.reload = (void*)return_false,
|
||||
.get_features = _get_features,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
},
|
||||
@@ -88,7 +115,6 @@ plugin_t *duplicheck_plugin_create()
|
||||
return NULL;
|
||||
}
|
||||
this->listener = duplicheck_listener_create(this->notify);
|
||||
charon->bus->add_listener(charon->bus, &this->listener->listener);
|
||||
|
||||
return &this->public.plugin;
|
||||
}
|
||||
|
||||
@@ -39,9 +39,4 @@ struct eap_peap_plugin_t {
|
||||
plugin_t plugin;
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a eap_peap_plugin instance.
|
||||
*/
|
||||
plugin_t *eap_peap_plugin_create();
|
||||
|
||||
#endif /** EAP_PEAP_PLUGIN_H_ @}*/
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Tobias Brunner
|
||||
* Copyright (C) 2009 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
@@ -186,12 +187,57 @@ METHOD(plugin_t, get_name, char*,
|
||||
return "eap-radius";
|
||||
}
|
||||
|
||||
/**
|
||||
* Register listener
|
||||
*/
|
||||
static bool plugin_cb(private_eap_radius_plugin_t *this,
|
||||
plugin_feature_t *feature, bool reg, void *cb_data)
|
||||
{
|
||||
if (reg)
|
||||
{
|
||||
this->accounting = eap_radius_accounting_create();
|
||||
this->forward = eap_radius_forward_create();
|
||||
this->provider = eap_radius_provider_create();
|
||||
|
||||
load_configs(this);
|
||||
|
||||
if (lib->settings->get_bool(lib->settings,
|
||||
"%s.plugins.eap-radius.dae.enable", FALSE, charon->name))
|
||||
{
|
||||
this->dae = eap_radius_dae_create(this->accounting);
|
||||
}
|
||||
if (this->forward)
|
||||
{
|
||||
charon->bus->add_listener(charon->bus, &this->forward->listener);
|
||||
}
|
||||
hydra->attributes->add_provider(hydra->attributes,
|
||||
&this->provider->provider);
|
||||
}
|
||||
else
|
||||
{
|
||||
hydra->attributes->remove_provider(hydra->attributes,
|
||||
&this->provider->provider);
|
||||
if (this->forward)
|
||||
{
|
||||
charon->bus->remove_listener(charon->bus, &this->forward->listener);
|
||||
this->forward->destroy(this->forward);
|
||||
}
|
||||
DESTROY_IF(this->dae);
|
||||
this->provider->destroy(this->provider);
|
||||
this->accounting->destroy(this->accounting);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(plugin_t, get_features, int,
|
||||
eap_radius_plugin_t *this, plugin_feature_t *features[])
|
||||
private_eap_radius_plugin_t *this, plugin_feature_t *features[])
|
||||
{
|
||||
static plugin_feature_t f[] = {
|
||||
PLUGIN_CALLBACK(eap_method_register, eap_radius_create),
|
||||
PLUGIN_PROVIDE(EAP_SERVER, EAP_RADIUS),
|
||||
PLUGIN_DEPENDS(CUSTOM, "eap-radius"),
|
||||
PLUGIN_CALLBACK((plugin_feature_callback_t)plugin_cb, NULL),
|
||||
PLUGIN_PROVIDE(CUSTOM, "eap-radius"),
|
||||
PLUGIN_DEPENDS(HASHER, HASH_MD5),
|
||||
PLUGIN_DEPENDS(SIGNER, AUTH_HMAC_MD5_128),
|
||||
PLUGIN_DEPENDS(RNG, RNG_WEAK),
|
||||
@@ -215,19 +261,9 @@ METHOD(plugin_t, reload, bool,
|
||||
METHOD(plugin_t, destroy, void,
|
||||
private_eap_radius_plugin_t *this)
|
||||
{
|
||||
hydra->attributes->remove_provider(hydra->attributes,
|
||||
&this->provider->provider);
|
||||
this->provider->destroy(this->provider);
|
||||
if (this->forward)
|
||||
{
|
||||
charon->bus->remove_listener(charon->bus, &this->forward->listener);
|
||||
this->forward->destroy(this->forward);
|
||||
}
|
||||
DESTROY_IF(this->dae);
|
||||
this->configs->destroy_offset(this->configs,
|
||||
offsetof(radius_config_t, destroy));
|
||||
this->lock->destroy(this->lock);
|
||||
this->accounting->destroy(this->accounting);
|
||||
free(this);
|
||||
instance = NULL;
|
||||
}
|
||||
@@ -250,26 +286,9 @@ plugin_t *eap_radius_plugin_create()
|
||||
},
|
||||
.configs = linked_list_create(),
|
||||
.lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
|
||||
.accounting = eap_radius_accounting_create(),
|
||||
.forward = eap_radius_forward_create(),
|
||||
.provider = eap_radius_provider_create(),
|
||||
);
|
||||
|
||||
load_configs(this);
|
||||
instance = this;
|
||||
|
||||
if (lib->settings->get_bool(lib->settings,
|
||||
"%s.plugins.eap-radius.dae.enable", FALSE, charon->name))
|
||||
{
|
||||
this->dae = eap_radius_dae_create(this->accounting);
|
||||
}
|
||||
if (this->forward)
|
||||
{
|
||||
charon->bus->add_listener(charon->bus, &this->forward->listener);
|
||||
}
|
||||
hydra->attributes->add_provider(hydra->attributes,
|
||||
&this->provider->provider);
|
||||
|
||||
return &this->public.plugin;
|
||||
}
|
||||
|
||||
|
||||
@@ -39,9 +39,4 @@ struct eap_tls_plugin_t {
|
||||
plugin_t plugin;
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a eap_tls_plugin instance.
|
||||
*/
|
||||
plugin_t *eap_tls_plugin_create();
|
||||
|
||||
#endif /** EAP_TLS_PLUGIN_H_ @}*/
|
||||
|
||||
@@ -39,9 +39,4 @@ struct eap_ttls_plugin_t {
|
||||
plugin_t plugin;
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a eap_ttls_plugin instance.
|
||||
*/
|
||||
plugin_t *eap_ttls_plugin_create();
|
||||
|
||||
#endif /** EAP_TTLS_PLUGIN_H_ @}*/
|
||||
|
||||
@@ -49,10 +49,37 @@ METHOD(plugin_t, get_name, char*,
|
||||
return "error-notify";
|
||||
}
|
||||
|
||||
/**
|
||||
* Register listener
|
||||
*/
|
||||
static bool plugin_cb(private_error_notify_plugin_t *this,
|
||||
plugin_feature_t *feature, bool reg, void *cb_data)
|
||||
{
|
||||
if (reg)
|
||||
{
|
||||
charon->bus->add_listener(charon->bus, &this->listener->listener);
|
||||
}
|
||||
else
|
||||
{
|
||||
charon->bus->remove_listener(charon->bus, &this->listener->listener);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(plugin_t, get_features, int,
|
||||
private_error_notify_plugin_t *this, plugin_feature_t *features[])
|
||||
{
|
||||
static plugin_feature_t f[] = {
|
||||
PLUGIN_CALLBACK((plugin_feature_callback_t)plugin_cb, NULL),
|
||||
PLUGIN_PROVIDE(CUSTOM, "error-notify"),
|
||||
};
|
||||
*features = f;
|
||||
return countof(f);
|
||||
}
|
||||
|
||||
METHOD(plugin_t, destroy, void,
|
||||
private_error_notify_plugin_t *this)
|
||||
{
|
||||
charon->bus->remove_listener(charon->bus, &this->listener->listener);
|
||||
this->listener->destroy(this->listener);
|
||||
this->socket->destroy(this->socket);
|
||||
free(this);
|
||||
@@ -69,7 +96,7 @@ plugin_t *error_notify_plugin_create()
|
||||
.public = {
|
||||
.plugin = {
|
||||
.get_name = _get_name,
|
||||
.reload = (void*)return_false,
|
||||
.get_features = _get_features,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
},
|
||||
@@ -77,7 +104,6 @@ plugin_t *error_notify_plugin_create()
|
||||
);
|
||||
|
||||
this->listener = error_notify_listener_create(this->socket);
|
||||
charon->bus->add_listener(charon->bus, &this->listener->listener);
|
||||
|
||||
return &this->public.plugin;
|
||||
}
|
||||
|
||||
@@ -49,11 +49,38 @@ METHOD(plugin_t, get_name, char*,
|
||||
return "farp";
|
||||
}
|
||||
|
||||
/**
|
||||
* Register listener
|
||||
*/
|
||||
static bool plugin_cb(private_farp_plugin_t *this,
|
||||
plugin_feature_t *feature, bool reg, void *cb_data)
|
||||
{
|
||||
if (reg)
|
||||
{
|
||||
charon->bus->add_listener(charon->bus, &this->listener->listener);
|
||||
}
|
||||
else
|
||||
{
|
||||
charon->bus->remove_listener(charon->bus, &this->listener->listener);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(plugin_t, get_features, int,
|
||||
private_farp_plugin_t *this, plugin_feature_t *features[])
|
||||
{
|
||||
static plugin_feature_t f[] = {
|
||||
PLUGIN_CALLBACK((plugin_feature_callback_t)plugin_cb, NULL),
|
||||
PLUGIN_PROVIDE(CUSTOM, "farp"),
|
||||
};
|
||||
*features = f;
|
||||
return countof(f);
|
||||
}
|
||||
|
||||
METHOD(plugin_t, destroy, void,
|
||||
private_farp_plugin_t *this)
|
||||
{
|
||||
DESTROY_IF(this->spoofer);
|
||||
charon->bus->remove_listener(charon->bus, &this->listener->listener);
|
||||
this->listener->destroy(this->listener);
|
||||
free(this);
|
||||
}
|
||||
@@ -69,15 +96,13 @@ plugin_t *farp_plugin_create()
|
||||
.public = {
|
||||
.plugin = {
|
||||
.get_name = _get_name,
|
||||
.reload = (void*)return_false,
|
||||
.get_features = _get_features,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
},
|
||||
.listener = farp_listener_create(),
|
||||
);
|
||||
|
||||
charon->bus->add_listener(charon->bus, &this->listener->listener);
|
||||
|
||||
this->spoofer = farp_spoofer_create(this->listener);
|
||||
if (!this->spoofer)
|
||||
{
|
||||
@@ -86,4 +111,3 @@ plugin_t *farp_plugin_create()
|
||||
}
|
||||
return &this->public.plugin;
|
||||
}
|
||||
|
||||
|
||||
@@ -97,14 +97,46 @@ METHOD(plugin_t, get_name, char*,
|
||||
return "ha";
|
||||
}
|
||||
|
||||
/**
|
||||
* Register listener
|
||||
*/
|
||||
static bool plugin_cb(private_ha_plugin_t *this,
|
||||
plugin_feature_t *feature, bool reg, void *cb_data)
|
||||
{
|
||||
if (reg)
|
||||
{
|
||||
charon->bus->add_listener(charon->bus, &this->segments->listener);
|
||||
charon->bus->add_listener(charon->bus, &this->ike->listener);
|
||||
charon->bus->add_listener(charon->bus, &this->child->listener);
|
||||
hydra->attributes->add_provider(hydra->attributes,
|
||||
&this->attr->provider);
|
||||
}
|
||||
else
|
||||
{
|
||||
hydra->attributes->remove_provider(hydra->attributes,
|
||||
&this->attr->provider);
|
||||
charon->bus->remove_listener(charon->bus, &this->segments->listener);
|
||||
charon->bus->remove_listener(charon->bus, &this->ike->listener);
|
||||
charon->bus->remove_listener(charon->bus, &this->child->listener);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(plugin_t, get_features, int,
|
||||
private_ha_plugin_t *this, plugin_feature_t *features[])
|
||||
{
|
||||
static plugin_feature_t f[] = {
|
||||
PLUGIN_CALLBACK((plugin_feature_callback_t)plugin_cb, NULL),
|
||||
PLUGIN_PROVIDE(CUSTOM, "ha"),
|
||||
};
|
||||
*features = f;
|
||||
return countof(f);
|
||||
}
|
||||
|
||||
METHOD(plugin_t, destroy, void,
|
||||
private_ha_plugin_t *this)
|
||||
{
|
||||
DESTROY_IF(this->ctl);
|
||||
hydra->attributes->remove_provider(hydra->attributes, &this->attr->provider);
|
||||
charon->bus->remove_listener(charon->bus, &this->segments->listener);
|
||||
charon->bus->remove_listener(charon->bus, &this->ike->listener);
|
||||
charon->bus->remove_listener(charon->bus, &this->child->listener);
|
||||
this->ike->destroy(this->ike);
|
||||
this->child->destroy(this->child);
|
||||
this->dispatcher->destroy(this->dispatcher);
|
||||
@@ -151,7 +183,7 @@ plugin_t *ha_plugin_create()
|
||||
.public = {
|
||||
.plugin = {
|
||||
.get_name = _get_name,
|
||||
.reload = (void*)return_false,
|
||||
.get_features = _get_features,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
},
|
||||
@@ -182,10 +214,6 @@ plugin_t *ha_plugin_create()
|
||||
this->ike = ha_ike_create(this->socket, this->tunnel, this->cache);
|
||||
this->child = ha_child_create(this->socket, this->tunnel, this->segments,
|
||||
this->kernel);
|
||||
charon->bus->add_listener(charon->bus, &this->segments->listener);
|
||||
charon->bus->add_listener(charon->bus, &this->ike->listener);
|
||||
charon->bus->add_listener(charon->bus, &this->child->listener);
|
||||
hydra->attributes->add_provider(hydra->attributes, &this->attr->provider);
|
||||
|
||||
return &this->public.plugin;
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ struct ipseckey_cred_t {
|
||||
* Create an ipseckey_cred instance which uses the given resolver
|
||||
* to query the DNS for IPSECKEY resource records.
|
||||
*
|
||||
* @param res resolver to use
|
||||
* @param res resolver to use (gets adopted)
|
||||
* @return credential set
|
||||
*/
|
||||
ipseckey_cred_t *ipseckey_cred_create(resolver_t *res);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Tobias Brunner
|
||||
* Copyright (C) 2012 Reto Guadagnini
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
@@ -31,11 +32,6 @@ struct private_ipseckey_plugin_t {
|
||||
*/
|
||||
ipseckey_plugin_t public;
|
||||
|
||||
/**
|
||||
* DNS resolver instance
|
||||
*/
|
||||
resolver_t *res;
|
||||
|
||||
/**
|
||||
* credential set
|
||||
*/
|
||||
@@ -53,15 +49,74 @@ METHOD(plugin_t, get_name, char*,
|
||||
return "ipseckey";
|
||||
}
|
||||
|
||||
METHOD(plugin_t, reload, bool,
|
||||
private_ipseckey_plugin_t *this)
|
||||
{
|
||||
bool enabled = lib->settings->get_bool(lib->settings,
|
||||
"%s.plugins.ipseckey.enable", FALSE, charon->name);
|
||||
|
||||
if (enabled != this->enabled)
|
||||
{
|
||||
if (enabled)
|
||||
{
|
||||
lib->credmgr->add_set(lib->credmgr, &this->cred->set);
|
||||
}
|
||||
else
|
||||
{
|
||||
lib->credmgr->remove_set(lib->credmgr, &this->cred->set);
|
||||
}
|
||||
this->enabled = enabled;
|
||||
}
|
||||
DBG1(DBG_CFG, "ipseckey plugin is %sabled", this->enabled ? "en" : "dis");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create resolver and register credential set
|
||||
*/
|
||||
static bool plugin_cb(private_ipseckey_plugin_t *this,
|
||||
plugin_feature_t *feature, bool reg, void *cb_data)
|
||||
{
|
||||
if (reg)
|
||||
{
|
||||
resolver_t *res;
|
||||
|
||||
res = lib->resolver->create(lib->resolver);
|
||||
if (!res)
|
||||
{
|
||||
DBG1(DBG_CFG, "failed to create a DNS resolver instance");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
this->cred = ipseckey_cred_create(res);
|
||||
reload(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (this->enabled)
|
||||
{
|
||||
lib->credmgr->remove_set(lib->credmgr, &this->cred->set);
|
||||
}
|
||||
this->cred->destroy(this->cred);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(plugin_t, get_features, int,
|
||||
private_ipseckey_plugin_t *this, plugin_feature_t *features[])
|
||||
{
|
||||
static plugin_feature_t f[] = {
|
||||
PLUGIN_CALLBACK((plugin_feature_callback_t)plugin_cb, NULL),
|
||||
PLUGIN_PROVIDE(CUSTOM, "ipseckey"),
|
||||
PLUGIN_DEPENDS(RESOLVER),
|
||||
};
|
||||
*features = f;
|
||||
return countof(f);
|
||||
}
|
||||
|
||||
METHOD(plugin_t, destroy, void,
|
||||
private_ipseckey_plugin_t *this)
|
||||
{
|
||||
if (this->enabled)
|
||||
{
|
||||
lib->credmgr->remove_set(lib->credmgr, &this->cred->set);
|
||||
}
|
||||
DESTROY_IF(this->res);
|
||||
DESTROY_IF(this->cred);
|
||||
free(this);
|
||||
}
|
||||
|
||||
@@ -76,28 +131,12 @@ plugin_t *ipseckey_plugin_create()
|
||||
.public = {
|
||||
.plugin = {
|
||||
.get_name = _get_name,
|
||||
.reload = (void*)return_false,
|
||||
.get_features = _get_features,
|
||||
.reload = _reload,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
},
|
||||
.res = lib->resolver->create(lib->resolver),
|
||||
.enabled = lib->settings->get_bool(lib->settings,
|
||||
"%s.plugins.ipseckey.enable", FALSE, charon->name),
|
||||
);
|
||||
|
||||
if (!this->res)
|
||||
{
|
||||
DBG1(DBG_CFG, "failed to create a DNS resolver instance");
|
||||
destroy(this);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (this->enabled)
|
||||
{
|
||||
this->cred = ipseckey_cred_create(this->res);
|
||||
lib->credmgr->add_set(lib->credmgr, &this->cred->set);
|
||||
}
|
||||
|
||||
return &this->public.plugin;
|
||||
}
|
||||
|
||||
|
||||
@@ -43,10 +43,37 @@ METHOD(plugin_t, get_name, char*,
|
||||
return "led";
|
||||
}
|
||||
|
||||
/**
|
||||
* Register listener
|
||||
*/
|
||||
static bool plugin_cb(private_led_plugin_t *this,
|
||||
plugin_feature_t *feature, bool reg, void *cb_data)
|
||||
{
|
||||
if (reg)
|
||||
{
|
||||
charon->bus->add_listener(charon->bus, &this->listener->listener);
|
||||
}
|
||||
else
|
||||
{
|
||||
charon->bus->remove_listener(charon->bus, &this->listener->listener);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(plugin_t, get_features, int,
|
||||
private_led_plugin_t *this, plugin_feature_t *features[])
|
||||
{
|
||||
static plugin_feature_t f[] = {
|
||||
PLUGIN_CALLBACK((plugin_feature_callback_t)plugin_cb, NULL),
|
||||
PLUGIN_PROVIDE(CUSTOM, "led"),
|
||||
};
|
||||
*features = f;
|
||||
return countof(f);
|
||||
}
|
||||
|
||||
METHOD(plugin_t, destroy, void,
|
||||
private_led_plugin_t *this)
|
||||
{
|
||||
charon->bus->remove_listener(charon->bus, &this->listener->listener);
|
||||
this->listener->destroy(this->listener);
|
||||
free(this);
|
||||
}
|
||||
@@ -62,14 +89,12 @@ plugin_t *led_plugin_create()
|
||||
.public = {
|
||||
.plugin = {
|
||||
.get_name = _get_name,
|
||||
.reload = (void*)return_false,
|
||||
.get_features = _get_features,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
},
|
||||
.listener = led_listener_create(),
|
||||
);
|
||||
|
||||
charon->bus->add_listener(charon->bus, &this->listener->listener);
|
||||
|
||||
return &this->public.plugin;
|
||||
}
|
||||
|
||||
@@ -49,11 +49,38 @@ METHOD(plugin_t, get_name, char*,
|
||||
return "lookip";
|
||||
}
|
||||
|
||||
/**
|
||||
* Register listener
|
||||
*/
|
||||
static bool plugin_cb(private_lookip_plugin_t *this,
|
||||
plugin_feature_t *feature, bool reg, void *cb_data)
|
||||
{
|
||||
if (reg)
|
||||
{
|
||||
charon->bus->add_listener(charon->bus, &this->listener->listener);
|
||||
}
|
||||
else
|
||||
{
|
||||
charon->bus->remove_listener(charon->bus, &this->listener->listener);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(plugin_t, get_features, int,
|
||||
private_lookip_plugin_t *this, plugin_feature_t *features[])
|
||||
{
|
||||
static plugin_feature_t f[] = {
|
||||
PLUGIN_CALLBACK((plugin_feature_callback_t)plugin_cb, NULL),
|
||||
PLUGIN_PROVIDE(CUSTOM, "lookip"),
|
||||
};
|
||||
*features = f;
|
||||
return countof(f);
|
||||
}
|
||||
|
||||
METHOD(plugin_t, destroy, void,
|
||||
private_lookip_plugin_t *this)
|
||||
{
|
||||
this->socket->destroy(this->socket);
|
||||
charon->bus->remove_listener(charon->bus, &this->listener->listener);
|
||||
this->listener->destroy(this->listener);
|
||||
free(this);
|
||||
}
|
||||
@@ -69,14 +96,12 @@ plugin_t *lookip_plugin_create()
|
||||
.public = {
|
||||
.plugin = {
|
||||
.get_name = _get_name,
|
||||
.reload = (void*)return_false,
|
||||
.get_features = _get_features,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
},
|
||||
.listener = lookip_listener_create(),
|
||||
);
|
||||
|
||||
charon->bus->add_listener(charon->bus, &this->listener->listener);
|
||||
this->socket = lookip_socket_create(this->listener);
|
||||
|
||||
return &this->public.plugin;
|
||||
|
||||
@@ -42,6 +42,17 @@ METHOD(plugin_t, get_name, char*,
|
||||
return "maemo";
|
||||
}
|
||||
|
||||
METHOD(plugin_t, get_features, int,
|
||||
private_maemo_plugin_t *this, plugin_feature_t *features[])
|
||||
{
|
||||
static plugin_feature_t f[] = {
|
||||
PLUGIN_NOOP,
|
||||
PLUGIN_PROVIDE(CUSTOM, "maemo"),
|
||||
};
|
||||
*features = f;
|
||||
return countof(f);
|
||||
}
|
||||
|
||||
METHOD(plugin_t, destroy, void,
|
||||
private_maemo_plugin_t *this)
|
||||
{
|
||||
@@ -60,7 +71,7 @@ plugin_t *maemo_plugin_create()
|
||||
.public = {
|
||||
.plugin = {
|
||||
.get_name = _get_name,
|
||||
.reload = (void*)return_false,
|
||||
.get_features = _get_features,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
},
|
||||
@@ -74,4 +85,3 @@ plugin_t *maemo_plugin_create()
|
||||
|
||||
return &this->public.plugin;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Tobias Brunner
|
||||
* Copyright (C) 2008 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
@@ -60,16 +61,67 @@ METHOD(plugin_t, get_name, char*,
|
||||
return "medcli";
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect to database
|
||||
*/
|
||||
static bool open_database(private_medcli_plugin_t *this,
|
||||
plugin_feature_t *feature, bool reg, void *cb_data)
|
||||
{
|
||||
if (reg)
|
||||
{
|
||||
char *uri;
|
||||
|
||||
uri = lib->settings->get_str(lib->settings,
|
||||
"medcli.database", NULL);
|
||||
if (!uri)
|
||||
{
|
||||
DBG1(DBG_CFG, "mediation client database URI not defined, skipped");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
this->db = lib->db->create(lib->db, uri);
|
||||
if (this->db == NULL)
|
||||
{
|
||||
DBG1(DBG_CFG, "opening mediation client database failed");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
this->creds = medcli_creds_create(this->db);
|
||||
this->config = medcli_config_create(this->db);
|
||||
this->listener = medcli_listener_create(this->db);
|
||||
|
||||
lib->credmgr->add_set(lib->credmgr, &this->creds->set);
|
||||
charon->backends->add_backend(charon->backends, &this->config->backend);
|
||||
charon->bus->add_listener(charon->bus, &this->listener->listener);
|
||||
}
|
||||
else
|
||||
{
|
||||
charon->bus->remove_listener(charon->bus, &this->listener->listener);
|
||||
charon->backends->remove_backend(charon->backends, &this->config->backend);
|
||||
lib->credmgr->remove_set(lib->credmgr, &this->creds->set);
|
||||
this->listener->destroy(this->listener);
|
||||
this->config->destroy(this->config);
|
||||
this->creds->destroy(this->creds);
|
||||
this->db->destroy(this->db);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(plugin_t, get_features, int,
|
||||
private_medcli_plugin_t *this, plugin_feature_t *features[])
|
||||
{
|
||||
static plugin_feature_t f[] = {
|
||||
PLUGIN_CALLBACK((plugin_feature_callback_t)open_database, NULL),
|
||||
PLUGIN_PROVIDE(CUSTOM, "medcli"),
|
||||
PLUGIN_DEPENDS(DATABASE, DB_ANY),
|
||||
};
|
||||
*features = f;
|
||||
return countof(f);
|
||||
}
|
||||
|
||||
METHOD(plugin_t, destroy, void,
|
||||
private_medcli_plugin_t *this)
|
||||
{
|
||||
charon->bus->remove_listener(charon->bus, &this->listener->listener);
|
||||
charon->backends->remove_backend(charon->backends, &this->config->backend);
|
||||
lib->credmgr->remove_set(lib->credmgr, &this->creds->set);
|
||||
this->listener->destroy(this->listener);
|
||||
this->config->destroy(this->config);
|
||||
this->creds->destroy(this->creds);
|
||||
this->db->destroy(this->db);
|
||||
free(this);
|
||||
}
|
||||
|
||||
@@ -78,44 +130,17 @@ METHOD(plugin_t, destroy, void,
|
||||
*/
|
||||
plugin_t *medcli_plugin_create()
|
||||
{
|
||||
char *uri;
|
||||
private_medcli_plugin_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.plugin = {
|
||||
.get_name = _get_name,
|
||||
.reload = (void*)return_false,
|
||||
.get_features = _get_features,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
uri = lib->settings->get_str(lib->settings,
|
||||
"medcli.database", NULL);
|
||||
if (!uri)
|
||||
{
|
||||
DBG1(DBG_CFG, "mediation client database URI not defined, skipped");
|
||||
free(this);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
this->db = lib->db->create(lib->db, uri);
|
||||
if (this->db == NULL)
|
||||
{
|
||||
DBG1(DBG_CFG, "opening mediation client database failed");
|
||||
free(this);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
this->creds = medcli_creds_create(this->db);
|
||||
this->config = medcli_config_create(this->db);
|
||||
this->listener = medcli_listener_create(this->db);
|
||||
|
||||
lib->credmgr->add_set(lib->credmgr, &this->creds->set);
|
||||
charon->backends->add_backend(charon->backends, &this->config->backend);
|
||||
charon->bus->add_listener(charon->bus, &this->listener->listener);
|
||||
|
||||
return &this->public.plugin;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Tobias Brunner
|
||||
* Copyright (C) 2008 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
@@ -54,14 +55,63 @@ METHOD(plugin_t, get_name, char*,
|
||||
return "medsrv";
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect to database
|
||||
*/
|
||||
static bool open_database(private_medsrv_plugin_t *this,
|
||||
plugin_feature_t *feature, bool reg, void *cb_data)
|
||||
{
|
||||
if (reg)
|
||||
{
|
||||
char *uri;
|
||||
|
||||
uri = lib->settings->get_str(lib->settings,
|
||||
"medsrv.database", NULL);
|
||||
if (!uri)
|
||||
{
|
||||
DBG1(DBG_CFG, "mediation database URI not defined, skipped");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
this->db = lib->db->create(lib->db, uri);
|
||||
if (this->db == NULL)
|
||||
{
|
||||
DBG1(DBG_CFG, "opening mediation server database failed");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
this->creds = medsrv_creds_create(this->db);
|
||||
this->config = medsrv_config_create(this->db);
|
||||
|
||||
lib->credmgr->add_set(lib->credmgr, &this->creds->set);
|
||||
charon->backends->add_backend(charon->backends, &this->config->backend);
|
||||
}
|
||||
else
|
||||
{
|
||||
charon->backends->remove_backend(charon->backends, &this->config->backend);
|
||||
lib->credmgr->remove_set(lib->credmgr, &this->creds->set);
|
||||
this->config->destroy(this->config);
|
||||
this->creds->destroy(this->creds);
|
||||
this->db->destroy(this->db);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(plugin_t, get_features, int,
|
||||
private_medsrv_plugin_t *this, plugin_feature_t *features[])
|
||||
{
|
||||
static plugin_feature_t f[] = {
|
||||
PLUGIN_CALLBACK((plugin_feature_callback_t)open_database, NULL),
|
||||
PLUGIN_PROVIDE(CUSTOM, "medsrv"),
|
||||
PLUGIN_DEPENDS(DATABASE, DB_ANY),
|
||||
};
|
||||
*features = f;
|
||||
return countof(f);
|
||||
}
|
||||
|
||||
METHOD(plugin_t, destroy, void,
|
||||
private_medsrv_plugin_t *this)
|
||||
{
|
||||
charon->backends->remove_backend(charon->backends, &this->config->backend);
|
||||
lib->credmgr->remove_set(lib->credmgr, &this->creds->set);
|
||||
this->config->destroy(this->config);
|
||||
this->creds->destroy(this->creds);
|
||||
this->db->destroy(this->db);
|
||||
free(this);
|
||||
}
|
||||
|
||||
@@ -70,42 +120,17 @@ METHOD(plugin_t, destroy, void,
|
||||
*/
|
||||
plugin_t *medsrv_plugin_create()
|
||||
{
|
||||
char *uri;
|
||||
private_medsrv_plugin_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.plugin = {
|
||||
.get_name = _get_name,
|
||||
.reload = (void*)return_false,
|
||||
.get_features = _get_features,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
uri = lib->settings->get_str(lib->settings,
|
||||
"medsrv.database", NULL);
|
||||
if (!uri)
|
||||
{
|
||||
DBG1(DBG_CFG, "mediation database URI not defined, skipped");
|
||||
free(this);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
this->db = lib->db->create(lib->db, uri);
|
||||
if (this->db == NULL)
|
||||
{
|
||||
DBG1(DBG_CFG, "opening mediation server database failed");
|
||||
free(this);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
this->creds = medsrv_creds_create(this->db);
|
||||
this->config = medsrv_config_create(this->db);
|
||||
|
||||
lib->credmgr->add_set(lib->credmgr, &this->creds->set);
|
||||
charon->backends->add_backend(charon->backends, &this->config->backend);
|
||||
|
||||
return &this->public.plugin;
|
||||
}
|
||||
|
||||
|
||||
@@ -43,10 +43,37 @@ METHOD(plugin_t, get_name, char*,
|
||||
return "radattr";
|
||||
}
|
||||
|
||||
/**
|
||||
* Register listener
|
||||
*/
|
||||
static bool plugin_cb(private_radattr_plugin_t *this,
|
||||
plugin_feature_t *feature, bool reg, void *cb_data)
|
||||
{
|
||||
if (reg)
|
||||
{
|
||||
charon->bus->add_listener(charon->bus, &this->listener->listener);
|
||||
}
|
||||
else
|
||||
{
|
||||
charon->bus->remove_listener(charon->bus, &this->listener->listener);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(plugin_t, get_features, int,
|
||||
private_radattr_plugin_t *this, plugin_feature_t *features[])
|
||||
{
|
||||
static plugin_feature_t f[] = {
|
||||
PLUGIN_CALLBACK((plugin_feature_callback_t)plugin_cb, NULL),
|
||||
PLUGIN_PROVIDE(CUSTOM, "radattr"),
|
||||
};
|
||||
*features = f;
|
||||
return countof(f);
|
||||
}
|
||||
|
||||
METHOD(plugin_t, destroy, void,
|
||||
private_radattr_plugin_t *this)
|
||||
{
|
||||
charon->bus->remove_listener(charon->bus, &this->listener->listener);
|
||||
this->listener->destroy(this->listener);
|
||||
free(this);
|
||||
}
|
||||
@@ -62,14 +89,12 @@ plugin_t *radattr_plugin_create()
|
||||
.public = {
|
||||
.plugin = {
|
||||
.get_name = _get_name,
|
||||
.reload = (void*)return_false,
|
||||
.get_features = _get_features,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
},
|
||||
.listener = radattr_listener_create(),
|
||||
);
|
||||
|
||||
charon->bus->add_listener(charon->bus, &this->listener->listener);
|
||||
|
||||
return &this->public.plugin;
|
||||
}
|
||||
|
||||
@@ -712,6 +712,17 @@ METHOD(plugin_t, get_name, char*,
|
||||
return "smp";
|
||||
}
|
||||
|
||||
METHOD(plugin_t, get_features, int,
|
||||
private_smp_t *this, plugin_feature_t *features[])
|
||||
{
|
||||
static plugin_feature_t f[] = {
|
||||
PLUGIN_NOOP,
|
||||
PLUGIN_PROVIDE(CUSTOM, "smp"),
|
||||
};
|
||||
*features = f;
|
||||
return countof(f);
|
||||
}
|
||||
|
||||
METHOD(plugin_t, destroy, void,
|
||||
private_smp_t *this)
|
||||
{
|
||||
@@ -732,7 +743,7 @@ plugin_t *smp_plugin_create()
|
||||
.public = {
|
||||
.plugin = {
|
||||
.get_name = _get_name,
|
||||
.reload = (void*)return_false,
|
||||
.get_features = _get_features,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
},
|
||||
@@ -777,4 +788,3 @@ plugin_t *smp_plugin_create()
|
||||
|
||||
return &this->public.plugin;
|
||||
}
|
||||
|
||||
|
||||
@@ -52,6 +52,7 @@ METHOD(plugin_t, get_features, int,
|
||||
static plugin_feature_t f[] = {
|
||||
PLUGIN_CALLBACK(socket_register, socket_default_socket_create),
|
||||
PLUGIN_PROVIDE(CUSTOM, "socket"),
|
||||
PLUGIN_SDEPEND(CUSTOM, "kernel-ipsec"),
|
||||
};
|
||||
*features = f;
|
||||
return countof(f);
|
||||
|
||||
@@ -40,6 +40,7 @@ METHOD(plugin_t, get_features, int,
|
||||
static plugin_feature_t f[] = {
|
||||
PLUGIN_CALLBACK(socket_register, socket_dynamic_socket_create),
|
||||
PLUGIN_PROVIDE(CUSTOM, "socket"),
|
||||
PLUGIN_SDEPEND(CUSTOM, "kernel-ipsec"),
|
||||
};
|
||||
*features = f;
|
||||
return countof(f);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Tobias Brunner
|
||||
* Copyright (C) 2008 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
@@ -16,6 +17,8 @@
|
||||
#include "sql_plugin.h"
|
||||
|
||||
#include <daemon.h>
|
||||
#include <plugins/plugin_feature.h>
|
||||
|
||||
#include "sql_config.h"
|
||||
#include "sql_cred.h"
|
||||
#include "sql_logger.h"
|
||||
@@ -59,16 +62,67 @@ METHOD(plugin_t, get_name, char*,
|
||||
return "sql";
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect to database
|
||||
*/
|
||||
static bool open_database(private_sql_plugin_t *this,
|
||||
plugin_feature_t *feature, bool reg, void *cb_data)
|
||||
{
|
||||
if (reg)
|
||||
{
|
||||
char *uri;
|
||||
|
||||
uri = lib->settings->get_str(lib->settings, "%s.plugins.sql.database",
|
||||
NULL, charon->name);
|
||||
if (!uri)
|
||||
{
|
||||
DBG1(DBG_CFG, "sql plugin: database URI not set");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
this->db = lib->db->create(lib->db, uri);
|
||||
if (!this->db)
|
||||
{
|
||||
DBG1(DBG_CFG, "sql plugin failed to connect to database");
|
||||
return FALSE;
|
||||
}
|
||||
this->config = sql_config_create(this->db);
|
||||
this->cred = sql_cred_create(this->db);
|
||||
this->logger = sql_logger_create(this->db);
|
||||
|
||||
charon->backends->add_backend(charon->backends, &this->config->backend);
|
||||
lib->credmgr->add_set(lib->credmgr, &this->cred->set);
|
||||
charon->bus->add_logger(charon->bus, &this->logger->logger);
|
||||
}
|
||||
else
|
||||
{
|
||||
charon->backends->remove_backend(charon->backends,
|
||||
&this->config->backend);
|
||||
lib->credmgr->remove_set(lib->credmgr, &this->cred->set);
|
||||
charon->bus->remove_logger(charon->bus, &this->logger->logger);
|
||||
this->config->destroy(this->config);
|
||||
this->cred->destroy(this->cred);
|
||||
this->logger->destroy(this->logger);
|
||||
this->db->destroy(this->db);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(plugin_t, get_features, int,
|
||||
private_sql_plugin_t *this, plugin_feature_t *features[])
|
||||
{
|
||||
static plugin_feature_t f[] = {
|
||||
PLUGIN_CALLBACK((plugin_feature_callback_t)open_database, NULL),
|
||||
PLUGIN_PROVIDE(CUSTOM, "sql"),
|
||||
PLUGIN_DEPENDS(DATABASE, DB_ANY),
|
||||
};
|
||||
*features = f;
|
||||
return countof(f);
|
||||
}
|
||||
|
||||
METHOD(plugin_t, destroy, void,
|
||||
private_sql_plugin_t *this)
|
||||
{
|
||||
charon->backends->remove_backend(charon->backends, &this->config->backend);
|
||||
lib->credmgr->remove_set(lib->credmgr, &this->cred->set);
|
||||
charon->bus->remove_logger(charon->bus, &this->logger->logger);
|
||||
this->config->destroy(this->config);
|
||||
this->cred->destroy(this->cred);
|
||||
this->logger->destroy(this->logger);
|
||||
this->db->destroy(this->db);
|
||||
free(this);
|
||||
}
|
||||
|
||||
@@ -77,42 +131,17 @@ METHOD(plugin_t, destroy, void,
|
||||
*/
|
||||
plugin_t *sql_plugin_create()
|
||||
{
|
||||
char *uri;
|
||||
private_sql_plugin_t *this;
|
||||
|
||||
uri = lib->settings->get_str(lib->settings, "%s.plugins.sql.database",
|
||||
NULL, charon->name);
|
||||
if (!uri)
|
||||
{
|
||||
DBG1(DBG_CFG, "sql plugin: database URI not set");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.plugin = {
|
||||
.get_name = _get_name,
|
||||
.reload = (void*)return_false,
|
||||
.get_features = _get_features,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
},
|
||||
.db = lib->db->create(lib->db, uri),
|
||||
);
|
||||
|
||||
if (!this->db)
|
||||
{
|
||||
DBG1(DBG_CFG, "sql plugin failed to connect to database");
|
||||
free(this);
|
||||
return NULL;
|
||||
}
|
||||
this->config = sql_config_create(this->db);
|
||||
this->cred = sql_cred_create(this->db);
|
||||
this->logger = sql_logger_create(this->db);
|
||||
|
||||
charon->backends->add_backend(charon->backends, &this->config->backend);
|
||||
lib->credmgr->add_set(lib->credmgr, &this->cred->set);
|
||||
charon->bus->add_logger(charon->bus, &this->logger->logger);
|
||||
|
||||
return &this->public.plugin;
|
||||
}
|
||||
|
||||
|
||||
@@ -1364,6 +1364,7 @@ static void list_plugins(FILE *out)
|
||||
free(str);
|
||||
}
|
||||
}
|
||||
list->destroy(list);
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Tobias Brunner
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* Copyright (C) 2013 Martin Willi
|
||||
* Copyright (C) 2013 revosec AG
|
||||
*
|
||||
@@ -68,17 +71,6 @@ METHOD(plugin_t, get_name, char*,
|
||||
return "systime-fix";
|
||||
}
|
||||
|
||||
METHOD(plugin_t, destroy, void,
|
||||
private_systime_fix_plugin_t *this)
|
||||
{
|
||||
if (this->validator)
|
||||
{
|
||||
lib->credmgr->remove_validator(lib->credmgr, &this->validator->validator);
|
||||
this->validator->destroy(this->validator);
|
||||
}
|
||||
free(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if all certificates associated to an IKE_SA have valid lifetimes
|
||||
*/
|
||||
@@ -215,11 +207,57 @@ static bool load_validator(private_systime_fix_plugin_t *this)
|
||||
|
||||
DBG1(DBG_CFG, "enabling %s, threshold: %s", get_name(this), asctime(&tm));
|
||||
this->validator = systime_fix_validator_create(this->threshold);
|
||||
lib->credmgr->add_validator(lib->credmgr, &this->validator->validator);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load validator
|
||||
*/
|
||||
static bool plugin_cb(private_systime_fix_plugin_t *this,
|
||||
plugin_feature_t *feature, bool reg, void *cb_data)
|
||||
{
|
||||
if (reg)
|
||||
{
|
||||
if (!load_validator(this))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
lib->credmgr->add_validator(lib->credmgr, &this->validator->validator);
|
||||
if (this->interval != 0)
|
||||
{
|
||||
DBG1(DBG_CFG, "starting systime check, interval: %ds",
|
||||
this->interval);
|
||||
lib->scheduler->schedule_job(lib->scheduler, (job_t*)
|
||||
callback_job_create((callback_job_cb_t)check_systime,
|
||||
this, NULL, NULL), this->interval);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lib->credmgr->remove_validator(lib->credmgr,
|
||||
&this->validator->validator);
|
||||
this->validator->destroy(this->validator);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(plugin_t, get_features, int,
|
||||
private_systime_fix_plugin_t *this, plugin_feature_t *features[])
|
||||
{
|
||||
static plugin_feature_t f[] = {
|
||||
PLUGIN_CALLBACK((plugin_feature_callback_t)plugin_cb, NULL),
|
||||
PLUGIN_PROVIDE(CUSTOM, "systime-fix"),
|
||||
};
|
||||
*features = f;
|
||||
return countof(f);
|
||||
}
|
||||
|
||||
METHOD(plugin_t, destroy, void,
|
||||
private_systime_fix_plugin_t *this)
|
||||
{
|
||||
free(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Plugin constructor
|
||||
*/
|
||||
@@ -231,7 +269,7 @@ plugin_t *systime_fix_plugin_create()
|
||||
.public = {
|
||||
.plugin = {
|
||||
.get_name = _get_name,
|
||||
.reload = (void*)return_false,
|
||||
.get_features = _get_features,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
},
|
||||
@@ -241,16 +279,5 @@ plugin_t *systime_fix_plugin_create()
|
||||
"%s.plugins.%s.reauth", FALSE, charon->name, get_name(this)),
|
||||
);
|
||||
|
||||
if (load_validator(this))
|
||||
{
|
||||
if (this->interval != 0)
|
||||
{
|
||||
DBG1(DBG_CFG, "starting systime check, interval: %ds",
|
||||
this->interval);
|
||||
lib->scheduler->schedule_job(lib->scheduler, (job_t*)
|
||||
callback_job_create((callback_job_cb_t)check_systime, this,
|
||||
NULL, NULL), this->interval);
|
||||
}
|
||||
}
|
||||
return &this->public.plugin;
|
||||
}
|
||||
|
||||
@@ -64,11 +64,40 @@ METHOD(plugin_t, get_name, char*,
|
||||
return "uci";
|
||||
}
|
||||
|
||||
/**
|
||||
* Register backend
|
||||
*/
|
||||
static bool plugin_cb(private_uci_plugin_t *this,
|
||||
plugin_feature_t *feature, bool reg, void *cb_data)
|
||||
{
|
||||
if (reg)
|
||||
{
|
||||
charon->backends->add_backend(charon->backends, &this->config->backend);
|
||||
lib->credmgr->add_set(lib->credmgr, &this->creds->credential_set);
|
||||
}
|
||||
else
|
||||
{
|
||||
charon->backends->remove_backend(charon->backends,
|
||||
&this->config->backend);
|
||||
lib->credmgr->remove_set(lib->credmgr, &this->creds->credential_set);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(plugin_t, get_features, int,
|
||||
private_uci_plugin_t *this, plugin_feature_t *features[])
|
||||
{
|
||||
static plugin_feature_t f[] = {
|
||||
PLUGIN_CALLBACK((plugin_feature_callback_t)plugin_cb, NULL),
|
||||
PLUGIN_PROVIDE(CUSTOM, "uci"),
|
||||
};
|
||||
*features = f;
|
||||
return countof(f);
|
||||
}
|
||||
|
||||
METHOD(plugin_t, destroy, void,
|
||||
private_uci_plugin_t *this)
|
||||
{
|
||||
charon->backends->remove_backend(charon->backends, &this->config->backend);
|
||||
lib->credmgr->remove_set(lib->credmgr, &this->creds->credential_set);
|
||||
this->config->destroy(this->config);
|
||||
this->creds->destroy(this->creds);
|
||||
this->parser->destroy(this->parser);
|
||||
@@ -87,7 +116,7 @@ plugin_t *uci_plugin_create()
|
||||
.public = {
|
||||
.plugin = {
|
||||
.get_name = _get_name,
|
||||
.reload = (void*)return_false,
|
||||
.get_features = _get_features,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
},
|
||||
@@ -97,9 +126,5 @@ plugin_t *uci_plugin_create()
|
||||
this->config = uci_config_create(this->parser);
|
||||
this->creds = uci_creds_create(this->parser);
|
||||
|
||||
charon->backends->add_backend(charon->backends, &this->config->backend);
|
||||
lib->credmgr->add_set(lib->credmgr, &this->creds->credential_set);
|
||||
|
||||
return &this->public.plugin;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Tobias Brunner
|
||||
* Copyright (C) 2007 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
@@ -98,6 +99,32 @@ METHOD(plugin_t, get_name, char*,
|
||||
return "unit-tester";
|
||||
}
|
||||
|
||||
/**
|
||||
* We currently don't depend explicitly on any plugin features. But in case
|
||||
* activated tests depend on such features we at least try to run them in plugin
|
||||
* order.
|
||||
*/
|
||||
static bool plugin_cb(private_unit_tester_t *this,
|
||||
plugin_feature_t *feature, bool reg, void *cb_data)
|
||||
{
|
||||
if (reg)
|
||||
{
|
||||
run_tests(this);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(plugin_t, get_features, int,
|
||||
private_unit_tester_t *this, plugin_feature_t *features[])
|
||||
{
|
||||
static plugin_feature_t f[] = {
|
||||
PLUGIN_CALLBACK((plugin_feature_callback_t)plugin_cb, NULL),
|
||||
PLUGIN_PROVIDE(CUSTOM, "unit-tester"),
|
||||
};
|
||||
*features = f;
|
||||
return countof(f);
|
||||
}
|
||||
|
||||
METHOD(plugin_t, destroy, void,
|
||||
private_unit_tester_t *this)
|
||||
{
|
||||
@@ -115,14 +142,11 @@ plugin_t *unit_tester_plugin_create()
|
||||
.public = {
|
||||
.plugin = {
|
||||
.get_name = _get_name,
|
||||
.reload = (void*)return_false,
|
||||
.get_features = _get_features,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
run_tests(this);
|
||||
|
||||
return &this->public.plugin;
|
||||
}
|
||||
|
||||
|
||||
@@ -55,14 +55,47 @@ METHOD(plugin_t, get_name, char*,
|
||||
return "unity";
|
||||
}
|
||||
|
||||
/**
|
||||
* Register listener
|
||||
*/
|
||||
static bool plugin_cb(private_unity_plugin_t *this,
|
||||
plugin_feature_t *feature, bool reg, void *cb_data)
|
||||
{
|
||||
if (reg)
|
||||
{
|
||||
hydra->attributes->add_handler(hydra->attributes,
|
||||
&this->handler->handler);
|
||||
hydra->attributes->add_provider(hydra->attributes,
|
||||
&this->provider->provider);
|
||||
charon->bus->add_listener(charon->bus, &this->narrower->listener);
|
||||
}
|
||||
else
|
||||
{
|
||||
charon->bus->remove_listener(charon->bus, &this->narrower->listener);
|
||||
hydra->attributes->remove_handler(hydra->attributes,
|
||||
&this->handler->handler);
|
||||
hydra->attributes->remove_provider(hydra->attributes,
|
||||
&this->provider->provider);
|
||||
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(plugin_t, get_features, int,
|
||||
private_unity_plugin_t *this, plugin_feature_t *features[])
|
||||
{
|
||||
static plugin_feature_t f[] = {
|
||||
PLUGIN_CALLBACK((plugin_feature_callback_t)plugin_cb, NULL),
|
||||
PLUGIN_PROVIDE(CUSTOM, "unity"),
|
||||
};
|
||||
*features = f;
|
||||
return countof(f);
|
||||
}
|
||||
|
||||
METHOD(plugin_t, destroy, void,
|
||||
private_unity_plugin_t *this)
|
||||
{
|
||||
charon->bus->remove_listener(charon->bus, &this->narrower->listener);
|
||||
this->narrower->destroy(this->narrower);
|
||||
hydra->attributes->remove_handler(hydra->attributes, &this->handler->handler);
|
||||
hydra->attributes->remove_provider(hydra->attributes,
|
||||
&this->provider->provider);
|
||||
this->handler->destroy(this->handler);
|
||||
this->provider->destroy(this->provider);
|
||||
free(this);
|
||||
@@ -79,18 +112,14 @@ plugin_t *unity_plugin_create()
|
||||
.public = {
|
||||
.plugin = {
|
||||
.get_name = _get_name,
|
||||
.reload = (void*)return_false,
|
||||
.get_features = _get_features,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
},
|
||||
.handler = unity_handler_create(),
|
||||
.provider = unity_provider_create(),
|
||||
);
|
||||
hydra->attributes->add_handler(hydra->attributes, &this->handler->handler);
|
||||
hydra->attributes->add_provider(hydra->attributes, &this->provider->provider);
|
||||
|
||||
this->narrower = unity_narrow_create(this->handler),
|
||||
charon->bus->add_listener(charon->bus, &this->narrower->listener);
|
||||
this->narrower = unity_narrow_create(this->handler);
|
||||
|
||||
return &this->public.plugin;
|
||||
}
|
||||
|
||||
@@ -49,17 +49,52 @@ METHOD(plugin_t, get_name, char*,
|
||||
return "updown";
|
||||
}
|
||||
|
||||
/**
|
||||
* Register listener
|
||||
*/
|
||||
static bool plugin_cb(private_updown_plugin_t *this,
|
||||
plugin_feature_t *feature, bool reg, void *cb_data)
|
||||
{
|
||||
if (reg)
|
||||
{
|
||||
if (lib->settings->get_bool(lib->settings,
|
||||
"charon.plugins.updown.dns_handler", FALSE))
|
||||
{
|
||||
this->handler = updown_handler_create();
|
||||
hydra->attributes->add_handler(hydra->attributes,
|
||||
&this->handler->handler);
|
||||
}
|
||||
this->listener = updown_listener_create(this->handler);
|
||||
charon->bus->add_listener(charon->bus, &this->listener->listener);
|
||||
}
|
||||
else
|
||||
{
|
||||
charon->bus->remove_listener(charon->bus, &this->listener->listener);
|
||||
this->listener->destroy(this->listener);
|
||||
if (this->handler)
|
||||
{
|
||||
this->handler->destroy(this->handler);
|
||||
hydra->attributes->remove_handler(hydra->attributes,
|
||||
&this->handler->handler);
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(plugin_t, get_features, int,
|
||||
private_updown_plugin_t *this, plugin_feature_t *features[])
|
||||
{
|
||||
static plugin_feature_t f[] = {
|
||||
PLUGIN_CALLBACK((plugin_feature_callback_t)plugin_cb, NULL),
|
||||
PLUGIN_PROVIDE(CUSTOM, "updown"),
|
||||
};
|
||||
*features = f;
|
||||
return countof(f);
|
||||
}
|
||||
|
||||
METHOD(plugin_t, destroy, void,
|
||||
private_updown_plugin_t *this)
|
||||
{
|
||||
charon->bus->remove_listener(charon->bus, &this->listener->listener);
|
||||
this->listener->destroy(this->listener);
|
||||
if (this->handler)
|
||||
{
|
||||
hydra->attributes->remove_handler(hydra->attributes,
|
||||
&this->handler->handler);
|
||||
this->handler->destroy(this->handler);
|
||||
}
|
||||
free(this);
|
||||
}
|
||||
|
||||
@@ -74,22 +109,11 @@ plugin_t *updown_plugin_create()
|
||||
.public = {
|
||||
.plugin = {
|
||||
.get_name = _get_name,
|
||||
.reload = (void*)return_false,
|
||||
.get_features = _get_features,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
if (lib->settings->get_bool(lib->settings,
|
||||
"charon.plugins.updown.dns_handler", FALSE))
|
||||
{
|
||||
this->handler = updown_handler_create();
|
||||
hydra->attributes->add_handler(hydra->attributes,
|
||||
&this->handler->handler);
|
||||
}
|
||||
this->listener = updown_listener_create(this->handler);
|
||||
charon->bus->add_listener(charon->bus, &this->listener->listener);
|
||||
|
||||
return &this->public.plugin;
|
||||
}
|
||||
|
||||
|
||||
@@ -49,10 +49,37 @@ METHOD(plugin_t, get_name, char*,
|
||||
return "whitelist";
|
||||
}
|
||||
|
||||
/**
|
||||
* Register listener
|
||||
*/
|
||||
static bool plugin_cb(private_whitelist_plugin_t *this,
|
||||
plugin_feature_t *feature, bool reg, void *cb_data)
|
||||
{
|
||||
if (reg)
|
||||
{
|
||||
charon->bus->add_listener(charon->bus, &this->listener->listener);
|
||||
}
|
||||
else
|
||||
{
|
||||
charon->bus->remove_listener(charon->bus, &this->listener->listener);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(plugin_t, get_features, int,
|
||||
private_whitelist_plugin_t *this, plugin_feature_t *features[])
|
||||
{
|
||||
static plugin_feature_t f[] = {
|
||||
PLUGIN_CALLBACK((plugin_feature_callback_t)plugin_cb, NULL),
|
||||
PLUGIN_PROVIDE(CUSTOM, "whitelist"),
|
||||
};
|
||||
*features = f;
|
||||
return countof(f);
|
||||
}
|
||||
|
||||
METHOD(plugin_t, destroy, void,
|
||||
private_whitelist_plugin_t *this)
|
||||
{
|
||||
charon->bus->remove_listener(charon->bus, &this->listener->listener);
|
||||
this->listener->destroy(this->listener);
|
||||
DESTROY_IF(this->control);
|
||||
free(this);
|
||||
@@ -69,7 +96,7 @@ plugin_t *whitelist_plugin_create()
|
||||
.public = {
|
||||
.plugin = {
|
||||
.get_name = _get_name,
|
||||
.reload = (void*)return_false,
|
||||
.get_features = _get_features,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
},
|
||||
@@ -77,7 +104,5 @@ plugin_t *whitelist_plugin_create()
|
||||
);
|
||||
this->control = whitelist_control_create(this->listener);
|
||||
|
||||
charon->bus->add_listener(charon->bus, &this->listener->listener);
|
||||
|
||||
return &this->public.plugin;
|
||||
}
|
||||
|
||||
@@ -42,6 +42,36 @@ METHOD(plugin_t, get_name, char*,
|
||||
return "attr";
|
||||
}
|
||||
|
||||
/**
|
||||
* Register provider
|
||||
*/
|
||||
static bool plugin_cb(private_attr_plugin_t *this,
|
||||
plugin_feature_t *feature, bool reg, void *cb_data)
|
||||
{
|
||||
if (reg)
|
||||
{
|
||||
hydra->attributes->add_provider(hydra->attributes,
|
||||
&this->provider->provider);
|
||||
}
|
||||
else
|
||||
{
|
||||
hydra->attributes->remove_provider(hydra->attributes,
|
||||
&this->provider->provider);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(plugin_t, get_features, int,
|
||||
private_attr_plugin_t *this, plugin_feature_t *features[])
|
||||
{
|
||||
static plugin_feature_t f[] = {
|
||||
PLUGIN_CALLBACK((plugin_feature_callback_t)plugin_cb, NULL),
|
||||
PLUGIN_PROVIDE(CUSTOM, "attr"),
|
||||
};
|
||||
*features = f;
|
||||
return countof(f);
|
||||
}
|
||||
|
||||
METHOD(plugin_t, reload, bool,
|
||||
private_attr_plugin_t *this)
|
||||
{
|
||||
@@ -52,7 +82,6 @@ METHOD(plugin_t, reload, bool,
|
||||
METHOD(plugin_t, destroy, void,
|
||||
private_attr_plugin_t *this)
|
||||
{
|
||||
hydra->attributes->remove_provider(hydra->attributes, &this->provider->provider);
|
||||
this->provider->destroy(this->provider);
|
||||
free(this);
|
||||
}
|
||||
@@ -68,14 +97,13 @@ plugin_t *attr_plugin_create()
|
||||
.public = {
|
||||
.plugin = {
|
||||
.get_name = _get_name,
|
||||
.get_features = _get_features,
|
||||
.reload = _reload,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
},
|
||||
.provider = attr_provider_create(),
|
||||
);
|
||||
hydra->attributes->add_provider(hydra->attributes, &this->provider->provider);
|
||||
|
||||
return &this->public.plugin;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Tobias Brunner
|
||||
* Copyright (C) 2008 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
@@ -15,6 +16,7 @@
|
||||
|
||||
#include <hydra.h>
|
||||
#include <utils/debug.h>
|
||||
#include <plugins/plugin_feature.h>
|
||||
|
||||
#include "attr_sql_plugin.h"
|
||||
#include "sql_attribute.h"
|
||||
@@ -48,12 +50,59 @@ METHOD(plugin_t, get_name, char*,
|
||||
return "attr-sql";
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect to database
|
||||
*/
|
||||
static bool open_database(private_attr_sql_plugin_t *this,
|
||||
plugin_feature_t *feature, bool reg, void *cb_data)
|
||||
{
|
||||
if (reg)
|
||||
{
|
||||
char *uri;
|
||||
|
||||
uri = lib->settings->get_str(lib->settings,
|
||||
"libhydra.plugins.attr-sql.database", NULL);
|
||||
if (!uri)
|
||||
{
|
||||
DBG1(DBG_CFG, "attr-sql plugin: database URI not set");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
this->db = lib->db->create(lib->db, uri);
|
||||
if (!this->db)
|
||||
{
|
||||
DBG1(DBG_CFG, "attr-sql plugin failed to connect to database");
|
||||
return FALSE;
|
||||
}
|
||||
this->attribute = sql_attribute_create(this->db);
|
||||
hydra->attributes->add_provider(hydra->attributes,
|
||||
&this->attribute->provider);
|
||||
}
|
||||
else
|
||||
{
|
||||
hydra->attributes->remove_provider(hydra->attributes,
|
||||
&this->attribute->provider);
|
||||
this->attribute->destroy(this->attribute);
|
||||
this->db->destroy(this->db);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(plugin_t, get_features, int,
|
||||
private_attr_sql_plugin_t *this, plugin_feature_t *features[])
|
||||
{
|
||||
static plugin_feature_t f[] = {
|
||||
PLUGIN_CALLBACK((plugin_feature_callback_t)open_database, NULL),
|
||||
PLUGIN_PROVIDE(CUSTOM, "attr-sql"),
|
||||
PLUGIN_DEPENDS(DATABASE, DB_ANY),
|
||||
};
|
||||
*features = f;
|
||||
return countof(f);
|
||||
}
|
||||
|
||||
METHOD(plugin_t, destroy, void,
|
||||
private_attr_sql_plugin_t *this)
|
||||
{
|
||||
hydra->attributes->remove_provider(hydra->attributes, &this->attribute->provider);
|
||||
this->attribute->destroy(this->attribute);
|
||||
this->db->destroy(this->db);
|
||||
free(this);
|
||||
}
|
||||
|
||||
@@ -63,36 +112,16 @@ METHOD(plugin_t, destroy, void,
|
||||
plugin_t *attr_sql_plugin_create()
|
||||
{
|
||||
private_attr_sql_plugin_t *this;
|
||||
char *uri;
|
||||
|
||||
uri = lib->settings->get_str(lib->settings, "libhydra.plugins.attr-sql.database",
|
||||
NULL);
|
||||
if (!uri)
|
||||
{
|
||||
DBG1(DBG_CFG, "attr-sql plugin: database URI not set");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.plugin = {
|
||||
.get_name = _get_name,
|
||||
.reload = (void*)return_false,
|
||||
.get_features = _get_features,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
},
|
||||
.db = lib->db->create(lib->db, uri),
|
||||
);
|
||||
|
||||
if (!this->db)
|
||||
{
|
||||
DBG1(DBG_CFG, "attr-sql plugin failed to connect to database");
|
||||
free(this);
|
||||
return NULL;
|
||||
}
|
||||
this->attribute = sql_attribute_create(this->db);
|
||||
hydra->attributes->add_provider(hydra->attributes, &this->attribute->provider);
|
||||
|
||||
return &this->public.plugin;
|
||||
}
|
||||
|
||||
|
||||
@@ -42,10 +42,39 @@ METHOD(plugin_t, get_name, char*,
|
||||
return "resolve";
|
||||
}
|
||||
|
||||
/**
|
||||
* Register handler
|
||||
*/
|
||||
static bool plugin_cb(private_resolve_plugin_t *this,
|
||||
plugin_feature_t *feature, bool reg, void *cb_data)
|
||||
{
|
||||
if (reg)
|
||||
{
|
||||
hydra->attributes->add_handler(hydra->attributes,
|
||||
&this->handler->handler);
|
||||
}
|
||||
else
|
||||
{
|
||||
hydra->attributes->remove_handler(hydra->attributes,
|
||||
&this->handler->handler);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(plugin_t, get_features, int,
|
||||
private_resolve_plugin_t *this, plugin_feature_t *features[])
|
||||
{
|
||||
static plugin_feature_t f[] = {
|
||||
PLUGIN_CALLBACK((plugin_feature_callback_t)plugin_cb, NULL),
|
||||
PLUGIN_PROVIDE(CUSTOM, "resolve"),
|
||||
};
|
||||
*features = f;
|
||||
return countof(f);
|
||||
}
|
||||
|
||||
METHOD(plugin_t, destroy, void,
|
||||
private_resolve_plugin_t *this)
|
||||
{
|
||||
hydra->attributes->remove_handler(hydra->attributes, &this->handler->handler);
|
||||
this->handler->destroy(this->handler);
|
||||
free(this);
|
||||
}
|
||||
@@ -61,13 +90,12 @@ plugin_t *resolve_plugin_create()
|
||||
.public = {
|
||||
.plugin = {
|
||||
.get_name = _get_name,
|
||||
.reload = (void*)return_false,
|
||||
.get_features = _get_features,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
},
|
||||
.handler = resolve_handler_create(),
|
||||
);
|
||||
hydra->attributes->add_handler(hydra->attributes, &this->handler->handler);
|
||||
|
||||
return &this->public.plugin;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2008 Martin Willi
|
||||
* Copyright (C) 2009 Andreas Steffen
|
||||
* Copyright (C) 2008 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
@@ -38,11 +38,20 @@ METHOD(plugin_t, get_name, char*,
|
||||
return "blowfish";
|
||||
}
|
||||
|
||||
METHOD(plugin_t, get_features, int,
|
||||
private_blowfish_plugin_t *this, plugin_feature_t *features[])
|
||||
{
|
||||
static plugin_feature_t f[] = {
|
||||
PLUGIN_REGISTER(CRYPTER, blowfish_crypter_create),
|
||||
PLUGIN_PROVIDE(CRYPTER, ENCR_BLOWFISH, 0),
|
||||
};
|
||||
*features = f;
|
||||
return countof(f);
|
||||
}
|
||||
|
||||
METHOD(plugin_t, destroy, void,
|
||||
private_blowfish_plugin_t *this)
|
||||
{
|
||||
lib->crypto->remove_crypter(lib->crypto,
|
||||
(crypter_constructor_t)blowfish_crypter_create);
|
||||
free(this);
|
||||
}
|
||||
|
||||
@@ -57,15 +66,11 @@ plugin_t *blowfish_plugin_create()
|
||||
.public = {
|
||||
.plugin = {
|
||||
.get_name = _get_name,
|
||||
.reload = (void*)return_false,
|
||||
.get_features = _get_features,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
lib->crypto->add_crypter(lib->crypto, ENCR_BLOWFISH, get_name(this),
|
||||
(crypter_constructor_t)blowfish_crypter_create);
|
||||
|
||||
return &this->public.plugin;
|
||||
}
|
||||
|
||||
|
||||
@@ -42,10 +42,39 @@ METHOD(plugin_t, get_name, char*,
|
||||
return "constraints";
|
||||
}
|
||||
|
||||
/**
|
||||
* Register validator
|
||||
*/
|
||||
static bool plugin_cb(private_constraints_plugin_t *this,
|
||||
plugin_feature_t *feature, bool reg, void *cb_data)
|
||||
{
|
||||
if (reg)
|
||||
{
|
||||
lib->credmgr->add_validator(lib->credmgr, &this->validator->validator);
|
||||
}
|
||||
else
|
||||
{
|
||||
lib->credmgr->remove_validator(lib->credmgr,
|
||||
&this->validator->validator);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(plugin_t, get_features, int,
|
||||
private_constraints_plugin_t *this, plugin_feature_t *features[])
|
||||
{
|
||||
static plugin_feature_t f[] = {
|
||||
PLUGIN_CALLBACK((plugin_feature_callback_t)plugin_cb, NULL),
|
||||
PLUGIN_PROVIDE(CUSTOM, "constraints"),
|
||||
PLUGIN_SDEPEND(CERT_DECODE, CERT_X509),
|
||||
};
|
||||
*features = f;
|
||||
return countof(f);
|
||||
}
|
||||
|
||||
METHOD(plugin_t, destroy, void,
|
||||
private_constraints_plugin_t *this)
|
||||
{
|
||||
lib->credmgr->remove_validator(lib->credmgr, &this->validator->validator);
|
||||
this->validator->destroy(this->validator);
|
||||
free(this);
|
||||
}
|
||||
@@ -61,13 +90,12 @@ plugin_t *constraints_plugin_create()
|
||||
.public = {
|
||||
.plugin = {
|
||||
.get_name = _get_name,
|
||||
.reload = (void*)return_false,
|
||||
.get_features = _get_features,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
},
|
||||
.validator = constraints_validator_create(),
|
||||
);
|
||||
lib->credmgr->add_validator(lib->credmgr, &this->validator->validator);
|
||||
|
||||
return &this->public.plugin;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Tobias Brunner
|
||||
* Copyright (C) 2008 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
@@ -21,6 +22,7 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include <library.h>
|
||||
#include <plugins/plugin_feature.h>
|
||||
#include <utils/debug.h>
|
||||
|
||||
typedef struct private_padlock_plugin_t private_padlock_plugin_t;
|
||||
@@ -107,28 +109,49 @@ METHOD(plugin_t, get_name, char*,
|
||||
return "padlock";
|
||||
}
|
||||
|
||||
METHOD(plugin_t, get_features, int,
|
||||
private_padlock_plugin_t *this, plugin_feature_t *features[])
|
||||
{
|
||||
static plugin_feature_t f_rng[] = {
|
||||
PLUGIN_REGISTER(RNG, padlock_rng_create),
|
||||
PLUGIN_PROVIDE(RNG, RNG_WEAK),
|
||||
PLUGIN_PROVIDE(RNG, RNG_STRONG),
|
||||
PLUGIN_PROVIDE(RNG, RNG_TRUE),
|
||||
};
|
||||
static plugin_feature_t f_aes[] = {
|
||||
PLUGIN_REGISTER(CRYPTER, padlock_aes_crypter_create),
|
||||
PLUGIN_PROVIDE(CRYPTER, ENCR_AES_CBC, 16),
|
||||
};
|
||||
static plugin_feature_t f_sha1[] = {
|
||||
PLUGIN_REGISTER(HASHER, padlock_sha1_hasher_create),
|
||||
PLUGIN_PROVIDE(HASHER, HASH_SHA1),
|
||||
};
|
||||
static plugin_feature_t f[countof(f_rng) + countof(f_aes) +
|
||||
countof(f_sha1)] = {};
|
||||
static int count = 0;
|
||||
|
||||
if (!count)
|
||||
{ /* initialize only once */
|
||||
if (this->features & PADLOCK_RNG_ENABLED)
|
||||
{
|
||||
plugin_features_add(f, f_rng, countof(f_rng), &count);
|
||||
}
|
||||
if (this->features & PADLOCK_ACE2_ENABLED)
|
||||
{
|
||||
plugin_features_add(f, f_aes, countof(f_aes), &count);
|
||||
}
|
||||
if (this->features & PADLOCK_PHE_ENABLED)
|
||||
{
|
||||
plugin_features_add(f, f_sha1, countof(f_sha1), &count);
|
||||
}
|
||||
}
|
||||
*features = f;
|
||||
return count;
|
||||
}
|
||||
|
||||
METHOD(plugin_t, destroy, void,
|
||||
private_padlock_plugin_t *this)
|
||||
{
|
||||
if (this->features & PADLOCK_RNG_ENABLED)
|
||||
{
|
||||
lib->crypto->remove_rng(lib->crypto,
|
||||
(rng_constructor_t)padlock_rng_create);
|
||||
lib->crypto->remove_rng(lib->crypto,
|
||||
(rng_constructor_t)padlock_rng_create);
|
||||
lib->crypto->remove_rng(lib->crypto,
|
||||
(rng_constructor_t)padlock_rng_create);
|
||||
}
|
||||
if (this->features & PADLOCK_ACE2_ENABLED)
|
||||
{
|
||||
lib->crypto->remove_crypter(lib->crypto,
|
||||
(crypter_constructor_t)padlock_aes_crypter_create);
|
||||
}
|
||||
if (this->features & PADLOCK_PHE_ENABLED)
|
||||
{
|
||||
lib->crypto->remove_hasher(lib->crypto,
|
||||
(hasher_constructor_t)padlock_sha1_hasher_create);
|
||||
}
|
||||
free(this);
|
||||
}
|
||||
|
||||
@@ -143,7 +166,7 @@ plugin_t *padlock_plugin_create()
|
||||
.public = {
|
||||
.plugin = {
|
||||
.get_name = _get_name,
|
||||
.reload = (void*)return_false,
|
||||
.get_features = _get_features,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
},
|
||||
@@ -167,24 +190,5 @@ plugin_t *padlock_plugin_create()
|
||||
this->features & PADLOCK_PHE_ENABLED ? " PHE" : "",
|
||||
this->features & PADLOCK_PMM_ENABLED ? " PMM" : "");
|
||||
|
||||
if (this->features & PADLOCK_RNG_ENABLED)
|
||||
{
|
||||
lib->crypto->add_rng(lib->crypto, RNG_TRUE, get_name(this),
|
||||
(rng_constructor_t)padlock_rng_create);
|
||||
lib->crypto->add_rng(lib->crypto, RNG_STRONG, get_name(this),
|
||||
(rng_constructor_t)padlock_rng_create);
|
||||
lib->crypto->add_rng(lib->crypto, RNG_WEAK, get_name(this),
|
||||
(rng_constructor_t)padlock_rng_create);
|
||||
}
|
||||
if (this->features & PADLOCK_ACE2_ENABLED)
|
||||
{
|
||||
lib->crypto->add_crypter(lib->crypto, ENCR_AES_CBC, get_name(this),
|
||||
(crypter_constructor_t)padlock_aes_crypter_create);
|
||||
}
|
||||
if (this->features & PADLOCK_PHE_ENABLED)
|
||||
{
|
||||
lib->crypto->add_hasher(lib->crypto, HASH_SHA1, get_name(this),
|
||||
(hasher_constructor_t)padlock_sha1_hasher_create);
|
||||
}
|
||||
return &this->public.plugin;
|
||||
}
|
||||
|
||||
@@ -185,19 +185,6 @@ METHOD(plugin_t, reload, bool,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a set of features
|
||||
*/
|
||||
static inline void add_features(plugin_feature_t *f, plugin_feature_t *n,
|
||||
int count, int *pos)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
f[(*pos)++] = n[i];
|
||||
}
|
||||
}
|
||||
|
||||
METHOD(plugin_t, get_features, int,
|
||||
private_pkcs11_plugin_t *this, plugin_feature_t *features[])
|
||||
{
|
||||
@@ -261,32 +248,32 @@ METHOD(plugin_t, get_features, int,
|
||||
{ /* initialize only once */
|
||||
bool use_ecc = lib->settings->get_bool(lib->settings,
|
||||
"libstrongswan.plugins.pkcs11.use_ecc", FALSE);
|
||||
add_features(f, f_manager, countof(f_manager), &count);
|
||||
plugin_features_add(f, f_manager, countof(f_manager), &count);
|
||||
/* private key handling for EC keys is not disabled by use_ecc */
|
||||
add_features(f, f_privkey, countof(f_privkey), &count);
|
||||
plugin_features_add(f, f_privkey, countof(f_privkey), &count);
|
||||
if (lib->settings->get_bool(lib->settings,
|
||||
"libstrongswan.plugins.pkcs11.use_pubkey", FALSE))
|
||||
{
|
||||
add_features(f, f_pubkey, countof(f_pubkey) - (use_ecc ? 0 : 1),
|
||||
&count);
|
||||
plugin_features_add(f, f_pubkey, countof(f_pubkey) - (use_ecc ? 0 : 1),
|
||||
&count);
|
||||
}
|
||||
if (lib->settings->get_bool(lib->settings,
|
||||
"libstrongswan.plugins.pkcs11.use_hasher", FALSE))
|
||||
{
|
||||
add_features(f, f_hash, countof(f_hash), &count);
|
||||
plugin_features_add(f, f_hash, countof(f_hash), &count);
|
||||
}
|
||||
if (lib->settings->get_bool(lib->settings,
|
||||
"libstrongswan.plugins.pkcs11.use_rng", FALSE))
|
||||
{
|
||||
add_features(f, f_rng, countof(f_rng), &count);
|
||||
plugin_features_add(f, f_rng, countof(f_rng), &count);
|
||||
}
|
||||
if (lib->settings->get_bool(lib->settings,
|
||||
"libstrongswan.plugins.pkcs11.use_dh", FALSE))
|
||||
{
|
||||
add_features(f, f_dh, countof(f_dh), &count);
|
||||
plugin_features_add(f, f_dh, countof(f_dh), &count);
|
||||
if (use_ecc)
|
||||
{
|
||||
add_features(f, f_ecdh, countof(f_ecdh), &count);
|
||||
plugin_features_add(f, f_ecdh, countof(f_ecdh), &count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2012 Tobias Brunner
|
||||
* Copyright (C) 2012-2013 Tobias Brunner
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* Copyright (C) 2011 Martin Willi
|
||||
@@ -50,6 +50,7 @@ ENUM(plugin_feature_names, FEATURE_NONE, FEATURE_CUSTOM,
|
||||
"XAUTH_CLIENT",
|
||||
"DATABASE",
|
||||
"FETCHER",
|
||||
"RESOLVER",
|
||||
"CUSTOM",
|
||||
);
|
||||
|
||||
@@ -67,6 +68,7 @@ u_int32_t plugin_feature_hash(plugin_feature_t *feature)
|
||||
case FEATURE_NONCE_GEN:
|
||||
case FEATURE_DATABASE:
|
||||
case FEATURE_FETCHER:
|
||||
case FEATURE_RESOLVER:
|
||||
/* put these special cases in their (type-specific) buckets */
|
||||
data = chunk_empty;
|
||||
break;
|
||||
@@ -133,6 +135,7 @@ bool plugin_feature_matches(plugin_feature_t *a, plugin_feature_t *b)
|
||||
case FEATURE_RNG:
|
||||
return a->arg.rng_quality <= b->arg.rng_quality;
|
||||
case FEATURE_NONCE_GEN:
|
||||
case FEATURE_RESOLVER:
|
||||
return TRUE;
|
||||
case FEATURE_PRIVKEY:
|
||||
case FEATURE_PRIVKEY_GEN:
|
||||
@@ -169,6 +172,56 @@ bool plugin_feature_matches(plugin_feature_t *a, plugin_feature_t *b)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* See header.
|
||||
*/
|
||||
bool plugin_feature_equals(plugin_feature_t *a, plugin_feature_t *b)
|
||||
{
|
||||
if (a->type == b->type)
|
||||
{
|
||||
switch (a->type)
|
||||
{
|
||||
case FEATURE_NONE:
|
||||
case FEATURE_CRYPTER:
|
||||
case FEATURE_AEAD:
|
||||
case FEATURE_SIGNER:
|
||||
case FEATURE_HASHER:
|
||||
case FEATURE_PRF:
|
||||
case FEATURE_DH:
|
||||
case FEATURE_NONCE_GEN:
|
||||
case FEATURE_RESOLVER:
|
||||
case FEATURE_PRIVKEY:
|
||||
case FEATURE_PRIVKEY_GEN:
|
||||
case FEATURE_PUBKEY:
|
||||
case FEATURE_PRIVKEY_SIGN:
|
||||
case FEATURE_PUBKEY_VERIFY:
|
||||
case FEATURE_PRIVKEY_DECRYPT:
|
||||
case FEATURE_PUBKEY_ENCRYPT:
|
||||
case FEATURE_CERT_DECODE:
|
||||
case FEATURE_CERT_ENCODE:
|
||||
case FEATURE_CONTAINER_DECODE:
|
||||
case FEATURE_CONTAINER_ENCODE:
|
||||
case FEATURE_EAP_SERVER:
|
||||
case FEATURE_EAP_PEER:
|
||||
case FEATURE_CUSTOM:
|
||||
case FEATURE_XAUTH_SERVER:
|
||||
case FEATURE_XAUTH_PEER:
|
||||
return plugin_feature_matches(a, b);
|
||||
case FEATURE_RNG:
|
||||
return a->arg.rng_quality == b->arg.rng_quality;
|
||||
case FEATURE_DATABASE:
|
||||
return a->arg.database == b->arg.database;
|
||||
case FEATURE_FETCHER:
|
||||
if (a->arg.fetcher && b->arg.fetcher)
|
||||
{
|
||||
return streq(a->arg.fetcher, b->arg.fetcher);
|
||||
}
|
||||
return !a->arg.fetcher && !b->arg.fetcher;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* See header.
|
||||
*/
|
||||
@@ -236,6 +289,7 @@ char* plugin_feature_get_string(plugin_feature_t *feature)
|
||||
}
|
||||
break;
|
||||
case FEATURE_NONCE_GEN:
|
||||
case FEATURE_RESOLVER:
|
||||
if (asprintf(&str, "%N", plugin_feature_names, feature->type) > 0)
|
||||
{
|
||||
return str;
|
||||
@@ -413,6 +467,9 @@ bool plugin_feature_load(plugin_t *plugin, plugin_feature_t *feature,
|
||||
lib->fetcher->add_fetcher(lib->fetcher, reg->arg.reg.f,
|
||||
feature->arg.fetcher);
|
||||
break;
|
||||
case FEATURE_RESOLVER:
|
||||
lib->resolver->add_resolver(lib->resolver, reg->arg.reg.f);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -485,6 +542,9 @@ bool plugin_feature_unload(plugin_t *plugin, plugin_feature_t *feature,
|
||||
case FEATURE_FETCHER:
|
||||
lib->fetcher->remove_fetcher(lib->fetcher, reg->arg.reg.f);
|
||||
break;
|
||||
case FEATURE_RESOLVER:
|
||||
lib->resolver->remove_resolver(lib->resolver, reg->arg.reg.f);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2012 Tobias Brunner
|
||||
* Copyright (C) 2012-2013 Tobias Brunner
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* Copyright (C) 2011 Martin Willi
|
||||
@@ -150,6 +150,8 @@ struct plugin_feature_t {
|
||||
FEATURE_DATABASE,
|
||||
/** fetcher_t */
|
||||
FEATURE_FETCHER,
|
||||
/** resolver_t */
|
||||
FEATURE_RESOLVER,
|
||||
/** custom feature, described with a string */
|
||||
FEATURE_CUSTOM,
|
||||
} type;
|
||||
@@ -294,6 +296,7 @@ struct plugin_feature_t {
|
||||
#define _PLUGIN_FEATURE_EAP_PEER(kind, type) __PLUGIN_FEATURE(kind, EAP_PEER, .eap = type)
|
||||
#define _PLUGIN_FEATURE_DATABASE(kind, type) __PLUGIN_FEATURE(kind, DATABASE, .database = type)
|
||||
#define _PLUGIN_FEATURE_FETCHER(kind, type) __PLUGIN_FEATURE(kind, FETCHER, .fetcher = type)
|
||||
#define _PLUGIN_FEATURE_RESOLVER(kind, ...) __PLUGIN_FEATURE(kind, RESOLVER, .custom = NULL)
|
||||
#define _PLUGIN_FEATURE_CUSTOM(kind, name) __PLUGIN_FEATURE(kind, CUSTOM, .custom = name)
|
||||
#define _PLUGIN_FEATURE_XAUTH_SERVER(kind, name) __PLUGIN_FEATURE(kind, XAUTH_SERVER, .xauth = name)
|
||||
#define _PLUGIN_FEATURE_XAUTH_PEER(kind, name) __PLUGIN_FEATURE(kind, XAUTH_PEER, .xauth = name)
|
||||
@@ -317,6 +320,7 @@ struct plugin_feature_t {
|
||||
#define _PLUGIN_FEATURE_REGISTER_CONTAINER_ENCODE(type, f, final)__PLUGIN_FEATURE_REGISTER_BUILDER(type, f, final)
|
||||
#define _PLUGIN_FEATURE_REGISTER_DATABASE(type, f) __PLUGIN_FEATURE_REGISTER(type, f)
|
||||
#define _PLUGIN_FEATURE_REGISTER_FETCHER(type, f) __PLUGIN_FEATURE_REGISTER(type, f)
|
||||
#define _PLUGIN_FEATURE_REGISTER_RESOLVER(type, f) __PLUGIN_FEATURE_REGISTER(type, f)
|
||||
|
||||
#define _PLUGIN_FEATURE_CALLBACK(_cb, _data) (plugin_feature_t){ FEATURE_CALLBACK, FEATURE_NONE, .arg.cb = { .f = _cb, .data = _data } }
|
||||
|
||||
@@ -325,6 +329,27 @@ struct plugin_feature_t {
|
||||
*/
|
||||
extern enum_name_t *plugin_feature_names;
|
||||
|
||||
/**
|
||||
* Add a set of plugin features to the given array, which must have enough space
|
||||
* to store the added features.
|
||||
*
|
||||
* @param features the array of plugin features to extend
|
||||
* @param to_add the features to add
|
||||
* @param count number of features to add
|
||||
* @param pos current position in the features array, gets advanced
|
||||
*/
|
||||
static inline void plugin_features_add(plugin_feature_t *features,
|
||||
plugin_feature_t *to_add,
|
||||
int count, int *pos)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
features[(*pos)++] = to_add[i];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates a hash value for the given feature.
|
||||
*
|
||||
@@ -340,12 +365,25 @@ u_int32_t plugin_feature_hash(plugin_feature_t *feature);
|
||||
/**
|
||||
* Check if feature a matches to feature b.
|
||||
*
|
||||
* This is no check for equality. For instance, for FEATURE_RNG a matches b if
|
||||
* a's strength is at least the strength of b. Or for FEATURE_SQL if a is
|
||||
* DB_ANY it will match b if it is of the same type.
|
||||
*
|
||||
* @param a feature to check
|
||||
* @param b feature to match against
|
||||
* @return TRUE if a matches b
|
||||
*/
|
||||
bool plugin_feature_matches(plugin_feature_t *a, plugin_feature_t *b);
|
||||
|
||||
/**
|
||||
* Check if feature a equals feature b.
|
||||
*
|
||||
* @param a feature
|
||||
* @param b feature to compare
|
||||
* @return TRUE if a equals b
|
||||
*/
|
||||
bool plugin_feature_equals(plugin_feature_t *a, plugin_feature_t *b);
|
||||
|
||||
/**
|
||||
* Get a string describing feature.
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2012 Tobias Brunner
|
||||
* Copyright (C) 2010-2013 Tobias Brunner
|
||||
* Copyright (C) 2007 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
@@ -30,6 +30,8 @@
|
||||
#include <utils/integrity_checker.h>
|
||||
|
||||
typedef struct private_plugin_loader_t private_plugin_loader_t;
|
||||
typedef struct registered_feature_t registered_feature_t;
|
||||
typedef struct provided_feature_t provided_feature_t;
|
||||
typedef struct plugin_entry_t plugin_entry_t;
|
||||
|
||||
/**
|
||||
@@ -48,9 +50,14 @@ struct private_plugin_loader_t {
|
||||
linked_list_t *plugins;
|
||||
|
||||
/**
|
||||
* Hashtable for loaded features, as plugin_feature_t
|
||||
* Hashtable for registered features, as registered_feature_t
|
||||
*/
|
||||
hashtable_t *loaded_features;
|
||||
hashtable_t *features;
|
||||
|
||||
/**
|
||||
* Loaded features (stored in reverse order), as provided_feature_t
|
||||
*/
|
||||
linked_list_t *loaded;
|
||||
|
||||
/**
|
||||
* List of names of loaded plugins
|
||||
@@ -58,6 +65,80 @@ struct private_plugin_loader_t {
|
||||
char *loaded_plugins;
|
||||
};
|
||||
|
||||
/**
|
||||
* Registered plugin feature
|
||||
*/
|
||||
struct registered_feature_t {
|
||||
|
||||
/**
|
||||
* The registered feature
|
||||
*/
|
||||
plugin_feature_t *feature;
|
||||
|
||||
/**
|
||||
* List of plugins providing this feature, as provided_feature_t
|
||||
*/
|
||||
linked_list_t *plugins;
|
||||
};
|
||||
|
||||
/**
|
||||
* Hash a registered feature
|
||||
*/
|
||||
static bool registered_feature_hash(registered_feature_t *this)
|
||||
{
|
||||
return plugin_feature_hash(this->feature);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare two registered features
|
||||
*/
|
||||
static bool registered_feature_equals(registered_feature_t *a,
|
||||
registered_feature_t *b)
|
||||
{
|
||||
return plugin_feature_equals(a->feature, b->feature);
|
||||
}
|
||||
|
||||
/**
|
||||
* Feature as provided by a plugin
|
||||
*/
|
||||
struct provided_feature_t {
|
||||
|
||||
/**
|
||||
* Plugin providing the feature
|
||||
*/
|
||||
plugin_entry_t *entry;
|
||||
|
||||
/**
|
||||
* FEATURE_REGISTER or FEATURE_CALLBACK entry
|
||||
*/
|
||||
plugin_feature_t *reg;
|
||||
|
||||
/**
|
||||
* The provided feature (followed by dependencies)
|
||||
*/
|
||||
plugin_feature_t *feature;
|
||||
|
||||
/**
|
||||
* Maximum number of dependencies (following feature)
|
||||
*/
|
||||
int dependencies;
|
||||
|
||||
/**
|
||||
* TRUE if currently loading this feature (to prevent loops)
|
||||
*/
|
||||
bool loading;
|
||||
|
||||
/**
|
||||
* TRUE if feature loaded
|
||||
*/
|
||||
bool loaded;
|
||||
|
||||
/**
|
||||
* TRUE if feature failed to load
|
||||
*/
|
||||
bool failed;
|
||||
};
|
||||
|
||||
/**
|
||||
* Entry for a plugin
|
||||
*/
|
||||
@@ -79,14 +160,9 @@ struct plugin_entry_t {
|
||||
void *handle;
|
||||
|
||||
/**
|
||||
* List of loaded features
|
||||
* List of features, as provided_feature_t
|
||||
*/
|
||||
linked_list_t *loaded;
|
||||
|
||||
/**
|
||||
* List features failed to load
|
||||
*/
|
||||
linked_list_t *failed;
|
||||
linked_list_t *features;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -99,8 +175,7 @@ static void plugin_entry_destroy(plugin_entry_t *entry)
|
||||
{
|
||||
dlclose(entry->handle);
|
||||
}
|
||||
entry->loaded->destroy(entry->loaded);
|
||||
entry->failed->destroy(entry->failed);
|
||||
entry->features->destroy(entry->features);
|
||||
free(entry);
|
||||
}
|
||||
|
||||
@@ -176,14 +251,6 @@ static plugin_t *static_features_create(const char *name,
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare function for hashtable of loaded features.
|
||||
*/
|
||||
static bool plugin_feature_equals(plugin_feature_t *a, plugin_feature_t *b)
|
||||
{
|
||||
return a == b;
|
||||
}
|
||||
|
||||
/**
|
||||
* create a plugin
|
||||
* returns: NOT_FOUND, if the constructor was not found
|
||||
@@ -228,8 +295,7 @@ static status_t create_plugin(private_plugin_loader_t *this, void *handle,
|
||||
INIT(*entry,
|
||||
.plugin = plugin,
|
||||
.critical = critical,
|
||||
.loaded = linked_list_create(),
|
||||
.failed = linked_list_create(),
|
||||
.features = linked_list_create(),
|
||||
);
|
||||
DBG2(DBG_LIB, "plugin '%s': loaded successfully", name);
|
||||
return SUCCESS;
|
||||
@@ -238,8 +304,8 @@ static status_t create_plugin(private_plugin_loader_t *this, void *handle,
|
||||
/**
|
||||
* load a single plugin
|
||||
*/
|
||||
static bool load_plugin(private_plugin_loader_t *this, char *name, char *file,
|
||||
bool critical)
|
||||
static plugin_entry_t *load_plugin(private_plugin_loader_t *this, char *name,
|
||||
char *file, bool critical)
|
||||
{
|
||||
plugin_entry_t *entry;
|
||||
void *handle;
|
||||
@@ -248,7 +314,7 @@ static bool load_plugin(private_plugin_loader_t *this, char *name, char *file,
|
||||
{
|
||||
case SUCCESS:
|
||||
this->plugins->insert_last(this->plugins, entry);
|
||||
return TRUE;
|
||||
return entry;
|
||||
case NOT_FOUND:
|
||||
if (file)
|
||||
{ /* try to load the plugin from a file */
|
||||
@@ -256,7 +322,7 @@ static bool load_plugin(private_plugin_loader_t *this, char *name, char *file,
|
||||
}
|
||||
/* fall-through */
|
||||
default:
|
||||
return FALSE;
|
||||
return NULL;
|
||||
}
|
||||
if (lib->integrity)
|
||||
{
|
||||
@@ -264,23 +330,33 @@ static bool load_plugin(private_plugin_loader_t *this, char *name, char *file,
|
||||
{
|
||||
DBG1(DBG_LIB, "plugin '%s': failed file integrity test of '%s'",
|
||||
name, file);
|
||||
return FALSE;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
handle = dlopen(file, RTLD_LAZY);
|
||||
if (handle == NULL)
|
||||
{
|
||||
DBG1(DBG_LIB, "plugin '%s' failed to load: %s", name, dlerror());
|
||||
return FALSE;
|
||||
return NULL;
|
||||
}
|
||||
if (create_plugin(this, handle, name, TRUE, critical, &entry) != SUCCESS)
|
||||
{
|
||||
dlclose(handle);
|
||||
return FALSE;
|
||||
return NULL;
|
||||
}
|
||||
entry->handle = handle;
|
||||
this->plugins->insert_last(this->plugins, entry);
|
||||
return TRUE;
|
||||
return entry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert enumerated provided_feature_t to plugin_feature_t
|
||||
*/
|
||||
static bool feature_filter(void *null, provided_feature_t **provided,
|
||||
plugin_feature_t **feature)
|
||||
{
|
||||
*feature = (*provided)->feature;
|
||||
return (*provided)->loaded;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -289,10 +365,16 @@ static bool load_plugin(private_plugin_loader_t *this, char *name, char *file,
|
||||
static bool plugin_filter(void *null, plugin_entry_t **entry, plugin_t **plugin,
|
||||
void *in, linked_list_t **list)
|
||||
{
|
||||
*plugin = (*entry)->plugin;
|
||||
plugin_entry_t *this = *entry;
|
||||
|
||||
*plugin = this->plugin;
|
||||
if (list)
|
||||
{
|
||||
*list = (*entry)->loaded;
|
||||
enumerator_t *features;
|
||||
features = enumerator_create_filter(
|
||||
this->features->create_enumerator(this->features),
|
||||
(void*)feature_filter, NULL, NULL);
|
||||
*list = linked_list_create_from_enumerator(features);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
@@ -336,7 +418,6 @@ static char* loaded_plugins_list(private_plugin_loader_t *this)
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if a plugin is already loaded
|
||||
*/
|
||||
@@ -360,59 +441,171 @@ static bool plugin_loaded(private_plugin_loader_t *this, char *name)
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a feature of a plugin is already loaded
|
||||
* Forward declaration
|
||||
*/
|
||||
static bool feature_loaded(private_plugin_loader_t *this, plugin_entry_t *entry,
|
||||
plugin_feature_t *feature)
|
||||
static void load_provided(private_plugin_loader_t *this,
|
||||
provided_feature_t *provided,
|
||||
int level);
|
||||
|
||||
/**
|
||||
* Used to find a loaded feature
|
||||
*/
|
||||
static bool is_feature_loaded(provided_feature_t *item)
|
||||
{
|
||||
return entry->loaded->find_first(entry->loaded, NULL,
|
||||
(void**)&feature) == SUCCESS;
|
||||
return item->loaded;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if loading a feature of a plugin failed
|
||||
* Used to find a loadable feature
|
||||
*/
|
||||
static bool feature_failed(private_plugin_loader_t *this, plugin_entry_t *entry,
|
||||
plugin_feature_t *feature)
|
||||
static bool is_feature_loadable(provided_feature_t *item)
|
||||
{
|
||||
return entry->failed->find_first(entry->failed, NULL,
|
||||
(void**)&feature) == SUCCESS;
|
||||
return !item->loading && !item->loaded && !item->failed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if dependencies are satisfied
|
||||
* Find a loaded and matching feature
|
||||
*/
|
||||
static bool dependencies_satisfied(private_plugin_loader_t *this,
|
||||
plugin_entry_t *entry, bool soft, bool report,
|
||||
plugin_feature_t *features, int count)
|
||||
static bool loaded_feature_matches(registered_feature_t *a,
|
||||
registered_feature_t *b)
|
||||
{
|
||||
if (plugin_feature_matches(a->feature, b->feature))
|
||||
{
|
||||
return b->plugins->find_first(b->plugins, (void*)is_feature_loaded,
|
||||
NULL) == SUCCESS;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a loadable module that equals the requested feature
|
||||
*/
|
||||
static bool loadable_feature_equals(registered_feature_t *a,
|
||||
registered_feature_t *b)
|
||||
{
|
||||
if (plugin_feature_equals(a->feature, b->feature))
|
||||
{
|
||||
return b->plugins->find_first(b->plugins, (void*)is_feature_loadable,
|
||||
NULL) == SUCCESS;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a loadable module that matches the requested feature
|
||||
*/
|
||||
static bool loadable_feature_matches(registered_feature_t *a,
|
||||
registered_feature_t *b)
|
||||
{
|
||||
if (plugin_feature_matches(a->feature, b->feature))
|
||||
{
|
||||
return b->plugins->find_first(b->plugins, (void*)is_feature_loadable,
|
||||
NULL) == SUCCESS;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a compatible plugin feature for the given depencency
|
||||
*/
|
||||
static bool find_compatible_feature(private_plugin_loader_t *this,
|
||||
plugin_feature_t *dependency)
|
||||
{
|
||||
registered_feature_t *feature, lookup = {
|
||||
.feature = dependency,
|
||||
};
|
||||
|
||||
feature = this->features->get_match(this->features, &lookup,
|
||||
(void*)loaded_feature_matches);
|
||||
return feature != NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a registered plugin feature
|
||||
*/
|
||||
static void load_registered(private_plugin_loader_t *this,
|
||||
registered_feature_t *registered,
|
||||
int level)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
provided_feature_t *provided;
|
||||
|
||||
enumerator = registered->plugins->create_enumerator(registered->plugins);
|
||||
while (enumerator->enumerate(enumerator, &provided))
|
||||
{
|
||||
load_provided(this, provided, level);
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to load dependencies of the given feature
|
||||
*/
|
||||
static bool load_dependencies(private_plugin_loader_t *this,
|
||||
provided_feature_t *provided,
|
||||
int level)
|
||||
{
|
||||
registered_feature_t *registered, lookup;
|
||||
int indent = level * 2;
|
||||
int i;
|
||||
|
||||
/* first entry is provided feature, followed by dependencies */
|
||||
for (i = 1; i < count; i++)
|
||||
for (i = 1; i < provided->dependencies; i++)
|
||||
{
|
||||
plugin_feature_t *found;
|
||||
|
||||
if (features[i].kind != FEATURE_DEPENDS &&
|
||||
features[i].kind != FEATURE_SDEPEND)
|
||||
if (provided->feature[i].kind != FEATURE_DEPENDS &&
|
||||
provided->feature[i].kind != FEATURE_SDEPEND)
|
||||
{ /* end of dependencies */
|
||||
break;
|
||||
}
|
||||
found = this->loaded_features->get_match(this->loaded_features,
|
||||
&features[i], (hashtable_equals_t)plugin_feature_matches);
|
||||
if (!found && (features[i].kind != FEATURE_SDEPEND || soft))
|
||||
{
|
||||
if (report)
|
||||
{
|
||||
char *provide, *depend, *name;
|
||||
|
||||
name = entry->plugin->get_name(entry->plugin);
|
||||
provide = plugin_feature_get_string(&features[0]);
|
||||
depend = plugin_feature_get_string(&features[i]);
|
||||
DBG2(DBG_LIB, "feature %s in '%s' plugin has unsatisfied "
|
||||
"dependency: %s", provide, name, depend);
|
||||
free(provide);
|
||||
free(depend);
|
||||
/* we load the feature even if a compatible one is already loaded,
|
||||
* otherwise e.g. a specific database implementation loaded before
|
||||
* another might cause a plugin feature loaded in-between to fail */
|
||||
lookup.feature = &provided->feature[i];
|
||||
do
|
||||
{ /* prefer an exactly matching feature, could be omitted but
|
||||
* results in a more predictable behavior */
|
||||
registered = this->features->get_match(this->features,
|
||||
&lookup,
|
||||
(void*)loadable_feature_equals);
|
||||
if (!registered)
|
||||
{ /* try fuzzy matching */
|
||||
registered = this->features->get_match(this->features,
|
||||
&lookup,
|
||||
(void*)loadable_feature_matches);
|
||||
}
|
||||
if (registered)
|
||||
{
|
||||
load_registered(this, registered, level);
|
||||
}
|
||||
/* we could stop after finding one but for dependencies like
|
||||
* DB_ANY it might be needed to load all matching features */
|
||||
}
|
||||
while (registered);
|
||||
|
||||
if (!find_compatible_feature(this, &provided->feature[i]))
|
||||
{
|
||||
char *name, *provide, *depend;
|
||||
bool soft = provided->feature[i].kind == FEATURE_SDEPEND;
|
||||
|
||||
name = provided->entry->plugin->get_name(provided->entry->plugin);
|
||||
provide = plugin_feature_get_string(&provided->feature[0]);
|
||||
depend = plugin_feature_get_string(&provided->feature[i]);
|
||||
if (soft)
|
||||
{
|
||||
DBG2(DBG_LIB, "%*sfeature %s in plugin '%s' has unmet soft "
|
||||
"dependency: %s", indent, "", provide, name, depend);
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG1(DBG_LIB, "feature %s in plugin '%s' has unmet dependency: "
|
||||
"%s", provide, name, depend);
|
||||
}
|
||||
free(provide);
|
||||
free(depend);
|
||||
if (soft)
|
||||
{ /* it's ok if we can't resolve soft dependencies */
|
||||
continue;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
@@ -421,128 +614,133 @@ static bool dependencies_satisfied(private_plugin_loader_t *this,
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a given feature is still required as dependency
|
||||
* Load registered plugin features
|
||||
*/
|
||||
static bool dependency_required(private_plugin_loader_t *this,
|
||||
plugin_feature_t *dep)
|
||||
static void load_feature(private_plugin_loader_t *this,
|
||||
provided_feature_t *provided,
|
||||
int level)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
plugin_feature_t *features;
|
||||
plugin_entry_t *entry;
|
||||
if (load_dependencies(this, provided, level))
|
||||
{
|
||||
if (plugin_feature_load(provided->entry->plugin, provided->feature,
|
||||
provided->reg))
|
||||
{
|
||||
provided->loaded = TRUE;
|
||||
/* insert first so we can unload the features in reverse order */
|
||||
this->loaded->insert_first(this->loaded, provided);
|
||||
}
|
||||
else
|
||||
{
|
||||
provided->failed = TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ /* TODO: we could check the current level and set a different flag when
|
||||
* being loaded as dependency. If there are loops there is a chance the
|
||||
* feature can be loaded later when loading the feature directly. */
|
||||
provided->failed = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a provided feature
|
||||
*/
|
||||
static void load_provided(private_plugin_loader_t *this,
|
||||
provided_feature_t *provided,
|
||||
int level)
|
||||
{
|
||||
char *name, *provide;
|
||||
int indent = level * 2;
|
||||
|
||||
if (provided->loaded || provided->failed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
name = provided->entry->plugin->get_name(provided->entry->plugin);
|
||||
provide = plugin_feature_get_string(provided->feature);
|
||||
if (provided->loading)
|
||||
{ /* prevent loop */
|
||||
DBG2(DBG_LIB, "%*sloop detected while loading %s in plugin '%s'",
|
||||
indent, "", provide, name);
|
||||
free(provide);
|
||||
return;
|
||||
}
|
||||
DBG2(DBG_LIB, "%*sloading feature %s in plugin '%s'",
|
||||
indent, "", provide, name);
|
||||
free(provide);
|
||||
|
||||
provided->loading = TRUE;
|
||||
load_feature(this, provided, level + 1);
|
||||
provided->loading = FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load registered plugin features
|
||||
*/
|
||||
static void load_features(private_plugin_loader_t *this)
|
||||
{
|
||||
enumerator_t *enumerator, *inner;
|
||||
plugin_entry_t *plugin;
|
||||
provided_feature_t *provided;
|
||||
|
||||
/* we do this in plugin order to allow implicit dependencies to be resolved
|
||||
* by reordering plugins */
|
||||
enumerator = this->plugins->create_enumerator(this->plugins);
|
||||
while (enumerator->enumerate(enumerator, &plugin))
|
||||
{
|
||||
inner = plugin->features->create_enumerator(plugin->features);
|
||||
while (inner->enumerate(inner, &provided))
|
||||
{
|
||||
load_provided(this, provided, 0);
|
||||
}
|
||||
inner->destroy(inner);
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register plugin features provided by the given plugin
|
||||
*/
|
||||
static void register_features(private_plugin_loader_t *this,
|
||||
plugin_entry_t *entry)
|
||||
{
|
||||
plugin_feature_t *feature, *reg;
|
||||
registered_feature_t *registered, lookup;
|
||||
provided_feature_t *provided;
|
||||
int count, i;
|
||||
|
||||
enumerator = this->plugins->create_enumerator(this->plugins);
|
||||
while (enumerator->enumerate(enumerator, &entry))
|
||||
{
|
||||
if (!entry->plugin->get_features)
|
||||
{ /* features not supported */
|
||||
continue;
|
||||
}
|
||||
count = entry->plugin->get_features(entry->plugin, &features);
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
if (&features[i] != dep &&
|
||||
feature_loaded(this, entry, &features[i]))
|
||||
{
|
||||
while (++i < count && (features[i].kind == FEATURE_DEPENDS ||
|
||||
features[i].kind == FEATURE_SDEPEND))
|
||||
{
|
||||
if (plugin_feature_matches(&features[i], dep))
|
||||
{
|
||||
enumerator->destroy(enumerator);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!entry->plugin->get_features)
|
||||
{ /* feature interface not supported */
|
||||
DBG1(DBG_LIB, "plugin '%s' does not provide features, deprecated",
|
||||
entry->plugin->get_name(entry->plugin));
|
||||
return;
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load plugin features in correct order
|
||||
*/
|
||||
static int load_features(private_plugin_loader_t *this, bool soft, bool report)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
plugin_feature_t *feature, *reg;
|
||||
plugin_entry_t *entry;
|
||||
int count, i, loaded = 0;
|
||||
|
||||
enumerator = this->plugins->create_enumerator(this->plugins);
|
||||
while (enumerator->enumerate(enumerator, &entry))
|
||||
{
|
||||
if (!entry->plugin->get_features)
|
||||
{ /* feature interface not supported */
|
||||
continue;
|
||||
}
|
||||
reg = NULL;
|
||||
count = entry->plugin->get_features(entry->plugin, &feature);
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
switch (feature->kind)
|
||||
{
|
||||
case FEATURE_PROVIDE:
|
||||
if (!feature_loaded(this, entry, feature) &&
|
||||
!feature_failed(this, entry, feature) &&
|
||||
dependencies_satisfied(this, entry, soft, report,
|
||||
feature, count - i))
|
||||
{
|
||||
if (plugin_feature_load(entry->plugin, feature, reg))
|
||||
{
|
||||
this->loaded_features->put(this->loaded_features,
|
||||
feature, feature);
|
||||
entry->loaded->insert_last(entry->loaded, feature);
|
||||
loaded++;
|
||||
}
|
||||
else
|
||||
{
|
||||
entry->failed->insert_last(entry->failed, feature);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case FEATURE_REGISTER:
|
||||
case FEATURE_CALLBACK:
|
||||
reg = feature;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
feature++;
|
||||
}
|
||||
if (loaded && !report)
|
||||
{ /* got new feature, restart from beginning of list */
|
||||
break;
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
return loaded;
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to unload plugin features on which is not depended anymore
|
||||
*/
|
||||
static int unload_features(private_plugin_loader_t *this, plugin_entry_t *entry)
|
||||
{
|
||||
plugin_feature_t *feature, *reg = NULL;
|
||||
int count, i, unloaded = 0;
|
||||
|
||||
reg = NULL;
|
||||
count = entry->plugin->get_features(entry->plugin, &feature);
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
switch (feature->kind)
|
||||
{
|
||||
case FEATURE_PROVIDE:
|
||||
if (feature_loaded(this, entry, feature) &&
|
||||
!dependency_required(this, feature) &&
|
||||
plugin_feature_unload(entry->plugin, feature, reg))
|
||||
lookup.feature = feature;
|
||||
registered = this->features->get(this->features, &lookup);
|
||||
if (!registered)
|
||||
{
|
||||
this->loaded_features->remove(this->loaded_features,
|
||||
feature);
|
||||
entry->loaded->remove(entry->loaded, feature, NULL);
|
||||
unloaded++;
|
||||
INIT(registered,
|
||||
.feature = feature,
|
||||
.plugins = linked_list_create(),
|
||||
);
|
||||
this->features->put(this->features, registered, registered);
|
||||
}
|
||||
INIT(provided,
|
||||
.entry = entry,
|
||||
.feature = feature,
|
||||
.reg = reg,
|
||||
.dependencies = count - i,
|
||||
);
|
||||
registered->plugins->insert_last(registered->plugins,
|
||||
provided);
|
||||
entry->features->insert_last(entry->features, provided);
|
||||
break;
|
||||
case FEATURE_REGISTER:
|
||||
case FEATURE_CALLBACK:
|
||||
@@ -553,7 +751,54 @@ static int unload_features(private_plugin_loader_t *this, plugin_entry_t *entry)
|
||||
}
|
||||
feature++;
|
||||
}
|
||||
return unloaded;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister a plugin feature
|
||||
*/
|
||||
static void unregister_feature(private_plugin_loader_t *this,
|
||||
provided_feature_t *provided)
|
||||
{
|
||||
registered_feature_t *registered, lookup;
|
||||
|
||||
lookup.feature = provided->feature;
|
||||
registered = this->features->get(this->features, &lookup);
|
||||
if (registered)
|
||||
{
|
||||
registered->plugins->remove(registered->plugins, provided, NULL);
|
||||
if (registered->plugins->get_count(registered->plugins) == 0)
|
||||
{
|
||||
this->features->remove(this->features, &lookup);
|
||||
registered->plugins->destroy(registered->plugins);
|
||||
free(registered);
|
||||
}
|
||||
else if (registered->feature == provided->feature)
|
||||
{ /* update feature in case the providing plugin gets unloaded */
|
||||
provided_feature_t *first;
|
||||
|
||||
registered->plugins->get_first(registered->plugins, (void**)&first);
|
||||
registered->feature = first->feature;
|
||||
}
|
||||
}
|
||||
free(provided);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister plugin features
|
||||
*/
|
||||
static void unregister_features(private_plugin_loader_t *this,
|
||||
plugin_entry_t *entry)
|
||||
{
|
||||
provided_feature_t *provided;
|
||||
enumerator_t *enumerator;
|
||||
|
||||
enumerator = entry->features->create_enumerator(entry->features);
|
||||
while (enumerator->enumerate(enumerator, &provided))
|
||||
{
|
||||
entry->features->remove_at(entry->features, enumerator);
|
||||
unregister_feature(this, provided);
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -561,44 +806,43 @@ static int unload_features(private_plugin_loader_t *this, plugin_entry_t *entry)
|
||||
*/
|
||||
static bool missing_critical_features(private_plugin_loader_t *this)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
enumerator_t *enumerator, *features;
|
||||
plugin_entry_t *entry;
|
||||
bool critical_failed = FALSE;
|
||||
|
||||
enumerator = this->plugins->create_enumerator(this->plugins);
|
||||
while (enumerator->enumerate(enumerator, &entry))
|
||||
{
|
||||
if (!entry->plugin->get_features)
|
||||
{ /* feature interface not supported */
|
||||
provided_feature_t *provided;
|
||||
char *name, *provide;
|
||||
int failed = 0;
|
||||
|
||||
if (!entry->plugin->get_features ||
|
||||
!entry->critical)
|
||||
{ /* feature interface not supported, or not critical */
|
||||
continue;
|
||||
}
|
||||
if (entry->critical)
|
||||
{
|
||||
plugin_feature_t *feature;
|
||||
char *name, *provide;
|
||||
int count, i, failed = 0;
|
||||
|
||||
name = entry->plugin->get_name(entry->plugin);
|
||||
count = entry->plugin->get_features(entry->plugin, &feature);
|
||||
for (i = 0; i < count; i++, feature++)
|
||||
name = entry->plugin->get_name(entry->plugin);
|
||||
features = entry->features->create_enumerator(entry->features);
|
||||
while (features->enumerate(features, &provided))
|
||||
{
|
||||
if (!provided->loaded)
|
||||
{
|
||||
if (feature->kind == FEATURE_PROVIDE &&
|
||||
!feature_loaded(this, entry, feature))
|
||||
{
|
||||
provide = plugin_feature_get_string(feature);
|
||||
DBG2(DBG_LIB, " failed to load %s in critical plugin '%s'",
|
||||
provide, name);
|
||||
free(provide);
|
||||
failed++;
|
||||
}
|
||||
}
|
||||
if (failed)
|
||||
{
|
||||
DBG1(DBG_LIB, "failed to load %d feature%s in critical plugin "
|
||||
"'%s'", failed, failed > 1 ? "s" : "", name);
|
||||
critical_failed = TRUE;
|
||||
provide = plugin_feature_get_string(provided->feature);
|
||||
DBG2(DBG_LIB, " failed to load %s in critical plugin '%s'",
|
||||
provide, name);
|
||||
free(provide);
|
||||
failed++;
|
||||
}
|
||||
}
|
||||
features->destroy(features);
|
||||
if (failed)
|
||||
{
|
||||
DBG1(DBG_LIB, "failed to load %d feature%s in critical plugin '%s'",
|
||||
failed, failed > 1 ? "s" : "", name);
|
||||
critical_failed = TRUE;
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
@@ -606,7 +850,7 @@ static bool missing_critical_features(private_plugin_loader_t *this)
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove plugins that we were not able to load any features from.
|
||||
* Remove plugins we were not able to load any plugin features from.
|
||||
*/
|
||||
static void purge_plugins(private_plugin_loader_t *this)
|
||||
{
|
||||
@@ -620,9 +864,13 @@ static void purge_plugins(private_plugin_loader_t *this)
|
||||
{ /* feature interface not supported */
|
||||
continue;
|
||||
}
|
||||
if (!entry->loaded->get_count(entry->loaded))
|
||||
if (entry->features->find_first(entry->features,
|
||||
(void*)is_feature_loaded, NULL) != SUCCESS)
|
||||
{
|
||||
DBG2(DBG_LIB, "unloading plugin '%s' without loaded features",
|
||||
entry->plugin->get_name(entry->plugin));
|
||||
this->plugins->remove_at(this->plugins, enumerator);
|
||||
unregister_features(this, entry);
|
||||
plugin_entry_destroy(entry);
|
||||
}
|
||||
}
|
||||
@@ -641,10 +889,10 @@ METHOD(plugin_loader_t, add_static_features, void,
|
||||
INIT(entry,
|
||||
.plugin = plugin,
|
||||
.critical = critical,
|
||||
.loaded = linked_list_create(),
|
||||
.failed = linked_list_create(),
|
||||
.features = linked_list_create(),
|
||||
);
|
||||
this->plugins->insert_last(this->plugins, entry);
|
||||
register_features(this, entry);
|
||||
}
|
||||
|
||||
METHOD(plugin_loader_t, load_plugins, bool,
|
||||
@@ -664,6 +912,7 @@ METHOD(plugin_loader_t, load_plugins, bool,
|
||||
enumerator = enumerator_create_token(list, " ", " ");
|
||||
while (!critical_failed && enumerator->enumerate(enumerator, &token))
|
||||
{
|
||||
plugin_entry_t *entry;
|
||||
bool critical = FALSE;
|
||||
char buf[PATH_MAX], *file = NULL;
|
||||
int len;
|
||||
@@ -689,29 +938,22 @@ METHOD(plugin_loader_t, load_plugins, bool,
|
||||
}
|
||||
file = buf;
|
||||
}
|
||||
if (!load_plugin(this, token, file, critical) && critical)
|
||||
entry = load_plugin(this, token, file, critical);
|
||||
if (entry)
|
||||
{
|
||||
register_features(this, entry);
|
||||
}
|
||||
else if (critical)
|
||||
{
|
||||
critical_failed = TRUE;
|
||||
DBG1(DBG_LIB, "loading critical plugin '%s' failed", token);
|
||||
}
|
||||
free(token);
|
||||
/* TODO: we currently load features after each plugin is loaded. This
|
||||
* will not be necessary once we have features support in all plugins.
|
||||
*/
|
||||
while (load_features(this, TRUE, FALSE))
|
||||
{
|
||||
/* try load new features until we don't get new ones */
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
if (!critical_failed)
|
||||
{
|
||||
while (load_features(this, FALSE, FALSE))
|
||||
{
|
||||
/* enforce loading features, ignoring soft dependencies */
|
||||
}
|
||||
/* report missing dependencies */
|
||||
load_features(this, FALSE, TRUE);
|
||||
load_features(this);
|
||||
/* check for unloaded features provided by critical plugins */
|
||||
critical_failed = missing_critical_features(this);
|
||||
/* unload plugins that we were not able to load any features for */
|
||||
@@ -725,44 +967,42 @@ METHOD(plugin_loader_t, load_plugins, bool,
|
||||
return !critical_failed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unload plugin features, they are registered in reverse order
|
||||
*/
|
||||
static void unload_features(private_plugin_loader_t *this)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
provided_feature_t *provided;
|
||||
plugin_entry_t *entry;
|
||||
|
||||
enumerator = this->loaded->create_enumerator(this->loaded);
|
||||
while (enumerator->enumerate(enumerator, &provided))
|
||||
{
|
||||
entry = provided->entry;
|
||||
plugin_feature_unload(entry->plugin, provided->feature, provided->reg);
|
||||
this->loaded->remove_at(this->loaded, enumerator);
|
||||
entry->features->remove(entry->features, provided, NULL);
|
||||
unregister_feature(this, provided);
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
}
|
||||
|
||||
METHOD(plugin_loader_t, unload, void,
|
||||
private_plugin_loader_t *this)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
plugin_entry_t *entry;
|
||||
linked_list_t *list;
|
||||
|
||||
/* unload plugins in reverse order, for those not supporting features */
|
||||
list = linked_list_create();
|
||||
/* unload features followed by plugins, in reverse order */
|
||||
unload_features(this);
|
||||
while (this->plugins->remove_last(this->plugins, (void**)&entry) == SUCCESS)
|
||||
{
|
||||
list->insert_last(list, entry);
|
||||
}
|
||||
while (list->remove_last(list, (void**)&entry) == SUCCESS)
|
||||
{
|
||||
this->plugins->insert_first(this->plugins, entry);
|
||||
}
|
||||
list->destroy(list);
|
||||
while (this->plugins->get_count(this->plugins))
|
||||
{
|
||||
enumerator = this->plugins->create_enumerator(this->plugins);
|
||||
while (enumerator->enumerate(enumerator, &entry))
|
||||
{
|
||||
if (entry->plugin->get_features)
|
||||
{ /* supports features */
|
||||
while (unload_features(this, entry));
|
||||
}
|
||||
if (entry->loaded->get_count(entry->loaded) == 0)
|
||||
{
|
||||
if (lib->leak_detective)
|
||||
{ /* keep handle to report leaks properly */
|
||||
entry->handle = NULL;
|
||||
}
|
||||
this->plugins->remove_at(this->plugins, enumerator);
|
||||
plugin_entry_destroy(entry);
|
||||
}
|
||||
if (lib->leak_detective)
|
||||
{ /* keep handle to report leaks properly */
|
||||
entry->handle = NULL;
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
unregister_features(this, entry);
|
||||
plugin_entry_destroy(entry);
|
||||
}
|
||||
free(this->loaded_plugins);
|
||||
this->loaded_plugins = NULL;
|
||||
@@ -824,7 +1064,8 @@ METHOD(plugin_loader_t, destroy, void,
|
||||
private_plugin_loader_t *this)
|
||||
{
|
||||
unload(this);
|
||||
this->loaded_features->destroy(this->loaded_features);
|
||||
this->features->destroy(this->features);
|
||||
this->loaded->destroy(this->loaded);
|
||||
this->plugins->destroy(this->plugins);
|
||||
free(this->loaded_plugins);
|
||||
free(this);
|
||||
@@ -848,11 +1089,11 @@ plugin_loader_t *plugin_loader_create()
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.plugins = linked_list_create(),
|
||||
.loaded_features = hashtable_create(
|
||||
(hashtable_hash_t)plugin_feature_hash,
|
||||
(hashtable_equals_t)plugin_feature_equals, 64),
|
||||
.loaded = linked_list_create(),
|
||||
.features = hashtable_create(
|
||||
(hashtable_hash_t)registered_feature_hash,
|
||||
(hashtable_equals_t)registered_feature_equals, 64),
|
||||
);
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2012 Tobias Brunner
|
||||
* Copyright (C) 2012-2013 Tobias Brunner
|
||||
* Copyright (C) 2007 Martin Willi
|
||||
* Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
@@ -84,9 +84,9 @@ struct plugin_loader_t {
|
||||
/**
|
||||
* Create an enumerator over all loaded plugins.
|
||||
*
|
||||
* In addition to the plugin, the enumerator returns a list of pointers to
|
||||
* plugin features currently loaded (if the argument is not NULL).
|
||||
* This list is to be read only.
|
||||
* In addition to the plugin, the enumerator optionally provides a list of
|
||||
* pointers to plugin features currently loaded.
|
||||
* This list has to be destroyed.
|
||||
*
|
||||
* @return enumerator over plugin_t*, linked_list_t*
|
||||
*/
|
||||
|
||||
@@ -42,10 +42,43 @@ METHOD(plugin_t, get_name, char*,
|
||||
return "revocation";
|
||||
}
|
||||
|
||||
/**
|
||||
* Register validator
|
||||
*/
|
||||
static bool plugin_cb(private_revocation_plugin_t *this,
|
||||
plugin_feature_t *feature, bool reg, void *cb_data)
|
||||
{
|
||||
if (reg)
|
||||
{
|
||||
lib->credmgr->add_validator(lib->credmgr, &this->validator->validator);
|
||||
}
|
||||
else
|
||||
{
|
||||
lib->credmgr->remove_validator(lib->credmgr,
|
||||
&this->validator->validator);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(plugin_t, get_features, int,
|
||||
private_revocation_plugin_t *this, plugin_feature_t *features[])
|
||||
{
|
||||
static plugin_feature_t f[] = {
|
||||
PLUGIN_CALLBACK((plugin_feature_callback_t)plugin_cb, NULL),
|
||||
PLUGIN_PROVIDE(CUSTOM, "revocation"),
|
||||
PLUGIN_SDEPEND(CERT_ENCODE, CERT_X509_OCSP_REQUEST),
|
||||
PLUGIN_SDEPEND(CERT_DECODE, CERT_X509_OCSP_RESPONSE),
|
||||
PLUGIN_SDEPEND(CERT_DECODE, CERT_X509_CRL),
|
||||
PLUGIN_SDEPEND(CERT_DECODE, CERT_X509),
|
||||
PLUGIN_SDEPEND(FETCHER, NULL),
|
||||
};
|
||||
*features = f;
|
||||
return countof(f);
|
||||
}
|
||||
|
||||
METHOD(plugin_t, destroy, void,
|
||||
private_revocation_plugin_t *this)
|
||||
{
|
||||
lib->credmgr->remove_validator(lib->credmgr, &this->validator->validator);
|
||||
this->validator->destroy(this->validator);
|
||||
free(this);
|
||||
}
|
||||
@@ -61,13 +94,12 @@ plugin_t *revocation_plugin_create()
|
||||
.public = {
|
||||
.plugin = {
|
||||
.get_name = _get_name,
|
||||
.reload = (void*)return_false,
|
||||
.get_features = _get_features,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
},
|
||||
.validator = revocation_validator_create(),
|
||||
);
|
||||
lib->credmgr->add_validator(lib->credmgr, &this->validator->validator);
|
||||
|
||||
return &this->public.plugin;
|
||||
}
|
||||
|
||||
@@ -110,6 +110,17 @@ METHOD(plugin_t, get_name, char*,
|
||||
return "test-vectors";
|
||||
}
|
||||
|
||||
METHOD(plugin_t, get_features, int,
|
||||
private_test_vectors_plugin_t *this, plugin_feature_t *features[])
|
||||
{
|
||||
static plugin_feature_t f[] = {
|
||||
PLUGIN_NOOP,
|
||||
PLUGIN_PROVIDE(CUSTOM, "test-vectors"),
|
||||
};
|
||||
*features = f;
|
||||
return countof(f);
|
||||
}
|
||||
|
||||
METHOD(plugin_t, destroy, void,
|
||||
private_test_vectors_plugin_t *this)
|
||||
{
|
||||
@@ -128,7 +139,7 @@ plugin_t *test_vectors_plugin_create()
|
||||
.public = {
|
||||
.plugin = {
|
||||
.get_name = _get_name,
|
||||
.reload = (void*)return_false,
|
||||
.get_features = _get_features,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
},
|
||||
|
||||
@@ -37,10 +37,20 @@ METHOD(plugin_t, get_name, char*,
|
||||
return "unbound";
|
||||
}
|
||||
|
||||
METHOD(plugin_t, get_features, int,
|
||||
private_unbound_plugin_t *this, plugin_feature_t *features[])
|
||||
{
|
||||
static plugin_feature_t f[] = {
|
||||
PLUGIN_REGISTER(RESOLVER, unbound_resolver_create),
|
||||
PLUGIN_PROVIDE(RESOLVER),
|
||||
};
|
||||
*features = f;
|
||||
return countof(f);
|
||||
}
|
||||
|
||||
METHOD(plugin_t, destroy, void,
|
||||
private_unbound_plugin_t *this)
|
||||
{
|
||||
lib->resolver->remove_resolver(lib->resolver, unbound_resolver_create);
|
||||
free(this);
|
||||
}
|
||||
|
||||
@@ -55,12 +65,11 @@ plugin_t *unbound_plugin_create()
|
||||
.public = {
|
||||
.plugin = {
|
||||
.get_name = _get_name,
|
||||
.get_features = _get_features,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
lib->resolver->add_resolver(lib->resolver, unbound_resolver_create);
|
||||
|
||||
return &this->public.plugin;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user