Implemented support for multiple RADIUS servers
This commit is contained in:
@@ -17,15 +17,130 @@
|
||||
|
||||
#include "eap_radius.h"
|
||||
#include "radius_client.h"
|
||||
#include "radius_server.h"
|
||||
|
||||
#include <daemon.h>
|
||||
|
||||
/**
|
||||
* Default RADIUS server port, when not configured
|
||||
*/
|
||||
#define RADIUS_PORT 1812
|
||||
|
||||
typedef struct private_eap_radius_plugin_t private_eap_radius_plugin_t;
|
||||
|
||||
/**
|
||||
* Private data of an eap_radius_plugin_t object.
|
||||
*/
|
||||
struct private_eap_radius_plugin_t {
|
||||
|
||||
/**
|
||||
* Public radius_plugin_t interface.
|
||||
*/
|
||||
eap_radius_plugin_t public;
|
||||
|
||||
/**
|
||||
* List of RADIUS servers
|
||||
*/
|
||||
linked_list_t *servers;
|
||||
};
|
||||
|
||||
/**
|
||||
* Instance of the EAP plugin
|
||||
*/
|
||||
static private_eap_radius_plugin_t *instance = NULL;
|
||||
|
||||
METHOD(plugin_t, destroy, void,
|
||||
eap_radius_plugin_t *this)
|
||||
private_eap_radius_plugin_t *this)
|
||||
{
|
||||
charon->eap->remove_method(charon->eap, (eap_constructor_t)eap_radius_create);
|
||||
radius_client_cleanup();
|
||||
this->servers->destroy_offset(this->servers,
|
||||
offsetof(radius_server_t, destroy));
|
||||
free(this);
|
||||
instance = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load RADIUS servers from configuration
|
||||
*/
|
||||
static bool load_servers(private_eap_radius_plugin_t *this)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
radius_server_t *server;
|
||||
char *nas_identifier, *secret, *address, *section;
|
||||
int port, sockets, preference;
|
||||
|
||||
address = lib->settings->get_str(lib->settings,
|
||||
"charon.plugins.eap-radius.server", NULL);
|
||||
if (address)
|
||||
{ /* legacy configuration */
|
||||
secret = lib->settings->get_str(lib->settings,
|
||||
"charon.plugins.eap-radius.secret", NULL);
|
||||
if (!secret)
|
||||
{
|
||||
DBG1(DBG_CFG, "no RADUIS secret defined");
|
||||
return FALSE;
|
||||
}
|
||||
nas_identifier = lib->settings->get_str(lib->settings,
|
||||
"charon.plugins.eap-radius.nas_identifier", "strongSwan");
|
||||
port = lib->settings->get_int(lib->settings,
|
||||
"charon.plugins.eap-radius.port", RADIUS_PORT);
|
||||
sockets = lib->settings->get_int(lib->settings,
|
||||
"charon.plugins.eap-radius.sockets", 1);
|
||||
server = radius_server_create(address, port, nas_identifier,
|
||||
secret, sockets, 0);
|
||||
if (!server)
|
||||
{
|
||||
DBG1(DBG_CFG, "no RADUIS server defined");
|
||||
return FALSE;
|
||||
}
|
||||
this->servers->insert_last(this->servers, server);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
enumerator = lib->settings->create_section_enumerator(lib->settings,
|
||||
"charon.plugins.eap-radius.servers");
|
||||
while (enumerator->enumerate(enumerator, §ion))
|
||||
{
|
||||
address = lib->settings->get_str(lib->settings,
|
||||
"charon.plugins.eap-radius.servers.%s.address", NULL, section);
|
||||
if (!address)
|
||||
{
|
||||
DBG1(DBG_CFG, "RADIUS server '%s' misses address, skipped", section);
|
||||
continue;
|
||||
}
|
||||
secret = lib->settings->get_str(lib->settings,
|
||||
"charon.plugins.eap-radius.servers.%s.secret", NULL, section);
|
||||
if (!secret)
|
||||
{
|
||||
DBG1(DBG_CFG, "RADIUS server '%s' misses secret, skipped", section);
|
||||
continue;
|
||||
}
|
||||
nas_identifier = lib->settings->get_str(lib->settings,
|
||||
"charon.plugins.eap-radius.servers.%s.nas_identifier",
|
||||
"strongSwan", section);
|
||||
port = lib->settings->get_int(lib->settings,
|
||||
"charon.plugins.eap-radius.servers.%s.port", RADIUS_PORT, section);
|
||||
sockets = lib->settings->get_int(lib->settings,
|
||||
"charon.plugins.eap-radius.servers.%s.sockets", 1, section);
|
||||
preference = lib->settings->get_int(lib->settings,
|
||||
"charon.plugins.eap-radius.servers.%s.preference", 0, section);
|
||||
server = radius_server_create(address, port, nas_identifier,
|
||||
secret, sockets, preference);
|
||||
if (!server)
|
||||
{
|
||||
DBG1(DBG_CFG, "loading RADIUS server '%s' failed, skipped", section);
|
||||
continue;
|
||||
}
|
||||
this->servers->insert_last(this->servers, server);
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
if (this->servers->get_count(this->servers) == 0)
|
||||
{
|
||||
DBG1(DBG_CFG, "no valid RADIUS server configuration found");
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -33,21 +148,35 @@ METHOD(plugin_t, destroy, void,
|
||||
*/
|
||||
plugin_t *eap_radius_plugin_create()
|
||||
{
|
||||
eap_radius_plugin_t *this;
|
||||
|
||||
if (!radius_client_init())
|
||||
{
|
||||
DBG1(DBG_CFG, "RADIUS plugin initialization failed");
|
||||
return NULL;
|
||||
}
|
||||
private_eap_radius_plugin_t *this;
|
||||
|
||||
INIT(this,
|
||||
.plugin.destroy = _destroy,
|
||||
.public.plugin.destroy = _destroy,
|
||||
.servers = linked_list_create(),
|
||||
);
|
||||
|
||||
if (!load_servers(this))
|
||||
{
|
||||
destroy(this);
|
||||
return NULL;
|
||||
}
|
||||
charon->eap->add_method(charon->eap, EAP_RADIUS, 0,
|
||||
EAP_SERVER, (eap_constructor_t)eap_radius_create);
|
||||
|
||||
return &this->plugin;
|
||||
instance = this;
|
||||
|
||||
return &this->public.plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
enumerator_t *eap_radius_create_server_enumerator()
|
||||
{
|
||||
if (instance)
|
||||
{
|
||||
return instance->servers->create_enumerator(instance->servers);
|
||||
}
|
||||
return enumerator_create_empty();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user