summaryrefslogtreecommitdiff
path: root/src/libcharon/plugins/eap_radius/eap_radius_plugin.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libcharon/plugins/eap_radius/eap_radius_plugin.c')
-rw-r--r--src/libcharon/plugins/eap_radius/eap_radius_plugin.c150
1 files changed, 139 insertions, 11 deletions
diff --git a/src/libcharon/plugins/eap_radius/eap_radius_plugin.c b/src/libcharon/plugins/eap_radius/eap_radius_plugin.c
index 7d2788c3e..91aae2f62 100644
--- a/src/libcharon/plugins/eap_radius/eap_radius_plugin.c
+++ b/src/libcharon/plugins/eap_radius/eap_radius_plugin.c
@@ -17,17 +17,130 @@
#include "eap_radius.h"
#include "radius_client.h"
+#include "radius_server.h"
#include <daemon.h>
/**
- * Implementation of plugin_t.destroy
+ * Default RADIUS server port, when not configured
*/
-static void destroy(eap_radius_plugin_t *this)
+#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,
+ 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, &section))
+ {
+ 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;
}
/*
@@ -35,20 +148,35 @@ static void destroy(eap_radius_plugin_t *this)
*/
plugin_t *eap_radius_plugin_create()
{
- eap_radius_plugin_t *this;
+ private_eap_radius_plugin_t *this;
+
+ INIT(this,
+ .public.plugin.destroy = _destroy,
+ .servers = linked_list_create(),
+ );
- if (!radius_client_init())
+ if (!load_servers(this))
{
- DBG1(DBG_CFG, "RADIUS plugin initialization failed");
+ destroy(this);
return NULL;
}
-
- this = malloc_thing(eap_radius_plugin_t);
- this->plugin.destroy = (void(*)(plugin_t*))destroy;
-
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();
}