diff options
author | Andreas Steffen <andreas.steffen@strongswan.org> | 2012-08-20 12:27:14 +0200 |
---|---|---|
committer | Andreas Steffen <andreas.steffen@strongswan.org> | 2012-08-20 12:27:14 +0200 |
commit | c60310e62cb32b7f17cf1e660e8275db82a95b10 (patch) | |
tree | 5abb66e298862e257404a8cb54488fe228d609ec /src/libimcv | |
parent | 5ff8309889e5ca250fe3aa1b5facd978afbf2fc8 (diff) | |
download | strongswan-c60310e62cb32b7f17cf1e660e8275db82a95b10.tar.bz2 strongswan-c60310e62cb32b7f17cf1e660e8275db82a95b10.tar.xz |
implemented IETF Attribute Request attribute
Diffstat (limited to 'src/libimcv')
-rw-r--r-- | src/libimcv/Makefile.am | 1 | ||||
-rw-r--r-- | src/libimcv/ietf/ietf_attr.c | 8 | ||||
-rw-r--r-- | src/libimcv/ietf/ietf_attr_attr_request.c | 306 | ||||
-rw-r--r-- | src/libimcv/ietf/ietf_attr_attr_request.h | 71 |
4 files changed, 383 insertions, 3 deletions
diff --git a/src/libimcv/Makefile.am b/src/libimcv/Makefile.am index a29f9ec2c..63548647d 100644 --- a/src/libimcv/Makefile.am +++ b/src/libimcv/Makefile.am @@ -13,6 +13,7 @@ libimcv_la_SOURCES = \ ietf/ietf_attr_pa_tnc_error.h ietf/ietf_attr_pa_tnc_error.c \ ietf/ietf_attr_port_filter.h ietf/ietf_attr_port_filter.c \ ietf/ietf_attr_product_info.h ietf/ietf_attr_product_info.c \ + ietf/ietf_attr_attr_request.h ietf/ietf_attr_attr_request.c \ ita/ita_attr.h ita/ita_attr.c \ ita/ita_attr_command.h ita/ita_attr_command.c \ ita/ita_attr_dummy.h ita/ita_attr_dummy.c \ diff --git a/src/libimcv/ietf/ietf_attr.c b/src/libimcv/ietf/ietf_attr.c index 89c6fc8db..144b890ba 100644 --- a/src/libimcv/ietf/ietf_attr.c +++ b/src/libimcv/ietf/ietf_attr.c @@ -16,6 +16,7 @@ #include "ietf/ietf_attr_pa_tnc_error.h" #include "ietf/ietf_attr_port_filter.h" #include "ietf/ietf_attr_product_info.h" +#include "ietf/ietf_attr_attr_request.h" ENUM(ietf_attr_names, IETF_ATTR_TESTING, IETF_ATTR_FACTORY_DEFAULT_PWD_ENABLED, "Testing", @@ -40,14 +41,15 @@ pa_tnc_attr_t* ietf_attr_create_from_data(u_int32_t type, chunk_t value) { switch (type) { + case IETF_ATTR_ATTRIBUTE_REQUEST: + return ietf_attr_attr_request_create_from_data(value); + case IETF_ATTR_PRODUCT_INFORMATION: + return ietf_attr_product_info_create_from_data(value); case IETF_ATTR_PORT_FILTER: return ietf_attr_port_filter_create_from_data(value); case IETF_ATTR_PA_TNC_ERROR: return ietf_attr_pa_tnc_error_create_from_data(value); - case IETF_ATTR_PRODUCT_INFORMATION: - return ietf_attr_product_info_create_from_data(value); case IETF_ATTR_TESTING: - case IETF_ATTR_ATTRIBUTE_REQUEST: case IETF_ATTR_NUMERIC_VERSION: case IETF_ATTR_STRING_VERSION: case IETF_ATTR_OPERATIONAL_STATUS: diff --git a/src/libimcv/ietf/ietf_attr_attr_request.c b/src/libimcv/ietf/ietf_attr_attr_request.c new file mode 100644 index 000000000..48c467052 --- /dev/null +++ b/src/libimcv/ietf/ietf_attr_attr_request.c @@ -0,0 +1,306 @@ +/* + * Copyright (C) 2012 Andreas Steffen + * HSR 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 "imcv.h" +#include "ietf_attr_attr_request.h" + +#include <pa_tnc/pa_tnc_msg.h> +#include <bio/bio_writer.h> +#include <bio/bio_reader.h> +#include <utils/linked_list.h> + +#include <debug.h> + +typedef struct private_ietf_attr_attr_request_t private_ietf_attr_attr_request_t; +typedef struct entry_t entry_t; + +/** + * PA-TNC Product Information type (see section 4.2.2 of RFC 5792) + * + * 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Reserved | PA-TNC Attribute Vendor ID | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | PA-TNC Attribute Type | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Reserved | PA-TNC Attribute Vendor ID | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | PA-TNC Attribute Type | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +#define ATTR_REQUEST_ENTRY_SIZE 8 + +/** + * Private data of an ietf_attr_attr_request_t object. + */ +struct private_ietf_attr_attr_request_t { + + /** + * Public members of ietf_attr_attr_request_t + */ + ietf_attr_attr_request_t public; + + /** + * Attribute vendor ID + */ + pen_t vendor_id; + + /** + * Attribute type + */ + u_int32_t type; + + /** + * Attribute value + */ + chunk_t value; + + /** + * Noskip flag + */ + bool noskip_flag; + + /** + * List of requested attribute types + */ + linked_list_t *list; + + /** + * Reference count + */ + refcount_t ref; +}; + +/** + * Attribute type entry + */ +struct entry_t { + pen_t vendor_id; + u_int32_t type; +}; + +METHOD(pa_tnc_attr_t, get_vendor_id, pen_t, + private_ietf_attr_attr_request_t *this) +{ + return this->vendor_id; +} + +METHOD(pa_tnc_attr_t, get_type, u_int32_t, + private_ietf_attr_attr_request_t *this) +{ + return this->type; +} + +METHOD(pa_tnc_attr_t, get_value, chunk_t, + private_ietf_attr_attr_request_t *this) +{ + return this->value; +} + +METHOD(pa_tnc_attr_t, get_noskip_flag, bool, + private_ietf_attr_attr_request_t *this) +{ + return this->noskip_flag; +} + +METHOD(pa_tnc_attr_t, set_noskip_flag,void, + private_ietf_attr_attr_request_t *this, bool noskip) +{ + this->noskip_flag = noskip; +} + +METHOD(pa_tnc_attr_t, build, void, + private_ietf_attr_attr_request_t *this) +{ + bio_writer_t *writer; + enumerator_t *enumerator; + entry_t *entry; + + if (this->value.ptr) + { + return; + } + writer = bio_writer_create(ATTR_REQUEST_ENTRY_SIZE * + this->list->get_count(this->list)); + + enumerator = this->list->create_enumerator(this->list); + while (enumerator->enumerate(enumerator, &entry)) + { + writer->write_uint32(writer, entry->vendor_id); + writer->write_uint32(writer, entry->type); + } + enumerator->destroy(enumerator); + + this->value = chunk_clone(writer->get_buf(writer)); + writer->destroy(writer); +} + +METHOD(ietf_attr_attr_request_t, add, void, + private_ietf_attr_attr_request_t *this, pen_t vendor_id, u_int32_t type) +{ + entry_t *entry; + + entry = malloc_thing(entry_t); + entry->vendor_id = vendor_id; + entry->type = type; + this->list->insert_last(this->list, entry); +} + +METHOD(pa_tnc_attr_t, process, status_t, + private_ietf_attr_attr_request_t *this, u_int32_t *offset) +{ + bio_reader_t *reader; + enum_name_t *pa_attr_names; + pen_t vendor_id; + u_int32_t type; + u_int8_t reserved; + int count; + + count = this->value.len / ATTR_REQUEST_ENTRY_SIZE; + if (this->value.len != ATTR_REQUEST_ENTRY_SIZE * count) + { + DBG1(DBG_TNC, "incorrect attribute length for IETF attribute request"); + *offset = 0; + return FAILED; + } + + reader = bio_reader_create(this->value); + while (count--) + { + reader->read_uint8 (reader, &reserved); + reader->read_uint24(reader, &vendor_id); + reader->read_uint32(reader, &type); + + pa_attr_names = imcv_pa_tnc_attributes->get_names(imcv_pa_tnc_attributes, + vendor_id); + if (pa_attr_names) + { + DBG2(DBG_TNC, " 0x%06x/0x%08x '%N/%N'", vendor_id, type, + pen_names, vendor_id, pa_attr_names, type); + } + else + { + DBG2(DBG_TNC, " 0x%06x/0x%08x '%N'", vendor_id, type, + pen_names, vendor_id); + } + add(this, vendor_id, type); + } + reader->destroy(reader); + + return SUCCESS; +} + +METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*, + private_ietf_attr_attr_request_t *this) +{ + ref_get(&this->ref); + return &this->public.pa_tnc_attribute; +} + +METHOD(pa_tnc_attr_t, destroy, void, + private_ietf_attr_attr_request_t *this) +{ + if (ref_put(&this->ref)) + { + this->list->destroy_function(this->list, free); + free(this->value.ptr); + free(this); + } +} + +/** + * Enumerate attribute type entries + */ +static bool entry_filter(void *null, entry_t **entry, pen_t *vendor_id, + void *i2, u_int32_t *type) +{ + *vendor_id = (*entry)->vendor_id; + *type = (*entry)->type; + return TRUE; +} + +METHOD(ietf_attr_attr_request_t, create_enumerator, enumerator_t*, + private_ietf_attr_attr_request_t *this) +{ + return enumerator_create_filter(this->list->create_enumerator(this->list), + (void*)entry_filter, NULL, NULL); +} + +/** + * Described in header. + */ +pa_tnc_attr_t *ietf_attr_attr_request_create(pen_t vendor_id, u_int32_t type) +{ + private_ietf_attr_attr_request_t *this; + + INIT(this, + .public = { + .pa_tnc_attribute = { + .get_vendor_id = _get_vendor_id, + .get_type = _get_type, + .get_value = _get_value, + .get_noskip_flag = _get_noskip_flag, + .set_noskip_flag = _set_noskip_flag, + .build = _build, + .process = _process, + .get_ref = _get_ref, + .destroy = _destroy, + }, + .add = _add, + .create_enumerator = _create_enumerator, + }, + .vendor_id = PEN_IETF, + .type = IETF_ATTR_ATTRIBUTE_REQUEST, + .list = linked_list_create(), + .ref = 1, + ); + add(this, vendor_id, type); + + return &this->public.pa_tnc_attribute; +} + +/** + * Described in header. + */ +pa_tnc_attr_t *ietf_attr_attr_request_create_from_data(chunk_t data) +{ + private_ietf_attr_attr_request_t *this; + + INIT(this, + .public = { + .pa_tnc_attribute = { + .get_vendor_id = _get_vendor_id, + .get_type = _get_type, + .get_value = _get_value, + .build = _build, + .process = _process, + .get_ref = _get_ref, + .destroy = _destroy, + }, + .add = _add, + .create_enumerator = _create_enumerator, + }, + .vendor_id = PEN_IETF, + .type = IETF_ATTR_ATTRIBUTE_REQUEST, + .value = chunk_clone(data), + .list = linked_list_create(), + .ref = 1, + ); + + return &this->public.pa_tnc_attribute; +} + diff --git a/src/libimcv/ietf/ietf_attr_attr_request.h b/src/libimcv/ietf/ietf_attr_attr_request.h new file mode 100644 index 000000000..22c5be0a0 --- /dev/null +++ b/src/libimcv/ietf/ietf_attr_attr_request.h @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2012 Andreas Steffen + * HSR 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 ietf_attr_attr_requestt ietf_attr_attr_request + * @{ @ingroup ietf + */ + +#ifndef IETF_ATTR_ATTR_REQUEST_H_ +#define IETF_ATTR_ATTR_REQUEST_H_ + +typedef struct ietf_attr_attr_request_t ietf_attr_attr_request_t; + +#include "ietf_attr.h" +#include "pa_tnc/pa_tnc_attr.h" + + +/** + * Class implementing the IETF PA-TNC Attribute Request attribute. + * + */ +struct ietf_attr_attr_request_t { + + /** + * Public PA-TNC attribute interface + */ + pa_tnc_attr_t pa_tnc_attribute; + + /** + * Adds another attribute type to the attribute request + * + * @param vendor_id Attribute Vendor ID + * @param type Attribute Type + */ + void (*add)(ietf_attr_attr_request_t *this, pen_t vendor_id, u_int32_t type); + + /** + * Creates an enumerator over all attribute types contained + * in the attribute request + * + * @return Attribute Type enumerator returns (vendor ID, type) + */ + enumerator_t* (*create_enumerator)(ietf_attr_attr_request_t *this); +}; + +/** + * Creates an ietf_attr_attr_request_t object + * + */ +pa_tnc_attr_t* ietf_attr_attr_request_create(pen_t vendor_id, u_int32_t type); + +/** + * Creates an ietf_attr_attr_request_t object from received data + * + * @param value unparsed attribute value + */ +pa_tnc_attr_t* ietf_attr_attr_request_create_from_data(chunk_t value); + +#endif /** IETF_ATTR_ATTR_REQUEST_H_ @}*/ |