aboutsummaryrefslogtreecommitdiffstats
path: root/src/libcharon/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'src/libcharon/plugins')
-rw-r--r--src/libcharon/plugins/eap_radius/Makefile.am9
-rw-r--r--src/libcharon/plugins/eap_radius/eap_radius.c7
-rw-r--r--src/libcharon/plugins/eap_radius/eap_radius_accounting.c7
-rw-r--r--src/libcharon/plugins/eap_radius/eap_radius_dae.c2
-rw-r--r--src/libcharon/plugins/eap_radius/eap_radius_forward.h4
-rw-r--r--src/libcharon/plugins/eap_radius/eap_radius_plugin.c43
-rw-r--r--src/libcharon/plugins/eap_radius/eap_radius_plugin.h9
-rw-r--r--src/libcharon/plugins/eap_radius/radius_client.c185
-rw-r--r--src/libcharon/plugins/eap_radius/radius_client.h66
-rw-r--r--src/libcharon/plugins/eap_radius/radius_message.c491
-rw-r--r--src/libcharon/plugins/eap_radius/radius_message.h287
-rw-r--r--src/libcharon/plugins/eap_radius/radius_server.c221
-rw-r--r--src/libcharon/plugins/eap_radius/radius_server.h100
-rw-r--r--src/libcharon/plugins/eap_radius/radius_socket.c386
-rw-r--r--src/libcharon/plugins/eap_radius/radius_socket.h77
15 files changed, 55 insertions, 1839 deletions
diff --git a/src/libcharon/plugins/eap_radius/Makefile.am b/src/libcharon/plugins/eap_radius/Makefile.am
index 96bfa6fcb..181497ab5 100644
--- a/src/libcharon/plugins/eap_radius/Makefile.am
+++ b/src/libcharon/plugins/eap_radius/Makefile.am
@@ -1,12 +1,13 @@
INCLUDES = -I$(top_srcdir)/src/libstrongswan -I$(top_srcdir)/src/libhydra \
- -I$(top_srcdir)/src/libcharon
+ -I$(top_srcdir)/src/libcharon -I$(top_srcdir)/src/libradius
AM_CFLAGS = -rdynamic
if MONOLITHIC
noinst_LTLIBRARIES = libstrongswan-eap-radius.la
else
+libstrongswan_eap_radius_la_LIBADD = $(top_builddir)/src/libradius/libradius.la
plugin_LTLIBRARIES = libstrongswan-eap-radius.la
endif
@@ -15,10 +16,6 @@ libstrongswan_eap_radius_la_SOURCES = \
eap_radius.h eap_radius.c \
eap_radius_accounting.h eap_radius_accounting.c \
eap_radius_dae.h eap_radius_dae.c \
- eap_radius_forward.h eap_radius_forward.c \
- radius_server.h radius_server.c \
- radius_socket.h radius_socket.c \
- radius_client.h radius_client.c \
- radius_message.h radius_message.c
+ eap_radius_forward.h eap_radius_forward.c
libstrongswan_eap_radius_la_LDFLAGS = -module -avoid-version
diff --git a/src/libcharon/plugins/eap_radius/eap_radius.c b/src/libcharon/plugins/eap_radius/eap_radius.c
index f2b47e3f0..051d46ecf 100644
--- a/src/libcharon/plugins/eap_radius/eap_radius.c
+++ b/src/libcharon/plugins/eap_radius/eap_radius.c
@@ -14,10 +14,11 @@
*/
#include "eap_radius.h"
+#include "eap_radius_plugin.h"
#include "eap_radius_forward.h"
-#include "radius_message.h"
-#include "radius_client.h"
+#include <radius_message.h>
+#include <radius_client.h>
#include <daemon.h>
@@ -462,7 +463,7 @@ eap_radius_t *eap_radius_create(identification_t *server, identification_t *peer
"charon.plugins.eap-radius.filter_id", FALSE),
);
- this->client = radius_client_create();
+ this->client = eap_radius_create_client();
if (!this->client)
{
free(this);
diff --git a/src/libcharon/plugins/eap_radius/eap_radius_accounting.c b/src/libcharon/plugins/eap_radius/eap_radius_accounting.c
index 25013f62d..45be22704 100644
--- a/src/libcharon/plugins/eap_radius/eap_radius_accounting.c
+++ b/src/libcharon/plugins/eap_radius/eap_radius_accounting.c
@@ -14,11 +14,12 @@
*/
#include "eap_radius_accounting.h"
+#include "eap_radius_plugin.h"
#include <time.h>
-#include "radius_message.h"
-#include "radius_client.h"
+#include <radius_message.h>
+#include <radius_client.h>
#include <daemon.h>
#include <utils/hashtable.h>
#include <threading/mutex.h>
@@ -125,7 +126,7 @@ static bool send_message(private_eap_radius_accounting_t *this,
radius_client_t *client;
bool ack = FALSE;
- client = radius_client_create();
+ client = eap_radius_create_client();
if (client)
{
response = client->request(client, request);
diff --git a/src/libcharon/plugins/eap_radius/eap_radius_dae.c b/src/libcharon/plugins/eap_radius/eap_radius_dae.c
index 3ea587309..1cc19afaa 100644
--- a/src/libcharon/plugins/eap_radius/eap_radius_dae.c
+++ b/src/libcharon/plugins/eap_radius/eap_radius_dae.c
@@ -15,7 +15,7 @@
#include "eap_radius_dae.h"
-#include "radius_message.h"
+#include <radius_message.h>
#include <sys/types.h>
#include <sys/stat.h>
diff --git a/src/libcharon/plugins/eap_radius/eap_radius_forward.h b/src/libcharon/plugins/eap_radius/eap_radius_forward.h
index e1a8c4170..2c1dbf7a8 100644
--- a/src/libcharon/plugins/eap_radius/eap_radius_forward.h
+++ b/src/libcharon/plugins/eap_radius/eap_radius_forward.h
@@ -15,13 +15,13 @@
/**
* @defgroup eap_radius_forward eap_radius_forward
- * @{ @ingroup
+ * @{ @ingroup eap_radius
*/
#ifndef EAP_RADIUS_FORWARD_H_
#define EAP_RADIUS_FORWARD_H_
-#include "radius_message.h"
+#include <radius_message.h>
#include <bus/listeners/listener.h>
diff --git a/src/libcharon/plugins/eap_radius/eap_radius_plugin.c b/src/libcharon/plugins/eap_radius/eap_radius_plugin.c
index e544aaf3e..0caecc1ad 100644
--- a/src/libcharon/plugins/eap_radius/eap_radius_plugin.c
+++ b/src/libcharon/plugins/eap_radius/eap_radius_plugin.c
@@ -19,8 +19,9 @@
#include "eap_radius_accounting.h"
#include "eap_radius_dae.h"
#include "eap_radius_forward.h"
-#include "radius_client.h"
-#include "radius_server.h"
+
+#include <radius_client.h>
+#include <radius_server.h>
#include <daemon.h>
#include <threading/rwlock.h>
@@ -261,15 +262,43 @@ plugin_t *eap_radius_plugin_create()
/**
* See header
*/
-enumerator_t *eap_radius_create_server_enumerator()
+radius_client_t *eap_radius_create_client()
{
if (instance)
{
+ enumerator_t *enumerator;
+ radius_server_t *server, *selected = NULL;
+ int current, best = -1;
+
instance->lock->read_lock(instance->lock);
- return enumerator_create_cleaner(
- instance->servers->create_enumerator(instance->servers),
- (void*)instance->lock->unlock, instance->lock);
+ enumerator = instance->servers->create_enumerator(instance->servers);
+ while (enumerator->enumerate(enumerator, &server))
+ {
+ current = server->get_preference(server);
+ if (current > best ||
+ /* for two with equal preference, 50-50 chance */
+ (current == best && random() % 2 == 0))
+ {
+ DBG2(DBG_CFG, "RADIUS server '%s' is candidate: %d",
+ server->get_name(server), current);
+ best = current;
+ DESTROY_IF(selected);
+ selected = server->get_ref(server);
+ }
+ else
+ {
+ DBG2(DBG_CFG, "RADIUS server '%s' skipped: %d",
+ server->get_name(server), current);
+ }
+ }
+ enumerator->destroy(enumerator);
+ instance->lock->unlock(instance->lock);
+
+ if (selected)
+ {
+ return radius_client_create(selected);
+ }
}
- return enumerator_create_empty();
+ return NULL;
}
diff --git a/src/libcharon/plugins/eap_radius/eap_radius_plugin.h b/src/libcharon/plugins/eap_radius/eap_radius_plugin.h
index cb724364a..1570bd566 100644
--- a/src/libcharon/plugins/eap_radius/eap_radius_plugin.h
+++ b/src/libcharon/plugins/eap_radius/eap_radius_plugin.h
@@ -25,7 +25,8 @@
#define EAP_RADIUS_PLUGIN_H_
#include <plugins/plugin.h>
-#include <utils/enumerator.h>
+
+#include <radius_client.h>
typedef struct eap_radius_plugin_t eap_radius_plugin_t;
@@ -44,10 +45,10 @@ struct eap_radius_plugin_t {
};
/**
- * Create an enumerator over all loaded RADIUS servers.
+ * Get a RADIUS client instance to connect to servers.
*
- * @return enumerator over radius_server_t
+ * @return RADIUS client
*/
-enumerator_t *eap_radius_create_server_enumerator();
+radius_client_t *eap_radius_create_client();
#endif /** EAP_RADIUS_PLUGIN_H_ @}*/
diff --git a/src/libcharon/plugins/eap_radius/radius_client.c b/src/libcharon/plugins/eap_radius/radius_client.c
deleted file mode 100644
index 1a67096cb..000000000
--- a/src/libcharon/plugins/eap_radius/radius_client.c
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * 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 <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * 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 "radius_client.h"
-
-#include "eap_radius_plugin.h"
-#include "radius_server.h"
-
-#include <unistd.h>
-#include <errno.h>
-
-#include <debug.h>
-#include <utils/host.h>
-#include <utils/linked_list.h>
-#include <threading/condvar.h>
-#include <threading/mutex.h>
-
-typedef struct private_radius_client_t private_radius_client_t;
-
-/**
- * Private data of an radius_client_t object.
- */
-struct private_radius_client_t {
-
- /**
- * Public radius_client_t interface.
- */
- radius_client_t public;
-
- /**
- * Selected RADIUS server
- */
- radius_server_t *server;
-
- /**
- * RADIUS servers State attribute
- */
- chunk_t state;
-
- /**
- * EAP MSK, from MPPE keys
- */
- chunk_t msk;
-};
-
-/**
- * Save the state attribute to include in further request
- */
-static void save_state(private_radius_client_t *this, radius_message_t *msg)
-{
- enumerator_t *enumerator;
- int type;
- chunk_t data;
-
- enumerator = msg->create_enumerator(msg);
- while (enumerator->enumerate(enumerator, &type, &data))
- {
- if (type == RAT_STATE)
- {
- free(this->state.ptr);
- this->state = chunk_clone(data);
- enumerator->destroy(enumerator);
- return;
- }
- }
- enumerator->destroy(enumerator);
- /* no state attribute found, remove state */
- chunk_free(&this->state);
-}
-
-METHOD(radius_client_t, request, radius_message_t*,
- private_radius_client_t *this, radius_message_t *req)
-{
- char virtual[] = {0x00,0x00,0x00,0x05};
- radius_socket_t *socket;
- radius_message_t *res;
-
- /* we add the "Virtual" NAS-Port-Type, as we SHOULD include one */
- req->add(req, RAT_NAS_PORT_TYPE, chunk_create(virtual, sizeof(virtual)));
- /* add our NAS-Identifier */
- req->add(req, RAT_NAS_IDENTIFIER,
- this->server->get_nas_identifier(this->server));
- /* add State attribute, if server sent one */
- if (this->state.ptr)
- {
- req->add(req, RAT_STATE, this->state);
- }
- socket = this->server->get_socket(this->server);
- DBG1(DBG_CFG, "sending RADIUS %N to server '%s'", radius_message_code_names,
- req->get_code(req), this->server->get_name(this->server));
- res = socket->request(socket, req);
- if (res)
- {
- DBG1(DBG_CFG, "received RADIUS %N from server '%s'",
- radius_message_code_names, res->get_code(res),
- this->server->get_name(this->server));
- save_state(this, res);
- if (res->get_code(res) == RMC_ACCESS_ACCEPT)
- {
- chunk_clear(&this->msk);
- this->msk = socket->decrypt_msk(socket, req, res);
- }
- this->server->put_socket(this->server, socket, TRUE);
- return res;
- }
- this->server->put_socket(this->server, socket, FALSE);
- return NULL;
-}
-
-METHOD(radius_client_t, get_msk, chunk_t,
- private_radius_client_t *this)
-{
- return this->msk;
-}
-
-METHOD(radius_client_t, destroy, void,
- private_radius_client_t *this)
-{
- this->server->destroy(this->server);
- chunk_clear(&this->msk);
- free(this->state.ptr);
- free(this);
-}
-
-/**
- * See header
- */
-radius_client_t *radius_client_create()
-{
- private_radius_client_t *this;
- enumerator_t *enumerator;
- radius_server_t *server;
- int current, best = -1;
-
- INIT(this,
- .public = {
- .request = _request,
- .get_msk = _get_msk,
- .destroy = _destroy,
- },
- );
-
- enumerator = eap_radius_create_server_enumerator();
- while (enumerator->enumerate(enumerator, &server))
- {
- current = server->get_preference(server);
- if (current > best ||
- /* for two with equal preference, 50-50 chance */
- (current == best && random() % 2 == 0))
- {
- DBG2(DBG_CFG, "RADIUS server '%s' is candidate: %d",
- server->get_name(server), current);
- best = current;
- DESTROY_IF(this->server);
- this->server = server->get_ref(server);
- }
- else
- {
- DBG2(DBG_CFG, "RADIUS server '%s' skipped: %d",
- server->get_name(server), current);
- }
- }
- enumerator->destroy(enumerator);
-
- if (!this->server)
- {
- free(this);
- return NULL;
- }
-
- return &this->public;
-}
-
diff --git a/src/libcharon/plugins/eap_radius/radius_client.h b/src/libcharon/plugins/eap_radius/radius_client.h
deleted file mode 100644
index e4f3a7222..000000000
--- a/src/libcharon/plugins/eap_radius/radius_client.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * 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 <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * 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.
- */
-
-/**
- * @defgroup radius_client radius_client
- * @{ @ingroup eap_radius
- */
-
-#ifndef RADIUS_CLIENT_H_
-#define RADIUS_CLIENT_H_
-
-#include "radius_message.h"
-
-typedef struct radius_client_t radius_client_t;
-
-/**
- * RADIUS client functionality.
- *
- * To communicate with a RADIUS server, create a client and send messages over
- * it. The client allocates a socket from the best RADIUS server abailable.
- */
-struct radius_client_t {
-
- /**
- * Send a RADIUS request and wait for the response.
- *
- * The client fills in NAS-Identifier nad NAS-Port-Type
- *
- * @param msg RADIUS request message to send
- * @return response, NULL if timed out/verification failed
- */
- radius_message_t* (*request)(radius_client_t *this, radius_message_t *msg);
-
- /**
- * Get the EAP MSK after successful RADIUS authentication.
- *
- * @return MSK, allocated
- */
- chunk_t (*get_msk)(radius_client_t *this);
-
- /**
- * Destroy the client, release the socket.
- */
- void (*destroy)(radius_client_t *this);
-};
-
-/**
- * Create a RADIUS client.
- *
- * @return radius_client_t object
- */
-radius_client_t *radius_client_create();
-
-#endif /** RADIUS_CLIENT_H_ @}*/
diff --git a/src/libcharon/plugins/eap_radius/radius_message.c b/src/libcharon/plugins/eap_radius/radius_message.c
deleted file mode 100644
index ad8875423..000000000
--- a/src/libcharon/plugins/eap_radius/radius_message.c
+++ /dev/null
@@ -1,491 +0,0 @@
-/*
- * 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 <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * 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 "radius_message.h"
-
-#include <debug.h>
-#include <crypto/hashers/hasher.h>
-
-typedef struct private_radius_message_t private_radius_message_t;
-typedef struct rmsg_t rmsg_t;
-typedef struct rattr_t rattr_t;
-
-/**
- * RADIUS message header
- */
-struct rmsg_t {
- /** message code, radius_message_code_t */
- u_int8_t code;
- /** message identifier */
- u_int8_t identifier;
- /** length of Code, Identifier, Length, Authenticator and Attributes */
- u_int16_t length;
- /** message authenticator, MD5 hash */
- u_int8_t authenticator[HASH_SIZE_MD5];
- /** variable list of packed attributes */
- u_int8_t attributes[];
-} __attribute__((packed));
-
-/**
- * RADIUS message attribute.
- */
-struct rattr_t {
- /** attribute type, radius_attribute_type_t */
- u_int8_t type;
- /** length of the attriubte, including the Type, Length and Value fields */
- u_int8_t length;
- /** variable length attribute value */
- u_int8_t value[];
-} __attribute__((packed));
-
-/**
- * Private data of an radius_message_t object.
- */
-struct private_radius_message_t {
-
- /**
- * Public radius_message_t interface.
- */
- radius_message_t public;
-
- /**
- * message data, allocated
- */
- rmsg_t *msg;
-};
-
-ENUM_BEGIN(radius_message_code_names, RMC_ACCESS_REQUEST, RMC_ACCOUNTING_RESPONSE,
- "Access-Request",
- "Access-Accept",
- "Access-Reject",
- "Accounting-Request",
- "Accounting-Response");
-ENUM_NEXT(radius_message_code_names, RMC_ACCESS_CHALLENGE, RMC_ACCESS_CHALLENGE, RMC_ACCOUNTING_RESPONSE,
- "Access-Challenge");
-ENUM_NEXT(radius_message_code_names, RMC_DISCONNECT_REQUEST, RMC_COA_NAK, RMC_ACCESS_CHALLENGE,
- "Disconnect-Request",
- "Disconnect-ACK",
- "Disconnect-NAK",
- "CoA-Request",
- "CoA-ACK",
- "CoA-NAK");
-ENUM_END(radius_message_code_names, RMC_COA_NAK);
-
-ENUM(radius_attribute_type_names, RAT_USER_NAME, RAT_MIP6_HOME_LINK_PREFIX,
- "User-Name",
- "User-Password",
- "CHAP-Password",
- "NAS-IP-Address",
- "NAS-Port",
- "Service-Type",
- "Framed-Protocol",
- "Framed-IP-Address",
- "Framed-IP-Netmask",
- "Framed-Routing",
- "Filter-Id",
- "Framed-MTU",
- "Framed-Compression",
- "Login-IP-Host",
- "Login-Service",
- "Login-TCP-Port",
- "Unassigned",
- "Reply-Message",
- "Callback-Number",
- "Callback-Id",
- "Unassigned",
- "Framed-Route",
- "Framed-IPX-Network",
- "State",
- "Class",
- "Vendor-Specific",
- "Session-Timeout",
- "Idle-Timeout",
- "Termination-Action",
- "Called-Station-Id",
- "Calling-Station-Id",
- "NAS-Identifier",
- "Proxy-State",
- "Login-LAT-Service",
- "Login-LAT-Node",
- "Login-LAT-Group",
- "Framed-AppleTalk-Link",
- "Framed-AppleTalk-Network",
- "Framed-AppleTalk-Zone",
- "Acct-Status-Type",
- "Acct-Delay-Time",
- "Acct-Input-Octets",
- "Acct-Output-Octets",
- "Acct-Session-Id",
- "Acct-Authentic",
- "Acct-Session-Time",
- "Acct-Input-Packets",
- "Acct-Output-Packets",
- "Acct-Terminate-Cause",
- "Acct-Multi-Session-Id",
- "Acct-Link-Count",
- "Acct-Input-Gigawords",
- "Acct-Output-Gigawords",
- "Unassigned",
- "Event-Timestamp",
- "Egress-VLANID",
- "Ingress-Filters",
- "Egress-VLAN-Name",
- "User-Priority-Table",
- "CHAP-Challenge",
- "NAS-Port-Type",
- "Port-Limit",
- "Login-LAT-Port",
- "Tunnel-Type",
- "Tunnel-Medium-Type",
- "Tunnel-Client-Endpoint",
- "Tunnel-Server-Endpoint",
- "Acct-Tunnel-Connection",
- "Tunnel-Password",
- "ARAP-Password",
- "ARAP-Features",
- "ARAP-Zone-Access",
- "ARAP-Security",
- "ARAP-Security-Data",
- "Password-Retry",
- "Prompt",
- "Connect-Info",
- "Configuration-Token",
- "EAP-Message",
- "Message-Authenticator",
- "Tunnel-Private-Group-ID",
- "Tunnel-Assignment-ID",
- "Tunnel-Preference",
- "ARAP-Challenge-Response",
- "Acct-Interim-Interval",
- "Acct-Tunnel-Packets-Lost",
- "NAS-Port-Id",
- "Framed-Pool",
- "CUI",
- "Tunnel-Client-Auth-ID",
- "Tunnel-Server-Auth-ID",
- "NAS-Filter-Rule",
- "Unassigned",
- "Originating-Line-Info",
- "NAS-IPv6-Address",
- "Framed-Interface-Id",
- "Framed-IPv6-Prefix",
- "Login-IPv6-Host",
- "Framed-IPv6-Route",
- "Framed-IPv6-Pool",
- "Error-Cause",
- "EAP-Key-Name",
- "Digest-Response",
- "Digest-Realm",
- "Digest-Nonce",
- "Digest-Response-Auth",
- "Digest-Nextnonce",
- "Digest-Method",
- "Digest-URI",
- "Digest-Qop",
- "Digest-Algorithm",
- "Digest-Entity-Body-Hash",
- "Digest-CNonce",
- "Digest-Nonce-Count",
- "Digest-Username",
- "Digest-Opaque",
- "Digest-Auth-Param",
- "Digest-AKA-Auts",
- "Digest-Domain",
- "Digest-Stale",
- "Digest-HA1",
- "SIP-AOR",
- "Delegated-IPv6-Prefix",
- "MIP6-Feature-Vector",
- "MIP6-Home-Link-Prefix");
-
-/**
- * Attribute enumerator implementation
- */
-typedef struct {
- /** implements enumerator interface */
- enumerator_t public;
- /** currently pointing attribute */
- rattr_t *next;
- /** bytes left */
- int left;
-} attribute_enumerator_t;
-
-METHOD(enumerator_t, attribute_enumerate, bool,
- attribute_enumerator_t *this, int *type, chunk_t *data)
-{
- if (this->left == 0)
- {
- return FALSE;
- }
- if (this->left < sizeof(rattr_t) ||
- this->left < this->next->length)
- {
- DBG1(DBG_IKE, "RADIUS message truncated");
- return FALSE;
- }
- *type = this->next->type;
- data->ptr = this->next->value;
- data->len = this->next->length - sizeof(rattr_t);
- this->left -= this->next->length;
- this->next = ((void*)this->next) + this->next->length;
- return TRUE;
-}
-
-METHOD(radius_message_t, create_enumerator, enumerator_t*,
- private_radius_message_t *this)
-{
- attribute_enumerator_t *e;
-
- if (ntohs(this->msg->length) < sizeof(rmsg_t) + sizeof(rattr_t))
- {
- return enumerator_create_empty();
- }
- INIT(e,
- .public = {
- .enumerate = (void*)_attribute_enumerate,
- .destroy = (void*)free,
- },
- .next = (rattr_t*)this->msg->attributes,
- .left = ntohs(this->msg->length) - sizeof(rmsg_t),
- );
- return &e->public;
-}
-
-METHOD(radius_message_t, add, void,
- private_radius_message_t *this, radius_attribute_type_t type, chunk_t data)
-{
- rattr_t *attribute;
-
- data.len = min(data.len, 253);
- this->msg = realloc(this->msg,
- ntohs(this->msg->length) + sizeof(rattr_t) + data.len);
- attribute = ((void*)this->msg) + ntohs(this->msg->length);
- attribute->type = type;
- attribute->length = data.len + sizeof(rattr_t);
- memcpy(attribute->value, data.ptr, data.len);
- this->msg->length = htons(ntohs(this->msg->length) + attribute->length);
-}
-
-METHOD(radius_message_t, sign, void,
- private_radius_message_t *this, u_int8_t *req_auth, chunk_t secret,
- hasher_t *hasher, signer_t *signer, rng_t *rng)
-{
- if (rng == NULL)
- {
- chunk_t msg;
-
- if (req_auth)
- {
- memcpy(this->msg->authenticator, req_auth, HASH_SIZE_MD5);
- }
- else
- {
- memset(this->msg->authenticator, 0, sizeof(this->msg->authenticator));
- }
- msg = chunk_create((u_char*)this->msg, ntohs(this->msg->length));
- hasher->get_hash(hasher, msg, NULL);
- hasher->get_hash(hasher, secret, this->msg->authenticator);
- }
- else
- {
- char buf[HASH_SIZE_MD5];
-
- /* build Request-Authenticator */
- rng->get_bytes(rng, HASH_SIZE_MD5, this->msg->authenticator);
-
- /* build Message-Authenticator attribute, using 16 null bytes */
- memset(buf, 0, sizeof(buf));
- add(this, RAT_MESSAGE_AUTHENTICATOR, chunk_create(buf, sizeof(buf)));
- signer->get_signature(signer,
- chunk_create((u_char*)this->msg, ntohs(this->msg->length)),
- ((u_char*)this->msg) + ntohs(this->msg->length) - HASH_SIZE_MD5);
- }
-}
-
-METHOD(radius_message_t, verify, bool,
- private_radius_message_t *this, u_int8_t *req_auth, chunk_t secret,
- hasher_t *hasher, signer_t *signer)
-{
- char buf[HASH_SIZE_MD5], res_auth[HASH_SIZE_MD5];
- enumerator_t *enumerator;
- int type;
- chunk_t data, msg;
- bool has_eap = FALSE, has_auth = FALSE;
-
- /* replace Response by Request Authenticator for verification */
- memcpy(res_auth, this->msg->authenticator, HASH_SIZE_MD5);
- if (req_auth)
- {
- memcpy(this->msg->authenticator, req_auth, HASH_SIZE_MD5);
- }
- else
- {
- memset(this->msg->authenticator, 0, HASH_SIZE_MD5);
- }
- msg = chunk_create((u_char*)this->msg, ntohs(this->msg->length));
-
- /* verify Response-Authenticator */
- hasher->get_hash(hasher, msg, NULL);
- hasher->get_hash(hasher, secret, buf);
- if (!memeq(buf, res_auth, HASH_SIZE_MD5))
- {
- DBG1(DBG_CFG, "RADIUS Response-Authenticator verification failed");
- return FALSE;
- }
-
- /* verify Message-Authenticator attribute */
- enumerator = create_enumerator(this);
- while (enumerator->enumerate(enumerator, &type, &data))
- {
- if (type == RAT_MESSAGE_AUTHENTICATOR)
- {
- if (data.len != HASH_SIZE_MD5)
- {
- DBG1(DBG_CFG, "RADIUS Message-Authenticator invalid length");
- enumerator->destroy(enumerator);
- return FALSE;
- }
- memcpy(buf, data.ptr, data.len);
- memset(data.ptr, 0, data.len);
- if (signer->verify_signature(signer, msg,
- chunk_create(buf, sizeof(buf))))
- {
- /* restore Message-Authenticator */
- memcpy(data.ptr, buf, data.len);
- has_auth = TRUE;
- break;
- }
- else
- {
- DBG1(DBG_CFG, "RADIUS Message-Authenticator verification failed");
- enumerator->destroy(enumerator);
- return FALSE;
- }
- }
- else if (type == RAT_EAP_MESSAGE)
- {
- has_eap = TRUE;
- }
- }
- enumerator->destroy(enumerator);
- /* restore Response-Authenticator */
- memcpy(this->msg->authenticator, res_auth, HASH_SIZE_MD5);
-
- if (has_eap && !has_auth)
- { /* Message-Authenticator is required if we have an EAP-Message */
- DBG1(DBG_CFG, "RADIUS Message-Authenticator attribute missing");
- return FALSE;
- }
- return TRUE;
-}
-
-METHOD(radius_message_t, get_code, radius_message_code_t,
- private_radius_message_t *this)
-{
- return this->msg->code;
-}
-
-METHOD(radius_message_t, get_identifier, u_int8_t,
- private_radius_message_t *this)
-{
- return this->msg->identifier;
-}
-
-METHOD(radius_message_t, set_identifier, void,
- private_radius_message_t *this, u_int8_t identifier)
-{
- this->msg->identifier = identifier;
-}
-
-METHOD(radius_message_t, get_authenticator, u_int8_t*,
- private_radius_message_t *this)
-{
- return this->msg->authenticator;
-}
-
-
-METHOD(radius_message_t, get_encoding, chunk_t,
- private_radius_message_t *this)
-{
- return chunk_create((u_char*)this->msg, ntohs(this->msg->length));
-}
-
-METHOD(radius_message_t, destroy, void,
- private_radius_message_t *this)
-{
- free(this->msg);
- free(this);
-}
-
-/**
- * Generic constructor
- */
-static private_radius_message_t *radius_message_create_empty()
-{
- private_radius_message_t *this;
-
- INIT(this,
- .public = {
- .create_enumerator = _create_enumerator,
- .add = _add,
- .get_code = _get_code,
- .get_identifier = _get_identifier,
- .set_identifier = _set_identifier,
- .get_authenticator = _get_authenticator,
- .get_encoding = _get_encoding,
- .sign = _sign,
- .verify = _verify,
- .destroy = _destroy,
- },
- );
-
- return this;
-}
-
-/**
- * See header
- */
-radius_message_t *radius_message_create(radius_message_code_t code)
-{
- private_radius_message_t *this = radius_message_create_empty();
-
- INIT(this->msg,
- .code = code,
- .identifier = 0,
- .length = htons(sizeof(rmsg_t)),
- );
-
- return &this->public;
-}
-
-/**
- * See header
- */
-radius_message_t *radius_message_parse(chunk_t data)
-{
- private_radius_message_t *this = radius_message_create_empty();
-
- this->msg = malloc(data.len);
- memcpy(this->msg, data.ptr, data.len);
- if (data.len < sizeof(rmsg_t) ||
- ntohs(this->msg->length) != data.len)
- {
- DBG1(DBG_IKE, "RADIUS message has invalid length");
- destroy(this);
- return NULL;
- }
- return &this->public;
-}
-
diff --git a/src/libcharon/plugins/eap_radius/radius_message.h b/src/libcharon/plugins/eap_radius/radius_message.h
deleted file mode 100644
index 355714505..000000000
--- a/src/libcharon/plugins/eap_radius/radius_message.h
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * 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 <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * 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.
- */
-
-/**
- * @defgroup radius_message radius_message
- * @{ @ingroup eap_radius
- */
-
-#ifndef RADIUS_MESSAGE_H_
-#define RADIUS_MESSAGE_H_
-
-#include <library.h>
-
-typedef struct radius_message_t radius_message_t;
-typedef enum radius_message_code_t radius_message_code_t;
-typedef enum radius_attribute_type_t radius_attribute_type_t;
-
-/**
- * RADIUS Message Codes.
- */
-enum radius_message_code_t {
- RMC_ACCESS_REQUEST = 1,
- RMC_ACCESS_ACCEPT = 2,
- RMC_ACCESS_REJECT = 3,
- RMC_ACCOUNTING_REQUEST = 4,
- RMC_ACCOUNTING_RESPONSE = 5,
- RMC_ACCESS_CHALLENGE = 11,
- RMC_DISCONNECT_REQUEST = 40,
- RMC_DISCONNECT_ACK = 41,
- RMC_DISCONNECT_NAK = 42,
- RMC_COA_REQUEST = 43,
- RMC_COA_ACK = 44,
- RMC_COA_NAK = 45,
-};
-
-/**
- * Enum names for radius_attribute_type_t.
- */
-extern enum_name_t *radius_message_code_names;
-
-/**
- * RADIUS Attribute Types.
- */
-enum radius_attribute_type_t {
- RAT_USER_NAME = 1,
- RAT_USER_PASSWORD = 2,
- RAT_CHAP_PASSWORD = 3,
- RAT_NAS_IP_ADDRESS = 4,
- RAT_NAS_PORT = 5,
- RAT_SERVICE_TYPE = 6,
- RAT_FRAMED_PROTOCOL = 7,
- RAT_FRAMED_IP_ADDRESS = 8,
- RAT_FRAMED_IP_NETMASK = 9,
- RAT_FRAMED_ROUTING = 10,
- RAT_FILTER_ID = 11,
- RAT_FRAMED_MTU = 12,
- RAT_FRAMED_COMPRESSION = 13,
- RAT_LOGIN_IP_HOST = 14,
- RAT_LOGIN_SERVICE = 15,
- RAT_LOGIN_TCP_PORT = 16,
- RAT_REPLY_MESSAGE = 18,
- RAT_CALLBACK_NUMBER = 19,
- RAT_CALLBACK_ID = 20,
- RAT_FRAMED_ROUTE = 22,
- RAT_FRAMED_IPX_NETWORK = 23,
- RAT_STATE = 24,
- RAT_CLASS = 25,
- RAT_VENDOR_SPECIFIC = 26,
- RAT_SESSION_TIMEOUT = 27,
- RAT_IDLE_TIMEOUT = 28,
- RAT_TERMINATION_ACTION = 29,
- RAT_CALLED_STATION_ID = 30,
- RAT_CALLING_STATION_ID = 31,
- RAT_NAS_IDENTIFIER = 32,
- RAT_PROXY_STATE = 33,
- RAT_LOGIN_LAT_SERVICE = 34,
- RAT_LOGIN_LAT_NODE = 35,
- RAT_LOGIN_LAT_GROUP = 36,
- RAT_FRAMED_APPLETALK_LINK = 37,
- RAT_FRAMED_APPLETALK_NETWORK = 38,
- RAT_FRAMED_APPLETALK_ZONE = 39,
- RAT_ACCT_STATUS_TYPE = 40,
- RAT_ACCT_DELAY_TIME = 41,
- RAT_ACCT_INPUT_OCTETS = 42,
- RAT_ACCT_OUTPUT_OCTETS = 43,
- RAT_ACCT_SESSION_ID = 44,
- RAT_ACCT_AUTHENTIC = 45,
- RAT_ACCT_SESSION_TIME = 46,
- RAT_ACCT_INPUT_PACKETS = 47,
- RAT_ACCT_OUTPUT_PACKETS = 48,
- RAT_ACCT_TERMINATE_CAUSE = 49,
- RAT_ACCT_MULTI_SESSION_ID = 50,
- RAT_ACCT_LINK_COUNT = 51,
- RAT_ACCT_INPUT_GIGAWORDS = 52,
- RAT_ACCT_OUTPUT_GIGAWORDS = 53,
- RAT_EVENT_TIMESTAMP = 55,
- RAT_EGRESS_VLANID = 56,
- RAT_INGRESS_FILTERS = 57,
- RAT_EGRESS_VLAN_NAME = 58,
- RAT_USER_PRIORITY_TABLE = 59,
- RAT_CHAP_CHALLENGE = 60,
- RAT_NAS_PORT_TYPE = 61,
- RAT_PORT_LIMIT = 62,
- RAT_LOGIN_LAT_PORT = 63,
- RAT_TUNNEL_TYPE = 64,
- RAT_TUNNEL_MEDIUM_TYPE = 65,
- RAT_TUNNEL_CLIENT_ENDPOINT = 66,
- RAT_TUNNEL_SERVER_ENDPOINT = 67,
- RAT_ACCT_TUNNEL_CONNECTION = 68,
- RAT_TUNNEL_PASSWORD = 69,
- RAT_ARAP_PASSWORD = 70,
- RAT_ARAP_FEATURES = 71,
- RAT_ARAP_ZONE_ACCESS = 72,
- RAT_ARAP_SECURITY = 73,
- RAT_ARAP_SECURITY_DATA = 74,
- RAT_PASSWORD_RETRY = 75,
- RAT_PROMPT = 76,
- RAT_CONNECT_INFO = 77,
- RAT_CONFIGURATION_TOKEN = 78,
- RAT_EAP_MESSAGE = 79,
- RAT_MESSAGE_AUTHENTICATOR = 80,
- RAT_TUNNEL_PRIVATE_GROUP_ID = 81,
- RAT_TUNNEL_ASSIGNMENT_ID = 82,
- RAT_TUNNEL_PREFERENCE = 83,
- RAT_ARAP_CHALLENGE_RESPONSE = 84,
- RAT_ACCT_INTERIM_INTERVAL = 85,
- RAT_ACCT_TUNNEL_PACKETS_LOST = 86,
- RAT_NAS_PORT_ID = 87,
- RAT_FRAMED_POOL = 88,
- RAT_CUI = 89,
- RAT_TUNNEL_CLIENT_AUTH_ID = 90,
- RAT_TUNNEL_SERVER_AUTH_ID = 91,
- RAT_NAS_FILTER_RULE = 92,
- RAT_UNASSIGNED = 93,
- RAT_ORIGINATING_LINE_INFO = 94,
- RAT_NAS_IPV6_ADDRESS = 95,
- RAT_FRAMED_INTERFACE_ID = 96,
- RAT_FRAMED_IPV6_PREFIX = 97,
- RAT_LOGIN_IPV6_HOST = 98,
- RAT_FRAMED_IPV6_ROUTE = 99,
- RAT_FRAMED_IPV6_POOL = 100,
- RAT_ERROR_CAUSE = 101,
- RAT_EAP_KEY_NAME = 102,
- RAT_DIGEST_RESPONSE = 103,
- RAT_DIGEST_REALM = 104,
- RAT_DIGEST_NONCE = 105,
- RAT_DIGEST_RESPONSE_AUTH = 106,
- RAT_DIGEST_NEXTNONCE = 107,
- RAT_DIGEST_METHOD = 108,
- RAT_DIGEST_URI = 109,
- RAT_DIGEST_QOP = 110,
- RAT_DIGEST_ALGORITHM = 111,
- RAT_DIGEST_ENTITY_BODY_HASH = 112,
- RAT_DIGEST_CNONCE = 113,
- RAT_DIGEST_NONCE_COUNT = 114,
- RAT_DIGEST_USERNAME = 115,
- RAT_DIGEST_OPAQUE = 116,
- RAT_DIGEST_AUTH_PARAM = 117,
- RAT_DIGEST_AKA_AUTS = 118,
- RAT_DIGEST_DOMAIN = 119,
- RAT_DIGEST_STALE = 120,
- RAT_DIGEST_HA1 = 121,
- RAT_SIP_AOR = 122,
- RAT_DELEGATED_IPV6_PREFIX = 123,
- RAT_MIP6_FEATURE_VECTOR = 124,
- RAT_MIP6_HOME_LINK_PREFIX = 125,
-};
-
-/**
- * Enum names for radius_attribute_type_t.
- */
-extern enum_name_t *radius_attribute_type_names;
-
-/**
- * A RADIUS message, contains attributes.
- */
-struct radius_message_t {
-
- /**
- * Create an enumerator over contained RADIUS attributes.
- *
- * @return enumerator over (int type, chunk_t data)
- */
- enumerator_t* (*create_enumerator)(radius_message_t *this);
-
- /**
- * Add a RADIUS attribute to the message.
- *
- * @param type type of attribute to add
- * @param attribute data, gets cloned
- */
- void (*add)(radius_message_t *this, radius_attribute_type_t type,
- chunk_t data);
-
- /**
- * Get the message type (code).
- *
- * @return message code
- */
- radius_message_code_t (*get_code)(radius_message_t *this);
-
- /**
- * Get the message identifier.
- *
- * @return message identifier
- */
- u_int8_t (*get_identifier)(radius_message_t *this);
-
- /**
- * Set the message identifier.
- *
- * @param identifier message identifier
- */
- void (*set_identifier)(radius_message_t *this, u_int8_t identifier);
-
- /**
- * Get the 16 byte authenticator.
- *
- * @return pointer to the Authenticator field
- */
- u_int8_t* (*get_authenticator)(radius_message_t *this);
-
- /**
- * Get the RADIUS message in its encoded form.
- *
- * @return chunk pointing to internal RADIUS message.
- */
- chunk_t (*get_encoding)(radius_message_t *this);
-
- /**
- * Calculate and add the Message-Authenticator attribute to the message.
- *
- * @param req_auth 16 byte Authenticator of request, or NULL
- * @param secret shared RADIUS secret
- * @param signer HMAC-MD5 signer with secret set
- * @param hasher MD5 hasher
- * @param rng RNG to create Message-Authenticator, NULL to omit
- */
- void (*sign)(radius_message_t *this, u_int8_t *req_auth, chunk_t secret,
- hasher_t *hasher, signer_t *signer, rng_t *rng);
-
- /**
- * Verify the integrity of a received RADIUS message.
- *
- * @param req_auth 16 byte Authenticator of request, or NULL
- * @param secret shared RADIUS secret
- * @param signer HMAC-MD5 signer with secret set
- * @param hasher MD5 hasher
- */
- bool (*verify)(radius_message_t *this, u_int8_t *req_auth, chunk_t secret,
- hasher_t *hasher, signer_t *signer);
-
- /**
- * Destroy the message.
- */
- void (*destroy)(radius_message_t *this);
-};
-
-/**
- * Create an empty RADIUS message.
- *
- * @param code request type
- * @return radius_message_t object
- */
-radius_message_t *radius_message_create(radius_message_code_t code);
-
-/**
- * Parse and verify a recevied RADIUS message.
- *
- * @param data received message data
- * @return radius_message_t object, NULL if length invalid
- */
-radius_message_t *radius_message_parse(chunk_t data);
-
-#endif /** RADIUS_MESSAGE_H_ @}*/
diff --git a/src/libcharon/plugins/eap_radius/radius_server.c b/src/libcharon/plugins/eap_radius/radius_server.c
deleted file mode 100644
index 282f50892..000000000
--- a/src/libcharon/plugins/eap_radius/radius_server.c
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- * Copyright (C) 2010 Martin Willi
- * Copyright (C) 2010 revosec AG
- *
- * 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 <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * 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 "radius_server.h"
-
-#include <threading/mutex.h>
-#include <threading/condvar.h>
-#include <utils/linked_list.h>
-
-typedef struct private_radius_server_t private_radius_server_t;
-
-/**
- * Private data of an radius_server_t object.
- */
-struct private_radius_server_t {
-
- /**
- * Public radius_server_t interface.
- */
- radius_server_t public;
-
- /**
- * list of radius sockets, as radius_socket_t
- */
- linked_list_t *sockets;
-
- /**
- * Total number of sockets, in list + currently in use
- */
- int socket_count;
-
- /**
- * mutex to lock sockets list
- */
- mutex_t *mutex;
-
- /**
- * condvar to wait for sockets
- */
- condvar_t *condvar;
-
- /**
- * Server name
- */
- char *name;
-
- /**
- * NAS-Identifier
- */
- chunk_t nas_identifier;
-
- /**
- * Preference boost for this server
- */
- int preference;
-
- /**
- * Is the server currently reachable
- */
- bool reachable;
-
- /**
- * Retry counter for unreachable servers
- */
- int retry;
-
- /**
- * reference count
- */
- refcount_t ref;
-};
-
-METHOD(radius_server_t, get_socket, radius_socket_t*,
- private_radius_server_t *this)
-{
- radius_socket_t *skt;
-
- this->mutex->lock(this->mutex);
- while (this->sockets->remove_first(this->sockets, (void**)&skt) != SUCCESS)
- {
- this->condvar->wait(this->condvar, this->mutex);
- }
- this->mutex->unlock(this->mutex);
- return skt;
-}
-
-METHOD(radius_server_t, put_socket, void,
- private_radius_server_t *this, radius_socket_t *skt, bool result)
-{
- this->mutex->lock(this->mutex);
- this->sockets->insert_last(this->sockets, skt);
- this->mutex->unlock(this->mutex);
- this->condvar->signal(this->condvar);
- this->reachable = result;
-}
-
-METHOD(radius_server_t, get_nas_identifier, chunk_t,
- private_radius_server_t *this)
-{
- return this->nas_identifier;
-}
-
-METHOD(radius_server_t, get_preference, int,
- private_radius_server_t *this)
-{
- int pref;
-
- if (this->socket_count == 0)
- { /* don't have sockets, huh? */
- return -1;
- }
- /* calculate preference between 0-100 + boost */
- pref = this->preference;
- pref += this->sockets->get_count(this->sockets) * 100 / this->socket_count;
- if (this->reachable)
- { /* reachable server get a boost: pref = 110-210 + boost */
- return pref + 110;
- }
- /* Not reachable. Increase preference randomly to let it retry from
- * time to time, especially if other servers have high load. */
- this->retry++;
- if (this->retry % 128 == 0)
- { /* every 64th request gets 210, same as unloaded reachable */
- return pref + 110;
- }
- if (this->retry % 32 == 0)
- { /* every 32th request gets 190, wins against average loaded */
- return pref + 90;
- }
- if (this->retry % 8 == 0)
- { /* every 8th request gets 110, same as server under load */
- return pref + 10;
- }
- /* other get ~100, less than fully loaded */
- return pref;
-}
-
-METHOD(radius_server_t, get_name, char*,
- private_radius_server_t *this)
-{
- return this->name;
-}
-
-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,
- private_radius_server_t *this)
-{
- if (ref_put(&this->ref))
- {
- this->mutex->destroy(this->mutex);
- this->condvar->destroy(this->condvar);
- this->sockets->destroy_offset(this->sockets,
- offsetof(radius_socket_t, destroy));
- free(this);
- }
-}
-
-/**
- * See header
- */
-radius_server_t *radius_server_create(char *name, char *address,
- u_int16_t auth_port, u_int16_t acct_port,
- char *nas_identifier, char *secret,
- int sockets, int preference)
-{
- private_radius_server_t *this;
- radius_socket_t *socket;
-
- INIT(this,
- .public = {
- .get_socket = _get_socket,
- .put_socket = _put_socket,
- .get_nas_identifier = _get_nas_identifier,
- .get_preference = _get_preference,
- .get_name = _get_name,
- .get_ref = _get_ref,
- .destroy = _destroy,
- },
- .reachable = TRUE,
- .nas_identifier = chunk_create(nas_identifier, strlen(nas_identifier)),
- .socket_count = sockets,
- .sockets = linked_list_create(),
- .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
- .condvar = condvar_create(CONDVAR_TYPE_DEFAULT),
- .name = name,
- .preference = preference,
- .ref = 1,
- );
-
- while (sockets--)
- {
- socket = radius_socket_create(address, auth_port, acct_port,
- chunk_create(secret, strlen(secret)));
- if (!socket)
- {
- destroy(this);
- return NULL;
- }
- this->sockets->insert_last(this->sockets, socket);
- }
- return &this->public;
-}
diff --git a/src/libcharon/plugins/eap_radius/radius_server.h b/src/libcharon/plugins/eap_radius/radius_server.h
deleted file mode 100644
index 93b0e5d8d..000000000
--- a/src/libcharon/plugins/eap_radius/radius_server.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2010 Martin Willi
- * Copyright (C) 2010 revosec AG
- *
- * 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 <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * 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.
- */
-
-/**
- * @defgroup radius_server radius_server
- * @{ @ingroup eap_radius
- */
-
-#ifndef RADIUS_SERVER_H_
-#define RADIUS_SERVER_H_
-
-typedef struct radius_server_t radius_server_t;
-
-#include "radius_socket.h"
-
-/**
- * RADIUS server configuration.
- */
-struct radius_server_t {
-
- /**
- * Get a RADIUS socket from the pool to communicate with this server.
- *
- * @return RADIUS socket
- */
- radius_socket_t* (*get_socket)(radius_server_t *this);
-
- /**
- * Release a socket to the pool after use.
- *
- * @param skt RADIUS socket to release
- * @param result result of the socket use, TRUE for success
- */
- void (*put_socket)(radius_server_t *this, radius_socket_t *skt, bool result);
-
- /**
- * Get the NAS-Identifier to use with this server.
- *
- * @return NAS-Identifier, internal data
- */
- chunk_t (*get_nas_identifier)(radius_server_t *this);
-
- /**
- * Get the preference of this server.
- *
- * Based on the available sockets and the server reachability a preference
- * value is calculated: better servers return a higher value.
- */
- int (*get_preference)(radius_server_t *this);
-
- /**
- * Get the name of the RADIUS server.
- *
- * @return server name
- */
- char* (*get_name)(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.
- */
- void (*destroy)(radius_server_t *this);
-};
-
-/**
- * Create a radius_server instance.
- *
- * @param name server name
- * @param address server address
- * @param auth_port server port for authentication
- * @param acct_port server port for accounting
- * @param nas_identifier NAS-Identifier to use with this server
- * @param secret secret to use with this server
- * @param sockets number of sockets to create in pool
- * @param preference preference boost for this server
- */
-radius_server_t *radius_server_create(char *name, char *address,
- u_int16_t auth_port, u_int16_t acct_port,
- char *nas_identifier, char *secret,
- int sockets, int preference);
-
-#endif /** RADIUS_SERVER_H_ @}*/
diff --git a/src/libcharon/plugins/eap_radius/radius_socket.c b/src/libcharon/plugins/eap_radius/radius_socket.c
deleted file mode 100644
index 875bd61e9..000000000
--- a/src/libcharon/plugins/eap_radius/radius_socket.c
+++ /dev/null
@@ -1,386 +0,0 @@
-/*
- * Copyright (C) 2010 Martin Willi
- * Copyright (C) 2010 revosec AG
- *
- * 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 <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * 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 "radius_socket.h"
-
-#include <errno.h>
-#include <unistd.h>
-
-#include <debug.h>
-
-/**
- * Vendor-Id of Microsoft specific attributes
- */
-#define VENDOR_ID_MICROSOFT 311
-
-/**
- * Microsoft specific vendor attributes
- */
-#define MS_MPPE_SEND_KEY 16
-#define MS_MPPE_RECV_KEY 17
-
-typedef struct private_radius_socket_t private_radius_socket_t;
-
-/**
- * Private data of an radius_socket_t object.
- */
-struct private_radius_socket_t {
-
- /**
- * Public radius_socket_t interface.
- */
- radius_socket_t public;
-
- /**
- * Server port for authentication
- */
- u_int16_t auth_port;
-
- /**
- * socket file descriptor for authentication
- */
- int auth_fd;
-
- /**
- * Server port for accounting
- */
- u_int16_t acct_port;
-
- /**
- * socket file descriptor for accounting
- */
- int acct_fd;
-
- /**
- * Server address
- */
- char *address;
-
- /**
- * current RADIUS identifier
- */
- u_int8_t identifier;
-
- /**
- * hasher to use for response verification
- */
- hasher_t *hasher;
-
- /**
- * HMAC-MD5 signer to build Message-Authenticator attribute
- */
- signer_t *signer;
-
- /**
- * random number generator for RADIUS request authenticator
- */
- rng_t *rng;
-
- /**
- * RADIUS secret
- */
- chunk_t secret;
-};
-
-/**
- * Check or establish RADIUS connection
- */
-static bool check_connection(private_radius_socket_t *this,
- int *fd, u_int16_t port)
-{
- if (*fd == -1)
- {
- host_t *server;
-
- server = host_create_from_dns(this->address, AF_UNSPEC, port);
- if (!server)
- {
- DBG1(DBG_CFG, "resolving RADIUS server address '%s' failed",
- this->address);
- return FALSE;
- }
- *fd = socket(server->get_family(server), SOCK_DGRAM, IPPROTO_UDP);
- if (*fd == -1)
- {
- DBG1(DBG_CFG, "opening RADIUS socket for %#H failed: %s",
- server, strerror(errno));
- server->destroy(server);
- return FALSE;
- }
- if (connect(*fd, server->get_sockaddr(server),
- *server->get_sockaddr_len(server)) < 0)
- {
- DBG1(DBG_CFG, "connecting RADIUS socket to %#H failed: %s",
- server, strerror(errno));
- server->destroy(server);
- close(*fd);
- *fd = -1;
- return FALSE;
- }
- server->destroy(server);
- }
- return TRUE;
-}
-
-METHOD(radius_socket_t, request, radius_message_t*,
- private_radius_socket_t *this, radius_message_t *request)
-{
- chunk_t data;
- int i, *fd;
- u_int16_t port;
- rng_t *rng = NULL;
-
- if (request->get_code(request) == RMC_ACCOUNTING_REQUEST)
- {
- fd = &this->acct_fd;
- port = this->acct_port;
- }
- else
- {
- fd = &this->auth_fd;
- port = this->auth_port;
- rng = this->rng;
- }
-
- /* set Message Identifier */
- request->set_identifier(request, this->identifier++);
- /* sign the request */
- request->sign(request, NULL, this->secret, this->hasher, this->signer, rng);
-
- if (!check_connection(this, fd, port))
- {
- return NULL;
- }
-
- data = request->get_encoding(request);
- /* timeout after 2, 3, 4, 5 seconds */
- for (i = 2; i <= 5; i++)
- {
- radius_message_t *response;
- bool retransmit = FALSE;
- struct timeval tv;
- char buf[4096];
- fd_set fds;
- int res;
-
- if (send(*fd, data.ptr, data.len, 0) != data.len)
- {
- DBG1(DBG_CFG, "sending RADIUS message failed: %s", strerror(errno));
- return NULL;
- }
- tv.tv_sec = i;
- tv.tv_usec = 0;
-
- while (TRUE)
- {
- FD_ZERO(&fds);
- FD_SET(*fd, &fds);
- res = select((*fd) + 1, &fds, NULL, NULL, &tv);
- /* TODO: updated tv to time not waited. Linux does this for us. */
- if (res < 0)
- { /* failed */
- DBG1(DBG_CFG, "waiting for RADIUS message failed: %s",
- strerror(errno));
- break;
- }
- if (res == 0)
- { /* timeout */
- DBG1(DBG_CFG, "retransmitting RADIUS message");
- retransmit = TRUE;
- break;
- }
- res = recv(*fd, buf, sizeof(buf), MSG_DONTWAIT);
- if (res <= 0)
- {
- DBG1(DBG_CFG, "receiving RADIUS message failed: %s",
- strerror(errno));
- break;
- }
- response = radius_message_parse(chunk_create(buf, res));
- if (response)
- {
- if (response->verify(response,
- request->get_authenticator(request), this->secret,
- this->hasher, this->signer))
- {
- return response;
- }
- response->destroy(response);
- }
- DBG1(DBG_CFG, "received invalid RADIUS message, ignored");
- }
- if (!retransmit)
- {
- break;
- }
- }
- DBG1(DBG_CFG, "RADIUS server is not responding");
- return NULL;
-}
-
-/**
- * Decrypt a MS-MPPE-Send/Recv-Key
- */
-static chunk_t decrypt_mppe_key(private_radius_socket_t *this, u_int16_t salt,
- chunk_t C, radius_message_t *request)
-{
- chunk_t A, R, P, seed;
- u_char *c, *p;
-
- /**
- * From RFC2548 (encryption):
- * b(1) = MD5(S + R + A) c(1) = p(1) xor b(1) C = c(1)
- * b(2) = MD5(S + c(1)) c(2) = p(2) xor b(2) C = C + c(2)
- * . . .
- * b(i) = MD5(S + c(i-1)) c(i) = p(i) xor b(i) C = C + c(i)
- */
-
- if (C.len % HASH_SIZE_MD5 || C.len < HASH_SIZE_MD5)
- {
- return chunk_empty;
- }
-
- A = chunk_create((u_char*)&salt, sizeof(salt));
- R = chunk_create(request->get_authenticator(request), HASH_SIZE_MD5);
- P = chunk_alloca(C.len);
- p = P.ptr;
- c = C.ptr;
-
- seed = chunk_cata("cc", R, A);
-
- while (c < C.ptr + C.len)
- {
- /* b(i) = MD5(S + c(i-1)) */
- this->hasher->get_hash(this->hasher, this->secret, NULL);
- this->hasher->get_hash(this->hasher, seed, p);
-
- /* p(i) = b(i) xor c(1) */
- memxor(p, c, HASH_SIZE_MD5);
-
- /* prepare next round */
- seed = chunk_create(c, HASH_SIZE_MD5);
- c += HASH_SIZE_MD5;
- p += HASH_SIZE_MD5;
- }
-
- /* remove truncation, first byte is key length */
- if (*P.ptr >= P.len)
- { /* decryption failed? */
- return chunk_empty;
- }
- return chunk_clone(chunk_create(P.ptr + 1, *P.ptr));
-}
-
-METHOD(radius_socket_t, decrypt_msk, chunk_t,
- private_radius_socket_t *this, radius_message_t *request,
- radius_message_t *response)
-{
- struct {
- u_int32_t id;
- u_int8_t type;
- u_int8_t length;
- u_int16_t salt;
- u_int8_t key[];
- } __attribute__((packed)) *mppe_key;
- enumerator_t *enumerator;
- chunk_t data, send = chunk_empty, recv = chunk_empty;
- int type;
-
- enumerator = response->create_enumerator(response);
- while (enumerator->enumerate(enumerator, &type, &data))
- {
- if (type == RAT_VENDOR_SPECIFIC &&
- data.len > sizeof(*mppe_key))
- {
- mppe_key = (void*)data.ptr;
- if (ntohl(mppe_key->id) == VENDOR_ID_MICROSOFT &&
- mppe_key->length == data.len - sizeof(mppe_key->id))
- {
- data = chunk_create(mppe_key->key, data.len - sizeof(*mppe_key));
- if (mppe_key->type == MS_MPPE_SEND_KEY)
- {
- send = decrypt_mppe_key(this, mppe_key->salt, data, request);
- }
- if (mppe_key->type == MS_MPPE_RECV_KEY)
- {
- recv = decrypt_mppe_key(this, mppe_key->salt, data, request);
- }
- }
- }
- }
- enumerator->destroy(enumerator);
- if (send.ptr && recv.ptr)
- {
- return chunk_cat("mm", recv, send);
- }
- chunk_clear(&send);
- chunk_clear(&recv);
- return chunk_empty;
-}
-
-METHOD(radius_socket_t, destroy, void,
- private_radius_socket_t *this)
-{
- DESTROY_IF(this->hasher);
- DESTROY_IF(this->signer);
- DESTROY_IF(this->rng);
- if (this->auth_fd != -1)
- {
- close(this->auth_fd);
- };
- if (this->acct_fd != -1)
- {
- close(this->acct_fd);
- }
- free(this);
-}
-
-/**
- * See header
- */
-radius_socket_t *radius_socket_create(char *address, u_int16_t auth_port,
- u_int16_t acct_port, chunk_t secret)
-{
- private_radius_socket_t *this;
-
- INIT(this,
- .public = {
- .request = _request,
- .decrypt_msk = _decrypt_msk,
- .destroy = _destroy,
- },
- .address = address,
- .auth_port = auth_port,
- .auth_fd = -1,
- .acct_port = acct_port,
- .acct_fd = -1,
- );
-
- this->hasher = lib->crypto->create_hasher(lib->crypto, HASH_MD5);
- this->signer = lib->crypto->create_signer(lib->crypto, AUTH_HMAC_MD5_128);
- this->rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK);
- if (!this->hasher || !this->signer || !this->rng)
- {
- DBG1(DBG_CFG, "RADIUS initialization failed, HMAC/MD5/RNG required");
- destroy(this);
- return NULL;
- }
- this->secret = secret;
- this->signer->set_key(this->signer, secret);
- /* we use a random identifier, helps if we restart often */
- this->identifier = random();
-
- return &this->public;
-}
diff --git a/src/libcharon/plugins/eap_radius/radius_socket.h b/src/libcharon/plugins/eap_radius/radius_socket.h
deleted file mode 100644
index 0301ec6d0..000000000
--- a/src/libcharon/plugins/eap_radius/radius_socket.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2010 Martin Willi
- * Copyright (C) 2010 revosec AG
- *
- * 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 <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * 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.
- */
-
-/**
- * @defgroup radius_socket radius_socket
- * @{ @ingroup eap_radius
- */
-
-#ifndef RADIUS_SOCKET_H_
-#define RADIUS_SOCKET_H_
-
-typedef struct radius_socket_t radius_socket_t;
-
-#include "radius_message.h"
-
-#include <utils/host.h>
-
-/**
- * RADIUS socket to a server.
- */
-struct radius_socket_t {
-
- /**
- * Send a RADIUS request, wait for response.
- *
- * The socket fills in RADIUS Message identifier, builds a
- * Request-Authenticator and calculates the Message-Authenticator
- * attribute.
- * The received response gets verified using the Response-Identifier
- * and the Message-Authenticator attribute.
- *
- * @param request request message
- * @return response message, NULL if timed out
- */
- radius_message_t* (*request)(radius_socket_t *this,
- radius_message_t *request);
-
- /**
- * Decrypt the MSK encoded in a messages MS-MPPE-Send/Recv-Key.
- *
- * @param request associated RADIUS request message
- * @param response RADIUS response message containing attributes
- * @return allocated MSK, empty chunk if none found
- */
- chunk_t (*decrypt_msk)(radius_socket_t *this, radius_message_t *request,
- radius_message_t *response);
-
- /**
- * Destroy a radius_socket_t.
- */
- void (*destroy)(radius_socket_t *this);
-};
-
-/**
- * Create a radius_socket instance.
- *
- * @param address server name
- * @param auth_port server port for authentication
- * @param acct_port server port for accounting
- * @param secret RADIUS secret
- */
-radius_socket_t *radius_socket_create(char *address, u_int16_t auth_port,
- u_int16_t acct_port, chunk_t secret);
-
-#endif /** RADIUS_SOCKET_H_ @}*/