mirror of
https://github.com/strongswan/strongswan.git
synced 2025-12-08 00:00:29 -05:00
Added infrastructure to listen to RADIUS Dynamic Authorization Extension requests
This commit is contained in:
parent
3a42c08904
commit
85932ad24e
@ -14,6 +14,7 @@ libstrongswan_eap_radius_la_SOURCES = \
|
||||
eap_radius_plugin.h eap_radius_plugin.c \
|
||||
eap_radius.h eap_radius.c \
|
||||
eap_radius_accounting.h eap_radius_accounting.c \
|
||||
eap_radius_dae.h eap_radius_dae.c \
|
||||
radius_server.h radius_server.c \
|
||||
radius_socket.h radius_socket.c \
|
||||
radius_client.h radius_client.c \
|
||||
|
||||
183
src/libcharon/plugins/eap_radius/eap_radius_dae.c
Normal file
183
src/libcharon/plugins/eap_radius/eap_radius_dae.c
Normal file
@ -0,0 +1,183 @@
|
||||
/*
|
||||
* 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_dae.h"
|
||||
|
||||
#include "radius_message.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <daemon.h>
|
||||
#include <threading/thread.h>
|
||||
#include <processing/jobs/callback_job.h>
|
||||
|
||||
#define RADIUS_DAE_PORT 3799
|
||||
|
||||
typedef struct private_eap_radius_dae_t private_eap_radius_dae_t;
|
||||
|
||||
/**
|
||||
* Private data of an eap_radius_dae_t object.
|
||||
*/
|
||||
struct private_eap_radius_dae_t {
|
||||
|
||||
/**
|
||||
* Public eap_radius_dae_t interface.
|
||||
*/
|
||||
eap_radius_dae_t public;
|
||||
|
||||
/**
|
||||
* RADIUS session state
|
||||
*/
|
||||
eap_radius_accounting_t *accounting;
|
||||
|
||||
/**
|
||||
* Socket to listen on authorization extension port
|
||||
*/
|
||||
int fd;
|
||||
|
||||
/**
|
||||
* Listen job
|
||||
*/
|
||||
callback_job_t *job;
|
||||
};
|
||||
|
||||
/**
|
||||
* Receive RADIUS DAE requests
|
||||
*/
|
||||
static job_requeue_t receive(private_eap_radius_dae_t *this)
|
||||
{
|
||||
struct sockaddr_storage addr;
|
||||
socklen_t addr_len = sizeof(addr);
|
||||
radius_message_t *request;
|
||||
char buf[2048];
|
||||
ssize_t len;
|
||||
bool oldstate;
|
||||
|
||||
oldstate = thread_cancelability(TRUE);
|
||||
len = recvfrom(this->fd, buf, sizeof(buf), 0,
|
||||
(struct sockaddr*)&addr, &addr_len);
|
||||
thread_cancelability(oldstate);
|
||||
|
||||
if (len > 0)
|
||||
{
|
||||
request = radius_message_parse_response(chunk_create(buf, len));
|
||||
if (request)
|
||||
{
|
||||
switch (request->get_code(request))
|
||||
{
|
||||
case RMC_DISCONNECT_REQUEST:
|
||||
/* TODO */
|
||||
case RMC_COA_REQUEST:
|
||||
/* TODO */
|
||||
default:
|
||||
DBG1(DBG_CFG, "ignoring unsupported RADIUS DAE %N message",
|
||||
radius_message_code_names, request->get_code(request));
|
||||
break;
|
||||
}
|
||||
request->destroy(request);
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG1(DBG_NET, "ignoring invalid RADIUS DAE request");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG1(DBG_NET, "receving RADIUS DAE request failed: %s", strerror(errno));
|
||||
}
|
||||
return JOB_REQUEUE_DIRECT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Open DAE socket
|
||||
*/
|
||||
static bool open_socket(private_eap_radius_dae_t *this)
|
||||
{
|
||||
host_t *host;
|
||||
|
||||
this->fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
if (this->fd == -1)
|
||||
{
|
||||
DBG1(DBG_CFG, "unable to open RADIUS DAE socket: %s", strerror(errno));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
host = host_create_from_string(
|
||||
lib->settings->get_str(lib->settings,
|
||||
"charon.plugins.eap-radius.dae.listen", "0.0.0.0"),
|
||||
lib->settings->get_int(lib->settings,
|
||||
"charon.plugins.eap-radius.dae.port", RADIUS_DAE_PORT));
|
||||
if (!host)
|
||||
{
|
||||
DBG1(DBG_CFG, "invalid RADIUS DAE listen address");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (bind(this->fd, host->get_sockaddr(host),
|
||||
*host->get_sockaddr_len(host)) == -1)
|
||||
{
|
||||
DBG1(DBG_CFG, "unable to bind RADIUS DAE socket: %s", strerror(errno));
|
||||
host->destroy(host);
|
||||
return FALSE;
|
||||
}
|
||||
host->destroy(host);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
METHOD(eap_radius_dae_t, destroy, void,
|
||||
private_eap_radius_dae_t *this)
|
||||
{
|
||||
if (this->job)
|
||||
{
|
||||
this->job->cancel(this->job);
|
||||
}
|
||||
if (this->fd != -1)
|
||||
{
|
||||
close(this->fd);
|
||||
}
|
||||
free(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
eap_radius_dae_t *eap_radius_dae_create(eap_radius_accounting_t *accounting)
|
||||
{
|
||||
private_eap_radius_dae_t *this;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.accounting = accounting,
|
||||
.fd = -1,
|
||||
);
|
||||
|
||||
if (!open_socket(this))
|
||||
{
|
||||
destroy(this);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
this->job = callback_job_create_with_prio((callback_job_cb_t)receive,
|
||||
this, NULL, NULL, JOB_PRIO_CRITICAL);
|
||||
lib->processor->queue_job(lib->processor, (job_t*)this->job);
|
||||
|
||||
return &this->public;
|
||||
}
|
||||
44
src/libcharon/plugins/eap_radius/eap_radius_dae.h
Normal file
44
src/libcharon/plugins/eap_radius/eap_radius_dae.h
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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_dae eap_radius_dae
|
||||
* @{ @ingroup eap_radius
|
||||
*/
|
||||
|
||||
#ifndef EAP_RADIUS_DAE_H_
|
||||
#define EAP_RADIUS_DAE_H_
|
||||
|
||||
#include "eap_radius_accounting.h"
|
||||
|
||||
typedef struct eap_radius_dae_t eap_radius_dae_t;
|
||||
|
||||
/**
|
||||
* Dynamic Authorization Extensions (RFC 5176) for EAP-RADIUS.
|
||||
*/
|
||||
struct eap_radius_dae_t {
|
||||
|
||||
/**
|
||||
* Destroy a eap_radius_dae_t.
|
||||
*/
|
||||
void (*destroy)(eap_radius_dae_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a eap_radius_dae instance.
|
||||
*/
|
||||
eap_radius_dae_t *eap_radius_dae_create(eap_radius_accounting_t *accounting);
|
||||
|
||||
#endif /** EAP_RADIUS_DAE_H_ @}*/
|
||||
Loading…
x
Reference in New Issue
Block a user