diff options
Diffstat (limited to 'src/libimcv/ietf')
-rw-r--r-- | src/libimcv/ietf/ietf_attr.c | 63 | ||||
-rw-r--r-- | src/libimcv/ietf/ietf_attr.h | 63 | ||||
-rw-r--r-- | src/libimcv/ietf/ietf_attr_pa_tnc_error.c | 472 | ||||
-rw-r--r-- | src/libimcv/ietf/ietf_attr_pa_tnc_error.h | 134 | ||||
-rw-r--r-- | src/libimcv/ietf/ietf_attr_port_filter.c | 288 | ||||
-rw-r--r-- | src/libimcv/ietf/ietf_attr_port_filter.h | 74 | ||||
-rw-r--r-- | src/libimcv/ietf/ietf_attr_product_info.c | 255 | ||||
-rw-r--r-- | src/libimcv/ietf/ietf_attr_product_info.h | 67 |
8 files changed, 1416 insertions, 0 deletions
diff --git a/src/libimcv/ietf/ietf_attr.c b/src/libimcv/ietf/ietf_attr.c new file mode 100644 index 000000000..89c6fc8db --- /dev/null +++ b/src/libimcv/ietf/ietf_attr.c @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2011 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 "ietf_attr.h" +#include "ietf/ietf_attr_pa_tnc_error.h" +#include "ietf/ietf_attr_port_filter.h" +#include "ietf/ietf_attr_product_info.h" + +ENUM(ietf_attr_names, IETF_ATTR_TESTING, IETF_ATTR_FACTORY_DEFAULT_PWD_ENABLED, + "Testing", + "Attribute Request", + "Product Information", + "Numeric Version", + "String Version", + "Operational Status", + "Port Filter", + "Installed Packages", + "PA-TNC Error", + "Assessment Result", + "Remediation Instructions", + "Forwarding Enabled", + "Factory Default Password Enabled", +); + +/** + * See header + */ +pa_tnc_attr_t* ietf_attr_create_from_data(u_int32_t type, chunk_t value) +{ + switch (type) + { + 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: + case IETF_ATTR_INSTALLED_PACKAGES: + case IETF_ATTR_ASSESSMENT_RESULT: + case IETF_ATTR_REMEDIATION_INSTRUCTIONS: + case IETF_ATTR_FORWARDING_ENABLED: + case IETF_ATTR_FACTORY_DEFAULT_PWD_ENABLED: + case IETF_ATTR_RESERVED: + default: + return NULL; + } +} diff --git a/src/libimcv/ietf/ietf_attr.h b/src/libimcv/ietf/ietf_attr.h new file mode 100644 index 000000000..a1ba42565 --- /dev/null +++ b/src/libimcv/ietf/ietf_attr.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2011 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_attrt ietf_attr + * @{ @ingroup ietf_attr + */ + +#ifndef IETF_ATTR_H_ +#define IETF_ATTR_H_ + +#include "pa_tnc/pa_tnc_attr.h" + +#include <library.h> + +typedef enum ietf_attr_t ietf_attr_t; + +/** + * IETF standard PA-TNC attribute types defined by RFC 5792 + */ +enum ietf_attr_t { + IETF_ATTR_TESTING = 0, + IETF_ATTR_ATTRIBUTE_REQUEST = 1, + IETF_ATTR_PRODUCT_INFORMATION = 2, + IETF_ATTR_NUMERIC_VERSION = 3, + IETF_ATTR_STRING_VERSION = 4, + IETF_ATTR_OPERATIONAL_STATUS = 5, + IETF_ATTR_PORT_FILTER = 6, + IETF_ATTR_INSTALLED_PACKAGES = 7, + IETF_ATTR_PA_TNC_ERROR = 8, + IETF_ATTR_ASSESSMENT_RESULT = 9, + IETF_ATTR_REMEDIATION_INSTRUCTIONS = 10, + IETF_ATTR_FORWARDING_ENABLED = 11, + IETF_ATTR_FACTORY_DEFAULT_PWD_ENABLED = 12, + IETF_ATTR_RESERVED = 0xffffffff, +}; + +/** + * enum name for ietf_attr_t. + */ +extern enum_name_t *ietf_attr_names; + +/** + * Create an IETF PA-TNC attribute from data + * + * @param type attribute type + * @param value attribute value + */ +pa_tnc_attr_t* ietf_attr_create_from_data(u_int32_t type, chunk_t value); + +#endif /** IETF_ATTR_H_ @}*/ diff --git a/src/libimcv/ietf/ietf_attr_pa_tnc_error.c b/src/libimcv/ietf/ietf_attr_pa_tnc_error.c new file mode 100644 index 000000000..6daee1a77 --- /dev/null +++ b/src/libimcv/ietf/ietf_attr_pa_tnc_error.c @@ -0,0 +1,472 @@ +/* + * Copyright (C) 2011 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 "ietf_attr_pa_tnc_error.h" + +#include <pa_tnc/pa_tnc_msg.h> +#include <bio/bio_writer.h> +#include <bio/bio_reader.h> +#include <debug.h> + +ENUM(pa_tnc_error_code_names, PA_ERROR_RESERVED, + PA_ERROR_ATTR_TYPE_NOT_SUPPORTED, + "Reserved", + "Invalid Parameter", + "Version Not Supported", + "Attribute Type Not Supported" +); + +typedef struct private_ietf_attr_pa_tnc_error_t private_ietf_attr_pa_tnc_error_t; + +/** + * PA-TNC Error Attribute Type (see section 4.2.8 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 Error Code Vendor ID | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | PA-TNC Error Code | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Error Information (Variable Length) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +#define PA_ERROR_HEADER_SIZE 8 +#define PA_ERROR_RESERVED 0x00 + +/** + * All IETF Error Types return the first 8 bytes of the erroneous PA-TNC message + * + * 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 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Version | Copy of Reserved | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Message Identifier | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +#define PA_ERROR_MSG_INFO_SIZE 8 +#define PA_ERROR_MSG_INFO_MAX_SIZE 1024 + +/** + * "Invalid Parameter" Error Code + * 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 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Offset | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +/** + * "Version Not Supported" Error Code + * + * 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 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Max Version | Min Version | Reserved | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +#define PA_ERROR_VERSION_RESERVED 0x0000 + +/** + * "Attribute Type Not Supported" Error Code + * + * 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 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Flags | PA-TNC Attribute Vendor ID | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | PA-TNC Attribute Type | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +#define PA_ERROR_ATTR_INFO_SIZE 8 + +/** + * Private data of an ietf_attr_pa_tnc_error_t object. + */ +struct private_ietf_attr_pa_tnc_error_t { + + /** + * Public members of ietf_attr_pa_tnc_error_t + */ + ietf_attr_pa_tnc_error_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; + + /** + * Error code vendor ID + */ + pen_t error_vendor_id; + + /** + * Error code + */ + u_int32_t error_code; + + /** + * First 8 bytes of erroneous PA-TNC message + */ + chunk_t msg_info; + + /** + * First 8 bytes of unsupported PA-TNC attribute + */ + chunk_t attr_info; + + /** + * PA-TNC error offset + */ + u_int32_t error_offset; + + /** + * Reference count + */ + refcount_t ref; +}; + +METHOD(pa_tnc_attr_t, get_vendor_id, pen_t, + private_ietf_attr_pa_tnc_error_t *this) +{ + return this->vendor_id; +} + +METHOD(pa_tnc_attr_t, get_type, u_int32_t, + private_ietf_attr_pa_tnc_error_t *this) +{ + return this->type; +} + +METHOD(pa_tnc_attr_t, get_value, chunk_t, + private_ietf_attr_pa_tnc_error_t *this) +{ + return this->value; +} + +METHOD(pa_tnc_attr_t, get_noskip_flag, bool, + private_ietf_attr_pa_tnc_error_t *this) +{ + return this->noskip_flag; +} + +METHOD(pa_tnc_attr_t, set_noskip_flag,void, + private_ietf_attr_pa_tnc_error_t *this, bool noskip) +{ + this->noskip_flag = noskip; +} + +METHOD(pa_tnc_attr_t, build, void, + private_ietf_attr_pa_tnc_error_t *this) +{ + bio_writer_t *writer; + + writer = bio_writer_create(PA_ERROR_HEADER_SIZE + PA_ERROR_MSG_INFO_SIZE); + writer->write_uint8 (writer, PA_ERROR_RESERVED); + writer->write_uint24(writer, this->error_vendor_id); + writer->write_uint32(writer, this->error_code); + writer->write_data (writer, this->msg_info); + + if (this->error_vendor_id == PEN_IETF) + { + switch (this->error_code) + { + case PA_ERROR_INVALID_PARAMETER: + writer->write_uint32(writer, this->error_offset); + break; + case PA_ERROR_VERSION_NOT_SUPPORTED: + writer->write_uint8 (writer, PA_TNC_VERSION); + writer->write_uint8 (writer, PA_TNC_VERSION); + writer->write_uint16(writer, PA_ERROR_VERSION_RESERVED); + break; + case PA_ERROR_ATTR_TYPE_NOT_SUPPORTED: + writer->write_data(writer, this->attr_info); + break; + default: + break; + } + } + this->value = chunk_clone(writer->get_buf(writer)); + writer->destroy(writer); +} + +METHOD(pa_tnc_attr_t, process, status_t, + private_ietf_attr_pa_tnc_error_t *this, u_int32_t *offset) +{ + bio_reader_t *reader; + u_int8_t reserved; + + if (this->value.len < PA_ERROR_HEADER_SIZE) + { + DBG1(DBG_TNC, "insufficient data for PA-TNC error header"); + *offset = 0; + return FAILED; + } + reader = bio_reader_create(this->value); + reader->read_uint8 (reader, &reserved); + reader->read_uint24(reader, &this->error_vendor_id); + reader->read_uint32(reader, &this->error_code); + + if (this->error_vendor_id == PEN_IETF) + { + if (!reader->read_data(reader, PA_ERROR_MSG_INFO_SIZE, &this->msg_info)) + { + reader->destroy(reader); + DBG1(DBG_TNC, "insufficient data for IETF error information"); + *offset = PA_ERROR_HEADER_SIZE; + return FAILED; + } + this->msg_info = chunk_clone(this->msg_info); + + switch (this->error_code) + { + case PA_ERROR_INVALID_PARAMETER: + if (!reader->read_uint32(reader, &this->error_offset)) + { + reader->destroy(reader); + DBG1(DBG_TNC, "insufficient data for error offset field"); + *offset = PA_ERROR_HEADER_SIZE + PA_ERROR_MSG_INFO_SIZE; + return FAILED; + } + break; + case PA_ERROR_ATTR_TYPE_NOT_SUPPORTED: + if (!reader->read_data(reader, PA_ERROR_ATTR_INFO_SIZE, + &this->attr_info)) + { + reader->destroy(reader); + DBG1(DBG_TNC, "insufficient data for unsupported attribute " + "information"); + *offset = PA_ERROR_HEADER_SIZE + PA_ERROR_MSG_INFO_SIZE; + return FAILED; + } + this->attr_info = chunk_clone(this->attr_info); + break; + default: + break; + } + } + else + { + reader->read_data(reader, reader->remaining(reader), &this->msg_info); + this->msg_info = chunk_clone(this->msg_info); + } + reader->destroy(reader); + + return SUCCESS; +} + +METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*, + private_ietf_attr_pa_tnc_error_t *this) +{ + ref_get(&this->ref); + return &this->public.pa_tnc_attribute; +} + +METHOD(pa_tnc_attr_t, destroy, void, + private_ietf_attr_pa_tnc_error_t *this) +{ + if (ref_put(&this->ref)) + { + free(this->value.ptr); + free(this->msg_info.ptr); + free(this->attr_info.ptr); + free(this); + } +} + +METHOD(ietf_attr_pa_tnc_error_t, get_error_vendor_id, pen_t, + private_ietf_attr_pa_tnc_error_t *this) +{ + return this->error_vendor_id; +} + +METHOD(ietf_attr_pa_tnc_error_t, get_error_code, u_int32_t, + private_ietf_attr_pa_tnc_error_t *this) +{ + return this->error_code; +} + +METHOD(ietf_attr_pa_tnc_error_t, get_msg_info, chunk_t, + private_ietf_attr_pa_tnc_error_t *this) +{ + return this->msg_info; +} + +METHOD(ietf_attr_pa_tnc_error_t, get_attr_info, chunk_t, + private_ietf_attr_pa_tnc_error_t *this) +{ + return this->attr_info; +} + +METHOD(ietf_attr_pa_tnc_error_t, set_attr_info, void, + private_ietf_attr_pa_tnc_error_t *this, chunk_t attr_info) +{ + this->attr_info = chunk_clone(attr_info); +} + +METHOD(ietf_attr_pa_tnc_error_t, get_offset, u_int32_t, + private_ietf_attr_pa_tnc_error_t *this) +{ + return this->error_offset; +} + +/** + * Described in header. + */ +pa_tnc_attr_t *ietf_attr_pa_tnc_error_create(pen_t vendor_id, + u_int32_t error_code, + chunk_t msg_info) +{ + private_ietf_attr_pa_tnc_error_t *this; + + if (vendor_id == PEN_IETF) + { + msg_info.len = PA_ERROR_MSG_INFO_SIZE; + } + else if (msg_info.len > PA_ERROR_MSG_INFO_MAX_SIZE) + { + msg_info.len = PA_ERROR_MSG_INFO_MAX_SIZE; + } + + 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, + }, + .get_vendor_id = _get_error_vendor_id, + .get_error_code = _get_error_code, + .get_msg_info = _get_msg_info, + .get_attr_info = _get_attr_info, + .set_attr_info = _set_attr_info, + .get_offset = _get_offset, + }, + .vendor_id = PEN_IETF, + .type = IETF_ATTR_PA_TNC_ERROR, + .error_vendor_id = vendor_id, + .error_code = error_code, + .msg_info = chunk_clone(msg_info), + .ref = 1, + ); + + return &this->public.pa_tnc_attribute; +} + +/** + * Described in header. + */ +pa_tnc_attr_t *ietf_attr_pa_tnc_error_create_with_offset(pen_t vendor_id, + u_int32_t error_code, + chunk_t msg_info, + u_int32_t error_offset) +{ + private_ietf_attr_pa_tnc_error_t *this; + + /* the first 8 bytes of the erroneous PA-TNC message are sent back */ + msg_info.len = PA_ERROR_MSG_INFO_SIZE; + + 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, + }, + .get_vendor_id = _get_error_vendor_id, + .get_error_code = _get_error_code, + .get_msg_info = _get_msg_info, + .get_attr_info = _get_attr_info, + .set_attr_info = _set_attr_info, + .get_offset = _get_offset, + }, + .vendor_id = PEN_IETF, + .type = IETF_ATTR_PA_TNC_ERROR, + .error_vendor_id = vendor_id, + .error_code = error_code, + .msg_info = chunk_clone(msg_info), + .error_offset = error_offset, + .ref = 1, + ); + + return &this->public.pa_tnc_attribute; +} + +/** + * Described in header. + */ +pa_tnc_attr_t *ietf_attr_pa_tnc_error_create_from_data(chunk_t data) +{ + private_ietf_attr_pa_tnc_error_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, + }, + .get_vendor_id = _get_error_vendor_id, + .get_error_code = _get_error_code, + .get_msg_info = _get_msg_info, + .get_attr_info = _get_attr_info, + .set_attr_info = _set_attr_info, + .get_offset = _get_offset, + }, + .vendor_id = PEN_IETF, + .type = IETF_ATTR_PA_TNC_ERROR, + .value = chunk_clone(data), + .ref = 1, + ); + + return &this->public.pa_tnc_attribute; +} + + diff --git a/src/libimcv/ietf/ietf_attr_pa_tnc_error.h b/src/libimcv/ietf/ietf_attr_pa_tnc_error.h new file mode 100644 index 000000000..945e06c62 --- /dev/null +++ b/src/libimcv/ietf/ietf_attr_pa_tnc_error.h @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2011 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_pa_tnc_errort ietf_attr_pa_tnc_error + * @{ @ingroup ietf_attr_pa_tnc_error + */ + +#ifndef IETF_ATTR_PA_TNC_ERROR_H_ +#define IETF_ATTR_PA_TNC_ERROR_H_ + +typedef struct ietf_attr_pa_tnc_error_t ietf_attr_pa_tnc_error_t; +typedef enum pa_tnc_error_code_t pa_tnc_error_code_t; + +#include "ietf_attr.h" +#include "pa_tnc/pa_tnc_attr.h" + + +/** + * IETF Standard PA-TNC Error Codes as defined in section 4.2.8 of RFC 5792 + */ +enum pa_tnc_error_code_t { + PA_ERROR_RESERVED = 0, + PA_ERROR_INVALID_PARAMETER = 1, + PA_ERROR_VERSION_NOT_SUPPORTED = 2, + PA_ERROR_ATTR_TYPE_NOT_SUPPORTED = 3, +}; + +/** + * enum name for pa_tnc_error_code_t. + */ +extern enum_name_t *pa_tnc_error_code_names; + +/** + * Class implementing the IETF PA-TNC Error attribute. + * + */ +struct ietf_attr_pa_tnc_error_t { + + /** + * Public PA-TNC attribute interface + */ + pa_tnc_attr_t pa_tnc_attribute; + + /** + * Get PA-TNC error code vendor ID + * + * @return error code vendor ID + */ + pen_t (*get_vendor_id)(ietf_attr_pa_tnc_error_t *this); + + /** + * Get PA-TNC error code + * + * @return error code + */ + pa_tnc_error_code_t (*get_error_code)(ietf_attr_pa_tnc_error_t *this); + + /** + * Get first 8 bytes of erroneous PA-TNC message + * + * @return PA-TNC message info + */ + chunk_t (*get_msg_info)(ietf_attr_pa_tnc_error_t *this); + + /** + * Get first 8 bytes of unsupported PA-TNC attribute + * + * @return PA-TNC attribute info + */ + chunk_t (*get_attr_info)(ietf_attr_pa_tnc_error_t *this); + + /** + * Set first 8 bytes of unsupported PA-TNC attribute + * + * @param attr_info PA-TNC message info + */ + void (*set_attr_info)(ietf_attr_pa_tnc_error_t *this, chunk_t attr_info); + + /** + * Get the PA-TNC error offset + * + * @return PA-TNC error offset + */ + u_int32_t (*get_offset)(ietf_attr_pa_tnc_error_t *this); + +}; + +/** + * Creates an ietf_attr_pa_tnc_error_t object from an error code + * + * @param vendor_id PA-TNC error code vendor ID + * @param error_code PA-TNC error code + * @param header PA-TNC message header (first 8 bytes) + * + */ +pa_tnc_attr_t* ietf_attr_pa_tnc_error_create(pen_t vendor_id, + u_int32_t error_code, + chunk_t header); + +/** + * Creates an ietf_attr_pa_tnc_error_t object from an error code with offset + * + * @param vendor_id PA-TNC error code vendor ID + * @param error_code PA-TNC error code + * @param header PA-TNC message header (first 8 bytes) + * @param error_offset PA-TNC error offset in bytes + * + */ +pa_tnc_attr_t* ietf_attr_pa_tnc_error_create_with_offset(pen_t vendor_id, + u_int32_t error_code, + chunk_t header, + u_int32_t error_offset); + +/** + * Creates an ietf_attr_pa_tnc_error_t object from received data + * + * @param value unparsed attribute value + */ +pa_tnc_attr_t* ietf_attr_pa_tnc_error_create_from_data(chunk_t value); + +#endif /** IETF_ATTR_PA_TNC_ERROR_H_ @}*/ diff --git a/src/libimcv/ietf/ietf_attr_port_filter.c b/src/libimcv/ietf/ietf_attr_port_filter.c new file mode 100644 index 000000000..b53019657 --- /dev/null +++ b/src/libimcv/ietf/ietf_attr_port_filter.c @@ -0,0 +1,288 @@ +/* + * Copyright (C) 2011 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 "ietf_attr_port_filter.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_port_filter_t private_ietf_attr_port_filter_t; +typedef struct port_entry_t port_entry_t; + +/** + * Port Filter entry + */ +struct port_entry_t { + bool blocked; + u_int8_t protocol; + u_int16_t port; +}; + +/** + * PA-TNC Port Filter Type (see section 4.2.6 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 |B| Protocol | Port Number | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Reserved |B| Protocol | Port Number | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +#define PORT_FILTER_ENTRY_SIZE 4 + +/** + * Private data of an ietf_attr_port_filter_t object. + */ +struct private_ietf_attr_port_filter_t { + + /** + * Public members of ietf_attr_port_filter_t + */ + ietf_attr_port_filter_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 Port Filter entries + */ + linked_list_t *ports; + + /** + * Reference count + */ + refcount_t ref; +}; + +METHOD(pa_tnc_attr_t, get_vendor_id, pen_t, + private_ietf_attr_port_filter_t *this) +{ + return this->vendor_id; +} + +METHOD(pa_tnc_attr_t, get_type, u_int32_t, + private_ietf_attr_port_filter_t *this) +{ + return this->type; +} + +METHOD(pa_tnc_attr_t, get_value, chunk_t, + private_ietf_attr_port_filter_t *this) +{ + return this->value; +} + +METHOD(pa_tnc_attr_t, get_noskip_flag, bool, + private_ietf_attr_port_filter_t *this) +{ + return this->noskip_flag; +} + +METHOD(pa_tnc_attr_t, set_noskip_flag,void, + private_ietf_attr_port_filter_t *this, bool noskip) +{ + this->noskip_flag = noskip; +} + +METHOD(pa_tnc_attr_t, build, void, + private_ietf_attr_port_filter_t *this) +{ + bio_writer_t *writer; + enumerator_t *enumerator; + port_entry_t *entry; + + writer = bio_writer_create(this->ports->get_count(this->ports) * + PORT_FILTER_ENTRY_SIZE); + + enumerator = this->ports->create_enumerator(this->ports); + while (enumerator->enumerate(enumerator, &entry)) + { + writer->write_uint8 (writer, entry->blocked ? 0x01 : 0x00); + writer->write_uint8 (writer, entry->protocol); + writer->write_uint16(writer, entry->port); + } + enumerator->destroy(enumerator); + + this->value = chunk_clone(writer->get_buf(writer)); + writer->destroy(writer); +} + +METHOD(pa_tnc_attr_t, process, status_t, + private_ietf_attr_port_filter_t *this, u_int32_t *offset) +{ + bio_reader_t *reader; + port_entry_t *entry; + u_int8_t blocked; + + if (this->value.len % PORT_FILTER_ENTRY_SIZE) + { + DBG1(DBG_TNC, "ietf port filter attribute value is not a multiple of %d", + PORT_FILTER_ENTRY_SIZE); + *offset = 0; + return FAILED; + } + reader = bio_reader_create(this->value); + + while (reader->remaining(reader)) + { + entry = malloc_thing(port_entry_t); + reader->read_uint8 (reader, &blocked); + entry->blocked = blocked & 0x01; + reader->read_uint8 (reader, &entry->protocol); + reader->read_uint16(reader, &entry->port); + this->ports->insert_last(this->ports, entry); + } + reader->destroy(reader); + + return SUCCESS; +} + +METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*, + private_ietf_attr_port_filter_t *this) +{ + ref_get(&this->ref); + return &this->public.pa_tnc_attribute; +} + +METHOD(pa_tnc_attr_t, destroy, void, + private_ietf_attr_port_filter_t *this) +{ + if (ref_put(&this->ref)) + { + this->ports->destroy_function(this->ports, free); + free(this->value.ptr); + free(this); + } +} + +METHOD(ietf_attr_port_filter_t, add_port, void, + private_ietf_attr_port_filter_t *this, bool blocked, u_int8_t protocol, + u_int16_t port) +{ + port_entry_t *entry; + + entry = malloc_thing(port_entry_t); + entry->blocked = blocked; + entry->protocol = protocol; + entry->port = port; + this->ports->insert_last(this->ports, entry); +} + +/** + * Enumerate port filter entries + */ +static bool port_filter(void *null, port_entry_t **entry, + bool *blocked, void *i2, u_int8_t *protocol, void *i3, + u_int16_t *port) +{ + *blocked = (*entry)->blocked; + *protocol = (*entry)->protocol; + *port = (*entry)->port; + return TRUE; +} + +METHOD(ietf_attr_port_filter_t, create_port_enumerator, enumerator_t*, + private_ietf_attr_port_filter_t *this) +{ + return enumerator_create_filter(this->ports->create_enumerator(this->ports), + (void*)port_filter, NULL, NULL); +} + +/** + * Described in header. + */ +pa_tnc_attr_t *ietf_attr_port_filter_create(void) +{ + private_ietf_attr_port_filter_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_port = _add_port, + .create_port_enumerator = _create_port_enumerator, + }, + .vendor_id = PEN_IETF, + .type = IETF_ATTR_PORT_FILTER, + .ports = linked_list_create(), + .ref = 1, + ); + + return &this->public.pa_tnc_attribute; +} + +/** + * Described in header. + */ +pa_tnc_attr_t *ietf_attr_port_filter_create_from_data(chunk_t data) +{ + private_ietf_attr_port_filter_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_port = _add_port, + .create_port_enumerator = _create_port_enumerator, + }, + .vendor_id = PEN_IETF, + .type = IETF_ATTR_PORT_FILTER, + .value = chunk_clone(data), + .ports = linked_list_create(), + .ref = 1, + ); + + return &this->public.pa_tnc_attribute; +} + + diff --git a/src/libimcv/ietf/ietf_attr_port_filter.h b/src/libimcv/ietf/ietf_attr_port_filter.h new file mode 100644 index 000000000..ad5553417 --- /dev/null +++ b/src/libimcv/ietf/ietf_attr_port_filter.h @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2011 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_port_filtert ietf_attr_port_filter + * @{ @ingroup ietf_attr_port_filter + */ + +#ifndef IETF_ATTR_PORT_FILTER_H_ +#define IETF_ATTR_PORT_FILTER_H_ + +typedef struct ietf_attr_port_filter_t ietf_attr_port_filter_t; + +#include "ietf_attr.h" +#include "pa_tnc/pa_tnc_attr.h" + + +/** + * Class implementing the IETF PA-TNC Port Filter attribute. + * + */ +struct ietf_attr_port_filter_t { + + /** + * Public PA-TNC attribute interface + */ + pa_tnc_attr_t pa_tnc_attribute; + + /** + * Add a port entry + * + * @param blocked TRUE if blocked, FALSE if allowed + * @param protocol IP protocol type + * @param port TCP/UDP port number + */ + void (*add_port)(ietf_attr_port_filter_t *this, bool blocked, + u_int8_t protocol, u_int16_t port); + + /** + * Enumerates over all ports + * Format: bool *blocked, u_int8_t *protocol, u_int16_t *port + * + * @return enumerator + */ + enumerator_t* (*create_port_enumerator)(ietf_attr_port_filter_t *this); + +}; + +/** + * Creates an ietf_attr_port_filter_t object + * + */ +pa_tnc_attr_t* ietf_attr_port_filter_create(void); + +/** + * Creates an ietf_attr_port_filter_t object from received data + * + * @param value unparsed attribute value + */ +pa_tnc_attr_t* ietf_attr_port_filter_create_from_data(chunk_t value); + +#endif /** IETF_ATTR_PORT_FILTER_H_ @}*/ diff --git a/src/libimcv/ietf/ietf_attr_product_info.c b/src/libimcv/ietf/ietf_attr_product_info.c new file mode 100644 index 000000000..548793547 --- /dev/null +++ b/src/libimcv/ietf/ietf_attr_product_info.c @@ -0,0 +1,255 @@ +/* + * Copyright (C) 2011 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 "ietf_attr_product_info.h" + +#include <pa_tnc/pa_tnc_msg.h> +#include <bio/bio_writer.h> +#include <bio/bio_reader.h> +#include <debug.h> + +typedef struct private_ietf_attr_product_info_t private_ietf_attr_product_info_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 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Product Vendor ID | Product ID | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Product ID | Product Name (Variable Length) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +#define PRODUCT_INFO_MIN_SIZE 5 + +/** + * Private data of an ietf_attr_product_info_t object. + */ +struct private_ietf_attr_product_info_t { + + /** + * Public members of ietf_attr_product_info_t + */ + ietf_attr_product_info_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; + + /** + * Product vendor ID + */ + pen_t product_vendor_id; + + /** + * Product ID + */ + u_int16_t product_id; + + /** + * Product Name + */ + char *product_name; + + /** + * Reference count + */ + refcount_t ref; +}; + +METHOD(pa_tnc_attr_t, get_vendor_id, pen_t, + private_ietf_attr_product_info_t *this) +{ + return this->vendor_id; +} + +METHOD(pa_tnc_attr_t, get_type, u_int32_t, + private_ietf_attr_product_info_t *this) +{ + return this->type; +} + +METHOD(pa_tnc_attr_t, get_value, chunk_t, + private_ietf_attr_product_info_t *this) +{ + return this->value; +} + +METHOD(pa_tnc_attr_t, get_noskip_flag, bool, + private_ietf_attr_product_info_t *this) +{ + return this->noskip_flag; +} + +METHOD(pa_tnc_attr_t, set_noskip_flag,void, + private_ietf_attr_product_info_t *this, bool noskip) +{ + this->noskip_flag = noskip; +} + +METHOD(pa_tnc_attr_t, build, void, + private_ietf_attr_product_info_t *this) +{ + bio_writer_t *writer; + chunk_t product_name; + + product_name = chunk_create(this->product_name, strlen(this->product_name)); + + writer = bio_writer_create(PRODUCT_INFO_MIN_SIZE); + writer->write_uint24(writer, this->product_vendor_id); + writer->write_uint16(writer, this->product_id); + writer->write_data (writer, product_name); + + this->value = chunk_clone(writer->get_buf(writer)); + writer->destroy(writer); +} + +METHOD(pa_tnc_attr_t, process, status_t, + private_ietf_attr_product_info_t *this, u_int32_t *offset) +{ + bio_reader_t *reader; + chunk_t product_name; + + if (this->value.len < PRODUCT_INFO_MIN_SIZE) + { + DBG1(DBG_TNC, "insufficient data for IETF product information"); + *offset = 0; + return FAILED; + } + reader = bio_reader_create(this->value); + reader->read_uint24(reader, &this->product_vendor_id); + reader->read_uint16(reader, &this->product_id); + reader->read_data (reader, reader->remaining(reader), &product_name); + reader->destroy(reader); + + this->product_name = malloc(product_name.len + 1); + memcpy(this->product_name, product_name.ptr, product_name.len); + this->product_name[product_name.len] = '\0'; + + return SUCCESS; +} + +METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*, + private_ietf_attr_product_info_t *this) +{ + ref_get(&this->ref); + return &this->public.pa_tnc_attribute; +} + +METHOD(pa_tnc_attr_t, destroy, void, + private_ietf_attr_product_info_t *this) +{ + if (ref_put(&this->ref)) + { + free(this->product_name); + free(this->value.ptr); + free(this); + } +} + +METHOD(ietf_attr_product_info_t, get_info, char*, + private_ietf_attr_product_info_t *this, pen_t *vendor_id, u_int16_t *id) +{ + if (vendor_id) + { + *vendor_id = this->product_vendor_id; + } + if (id) + { + *id = this->product_id; + } + return this->product_name; +} + +/** + * Described in header. + */ +pa_tnc_attr_t *ietf_attr_product_info_create(pen_t vendor_id, u_int16_t id, + char *name) +{ + private_ietf_attr_product_info_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, + }, + .get_info = _get_info, + }, + .vendor_id = PEN_IETF, + .type = IETF_ATTR_PRODUCT_INFORMATION, + .product_vendor_id = vendor_id, + .product_id = id, + .product_name = strdup(name), + .ref = 1, + ); + + return &this->public.pa_tnc_attribute; +} + +/** + * Described in header. + */ +pa_tnc_attr_t *ietf_attr_product_info_create_from_data(chunk_t data) +{ + private_ietf_attr_product_info_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, + }, + .get_info = _get_info, + }, + .vendor_id = PEN_IETF, + .type = IETF_ATTR_PRODUCT_INFORMATION, + .value = chunk_clone(data), + .ref = 1, + ); + + return &this->public.pa_tnc_attribute; +} + diff --git a/src/libimcv/ietf/ietf_attr_product_info.h b/src/libimcv/ietf/ietf_attr_product_info.h new file mode 100644 index 000000000..f1dfc3e83 --- /dev/null +++ b/src/libimcv/ietf/ietf_attr_product_info.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2011 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_product_infot ietf_attr_product_info + * @{ @ingroup ietf + */ + +#ifndef IETF_ATTR_PRODUCT_INFO_H_ +#define IETF_ATTR_PRODUCT_INFO_H_ + +typedef struct ietf_attr_product_info_t ietf_attr_product_info_t; + +#include "ietf_attr.h" +#include "pa_tnc/pa_tnc_attr.h" + + +/** + * Class implementing the IETF PA-TNC Product Information attribute. + * + */ +struct ietf_attr_product_info_t { + + /** + * Public PA-TNC attribute interface + */ + pa_tnc_attr_t pa_tnc_attribute; + + /** + * Gets all product info + * + * @param vendor_id Product vendor ID + * @param id Product ID + * @return Product Name + */ + char* (*get_info)(ietf_attr_product_info_t *this, + pen_t *vendor_id, u_int16_t *id); + +}; + +/** + * Creates an ietf_attr_product_info_t object + * + */ +pa_tnc_attr_t* ietf_attr_product_info_create(pen_t vendor_id, u_int16_t id, + char *name); + +/** + * Creates an ietf_attr_product_info_t object from received data + * + * @param value unparsed attribute value + */ +pa_tnc_attr_t* ietf_attr_product_info_create_from_data(chunk_t value); + +#endif /** IETF_ATTR_PRODUCT_INFO_H_ @}*/ |