Added reload support to eap-radius plugin
This commit is contained in:
@@ -20,6 +20,7 @@
|
|||||||
#include "radius_server.h"
|
#include "radius_server.h"
|
||||||
|
|
||||||
#include <daemon.h>
|
#include <daemon.h>
|
||||||
|
#include <threading/rwlock.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default RADIUS server port, when not configured
|
* Default RADIUS server port, when not configured
|
||||||
@@ -42,6 +43,11 @@ struct private_eap_radius_plugin_t {
|
|||||||
* List of RADIUS servers
|
* List of RADIUS servers
|
||||||
*/
|
*/
|
||||||
linked_list_t *servers;
|
linked_list_t *servers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lock for server list
|
||||||
|
*/
|
||||||
|
rwlock_t *lock;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -49,26 +55,10 @@ struct private_eap_radius_plugin_t {
|
|||||||
*/
|
*/
|
||||||
static private_eap_radius_plugin_t *instance = NULL;
|
static private_eap_radius_plugin_t *instance = NULL;
|
||||||
|
|
||||||
METHOD(plugin_t, get_name, char*,
|
|
||||||
private_eap_radius_plugin_t *this)
|
|
||||||
{
|
|
||||||
return "eap-radius";
|
|
||||||
}
|
|
||||||
|
|
||||||
METHOD(plugin_t, destroy, void,
|
|
||||||
private_eap_radius_plugin_t *this)
|
|
||||||
{
|
|
||||||
charon->eap->remove_method(charon->eap, (eap_constructor_t)eap_radius_create);
|
|
||||||
this->servers->destroy_offset(this->servers,
|
|
||||||
offsetof(radius_server_t, destroy));
|
|
||||||
free(this);
|
|
||||||
instance = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load RADIUS servers from configuration
|
* Load RADIUS servers from configuration
|
||||||
*/
|
*/
|
||||||
static bool load_servers(private_eap_radius_plugin_t *this)
|
static void load_servers(private_eap_radius_plugin_t *this)
|
||||||
{
|
{
|
||||||
enumerator_t *enumerator;
|
enumerator_t *enumerator;
|
||||||
radius_server_t *server;
|
radius_server_t *server;
|
||||||
@@ -84,7 +74,7 @@ static bool load_servers(private_eap_radius_plugin_t *this)
|
|||||||
if (!secret)
|
if (!secret)
|
||||||
{
|
{
|
||||||
DBG1(DBG_CFG, "no RADUIS secret defined");
|
DBG1(DBG_CFG, "no RADUIS secret defined");
|
||||||
return FALSE;
|
return;
|
||||||
}
|
}
|
||||||
nas_identifier = lib->settings->get_str(lib->settings,
|
nas_identifier = lib->settings->get_str(lib->settings,
|
||||||
"charon.plugins.eap-radius.nas_identifier", "strongSwan");
|
"charon.plugins.eap-radius.nas_identifier", "strongSwan");
|
||||||
@@ -97,10 +87,10 @@ static bool load_servers(private_eap_radius_plugin_t *this)
|
|||||||
if (!server)
|
if (!server)
|
||||||
{
|
{
|
||||||
DBG1(DBG_CFG, "no RADUIS server defined");
|
DBG1(DBG_CFG, "no RADUIS server defined");
|
||||||
return FALSE;
|
return;
|
||||||
}
|
}
|
||||||
this->servers->insert_last(this->servers, server);
|
this->servers->insert_last(this->servers, server);
|
||||||
return TRUE;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
enumerator = lib->settings->create_section_enumerator(lib->settings,
|
enumerator = lib->settings->create_section_enumerator(lib->settings,
|
||||||
@@ -141,14 +131,40 @@ static bool load_servers(private_eap_radius_plugin_t *this)
|
|||||||
}
|
}
|
||||||
enumerator->destroy(enumerator);
|
enumerator->destroy(enumerator);
|
||||||
|
|
||||||
if (this->servers->get_count(this->servers) == 0)
|
DBG1(DBG_CFG, "loaded %d RADIUS server configuration%s",
|
||||||
{
|
this->servers->get_count(this->servers),
|
||||||
DBG1(DBG_CFG, "no valid RADIUS server configuration found");
|
this->servers->get_count(this->servers) == 1 ? "" : "s");
|
||||||
return FALSE;
|
}
|
||||||
}
|
|
||||||
|
METHOD(plugin_t, get_name, char*,
|
||||||
|
private_eap_radius_plugin_t *this)
|
||||||
|
{
|
||||||
|
return "eap-radius";
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(plugin_t, reload, bool,
|
||||||
|
private_eap_radius_plugin_t *this)
|
||||||
|
{
|
||||||
|
this->lock->write_lock(this->lock);
|
||||||
|
this->servers->destroy_offset(this->servers,
|
||||||
|
offsetof(radius_server_t, destroy));
|
||||||
|
this->servers = linked_list_create();
|
||||||
|
load_servers(this);
|
||||||
|
this->lock->unlock(this->lock);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
METHOD(plugin_t, destroy, void,
|
||||||
|
private_eap_radius_plugin_t *this)
|
||||||
|
{
|
||||||
|
charon->eap->remove_method(charon->eap, (eap_constructor_t)eap_radius_create);
|
||||||
|
this->servers->destroy_offset(this->servers,
|
||||||
|
offsetof(radius_server_t, destroy));
|
||||||
|
this->lock->destroy(this->lock);
|
||||||
|
free(this);
|
||||||
|
instance = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* see header file
|
* see header file
|
||||||
*/
|
*/
|
||||||
@@ -160,18 +176,16 @@ plugin_t *eap_radius_plugin_create()
|
|||||||
.public = {
|
.public = {
|
||||||
.plugin = {
|
.plugin = {
|
||||||
.get_name = _get_name,
|
.get_name = _get_name,
|
||||||
.reload = (void*)return_false,
|
.reload = _reload,
|
||||||
.destroy = _destroy,
|
.destroy = _destroy,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
.servers = linked_list_create(),
|
.servers = linked_list_create(),
|
||||||
|
.lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!load_servers(this))
|
load_servers(this);
|
||||||
{
|
|
||||||
destroy(this);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
charon->eap->add_method(charon->eap, EAP_RADIUS, 0,
|
charon->eap->add_method(charon->eap, EAP_RADIUS, 0,
|
||||||
EAP_SERVER, (eap_constructor_t)eap_radius_create);
|
EAP_SERVER, (eap_constructor_t)eap_radius_create);
|
||||||
|
|
||||||
@@ -187,7 +201,10 @@ enumerator_t *eap_radius_create_server_enumerator()
|
|||||||
{
|
{
|
||||||
if (instance)
|
if (instance)
|
||||||
{
|
{
|
||||||
return instance->servers->create_enumerator(instance->servers);
|
instance->lock->read_lock(instance->lock);
|
||||||
|
return enumerator_create_cleaner(
|
||||||
|
instance->servers->create_enumerator(instance->servers),
|
||||||
|
(void*)instance->lock->unlock, instance->lock);
|
||||||
}
|
}
|
||||||
return enumerator_create_empty();
|
return enumerator_create_empty();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -128,6 +128,7 @@ METHOD(radius_client_t, get_msk, chunk_t,
|
|||||||
METHOD(radius_client_t, destroy, void,
|
METHOD(radius_client_t, destroy, void,
|
||||||
private_radius_client_t *this)
|
private_radius_client_t *this)
|
||||||
{
|
{
|
||||||
|
this->server->destroy(this->server);
|
||||||
chunk_clear(&this->msk);
|
chunk_clear(&this->msk);
|
||||||
free(this->state.ptr);
|
free(this->state.ptr);
|
||||||
free(this);
|
free(this);
|
||||||
@@ -162,7 +163,8 @@ radius_client_t *radius_client_create()
|
|||||||
DBG2(DBG_CFG, "RADIUS server %H is candidate: %d",
|
DBG2(DBG_CFG, "RADIUS server %H is candidate: %d",
|
||||||
server->get_address(server), current);
|
server->get_address(server), current);
|
||||||
best = current;
|
best = current;
|
||||||
this->server = server;
|
DESTROY_IF(this->server);
|
||||||
|
this->server = server->get_ref(server);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -80,6 +80,11 @@ struct private_radius_server_t {
|
|||||||
* Retry counter for unreachable servers
|
* Retry counter for unreachable servers
|
||||||
*/
|
*/
|
||||||
int retry;
|
int retry;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reference count
|
||||||
|
*/
|
||||||
|
refcount_t ref;
|
||||||
};
|
};
|
||||||
|
|
||||||
METHOD(radius_server_t, get_socket, radius_socket_t*,
|
METHOD(radius_server_t, get_socket, radius_socket_t*,
|
||||||
@@ -153,15 +158,26 @@ METHOD(radius_server_t, get_address, host_t*,
|
|||||||
return this->host;
|
return this->host;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
METHOD(radius_server_t, get_ref, radius_server_t*,
|
||||||
|
private_radius_server_t *this)
|
||||||
|
{
|
||||||
|
ref_get(&this->ref);
|
||||||
|
return &this->public;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
METHOD(radius_server_t, destroy, void,
|
METHOD(radius_server_t, destroy, void,
|
||||||
private_radius_server_t *this)
|
private_radius_server_t *this)
|
||||||
{
|
{
|
||||||
DESTROY_IF(this->host);
|
if (ref_put(&this->ref))
|
||||||
this->mutex->destroy(this->mutex);
|
{
|
||||||
this->condvar->destroy(this->condvar);
|
DESTROY_IF(this->host);
|
||||||
this->sockets->destroy_offset(this->sockets,
|
this->mutex->destroy(this->mutex);
|
||||||
offsetof(radius_socket_t, destroy));
|
this->condvar->destroy(this->condvar);
|
||||||
free(this);
|
this->sockets->destroy_offset(this->sockets,
|
||||||
|
offsetof(radius_socket_t, destroy));
|
||||||
|
free(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -180,6 +196,7 @@ radius_server_t *radius_server_create(char *server, u_int16_t port,
|
|||||||
.get_nas_identifier = _get_nas_identifier,
|
.get_nas_identifier = _get_nas_identifier,
|
||||||
.get_preference = _get_preference,
|
.get_preference = _get_preference,
|
||||||
.get_address = _get_address,
|
.get_address = _get_address,
|
||||||
|
.get_ref = _get_ref,
|
||||||
.destroy = _destroy,
|
.destroy = _destroy,
|
||||||
},
|
},
|
||||||
.reachable = TRUE,
|
.reachable = TRUE,
|
||||||
@@ -190,6 +207,7 @@ radius_server_t *radius_server_create(char *server, u_int16_t port,
|
|||||||
.condvar = condvar_create(CONDVAR_TYPE_DEFAULT),
|
.condvar = condvar_create(CONDVAR_TYPE_DEFAULT),
|
||||||
.host = host_create_from_dns(server, 0, port),
|
.host = host_create_from_dns(server, 0, port),
|
||||||
.preference = preference,
|
.preference = preference,
|
||||||
|
.ref = 1,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!this->host)
|
if (!this->host)
|
||||||
|
|||||||
@@ -67,6 +67,13 @@ struct radius_server_t {
|
|||||||
*/
|
*/
|
||||||
host_t* (*get_address)(radius_server_t *this);
|
host_t* (*get_address)(radius_server_t *this);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Increase reference count of this server.
|
||||||
|
*
|
||||||
|
* @return this
|
||||||
|
*/
|
||||||
|
radius_server_t* (*get_ref)(radius_server_t *this);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destroy a radius_server_t.
|
* Destroy a radius_server_t.
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user