Moved TLS stack to its own library
[strongswan.git] / src / libcharon / plugins / eap_radius / eap_radius_plugin.c
1 /*
2 * Copyright (C) 2009 Martin Willi
3 * Hochschule fuer Technik Rapperswil
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16 #include "eap_radius_plugin.h"
17
18 #include "eap_radius.h"
19 #include "radius_client.h"
20 #include "radius_server.h"
21
22 #include <daemon.h>
23
24 /**
25 * Default RADIUS server port, when not configured
26 */
27 #define RADIUS_PORT 1812
28
29 typedef struct private_eap_radius_plugin_t private_eap_radius_plugin_t;
30
31 /**
32 * Private data of an eap_radius_plugin_t object.
33 */
34 struct private_eap_radius_plugin_t {
35
36 /**
37 * Public radius_plugin_t interface.
38 */
39 eap_radius_plugin_t public;
40
41 /**
42 * List of RADIUS servers
43 */
44 linked_list_t *servers;
45 };
46
47 /**
48 * Instance of the EAP plugin
49 */
50 static private_eap_radius_plugin_t *instance = NULL;
51
52 METHOD(plugin_t, destroy, void,
53 private_eap_radius_plugin_t *this)
54 {
55 charon->eap->remove_method(charon->eap, (eap_constructor_t)eap_radius_create);
56 this->servers->destroy_offset(this->servers,
57 offsetof(radius_server_t, destroy));
58 free(this);
59 instance = NULL;
60 }
61
62 /**
63 * Load RADIUS servers from configuration
64 */
65 static bool load_servers(private_eap_radius_plugin_t *this)
66 {
67 enumerator_t *enumerator;
68 radius_server_t *server;
69 char *nas_identifier, *secret, *address, *section;
70 int port, sockets, preference;
71
72 address = lib->settings->get_str(lib->settings,
73 "charon.plugins.eap-radius.server", NULL);
74 if (address)
75 { /* legacy configuration */
76 secret = lib->settings->get_str(lib->settings,
77 "charon.plugins.eap-radius.secret", NULL);
78 if (!secret)
79 {
80 DBG1(DBG_CFG, "no RADUIS secret defined");
81 return FALSE;
82 }
83 nas_identifier = lib->settings->get_str(lib->settings,
84 "charon.plugins.eap-radius.nas_identifier", "strongSwan");
85 port = lib->settings->get_int(lib->settings,
86 "charon.plugins.eap-radius.port", RADIUS_PORT);
87 sockets = lib->settings->get_int(lib->settings,
88 "charon.plugins.eap-radius.sockets", 1);
89 server = radius_server_create(address, port, nas_identifier,
90 secret, sockets, 0);
91 if (!server)
92 {
93 DBG1(DBG_CFG, "no RADUIS server defined");
94 return FALSE;
95 }
96 this->servers->insert_last(this->servers, server);
97 return TRUE;
98 }
99
100 enumerator = lib->settings->create_section_enumerator(lib->settings,
101 "charon.plugins.eap-radius.servers");
102 while (enumerator->enumerate(enumerator, &section))
103 {
104 address = lib->settings->get_str(lib->settings,
105 "charon.plugins.eap-radius.servers.%s.address", NULL, section);
106 if (!address)
107 {
108 DBG1(DBG_CFG, "RADIUS server '%s' misses address, skipped", section);
109 continue;
110 }
111 secret = lib->settings->get_str(lib->settings,
112 "charon.plugins.eap-radius.servers.%s.secret", NULL, section);
113 if (!secret)
114 {
115 DBG1(DBG_CFG, "RADIUS server '%s' misses secret, skipped", section);
116 continue;
117 }
118 nas_identifier = lib->settings->get_str(lib->settings,
119 "charon.plugins.eap-radius.servers.%s.nas_identifier",
120 "strongSwan", section);
121 port = lib->settings->get_int(lib->settings,
122 "charon.plugins.eap-radius.servers.%s.port", RADIUS_PORT, section);
123 sockets = lib->settings->get_int(lib->settings,
124 "charon.plugins.eap-radius.servers.%s.sockets", 1, section);
125 preference = lib->settings->get_int(lib->settings,
126 "charon.plugins.eap-radius.servers.%s.preference", 0, section);
127 server = radius_server_create(address, port, nas_identifier,
128 secret, sockets, preference);
129 if (!server)
130 {
131 DBG1(DBG_CFG, "loading RADIUS server '%s' failed, skipped", section);
132 continue;
133 }
134 this->servers->insert_last(this->servers, server);
135 }
136 enumerator->destroy(enumerator);
137
138 if (this->servers->get_count(this->servers) == 0)
139 {
140 DBG1(DBG_CFG, "no valid RADIUS server configuration found");
141 return FALSE;
142 }
143 return TRUE;
144 }
145
146 /*
147 * see header file
148 */
149 plugin_t *eap_radius_plugin_create()
150 {
151 private_eap_radius_plugin_t *this;
152
153 INIT(this,
154 .public.plugin.destroy = _destroy,
155 .servers = linked_list_create(),
156 );
157
158 if (!load_servers(this))
159 {
160 destroy(this);
161 return NULL;
162 }
163 charon->eap->add_method(charon->eap, EAP_RADIUS, 0,
164 EAP_SERVER, (eap_constructor_t)eap_radius_create);
165
166 instance = this;
167
168 return &this->public.plugin;
169 }
170
171 /**
172 * See header
173 */
174 enumerator_t *eap_radius_create_server_enumerator()
175 {
176 if (instance)
177 {
178 return instance->servers->create_enumerator(instance->servers);
179 }
180 return enumerator_create_empty();
181 }
182