Add a radius message method to enumerate vendor specific attributes
This commit is contained in:
@@ -16,6 +16,7 @@
|
|||||||
#include "radius_message.h"
|
#include "radius_message.h"
|
||||||
|
|
||||||
#include <utils/debug.h>
|
#include <utils/debug.h>
|
||||||
|
#include <bio/bio_reader.h>
|
||||||
#include <crypto/hashers/hasher.h>
|
#include <crypto/hashers/hasher.h>
|
||||||
|
|
||||||
typedef struct private_radius_message_t private_radius_message_t;
|
typedef struct private_radius_message_t private_radius_message_t;
|
||||||
@@ -271,6 +272,85 @@ METHOD(radius_message_t, create_enumerator, enumerator_t*,
|
|||||||
return &e->public;
|
return &e->public;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vendor attribute enumerator implementation
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
/** implements enumerator interface */
|
||||||
|
enumerator_t public;
|
||||||
|
/** inner attribute enumerator */
|
||||||
|
enumerator_t *inner;
|
||||||
|
/** current vendor ID */
|
||||||
|
u_int32_t vendor;
|
||||||
|
/** reader for current vendor ID */
|
||||||
|
bio_reader_t *reader;
|
||||||
|
} vendor_enumerator_t;
|
||||||
|
|
||||||
|
METHOD(enumerator_t, vendor_enumerate, bool,
|
||||||
|
vendor_enumerator_t *this, int *vendor, int *type, chunk_t *data)
|
||||||
|
{
|
||||||
|
chunk_t inner_data;
|
||||||
|
int inner_type;
|
||||||
|
u_int8_t type8, len;
|
||||||
|
|
||||||
|
while (TRUE)
|
||||||
|
{
|
||||||
|
if (this->reader)
|
||||||
|
{
|
||||||
|
if (this->reader->remaining(this->reader) >= 2 &&
|
||||||
|
this->reader->read_uint8(this->reader, &type8) &&
|
||||||
|
this->reader->read_uint8(this->reader, &len) && len >= 2 &&
|
||||||
|
this->reader->read_data(this->reader, len - 2, data))
|
||||||
|
{
|
||||||
|
*vendor = this->vendor;
|
||||||
|
*type = type8;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
this->reader->destroy(this->reader);
|
||||||
|
this->reader = NULL;
|
||||||
|
}
|
||||||
|
if (this->inner->enumerate(this->inner, &inner_type, &inner_data))
|
||||||
|
{
|
||||||
|
if (inner_type == RAT_VENDOR_SPECIFIC)
|
||||||
|
{
|
||||||
|
this->reader = bio_reader_create(inner_data);
|
||||||
|
if (!this->reader->read_uint32(this->reader, &this->vendor))
|
||||||
|
{
|
||||||
|
this->reader->destroy(this->reader);
|
||||||
|
this->reader = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
METHOD(enumerator_t, vendor_destroy, void,
|
||||||
|
vendor_enumerator_t *this)
|
||||||
|
{
|
||||||
|
DESTROY_IF(this->reader);
|
||||||
|
this->inner->destroy(this->inner);
|
||||||
|
free(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(radius_message_t, create_vendor_enumerator, enumerator_t*,
|
||||||
|
private_radius_message_t *this)
|
||||||
|
{
|
||||||
|
vendor_enumerator_t *e;
|
||||||
|
|
||||||
|
INIT(e,
|
||||||
|
.public = {
|
||||||
|
.enumerate = (void*)_vendor_enumerate,
|
||||||
|
.destroy = _vendor_destroy,
|
||||||
|
},
|
||||||
|
.inner = create_enumerator(this),
|
||||||
|
);
|
||||||
|
|
||||||
|
return &e->public;
|
||||||
|
}
|
||||||
|
|
||||||
METHOD(radius_message_t, add, void,
|
METHOD(radius_message_t, add, void,
|
||||||
private_radius_message_t *this, radius_attribute_type_t type, chunk_t data)
|
private_radius_message_t *this, radius_attribute_type_t type, chunk_t data)
|
||||||
{
|
{
|
||||||
@@ -474,6 +554,7 @@ static private_radius_message_t *radius_message_create_empty()
|
|||||||
INIT(this,
|
INIT(this,
|
||||||
.public = {
|
.public = {
|
||||||
.create_enumerator = _create_enumerator,
|
.create_enumerator = _create_enumerator,
|
||||||
|
.create_vendor_enumerator = _create_vendor_enumerator,
|
||||||
.add = _add,
|
.add = _add,
|
||||||
.get_code = _get_code,
|
.get_code = _get_code,
|
||||||
.get_identifier = _get_identifier,
|
.get_identifier = _get_identifier,
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
#define RADIUS_MESSAGE_H_
|
#define RADIUS_MESSAGE_H_
|
||||||
|
|
||||||
#include <library.h>
|
#include <library.h>
|
||||||
|
#include <pen/pen.h>
|
||||||
|
|
||||||
#define MAX_RADIUS_ATTRIBUTE_SIZE 253
|
#define MAX_RADIUS_ATTRIBUTE_SIZE 253
|
||||||
|
|
||||||
@@ -204,6 +205,16 @@ struct radius_message_t {
|
|||||||
*/
|
*/
|
||||||
enumerator_t* (*create_enumerator)(radius_message_t *this);
|
enumerator_t* (*create_enumerator)(radius_message_t *this);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an enumerator over contained RADIUS Vendor-ID attributes.
|
||||||
|
*
|
||||||
|
* This enumerator parses only vendor specific attributes in the format
|
||||||
|
* recommended in RFC2865.
|
||||||
|
*
|
||||||
|
* @return enumerator over (int vendor, int type, chunk_t data)
|
||||||
|
*/
|
||||||
|
enumerator_t* (*create_vendor_enumerator)(radius_message_t *this);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a RADIUS attribute to the message.
|
* Add a RADIUS attribute to the message.
|
||||||
*
|
*
|
||||||
|
|||||||
Reference in New Issue
Block a user