/* * Copyright (C) 2009 Martin Willi * Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. See . * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. */ #include "eap_radius_plugin.h" #include "eap_radius.h" #include "radius_client.h" #include "radius_server.h" #include /** * 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, 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 */ 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; } /* * see header file */ plugin_t *eap_radius_plugin_create() { private_eap_radius_plugin_t *this; INIT(this, .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); 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(); }