Forward specifcied RADIUS attributes between AAA backend and client
This commit is contained in:
@@ -15,6 +15,7 @@ libstrongswan_eap_radius_la_SOURCES = \
|
|||||||
eap_radius.h eap_radius.c \
|
eap_radius.h eap_radius.c \
|
||||||
eap_radius_accounting.h eap_radius_accounting.c \
|
eap_radius_accounting.h eap_radius_accounting.c \
|
||||||
eap_radius_dae.h eap_radius_dae.c \
|
eap_radius_dae.h eap_radius_dae.c \
|
||||||
|
eap_radius_forward.h eap_radius_forward.c \
|
||||||
radius_server.h radius_server.c \
|
radius_server.h radius_server.c \
|
||||||
radius_socket.h radius_socket.c \
|
radius_socket.h radius_socket.c \
|
||||||
radius_client.h radius_client.c \
|
radius_client.h radius_client.c \
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "eap_radius.h"
|
#include "eap_radius.h"
|
||||||
|
#include "eap_radius_forward.h"
|
||||||
|
|
||||||
#include "radius_message.h"
|
#include "radius_message.h"
|
||||||
#include "radius_client.h"
|
#include "radius_client.h"
|
||||||
@@ -175,10 +176,12 @@ METHOD(eap_method_t, initiate, status_t,
|
|||||||
{
|
{
|
||||||
add_eap_identity(this, request);
|
add_eap_identity(this, request);
|
||||||
}
|
}
|
||||||
|
eap_radius_forward_from_ike(request);
|
||||||
|
|
||||||
response = this->client->request(this->client, request);
|
response = this->client->request(this->client, request);
|
||||||
if (response)
|
if (response)
|
||||||
{
|
{
|
||||||
|
eap_radius_forward_to_ike(response);
|
||||||
if (radius2ike(this, response, out))
|
if (radius2ike(this, response, out))
|
||||||
{
|
{
|
||||||
status = NEED_MORE;
|
status = NEED_MORE;
|
||||||
@@ -327,9 +330,11 @@ METHOD(eap_method_t, process, status_t,
|
|||||||
}
|
}
|
||||||
request->add(request, RAT_EAP_MESSAGE, data);
|
request->add(request, RAT_EAP_MESSAGE, data);
|
||||||
|
|
||||||
|
eap_radius_forward_from_ike(request);
|
||||||
response = this->client->request(this->client, request);
|
response = this->client->request(this->client, request);
|
||||||
if (response)
|
if (response)
|
||||||
{
|
{
|
||||||
|
eap_radius_forward_to_ike(response);
|
||||||
switch (response->get_code(response))
|
switch (response->get_code(response))
|
||||||
{
|
{
|
||||||
case RMC_ACCESS_CHALLENGE:
|
case RMC_ACCESS_CHALLENGE:
|
||||||
|
|||||||
@@ -0,0 +1,458 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2012 Martin Willi
|
||||||
|
* Copyright (C) 2012 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 "eap_radius_forward.h"
|
||||||
|
|
||||||
|
#include <daemon.h>
|
||||||
|
#include <utils/linked_list.h>
|
||||||
|
#include <utils/hashtable.h>
|
||||||
|
#include <threading/mutex.h>
|
||||||
|
|
||||||
|
typedef struct private_eap_radius_forward_t private_eap_radius_forward_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Private data of an eap_radius_forward_t object.
|
||||||
|
*/
|
||||||
|
struct private_eap_radius_forward_t {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Public eap_radius_forward_t interface.
|
||||||
|
*/
|
||||||
|
eap_radius_forward_t public;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of attribute types to copy from IKE, as attr_t
|
||||||
|
*/
|
||||||
|
linked_list_t *from_attr;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of attribute types to copy to IKE, as attr_t
|
||||||
|
*/
|
||||||
|
linked_list_t *to_attr;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queued to forward from IKE, unique_id => linked_list_t of chunk_t
|
||||||
|
*/
|
||||||
|
hashtable_t *from;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queued to forward to IKE, unique_id => linked_list_t of chunk_t
|
||||||
|
*/
|
||||||
|
hashtable_t *to;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mutex to lock concurrent access to hashtables
|
||||||
|
*/
|
||||||
|
mutex_t *mutex;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RADIUS attribute selector
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
/** vendor ID, 0 for standard attributes */
|
||||||
|
u_int32_t vendor;
|
||||||
|
/** attribute type */
|
||||||
|
u_int8_t type;
|
||||||
|
} attr_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Single instance of this
|
||||||
|
*/
|
||||||
|
static private_eap_radius_forward_t *singleton = NULL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hashtable hash function
|
||||||
|
*/
|
||||||
|
static u_int hash(uintptr_t key)
|
||||||
|
{
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hashtable equals function
|
||||||
|
*/
|
||||||
|
static bool equals(uintptr_t a, uintptr_t b)
|
||||||
|
{
|
||||||
|
return a == b;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Free a queue entry
|
||||||
|
*/
|
||||||
|
static void free_attribute(chunk_t *chunk)
|
||||||
|
{
|
||||||
|
free(chunk->ptr);
|
||||||
|
free(chunk);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lookup/create an attribute queue from a table
|
||||||
|
*/
|
||||||
|
static linked_list_t *lookup_queue(private_eap_radius_forward_t *this,
|
||||||
|
hashtable_t *table)
|
||||||
|
{
|
||||||
|
linked_list_t *queue = NULL;
|
||||||
|
ike_sa_t *ike_sa;
|
||||||
|
uintptr_t id;
|
||||||
|
|
||||||
|
ike_sa = charon->bus->get_sa(charon->bus);
|
||||||
|
if (ike_sa && ike_sa->supports_extension(ike_sa, EXT_STRONGSWAN))
|
||||||
|
{
|
||||||
|
id = ike_sa->get_unique_id(ike_sa);
|
||||||
|
this->mutex->lock(this->mutex);
|
||||||
|
queue = table->get(table, (void*)id);
|
||||||
|
if (!queue)
|
||||||
|
{
|
||||||
|
queue = linked_list_create();
|
||||||
|
table->put(table, (void*)id, queue);
|
||||||
|
}
|
||||||
|
this->mutex->unlock(this->mutex);
|
||||||
|
}
|
||||||
|
return queue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove attribute queue from table
|
||||||
|
*/
|
||||||
|
static void remove_queue(private_eap_radius_forward_t *this,
|
||||||
|
hashtable_t *table, ike_sa_t *ike_sa)
|
||||||
|
{
|
||||||
|
linked_list_t *queue;
|
||||||
|
|
||||||
|
this->mutex->lock(this->mutex);
|
||||||
|
queue = table->remove(table, (void*)(uintptr_t)ike_sa->get_unique_id(ike_sa));
|
||||||
|
this->mutex->unlock(this->mutex);
|
||||||
|
if (queue)
|
||||||
|
{
|
||||||
|
queue->destroy_function(queue, (void*)free_attribute);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if RADIUS attribute is contained in selector
|
||||||
|
*/
|
||||||
|
static bool is_attribute_selected(linked_list_t *selector,
|
||||||
|
radius_attribute_type_t type, chunk_t data)
|
||||||
|
{
|
||||||
|
enumerator_t *enumerator;
|
||||||
|
u_int32_t vendor = 0;
|
||||||
|
attr_t *sel;
|
||||||
|
bool found = FALSE;
|
||||||
|
|
||||||
|
if (type == RAT_VENDOR_SPECIFIC)
|
||||||
|
{
|
||||||
|
if (data.len < 4)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
vendor = untoh32(data.ptr);
|
||||||
|
}
|
||||||
|
enumerator = selector->create_enumerator(selector);
|
||||||
|
while (!found && enumerator->enumerate(enumerator, &sel))
|
||||||
|
{
|
||||||
|
if (sel->vendor == vendor)
|
||||||
|
{
|
||||||
|
if (vendor)
|
||||||
|
{
|
||||||
|
if (sel->type == 0)
|
||||||
|
{ /* any of that vendor is fine */
|
||||||
|
found = TRUE;
|
||||||
|
}
|
||||||
|
else if (data.len > 4 && data.ptr[4] == sel->type)
|
||||||
|
{ /* vendor specific type field, as defined in RFC 2865 */
|
||||||
|
found = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (sel->type == type)
|
||||||
|
{
|
||||||
|
found = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
enumerator->destroy(enumerator);
|
||||||
|
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy RADIUS attributes from queue to a RADIUS message
|
||||||
|
*/
|
||||||
|
static void queue2radius(linked_list_t *queue, radius_message_t *message)
|
||||||
|
{
|
||||||
|
chunk_t *data;
|
||||||
|
|
||||||
|
while (queue->remove_last(queue, (void**)&data) == SUCCESS)
|
||||||
|
{
|
||||||
|
if (data->len >= 2)
|
||||||
|
{
|
||||||
|
message->add(message, data->ptr[0], chunk_skip(*data, 2));
|
||||||
|
}
|
||||||
|
free_attribute(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy RADIUS attributes from a RADIUS message to the queue
|
||||||
|
*/
|
||||||
|
static void radius2queue(radius_message_t *message, linked_list_t *queue,
|
||||||
|
linked_list_t *selector)
|
||||||
|
{
|
||||||
|
enumerator_t *enumerator;
|
||||||
|
int type;
|
||||||
|
chunk_t data, hdr, *ptr;
|
||||||
|
|
||||||
|
enumerator = message->create_enumerator(message);
|
||||||
|
while (enumerator->enumerate(enumerator, &type, &data))
|
||||||
|
{
|
||||||
|
if (is_attribute_selected(selector, type, data))
|
||||||
|
{
|
||||||
|
hdr = chunk_alloc(2);
|
||||||
|
hdr.ptr[0] = type;
|
||||||
|
hdr.ptr[1] = data.len + 2;
|
||||||
|
|
||||||
|
INIT(ptr);
|
||||||
|
*ptr = chunk_cat("mc", hdr, data);
|
||||||
|
queue->insert_last(queue, ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
enumerator->destroy(enumerator);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy RADIUS attribute nofifies from IKE message to queue
|
||||||
|
*/
|
||||||
|
static void ike2queue(message_t *message, linked_list_t *queue,
|
||||||
|
linked_list_t *selector)
|
||||||
|
{
|
||||||
|
enumerator_t *enumerator;
|
||||||
|
payload_t *payload;
|
||||||
|
notify_payload_t *notify;
|
||||||
|
chunk_t data, *ptr;
|
||||||
|
|
||||||
|
enumerator = message->create_payload_enumerator(message);
|
||||||
|
while (enumerator->enumerate(enumerator, &payload))
|
||||||
|
{
|
||||||
|
if (payload->get_type(payload) == NOTIFY)
|
||||||
|
{
|
||||||
|
notify = (notify_payload_t*)payload;
|
||||||
|
if (notify->get_notify_type(notify) == RADIUS_ATTRIBUTE)
|
||||||
|
{
|
||||||
|
data = notify->get_notification_data(notify);
|
||||||
|
if (data.len >= 2 && is_attribute_selected(selector,
|
||||||
|
data.ptr[0], chunk_skip(data, 2)))
|
||||||
|
{
|
||||||
|
INIT(ptr);
|
||||||
|
*ptr = chunk_clone(data);
|
||||||
|
queue->insert_last(queue, ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
enumerator->destroy(enumerator);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy RADUIS attributes from queue to IKE message notifies
|
||||||
|
*/
|
||||||
|
static void queue2ike(linked_list_t *queue, message_t *message)
|
||||||
|
{
|
||||||
|
chunk_t *data;
|
||||||
|
|
||||||
|
while (queue->remove_last(queue, (void**)&data) == SUCCESS)
|
||||||
|
{
|
||||||
|
message->add_notify(message, FALSE, RADIUS_ATTRIBUTE, *data);
|
||||||
|
free_attribute(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See header.
|
||||||
|
*/
|
||||||
|
void eap_radius_forward_from_ike(radius_message_t *request)
|
||||||
|
{
|
||||||
|
private_eap_radius_forward_t *this = singleton;
|
||||||
|
linked_list_t *queue;
|
||||||
|
|
||||||
|
if (this)
|
||||||
|
{
|
||||||
|
queue = lookup_queue(this, this->from);
|
||||||
|
if (queue)
|
||||||
|
{
|
||||||
|
queue2radius(queue, request);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See header.
|
||||||
|
*/
|
||||||
|
void eap_radius_forward_to_ike(radius_message_t *response)
|
||||||
|
{
|
||||||
|
private_eap_radius_forward_t *this = singleton;
|
||||||
|
linked_list_t *queue;
|
||||||
|
|
||||||
|
if (this)
|
||||||
|
{
|
||||||
|
queue = lookup_queue(this, this->to);
|
||||||
|
if (queue)
|
||||||
|
{
|
||||||
|
radius2queue(response, queue, this->to_attr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(listener_t, message, bool,
|
||||||
|
private_eap_radius_forward_t *this,
|
||||||
|
ike_sa_t *ike_sa, message_t *message, bool incoming)
|
||||||
|
{
|
||||||
|
linked_list_t *queue;
|
||||||
|
|
||||||
|
if (message->get_exchange_type(message) == IKE_AUTH)
|
||||||
|
{
|
||||||
|
if (incoming)
|
||||||
|
{
|
||||||
|
queue = lookup_queue(this, this->from);
|
||||||
|
if (queue)
|
||||||
|
{
|
||||||
|
ike2queue(message, queue, this->from_attr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
queue = lookup_queue(this, this->to);
|
||||||
|
if (queue)
|
||||||
|
{
|
||||||
|
queue2ike(queue, message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(listener_t, ike_updown, bool,
|
||||||
|
private_eap_radius_forward_t *this, ike_sa_t *ike_sa, bool up)
|
||||||
|
{
|
||||||
|
/* up or down, we don't need the state anymore */
|
||||||
|
remove_queue(this, this->from, ike_sa);
|
||||||
|
remove_queue(this, this->to, ike_sa);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse a selector string to a list of attr_t selectors
|
||||||
|
*/
|
||||||
|
static linked_list_t* parse_selector(char *selector)
|
||||||
|
{
|
||||||
|
enumerator_t *enumerator;
|
||||||
|
linked_list_t *list;
|
||||||
|
char *token, *pos;
|
||||||
|
|
||||||
|
list = linked_list_create();
|
||||||
|
enumerator = enumerator_create_token(selector, ",", " ");
|
||||||
|
while (enumerator->enumerate(enumerator, &token))
|
||||||
|
{
|
||||||
|
int type, vendor = 0;
|
||||||
|
attr_t *attr;
|
||||||
|
|
||||||
|
pos = strchr(token, ':');
|
||||||
|
if (pos)
|
||||||
|
{
|
||||||
|
*(pos++) = 0;
|
||||||
|
vendor = atoi(token);
|
||||||
|
token = pos;
|
||||||
|
}
|
||||||
|
type = enum_from_name(radius_attribute_type_names, token);
|
||||||
|
if (type == -1)
|
||||||
|
{
|
||||||
|
type = atoi(token);
|
||||||
|
}
|
||||||
|
if (vendor == 0 && type == 0)
|
||||||
|
{
|
||||||
|
DBG1(DBG_CFG, "ignoring unknown RADIUS attribute type '%s'", token);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
INIT(attr,
|
||||||
|
.type = type,
|
||||||
|
.vendor = vendor,
|
||||||
|
);
|
||||||
|
list->insert_last(list, attr);
|
||||||
|
if (!vendor)
|
||||||
|
{
|
||||||
|
DBG1(DBG_IKE, "forwarding RADIUS attribute %N",
|
||||||
|
radius_attribute_type_names, type);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DBG1(DBG_IKE, "forwarding RADIUS VSA %d-%d", vendor, type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
enumerator->destroy(enumerator);
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(eap_radius_forward_t, destroy, void,
|
||||||
|
private_eap_radius_forward_t *this)
|
||||||
|
{
|
||||||
|
this->from_attr->destroy_function(this->from_attr, free);
|
||||||
|
this->to_attr->destroy_function(this->to_attr, free);
|
||||||
|
this->from->destroy(this->from);
|
||||||
|
this->to->destroy(this->to);
|
||||||
|
this->mutex->destroy(this->mutex);
|
||||||
|
free(this);
|
||||||
|
singleton = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See header
|
||||||
|
*/
|
||||||
|
eap_radius_forward_t *eap_radius_forward_create()
|
||||||
|
{
|
||||||
|
private_eap_radius_forward_t *this;
|
||||||
|
|
||||||
|
INIT(this,
|
||||||
|
.public = {
|
||||||
|
.listener = {
|
||||||
|
.message = _message,
|
||||||
|
.ike_updown = _ike_updown,
|
||||||
|
},
|
||||||
|
.destroy = _destroy,
|
||||||
|
},
|
||||||
|
.from_attr = parse_selector(lib->settings->get_str(lib->settings,
|
||||||
|
"charon.plugins.eap-radius.forward.ike_to_radius", "")),
|
||||||
|
.to_attr = parse_selector(lib->settings->get_str(lib->settings,
|
||||||
|
"charon.plugins.eap-radius.forward.radius_to_ike", "")),
|
||||||
|
.from = hashtable_create((hashtable_hash_t)hash,
|
||||||
|
(hashtable_equals_t)equals, 8),
|
||||||
|
.to = hashtable_create((hashtable_hash_t)hash,
|
||||||
|
(hashtable_equals_t)equals, 8),
|
||||||
|
.mutex = mutex_create(MUTEX_TYPE_DEFAULT),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (this->from_attr->get_count(this->from_attr) == 0 &&
|
||||||
|
this->to_attr->get_count(this->to_attr) == 0)
|
||||||
|
{
|
||||||
|
destroy(this);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
singleton = this;
|
||||||
|
return &this->public;
|
||||||
|
}
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2012 Martin Willi
|
||||||
|
* Copyright (C) 2012 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 eap_radius_forward eap_radius_forward
|
||||||
|
* @{ @ingroup
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef EAP_RADIUS_FORWARD_H_
|
||||||
|
#define EAP_RADIUS_FORWARD_H_
|
||||||
|
|
||||||
|
#include "radius_message.h"
|
||||||
|
|
||||||
|
#include <bus/listeners/listener.h>
|
||||||
|
|
||||||
|
typedef struct eap_radius_forward_t eap_radius_forward_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Forward RADIUS attributes in Notifies between client and AAA backend.
|
||||||
|
*/
|
||||||
|
struct eap_radius_forward_t {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements a listener.
|
||||||
|
*/
|
||||||
|
listener_t listener;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroy a eap_radius_forward_t.
|
||||||
|
*/
|
||||||
|
void (*destroy)(eap_radius_forward_t *this);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a eap_radius_forward instance.
|
||||||
|
*/
|
||||||
|
eap_radius_forward_t *eap_radius_forward_create();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Forward RADIUS attributes from IKE notifies to a RADIUS request.
|
||||||
|
*
|
||||||
|
* @param request RADIUS request message to add attributes to
|
||||||
|
*/
|
||||||
|
void eap_radius_forward_from_ike(radius_message_t *request);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Forward RADIUS attributes from a RADIUS response to IKE notifies.
|
||||||
|
*
|
||||||
|
* @param response RADIUS respose to read notifies from
|
||||||
|
*/
|
||||||
|
void eap_radius_forward_to_ike(radius_message_t *response);
|
||||||
|
|
||||||
|
#endif /** EAP_RADIUS_FORWARD_H_ @}*/
|
||||||
@@ -18,6 +18,7 @@
|
|||||||
#include "eap_radius.h"
|
#include "eap_radius.h"
|
||||||
#include "eap_radius_accounting.h"
|
#include "eap_radius_accounting.h"
|
||||||
#include "eap_radius_dae.h"
|
#include "eap_radius_dae.h"
|
||||||
|
#include "eap_radius_forward.h"
|
||||||
#include "radius_client.h"
|
#include "radius_client.h"
|
||||||
#include "radius_server.h"
|
#include "radius_server.h"
|
||||||
|
|
||||||
@@ -65,6 +66,11 @@ struct private_eap_radius_plugin_t {
|
|||||||
* Dynamic authorization extensions
|
* Dynamic authorization extensions
|
||||||
*/
|
*/
|
||||||
eap_radius_dae_t *dae;
|
eap_radius_dae_t *dae;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RADIUS <-> IKE attribute forwarding
|
||||||
|
*/
|
||||||
|
eap_radius_forward_t *forward;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -194,6 +200,11 @@ METHOD(plugin_t, reload, bool,
|
|||||||
METHOD(plugin_t, destroy, void,
|
METHOD(plugin_t, destroy, void,
|
||||||
private_eap_radius_plugin_t *this)
|
private_eap_radius_plugin_t *this)
|
||||||
{
|
{
|
||||||
|
if (this->forward)
|
||||||
|
{
|
||||||
|
charon->bus->remove_listener(charon->bus, &this->forward->listener);
|
||||||
|
this->forward->destroy(this->forward);
|
||||||
|
}
|
||||||
DESTROY_IF(this->dae);
|
DESTROY_IF(this->dae);
|
||||||
this->servers->destroy_offset(this->servers,
|
this->servers->destroy_offset(this->servers,
|
||||||
offsetof(radius_server_t, destroy));
|
offsetof(radius_server_t, destroy));
|
||||||
@@ -223,6 +234,7 @@ plugin_t *eap_radius_plugin_create()
|
|||||||
.servers = linked_list_create(),
|
.servers = linked_list_create(),
|
||||||
.lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
|
.lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
|
||||||
.accounting = eap_radius_accounting_create(),
|
.accounting = eap_radius_accounting_create(),
|
||||||
|
.forward = eap_radius_forward_create(),
|
||||||
);
|
);
|
||||||
|
|
||||||
load_servers(this);
|
load_servers(this);
|
||||||
@@ -238,6 +250,10 @@ plugin_t *eap_radius_plugin_create()
|
|||||||
{
|
{
|
||||||
this->dae = eap_radius_dae_create(this->accounting);
|
this->dae = eap_radius_dae_create(this->accounting);
|
||||||
}
|
}
|
||||||
|
if (this->forward)
|
||||||
|
{
|
||||||
|
charon->bus->add_listener(charon->bus, &this->forward->listener);
|
||||||
|
}
|
||||||
|
|
||||||
return &this->public.plugin;
|
return &this->public.plugin;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user