diff options
Diffstat (limited to 'src/libimcv/ietf')
23 files changed, 2675 insertions, 50 deletions
diff --git a/src/libimcv/ietf/ietf_attr.c b/src/libimcv/ietf/ietf_attr.c index fc89c5716..2f3819898 100644 --- a/src/libimcv/ietf/ietf_attr.c +++ b/src/libimcv/ietf/ietf_attr.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2011 Andreas Steffen, HSR Hochschule fuer Technik Rapperswil + * Copyright (C) 2011-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 @@ -13,11 +14,19 @@ */ #include "ietf_attr.h" +#include "ietf/ietf_attr_assess_result.h" +#include "ietf/ietf_attr_attr_request.h" +#include "ietf/ietf_attr_fwd_enabled.h" +#include "ietf/ietf_attr_default_pwd_enabled.h" +#include "ietf/ietf_attr_installed_packages.h" +#include "ietf/ietf_attr_numeric_version.h" +#include "ietf/ietf_attr_op_status.h" #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" -#include "ietf/ietf_attr_assess_result.h" +#include "ietf/ietf_attr_remediation_instr.h" +#include "ietf/ietf_attr_string_version.h" + ENUM(ietf_attr_names, IETF_ATTR_TESTING, IETF_ATTR_FACTORY_DEFAULT_PWD_ENABLED, "Testing", @@ -46,20 +55,27 @@ pa_tnc_attr_t* ietf_attr_create_from_data(u_int32_t type, chunk_t value) 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_NUMERIC_VERSION: + return ietf_attr_numeric_version_create_from_data(value); + case IETF_ATTR_STRING_VERSION: + return ietf_attr_string_version_create_from_data(value); + case IETF_ATTR_OPERATIONAL_STATUS: + return ietf_attr_op_status_create_from_data(value); case IETF_ATTR_PORT_FILTER: return ietf_attr_port_filter_create_from_data(value); + case IETF_ATTR_INSTALLED_PACKAGES: + return ietf_attr_installed_packages_create_from_data(value); case IETF_ATTR_PA_TNC_ERROR: return ietf_attr_pa_tnc_error_create_from_data(value); case IETF_ATTR_ASSESSMENT_RESULT: return ietf_attr_assess_result_create_from_data(value); - case IETF_ATTR_TESTING: - case IETF_ATTR_NUMERIC_VERSION: - case IETF_ATTR_STRING_VERSION: - case IETF_ATTR_OPERATIONAL_STATUS: - case IETF_ATTR_INSTALLED_PACKAGES: case IETF_ATTR_REMEDIATION_INSTRUCTIONS: + return ietf_attr_remediation_instr_create_from_data(value); case IETF_ATTR_FORWARDING_ENABLED: + return ietf_attr_fwd_enabled_create_from_data(value); case IETF_ATTR_FACTORY_DEFAULT_PWD_ENABLED: + return ietf_attr_default_pwd_enabled_create_from_data(value); + case IETF_ATTR_TESTING: case IETF_ATTR_RESERVED: default: return NULL; diff --git a/src/libimcv/ietf/ietf_attr_assess_result.c b/src/libimcv/ietf/ietf_attr_assess_result.c index 6893730bf..1c0d6b0eb 100644 --- a/src/libimcv/ietf/ietf_attr_assess_result.c +++ b/src/libimcv/ietf/ietf_attr_assess_result.c @@ -18,7 +18,7 @@ #include <pa_tnc/pa_tnc_msg.h> #include <bio/bio_writer.h> #include <bio/bio_reader.h> -#include <debug.h> +#include <utils/debug.h> typedef struct private_ietf_attr_assess_result_t private_ietf_attr_assess_result_t; @@ -192,6 +192,8 @@ pa_tnc_attr_t *ietf_attr_assess_result_create_from_data(chunk_t data) .pa_tnc_attribute = { .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, diff --git a/src/libimcv/ietf/ietf_attr_attr_request.c b/src/libimcv/ietf/ietf_attr_attr_request.c index c0dcd0983..c93c9276e 100644 --- a/src/libimcv/ietf/ietf_attr_attr_request.c +++ b/src/libimcv/ietf/ietf_attr_attr_request.c @@ -19,9 +19,9 @@ #include <pa_tnc/pa_tnc_msg.h> #include <bio/bio_writer.h> #include <bio/bio_reader.h> -#include <utils/linked_list.h> +#include <collections/linked_list.h> -#include <debug.h> +#include <utils/debug.h> typedef struct private_ietf_attr_attr_request_t private_ietf_attr_attr_request_t; @@ -114,12 +114,12 @@ METHOD(pa_tnc_attr_t, build, void, { return; } - writer = bio_writer_create(ATTR_REQUEST_ENTRY_SIZE * + 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); } @@ -161,7 +161,7 @@ METHOD(pa_tnc_attr_t, process, status_t, reader = bio_reader_create(this->value); while (count--) { - reader->read_uint8 (reader, &reserved); + reader->read_uint8 (reader, &reserved); reader->read_uint24(reader, &vendor_id); reader->read_uint32(reader, &type); @@ -251,6 +251,8 @@ pa_tnc_attr_t *ietf_attr_attr_request_create_from_data(chunk_t data) .pa_tnc_attribute = { .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, @@ -259,7 +261,7 @@ pa_tnc_attr_t *ietf_attr_attr_request_create_from_data(chunk_t data) .add = _add, .create_enumerator = _create_enumerator, }, - .type = { PEN_IETF,IETF_ATTR_ATTRIBUTE_REQUEST }, + .type = { PEN_IETF, IETF_ATTR_ATTRIBUTE_REQUEST }, .value = chunk_clone(data), .list = linked_list_create(), .ref = 1, diff --git a/src/libimcv/ietf/ietf_attr_attr_request.h b/src/libimcv/ietf/ietf_attr_attr_request.h index 22c5be0a0..387ba345d 100644 --- a/src/libimcv/ietf/ietf_attr_attr_request.h +++ b/src/libimcv/ietf/ietf_attr_attr_request.h @@ -50,7 +50,7 @@ struct ietf_attr_attr_request_t { * Creates an enumerator over all attribute types contained * in the attribute request * - * @return Attribute Type enumerator returns (vendor ID, type) + * @return Attribute Type enumerator returns { vendor ID, type } */ enumerator_t* (*create_enumerator)(ietf_attr_attr_request_t *this); }; diff --git a/src/libimcv/ietf/ietf_attr_default_pwd_enabled.c b/src/libimcv/ietf/ietf_attr_default_pwd_enabled.c new file mode 100644 index 000000000..2022f45cf --- /dev/null +++ b/src/libimcv/ietf/ietf_attr_default_pwd_enabled.c @@ -0,0 +1,222 @@ +/* + * 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 "ietf_attr_default_pwd_enabled.h" + +#include <pa_tnc/pa_tnc_msg.h> +#include <bio/bio_writer.h> +#include <bio/bio_reader.h> +#include <utils/debug.h> + +typedef struct private_ietf_attr_default_pwd_enabled_t private_ietf_attr_default_pwd_enabled_t; + +/** + * PA-TNC Factory Default Password Enabled type (see section 4.2.12 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 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Factory Default Password Enabled | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +#define DEFAULT_PWD_ENABLED_SIZE 4 + +/** + * Private data of an ietf_attr_default_pwd_enabled_t object. + */ +struct private_ietf_attr_default_pwd_enabled_t { + + /** + * Public members of ietf_attr_default_pwd_enabled_t + */ + ietf_attr_default_pwd_enabled_t public; + + /** + * Vendor-specific attribute type + */ + pen_type_t type; + + /** + * Attribute value + */ + chunk_t value; + + /** + * Noskip flag + */ + bool noskip_flag; + + /** + * Factory Default Password Enabled status + */ + bool status; + + /** + * Reference count + */ + refcount_t ref; +}; + +METHOD(pa_tnc_attr_t, get_type, pen_type_t, + private_ietf_attr_default_pwd_enabled_t *this) +{ + return this->type; +} + +METHOD(pa_tnc_attr_t, get_value, chunk_t, + private_ietf_attr_default_pwd_enabled_t *this) +{ + return this->value; +} + +METHOD(pa_tnc_attr_t, get_noskip_flag, bool, + private_ietf_attr_default_pwd_enabled_t *this) +{ + return this->noskip_flag; +} + +METHOD(pa_tnc_attr_t, set_noskip_flag,void, + private_ietf_attr_default_pwd_enabled_t *this, bool noskip) +{ + this->noskip_flag = noskip; +} + +METHOD(pa_tnc_attr_t, build, void, + private_ietf_attr_default_pwd_enabled_t *this) +{ + bio_writer_t *writer; + + if (this->value.ptr) + { + return; + } + writer = bio_writer_create(DEFAULT_PWD_ENABLED_SIZE); + writer->write_uint32(writer, this->status); + + this->value = chunk_clone(writer->get_buf(writer)); + writer->destroy(writer); +} + +METHOD(pa_tnc_attr_t, process, status_t, + private_ietf_attr_default_pwd_enabled_t *this, u_int32_t *offset) +{ + bio_reader_t *reader; + u_int32_t status; + + *offset = 0; + + if (this->value.len != DEFAULT_PWD_ENABLED_SIZE) + { + DBG1(DBG_TNC, "incorrect size for IETF factory default password " + "enabled attribute"); + return FAILED; + } + reader = bio_reader_create(this->value); + reader->read_uint32(reader, &status); + reader->destroy(reader); + + if (status > TRUE) + { + DBG1(DBG_TNC, "IETF factory default password enabled field " + "has unknown value %u", status); + return FAILED; + } + this->status = status; + + return SUCCESS; +} + +METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*, + private_ietf_attr_default_pwd_enabled_t *this) +{ + ref_get(&this->ref); + return &this->public.pa_tnc_attribute; +} + +METHOD(pa_tnc_attr_t, destroy, void, + private_ietf_attr_default_pwd_enabled_t *this) +{ + if (ref_put(&this->ref)) + { + free(this->value.ptr); + free(this); + } +} + +METHOD(ietf_attr_default_pwd_enabled_t, get_status, bool, + private_ietf_attr_default_pwd_enabled_t *this) +{ + return this->status; +} + +/** + * Described in header. + */ +pa_tnc_attr_t *ietf_attr_default_pwd_enabled_create(bool status) +{ + private_ietf_attr_default_pwd_enabled_t *this; + + INIT(this, + .public = { + .pa_tnc_attribute = { + .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_status = _get_status, + }, + .type = { PEN_IETF, IETF_ATTR_FACTORY_DEFAULT_PWD_ENABLED }, + .status = status, + .ref = 1, + ); + + return &this->public.pa_tnc_attribute; +} + +/** + * Described in header. + */ +pa_tnc_attr_t *ietf_attr_default_pwd_enabled_create_from_data(chunk_t data) +{ + private_ietf_attr_default_pwd_enabled_t *this; + + INIT(this, + .public = { + .pa_tnc_attribute = { + .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_status = _get_status, + }, + .type = { PEN_IETF, IETF_ATTR_FACTORY_DEFAULT_PWD_ENABLED }, + .value = chunk_clone(data), + .ref = 1, + ); + + return &this->public.pa_tnc_attribute; +} + diff --git a/src/libimcv/ietf/ietf_attr_default_pwd_enabled.h b/src/libimcv/ietf/ietf_attr_default_pwd_enabled.h new file mode 100644 index 000000000..f6026b0e8 --- /dev/null +++ b/src/libimcv/ietf/ietf_attr_default_pwd_enabled.h @@ -0,0 +1,63 @@ +/* + * 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_default_pwd_enabled ietf_attr_default_pwd_enabled + * @{ @ingroup ietf + */ + +#ifndef IETF_ATTR_PWD_ENABLED_H_ +#define IETF_ATTR_PWD_ENABLED_H_ + +typedef struct ietf_attr_default_pwd_enabled_t ietf_attr_default_pwd_enabled_t; + +#include "ietf_attr.h" +#include "pa_tnc/pa_tnc_attr.h" + +/** + * Class implementing the IETF PA-TNC Factory Default Password Enabled attribute. + * + */ +struct ietf_attr_default_pwd_enabled_t { + + /** + * Public PA-TNC attribute interface + */ + pa_tnc_attr_t pa_tnc_attribute; + + /** + * Gets the Factory Default Password Enabled status + * + * @return Factory Default Password Enabled status + */ + bool (*get_status)(ietf_attr_default_pwd_enabled_t *this); + +}; + +/** + * Creates an ietf_attr_default_pwd_enabled_t object + * + * @param status Factory Default Password Enabled status + */ +pa_tnc_attr_t* ietf_attr_default_pwd_enabled_create(bool status); + +/** + * Creates an ietf_attr_default_pwd_enabled_t object from received data + * + * @param value unparsed attribute value + */ +pa_tnc_attr_t* ietf_attr_default_pwd_enabled_create_from_data(chunk_t value); + +#endif /** IETF_ATTR_PWD_ENABLED_H_ @}*/ diff --git a/src/libimcv/ietf/ietf_attr_fwd_enabled.c b/src/libimcv/ietf/ietf_attr_fwd_enabled.c new file mode 100644 index 000000000..911ee5b89 --- /dev/null +++ b/src/libimcv/ietf/ietf_attr_fwd_enabled.c @@ -0,0 +1,221 @@ +/* + * 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 "ietf_attr_fwd_enabled.h" + +#include <pa_tnc/pa_tnc_msg.h> +#include <bio/bio_writer.h> +#include <bio/bio_reader.h> +#include <utils/debug.h> + +typedef struct private_ietf_attr_fwd_enabled_t private_ietf_attr_fwd_enabled_t; + +/** + * PA-TNC Forwarding Enabled type (see section 4.2.11 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 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Forwarding Enabled | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +#define FORWARDING_ENABLED_SIZE 4 + +/** + * Private data of an ietf_attr_fwd_enabled_t object. + */ +struct private_ietf_attr_fwd_enabled_t { + + /** + * Public members of ietf_attr_fwd_enabled_t + */ + ietf_attr_fwd_enabled_t public; + + /** + * Vendor-specific attribute type + */ + pen_type_t type; + + /** + * Attribute value + */ + chunk_t value; + + /** + * Noskip flag + */ + bool noskip_flag; + + /** + * Forwarding Enabled status + */ + os_fwd_status_t fwd_status; + + /** + * Reference count + */ + refcount_t ref; +}; + +METHOD(pa_tnc_attr_t, get_type, pen_type_t, + private_ietf_attr_fwd_enabled_t *this) +{ + return this->type; +} + +METHOD(pa_tnc_attr_t, get_value, chunk_t, + private_ietf_attr_fwd_enabled_t *this) +{ + return this->value; +} + +METHOD(pa_tnc_attr_t, get_noskip_flag, bool, + private_ietf_attr_fwd_enabled_t *this) +{ + return this->noskip_flag; +} + +METHOD(pa_tnc_attr_t, set_noskip_flag,void, + private_ietf_attr_fwd_enabled_t *this, bool noskip) +{ + this->noskip_flag = noskip; +} + +METHOD(pa_tnc_attr_t, build, void, + private_ietf_attr_fwd_enabled_t *this) +{ + bio_writer_t *writer; + + if (this->value.ptr) + { + return; + } + writer = bio_writer_create(FORWARDING_ENABLED_SIZE); + writer->write_uint32(writer, this->fwd_status); + + this->value = chunk_clone(writer->get_buf(writer)); + writer->destroy(writer); +} + +METHOD(pa_tnc_attr_t, process, status_t, + private_ietf_attr_fwd_enabled_t *this, u_int32_t *offset) +{ + bio_reader_t *reader; + u_int32_t fwd_status; + + *offset = 0; + + if (this->value.len != FORWARDING_ENABLED_SIZE) + { + DBG1(DBG_TNC, "incorrect size for IETF forwarding enabled attribute"); + return FAILED; + } + reader = bio_reader_create(this->value); + reader->read_uint32(reader, &fwd_status); + reader->destroy(reader); + + if (fwd_status > OS_FWD_UNKNOWN) + { + DBG1(DBG_TNC, "IETF forwarding enabled field has unknown value %u", + fwd_status); + return FAILED; + } + this->fwd_status = fwd_status; + + return SUCCESS; +} + +METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*, + private_ietf_attr_fwd_enabled_t *this) +{ + ref_get(&this->ref); + return &this->public.pa_tnc_attribute; +} + +METHOD(pa_tnc_attr_t, destroy, void, + private_ietf_attr_fwd_enabled_t *this) +{ + if (ref_put(&this->ref)) + { + free(this->value.ptr); + free(this); + } +} + +METHOD(ietf_attr_fwd_enabled_t, get_status, os_fwd_status_t, + private_ietf_attr_fwd_enabled_t *this) +{ + return this->fwd_status; +} + +/** + * Described in header. + */ +pa_tnc_attr_t *ietf_attr_fwd_enabled_create(os_fwd_status_t fwd_status) +{ + private_ietf_attr_fwd_enabled_t *this; + + INIT(this, + .public = { + .pa_tnc_attribute = { + .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_status = _get_status, + }, + .type = { PEN_IETF, IETF_ATTR_FORWARDING_ENABLED }, + .fwd_status = fwd_status, + .ref = 1, + ); + + return &this->public.pa_tnc_attribute; +} + +/** + * Described in header. + */ +pa_tnc_attr_t *ietf_attr_fwd_enabled_create_from_data(chunk_t data) +{ + private_ietf_attr_fwd_enabled_t *this; + + INIT(this, + .public = { + .pa_tnc_attribute = { + .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_status = _get_status, + }, + .type = { PEN_IETF, IETF_ATTR_FORWARDING_ENABLED }, + .value = chunk_clone(data), + .ref = 1, + ); + + return &this->public.pa_tnc_attribute; +} + diff --git a/src/libimcv/ietf/ietf_attr_fwd_enabled.h b/src/libimcv/ietf/ietf_attr_fwd_enabled.h new file mode 100644 index 000000000..bfde1a7b1 --- /dev/null +++ b/src/libimcv/ietf/ietf_attr_fwd_enabled.h @@ -0,0 +1,64 @@ +/* + * 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_fwd_enabled ietf_attr_fwd_enabled + * @{ @ingroup ietf + */ + +#ifndef IETF_ATTR_FWD_ENABLED_H_ +#define IETF_ATTR_FWD_ENABLED_H_ + +typedef struct ietf_attr_fwd_enabled_t ietf_attr_fwd_enabled_t; + +#include "ietf_attr.h" +#include "pa_tnc/pa_tnc_attr.h" +#include "os_info/os_info.h" + +/** + * Class implementing the IETF PA-TNC Forwarding Enabled attribute. + * + */ +struct ietf_attr_fwd_enabled_t { + + /** + * Public PA-TNC attribute interface + */ + pa_tnc_attr_t pa_tnc_attribute; + + /** + * Gets the Forwarding Enabled status + * + * @return Forwarding Enabled status + */ + os_fwd_status_t (*get_status)(ietf_attr_fwd_enabled_t *this); + +}; + +/** + * Creates an ietf_attr_fwd_enabled_t object + * + * @param fwd_status Forwarding Enabled status + */ +pa_tnc_attr_t* ietf_attr_fwd_enabled_create(os_fwd_status_t fwd_status); + +/** + * Creates an ietf_attr_fwd_enabled_t object from received data + * + * @param value unparsed attribute value + */ +pa_tnc_attr_t* ietf_attr_fwd_enabled_create_from_data(chunk_t value); + +#endif /** IETF_ATTR_FWD_ENABLED_H_ @}*/ diff --git a/src/libimcv/ietf/ietf_attr_installed_packages.c b/src/libimcv/ietf/ietf_attr_installed_packages.c new file mode 100644 index 000000000..72a3c1344 --- /dev/null +++ b/src/libimcv/ietf/ietf_attr_installed_packages.c @@ -0,0 +1,335 @@ +/* + * 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 "ietf_attr_installed_packages.h" + +#include <string.h> + +#include <pa_tnc/pa_tnc_msg.h> +#include <bio/bio_writer.h> +#include <bio/bio_reader.h> +#include <collections/linked_list.h> +#include <utils/debug.h> + + +typedef struct private_ietf_attr_installed_packages_t private_ietf_attr_installed_packages_t; +typedef struct package_entry_t package_entry_t; + +/** + * PA-TNC Installed Packages Type (see section 4.2.7 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 | Package Count | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Pkg Name Len | Package Name (Variable Length) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Version Len | Package Version Number (Variable Length) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +#define INSTALLED_PACKAGES_MIN_SIZE 4 + +/** + * Private data of an ietf_attr_installed_packages_t object. + */ +struct private_ietf_attr_installed_packages_t { + + /** + * Public members of ietf_attr_installed_packages_t + */ + ietf_attr_installed_packages_t public; + + /** + * Vendor-specific attribute type + */ + pen_type_t type; + + /** + * Attribute value + */ + chunk_t value; + + /** + * Noskip flag + */ + bool noskip_flag; + + /** + * List of Installed Package entries + */ + linked_list_t *packages; + + /** + * Reference count + */ + refcount_t ref; +}; + +/** + * Package entry + */ +struct package_entry_t { + chunk_t name; + chunk_t version; +}; + +/** + * Free a package entry + */ +static void free_package_entry(package_entry_t *entry) +{ + free(entry->name.ptr); + free(entry->version.ptr); + free(entry); +} + +METHOD(pa_tnc_attr_t, get_type, pen_type_t, + private_ietf_attr_installed_packages_t *this) +{ + return this->type; +} + +METHOD(pa_tnc_attr_t, get_value, chunk_t, + private_ietf_attr_installed_packages_t *this) +{ + return this->value; +} + +METHOD(pa_tnc_attr_t, get_noskip_flag, bool, + private_ietf_attr_installed_packages_t *this) +{ + return this->noskip_flag; +} + +METHOD(pa_tnc_attr_t, set_noskip_flag,void, + private_ietf_attr_installed_packages_t *this, bool noskip) +{ + this->noskip_flag = noskip; +} + +METHOD(pa_tnc_attr_t, build, void, + private_ietf_attr_installed_packages_t *this) +{ + bio_writer_t *writer; + enumerator_t *enumerator; + package_entry_t *entry; + + if (this->value.ptr) + { + return; + } + writer = bio_writer_create(INSTALLED_PACKAGES_MIN_SIZE); + writer->write_uint16(writer, 0x0000); + writer->write_uint16(writer, this->packages->get_count(this->packages)); + + enumerator = this->packages->create_enumerator(this->packages); + while (enumerator->enumerate(enumerator, &entry)) + { + writer->write_data8(writer, entry->name); + writer->write_data8(writer, entry->version); + } + 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_installed_packages_t *this, u_int32_t *offset) +{ + bio_reader_t *reader; + package_entry_t *entry; + status_t status = FAILED; + chunk_t name, version; + u_int16_t reserved, count; + u_char *pos; + + *offset = 0; + + if (this->value.len < INSTALLED_PACKAGES_MIN_SIZE) + { + DBG1(DBG_TNC, "insufficient data for IETF installed packages"); + return FAILED; + } + reader = bio_reader_create(this->value); + reader->read_uint16(reader, &reserved); + reader->read_uint16(reader, &count); + *offset = INSTALLED_PACKAGES_MIN_SIZE; + + while (reader->remaining(reader)) + { + if (!reader->read_data8(reader, &name)) + { + DBG1(DBG_TNC, "insufficient data for IETF installed package name"); + goto end; + } + pos = memchr(name.ptr, '\0', name.len); + if (pos) + { + DBG1(DBG_TNC, "nul termination in IETF installed package name"); + *offset += 1 + (pos - name.ptr); + goto end; + } + *offset += 1 + name.len; + + if (!reader->read_data8(reader, &version)) + { + DBG1(DBG_TNC, "insufficient data for IETF installed package version"); + goto end; + } + pos = memchr(version.ptr, '\0', version.len); + if (pos) + { + DBG1(DBG_TNC, "nul termination in IETF installed package version"); + *offset += 1 + (pos - version.ptr); + goto end; + } + *offset += 1 + version.len; + + entry = malloc_thing(package_entry_t); + entry->name = chunk_clone(name); + entry->version = chunk_clone(version); + this->packages->insert_last(this->packages, entry); + } + + if (count != this->packages->get_count(this->packages)) + { + DBG1(DBG_TNC, "IETF installed package count unequal to " + "number of included packages"); + goto end; + } + status = SUCCESS; + +end: + reader->destroy(reader); + return status; +} + +METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*, + private_ietf_attr_installed_packages_t *this) +{ + ref_get(&this->ref); + return &this->public.pa_tnc_attribute; +} + +METHOD(pa_tnc_attr_t, destroy, void, + private_ietf_attr_installed_packages_t *this) +{ + if (ref_put(&this->ref)) + { + this->packages->destroy_function(this->packages, (void*)free_package_entry); + free(this->value.ptr); + free(this); + } +} + +METHOD(ietf_attr_installed_packages_t, add, void, + private_ietf_attr_installed_packages_t *this, chunk_t name, chunk_t version) +{ + package_entry_t *entry; + + /* restrict package name and package version number fields to 255 octets */ + name.len = min(255, name.len); + version.len = min(255, version.len); + + entry = malloc_thing(package_entry_t); + entry->name = chunk_clone(name); + entry->version = chunk_clone(version); + this->packages->insert_last(this->packages, entry); +} + +/** + * Enumerate package filter entries + */ +static bool package_filter(void *null, package_entry_t **entry, chunk_t *name, + void *i2, chunk_t *version) +{ + *name = (*entry)->name; + *version = (*entry)->version; + return TRUE; +} + +METHOD(ietf_attr_installed_packages_t, create_enumerator, enumerator_t*, + private_ietf_attr_installed_packages_t *this) +{ + return enumerator_create_filter( + this->packages->create_enumerator(this->packages), + (void*)package_filter, NULL, NULL); +} + +/** + * Described in header. + */ +pa_tnc_attr_t *ietf_attr_installed_packages_create(void) +{ + private_ietf_attr_installed_packages_t *this; + + INIT(this, + .public = { + .pa_tnc_attribute = { + .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, + }, + .type = { PEN_IETF, IETF_ATTR_INSTALLED_PACKAGES }, + .packages = linked_list_create(), + .ref = 1, + ); + + return &this->public.pa_tnc_attribute; +} + +/** + * Described in header. + */ +pa_tnc_attr_t *ietf_attr_installed_packages_create_from_data(chunk_t data) +{ + private_ietf_attr_installed_packages_t *this; + + INIT(this, + .public = { + .pa_tnc_attribute = { + .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, + }, + .type = {PEN_IETF, IETF_ATTR_INSTALLED_PACKAGES }, + .value = chunk_clone(data), + .packages = linked_list_create(), + .ref = 1, + ); + + return &this->public.pa_tnc_attribute; +} + + diff --git a/src/libimcv/ietf/ietf_attr_installed_packages.h b/src/libimcv/ietf/ietf_attr_installed_packages.h new file mode 100644 index 000000000..a9f6768e0 --- /dev/null +++ b/src/libimcv/ietf/ietf_attr_installed_packages.h @@ -0,0 +1,73 @@ +/* + * 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_installed_packagest ietf_attr_installed_packages + * @{ @ingroup ietf_attr_installed_packages + */ + +#ifndef IETF_ATTR_INSTALLED_PACKAGES_H_ +#define IETF_ATTR_INSTALLED_PACKAGES_H_ + +typedef struct ietf_attr_installed_packages_t ietf_attr_installed_packages_t; + +#include "ietf_attr.h" +#include "pa_tnc/pa_tnc_attr.h" + + +/** + * Class implementing the IETF PA-TNC Installed Packages attribute. + * + */ +struct ietf_attr_installed_packages_t { + + /** + * Public PA-TNC attribute interface + */ + pa_tnc_attr_t pa_tnc_attribute; + + /** + * Add a package entry + * + * @param name package name + * @param version package version number + */ + void (*add)(ietf_attr_installed_packages_t *this, chunk_t name, + chunk_t version); + + /** + * Enumerates over all packages + * Format: chunk_t name, chunk_t version + * + * @return enumerator + */ + enumerator_t* (*create_enumerator)(ietf_attr_installed_packages_t *this); + +}; + +/** + * Creates an ietf_attr_installed_packages_t object + * + */ +pa_tnc_attr_t* ietf_attr_installed_packages_create(void); + +/** + * Creates an ietf_attr_installed_packages_t object from received data + * + * @param value unparsed attribute value + */ +pa_tnc_attr_t* ietf_attr_installed_packages_create_from_data(chunk_t value); + +#endif /** IETF_ATTR_INSTALLED_PACKAGES_H_ @}*/ diff --git a/src/libimcv/ietf/ietf_attr_numeric_version.c b/src/libimcv/ietf/ietf_attr_numeric_version.c new file mode 100644 index 000000000..797205473 --- /dev/null +++ b/src/libimcv/ietf/ietf_attr_numeric_version.c @@ -0,0 +1,282 @@ +/* + * 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 "ietf_attr_numeric_version.h" + +#include <pa_tnc/pa_tnc_msg.h> +#include <bio/bio_writer.h> +#include <bio/bio_reader.h> +#include <utils/debug.h> + +typedef struct private_ietf_attr_numeric_version_t private_ietf_attr_numeric_version_t; + +/** + * PA-TNC Numeric Version type (see section 4.2.3 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 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Major Version Number | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Minor Version Number | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Build Number | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Service Pack Major | Service Pack Minor | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +#define NUMERIC_VERSION_SIZE 16 + +/** + * Private data of an ietf_attr_numeric_version_t object. + */ +struct private_ietf_attr_numeric_version_t { + + /** + * Public members of ietf_attr_numeric_version_t + */ + ietf_attr_numeric_version_t public; + + /** + * Vendor-specific attribute type + */ + pen_type_t type; + + /** + * Attribute value + */ + chunk_t value; + + /** + * Noskip flag + */ + bool noskip_flag; + + /** + * Major Version Number + */ + u_int32_t major_version; + + /** + * Minor Version Number + */ + u_int32_t minor_version; + + /** + * IBuild Number + */ + u_int32_t build; + + /** + * Service Pack Major Number + */ + u_int16_t service_pack_major; + + /** + * Service Pack Minor Number + */ + u_int16_t service_pack_minor; + + /** + * Reference count + */ + refcount_t ref; +}; + +METHOD(pa_tnc_attr_t, get_type, pen_type_t, + private_ietf_attr_numeric_version_t *this) +{ + return this->type; +} + +METHOD(pa_tnc_attr_t, get_value, chunk_t, + private_ietf_attr_numeric_version_t *this) +{ + return this->value; +} + +METHOD(pa_tnc_attr_t, get_noskip_flag, bool, + private_ietf_attr_numeric_version_t *this) +{ + return this->noskip_flag; +} + +METHOD(pa_tnc_attr_t, set_noskip_flag,void, + private_ietf_attr_numeric_version_t *this, bool noskip) +{ + this->noskip_flag = noskip; +} + +METHOD(pa_tnc_attr_t, build, void, + private_ietf_attr_numeric_version_t *this) +{ + bio_writer_t *writer; + + if (this->value.ptr) + { + return; + } + + writer = bio_writer_create(NUMERIC_VERSION_SIZE); + writer->write_uint32(writer, this->major_version); + writer->write_uint32(writer, this->minor_version); + writer->write_uint32(writer, this->build); + writer->write_uint16(writer, this->service_pack_major); + writer->write_uint16(writer, this->service_pack_minor); + + this->value = chunk_clone(writer->get_buf(writer)); + writer->destroy(writer); +} + +METHOD(pa_tnc_attr_t, process, status_t, + private_ietf_attr_numeric_version_t *this, u_int32_t *offset) +{ + bio_reader_t *reader; + + if (this->value.len < NUMERIC_VERSION_SIZE) + { + DBG1(DBG_TNC, "insufficient data for IETF numeric version"); + *offset = 0; + return FAILED; + } + reader = bio_reader_create(this->value); + reader->read_uint32(reader, &this->major_version); + reader->read_uint32(reader, &this->minor_version); + reader->read_uint32(reader, &this->build); + reader->read_uint16(reader, &this->service_pack_major); + reader->read_uint16(reader, &this->service_pack_minor); + reader->destroy(reader); + + return SUCCESS; +} + +METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*, + private_ietf_attr_numeric_version_t *this) +{ + ref_get(&this->ref); + return &this->public.pa_tnc_attribute; +} + +METHOD(pa_tnc_attr_t, destroy, void, + private_ietf_attr_numeric_version_t *this) +{ + if (ref_put(&this->ref)) + { + free(this->value.ptr); + free(this); + } +} + +METHOD(ietf_attr_numeric_version_t, get_version, void, + private_ietf_attr_numeric_version_t *this, u_int32_t *major, u_int32_t *minor) +{ + if (major) + { + *major = this->major_version; + } + if (minor) + { + *minor = this->minor_version; + } +} + +METHOD(ietf_attr_numeric_version_t, get_build, u_int32_t, + private_ietf_attr_numeric_version_t *this) +{ + return this->build; +} + +METHOD(ietf_attr_numeric_version_t, get_service_pack, void, + private_ietf_attr_numeric_version_t *this, u_int16_t *major, u_int16_t *minor) +{ + if (major) + { + *major = this->service_pack_major; + } + if (minor) + { + *minor = this->service_pack_minor; + } +} + +/** + * Described in header. + */ +pa_tnc_attr_t *ietf_attr_numeric_version_create(u_int32_t major, u_int32_t minor, + u_int32_t build, + u_int16_t service_pack_major, + u_int16_t service_pack_minor) +{ + private_ietf_attr_numeric_version_t *this; + + INIT(this, + .public = { + .pa_tnc_attribute = { + .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_version = _get_version, + .get_build = _get_build, + .get_service_pack = _get_service_pack, + }, + .type = { PEN_IETF, IETF_ATTR_NUMERIC_VERSION }, + .major_version = major, + .minor_version = minor, + .build = build, + .service_pack_major = service_pack_major, + .service_pack_minor = service_pack_minor, + .ref = 1, + ); + + return &this->public.pa_tnc_attribute; +} + +/** + * Described in header. + */ +pa_tnc_attr_t *ietf_attr_numeric_version_create_from_data(chunk_t data) +{ + private_ietf_attr_numeric_version_t *this; + + INIT(this, + .public = { + .pa_tnc_attribute = { + .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_version = _get_version, + .get_build = _get_build, + .get_service_pack = _get_service_pack, + }, + .type = { PEN_IETF, IETF_ATTR_NUMERIC_VERSION }, + .value = chunk_clone(data), + .ref = 1, + ); + + return &this->public.pa_tnc_attribute; +} diff --git a/src/libimcv/ietf/ietf_attr_numeric_version.h b/src/libimcv/ietf/ietf_attr_numeric_version.h new file mode 100644 index 000000000..f7d6c909d --- /dev/null +++ b/src/libimcv/ietf/ietf_attr_numeric_version.h @@ -0,0 +1,84 @@ +/* + * 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_numeric_versiont ietf_attr_numeric_version + * @{ @ingroup ietf + */ + +#ifndef IETF_ATTR_NUMERIC_VERSION_H_ +#define IETF_ATTR_NUMERIC_VERSION_H_ + +typedef struct ietf_attr_numeric_version_t ietf_attr_numeric_version_t; + +#include "ietf_attr.h" +#include "pa_tnc/pa_tnc_attr.h" + + +/** + * Class implementing the IETF PA-TNC String Version attribute. + * + */ +struct ietf_attr_numeric_version_t { + + /** + * Public PA-TNC attribute interface + */ + pa_tnc_attr_t pa_tnc_attribute; + + /** + * Gets the Major and Minor Version Numbers + * + * @param major Major Version Number + * @param minor Minor Version Number + */ + void (*get_version)(ietf_attr_numeric_version_t *this, + u_int32_t *major, u_int32_t *minor); + + /** + * Gets the Build Number + * + * @param major Major Version Number + * @param minor Minor Version Number + */ + u_int32_t (*get_build)(ietf_attr_numeric_version_t *this); + + /** + * Gets the Major and Minor Numbers of the Service Pack + * + * @param major Service Pack Major Number + * @param minor Servcie Pack Minor Number + */ + void (*get_service_pack)(ietf_attr_numeric_version_t *this, + u_int16_t *major, u_int16_t *minor); +}; + +/** + * Creates an ietf_attr_numeric_version_t object + * + */ +pa_tnc_attr_t* ietf_attr_numeric_version_create(u_int32_t major, u_int32_t minor, + u_int32_t build, + u_int16_t service_pack_major, + u_int16_t service_pack_minor); + +/** + * Creates an ietf_attr_numeric_version_t object from received data + * + * @param value unparsed attribute value + */ +pa_tnc_attr_t* ietf_attr_numeric_version_create_from_data(chunk_t value); + +#endif /** IETF_ATTR_NUMERIC_VERSION_H_ @}*/ diff --git a/src/libimcv/ietf/ietf_attr_op_status.c b/src/libimcv/ietf/ietf_attr_op_status.c new file mode 100644 index 000000000..d9610b29d --- /dev/null +++ b/src/libimcv/ietf/ietf_attr_op_status.c @@ -0,0 +1,314 @@ +/* + * 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 "ietf_attr_op_status.h" + +#include <pa_tnc/pa_tnc_msg.h> +#include <bio/bio_writer.h> +#include <bio/bio_reader.h> +#include <utils/debug.h> + +#include <time.h> + +typedef struct private_ietf_attr_op_status_t private_ietf_attr_op_status_t; + +ENUM(op_status_names, OP_STATUS_UNKNOWN, OP_STATUS_OPERATIONAL, + "unknown", + "not installed", + "installed", + "operational" +); + +ENUM(op_result_names, OP_RESULT_UNKNOWN, OP_RESULT_UNSUCCESSFUL, + "unknown", + "successful", + "errored", + "unsuccessful" +); + +/** + * PA-TNC Operational Status type (see section 4.2.5 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 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Status | Result | Reserved | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Last Use | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Last Use (continued) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Last Use (continued) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Last Use (continued) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Last Use (continued) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +#define OP_STATUS_SIZE 24 + +/** + * Private data of an ietf_attr_op_status_t object. + */ +struct private_ietf_attr_op_status_t { + + /** + * Public members of ietf_attr_op_status_t + */ + ietf_attr_op_status_t public; + + /** + * Vendor-specific attribute type + */ + pen_type_t type; + + /** + * Attribute value + */ + chunk_t value; + + /** + * Noskip flag + */ + bool noskip_flag; + + /** + * Status + */ + u_int8_t status; + + /** + * Result + */ + u_int8_t result; + + /** + * Last Use + */ + time_t last_use; + + /** + * Reference count + */ + refcount_t ref; +}; + +METHOD(pa_tnc_attr_t, get_type, pen_type_t, + private_ietf_attr_op_status_t *this) +{ + return this->type; +} + +METHOD(pa_tnc_attr_t, get_value, chunk_t, + private_ietf_attr_op_status_t *this) +{ + return this->value; +} + +METHOD(pa_tnc_attr_t, get_noskip_flag, bool, + private_ietf_attr_op_status_t *this) +{ + return this->noskip_flag; +} + +METHOD(pa_tnc_attr_t, set_noskip_flag,void, + private_ietf_attr_op_status_t *this, bool noskip) +{ + this->noskip_flag = noskip; +} + +METHOD(pa_tnc_attr_t, build, void, + private_ietf_attr_op_status_t *this) +{ + bio_writer_t *writer; + char last_use[24]; + struct tm t; + + if (this->value.ptr) + { + return; + } + + /* Conversion from time_t to RFC 3339 ASCII string */ + gmtime_r(&this->last_use, &t); + snprintf(last_use, 21, "%04d-%02d-%02dT%02d:%02d:%02dZ", 1900 + t.tm_year, + t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec); + + writer = bio_writer_create(OP_STATUS_SIZE); + writer->write_uint8 (writer, this->status); + writer->write_uint8 (writer, this->result); + writer->write_uint16(writer, 0x0000); + writer->write_data (writer, chunk_create(last_use, 20)); + + this->value = chunk_clone(writer->get_buf(writer)); + writer->destroy(writer); +} + +METHOD(pa_tnc_attr_t, process, status_t, + private_ietf_attr_op_status_t *this, u_int32_t *offset) +{ + bio_reader_t *reader; + chunk_t last_use; + u_int16_t reserved; + struct tm t; + + *offset = 0; + + if (this->value.len != OP_STATUS_SIZE) + { + DBG1(DBG_TNC, "incorrect size for IETF operational status"); + return FAILED; + } + reader = bio_reader_create(this->value); + reader->read_uint8 (reader, &this->status); + reader->read_uint8 (reader, &this->result); + reader->read_uint16(reader, &reserved); + reader->read_data (reader, 20, &last_use); + reader->destroy(reader); + + if (this->status > OP_STATUS_ROOF) + { + DBG1(DBG_TNC, "invalid status value %c for IETF operational status", + this->status); + return FAILED; + } + + *offset = 1; + + if (this->result > OP_RESULT_ROOF) + { + DBG1(DBG_TNC, "invalid result value %c for IETF operational status", + this->result); + return FAILED; + } + + *offset = 4; + + /* Conversion from RFC 3339 ASCII string to time_t */ + if (sscanf(last_use.ptr, "%4d-%2d-%2dT%2d:%2d:%2dZ", &t.tm_year, &t.tm_mon, + &t.tm_mday, &t.tm_hour, &t.tm_min, &t.tm_sec) != 6) + { + DBG1(DBG_TNC, "invalid last_use time format in IETF operational status"); + return FAILED; + } + t.tm_year -= 1900; + t.tm_mon -= 1; + t.tm_isdst = 0; + this->last_use = mktime(&t) - timezone; + + return SUCCESS; +} + +METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*, + private_ietf_attr_op_status_t *this) +{ + ref_get(&this->ref); + return &this->public.pa_tnc_attribute; +} + +METHOD(pa_tnc_attr_t, destroy, void, + private_ietf_attr_op_status_t *this) +{ + if (ref_put(&this->ref)) + { + free(this->value.ptr); + free(this); + } +} + +METHOD(ietf_attr_op_status_t, get_status, u_int8_t, + private_ietf_attr_op_status_t *this) +{ + return this->status; +} + +METHOD(ietf_attr_op_status_t, get_result, u_int8_t, + private_ietf_attr_op_status_t *this) +{ + return this->result; +} + +METHOD(ietf_attr_op_status_t, get_last_use, time_t, + private_ietf_attr_op_status_t *this) +{ + return this->last_use; +} + +/** + * Described in header. + */ +pa_tnc_attr_t *ietf_attr_op_status_create(u_int8_t status, u_int8_t result, + time_t last_use) +{ + private_ietf_attr_op_status_t *this; + + INIT(this, + .public = { + .pa_tnc_attribute = { + .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_status = _get_status, + .get_result = _get_result, + .get_last_use = _get_last_use, + }, + .type = { PEN_IETF, IETF_ATTR_OPERATIONAL_STATUS }, + .status = status, + .result = result, + .last_use = last_use, + .ref = 1, + ); + + return &this->public.pa_tnc_attribute; +} + +/** + * Described in header. + */ +pa_tnc_attr_t *ietf_attr_op_status_create_from_data(chunk_t data) +{ + private_ietf_attr_op_status_t *this; + + INIT(this, + .public = { + .pa_tnc_attribute = { + .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_status = _get_status, + .get_result = _get_result, + .get_last_use = _get_last_use, + }, + .type = { PEN_IETF, IETF_ATTR_OPERATIONAL_STATUS }, + .value = chunk_clone(data), + .ref = 1, + ); + + return &this->public.pa_tnc_attribute; +} + diff --git a/src/libimcv/ietf/ietf_attr_op_status.h b/src/libimcv/ietf/ietf_attr_op_status.h new file mode 100644 index 000000000..2e14148c4 --- /dev/null +++ b/src/libimcv/ietf/ietf_attr_op_status.h @@ -0,0 +1,107 @@ +/* + * 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_op_statust ietf_attr_op_status + * @{ @ingroup ietf + */ + +#ifndef IETF_ATTR_OP_STATUS_H_ +#define IETF_ATTR_OP_STATUS_H_ + +typedef struct ietf_attr_op_status_t ietf_attr_op_status_t; +typedef enum op_status_t op_status_t; +typedef enum op_result_t op_result_t; + +#include "ietf_attr.h" +#include "pa_tnc/pa_tnc_attr.h" + +/** + * Operational Status type + */ +enum op_status_t { + OP_STATUS_UNKNOWN = 0, + OP_STATUS_NOT_INSTALLED = 1, + OP_STATUS_INSTALLED = 2, + OP_STATUS_OPERATIONAL = 3, + OP_STATUS_ROOF = 3 +}; + +extern enum_name_t *op_status_names; + +/** + * Operational Result type + */ +enum op_result_t { + OP_RESULT_UNKNOWN = 0, + OP_RESULT_SUCCESSFUL = 1, + OP_RESULT_ERRORED = 2, + OP_RESULT_UNSUCCESSFUL = 3, + OP_RESULT_ROOF = 3 +}; + +extern enum_name_t *op_result_names; + +/** + * Class implementing the IETF PA-TNC Operational Status attribute. + * + */ +struct ietf_attr_op_status_t { + + /** + * Public PA-TNC attribute interface + */ + pa_tnc_attr_t pa_tnc_attribute; + + /** + * Gets the Operational Status + * + * @return Operational Status + */ + u_int8_t (*get_status)(ietf_attr_op_status_t *this); + + /** + * Gets the Operational Result + * + * @return Operational Result + */ + u_int8_t (*get_result)(ietf_attr_op_status_t *this); + + /** + * Gets the time of last use + * + * @return Time of last use + */ + time_t (*get_last_use)(ietf_attr_op_status_t *this); +}; + +/** + * Creates an ietf_attr_op_status_t object + * + * @param status Operational Status + * @param result Operational Result + * @param last_use Time of last use + */ +pa_tnc_attr_t* ietf_attr_op_status_create(u_int8_t status, u_int8_t result, + time_t last_use); + +/** + * Creates an ietf_attr_op_status_t object from received data + * + * @param value unparsed attribute value + */ +pa_tnc_attr_t* ietf_attr_op_status_create_from_data(chunk_t value); + +#endif /** IETF_ATTR_OP_STATUS_H_ @}*/ diff --git a/src/libimcv/ietf/ietf_attr_pa_tnc_error.c b/src/libimcv/ietf/ietf_attr_pa_tnc_error.c index 46f5d6716..f92022fe0 100644 --- a/src/libimcv/ietf/ietf_attr_pa_tnc_error.c +++ b/src/libimcv/ietf/ietf_attr_pa_tnc_error.c @@ -18,7 +18,7 @@ #include <pa_tnc/pa_tnc_msg.h> #include <bio/bio_writer.h> #include <bio/bio_reader.h> -#include <debug.h> +#include <utils/debug.h> ENUM(pa_tnc_error_code_names, PA_ERROR_RESERVED, PA_ERROR_ATTR_TYPE_NOT_SUPPORTED, @@ -80,7 +80,7 @@ typedef struct private_ietf_attr_pa_tnc_error_t private_ietf_attr_pa_tnc_error_t * | Max Version | Min Version | Reserved | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ - + #define PA_ERROR_VERSION_RESERVED 0x0000 /** @@ -186,7 +186,7 @@ METHOD(pa_tnc_attr_t, build, void, writer->write_uint24(writer, this->error_code.vendor_id); writer->write_uint32(writer, this->error_code.type); writer->write_data (writer, this->msg_info); - + if (this->error_code.vendor_id == PEN_IETF) { switch (this->error_code.type) @@ -272,7 +272,7 @@ METHOD(pa_tnc_attr_t, process, status_t, } reader->destroy(reader); - return SUCCESS; + return SUCCESS; } METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*, @@ -420,6 +420,8 @@ pa_tnc_attr_t *ietf_attr_pa_tnc_error_create_from_data(chunk_t data) .pa_tnc_attribute = { .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, diff --git a/src/libimcv/ietf/ietf_attr_pa_tnc_error.h b/src/libimcv/ietf/ietf_attr_pa_tnc_error.h index d28c524aa..a5a10d470 100644 --- a/src/libimcv/ietf/ietf_attr_pa_tnc_error.h +++ b/src/libimcv/ietf/ietf_attr_pa_tnc_error.h @@ -55,13 +55,6 @@ struct ietf_attr_pa_tnc_error_t { 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 Vendor-specific PA-TNC error code * * @return error code diff --git a/src/libimcv/ietf/ietf_attr_port_filter.c b/src/libimcv/ietf/ietf_attr_port_filter.c index 5ea52256b..8b8da3a41 100644 --- a/src/libimcv/ietf/ietf_attr_port_filter.c +++ b/src/libimcv/ietf/ietf_attr_port_filter.c @@ -17,8 +17,8 @@ #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> +#include <collections/linked_list.h> +#include <utils/debug.h> typedef struct private_ietf_attr_port_filter_t private_ietf_attr_port_filter_t; @@ -36,8 +36,8 @@ struct port_entry_t { /** * 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 + * 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 | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ @@ -152,7 +152,7 @@ METHOD(pa_tnc_attr_t, process, status_t, while (reader->remaining(reader)) { - entry = malloc_thing(port_entry_t); + entry = malloc_thing(port_entry_t); reader->read_uint8 (reader, &blocked); entry->blocked = blocked & 0x01; reader->read_uint8 (reader, &entry->protocol); @@ -161,7 +161,7 @@ METHOD(pa_tnc_attr_t, process, status_t, } reader->destroy(reader); - return SUCCESS; + return SUCCESS; } METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*, @@ -192,7 +192,7 @@ METHOD(ietf_attr_port_filter_t, add_port, void, entry->blocked = blocked; entry->protocol = protocol; entry->port = port; - this->ports->insert_last(this->ports, entry); + this->ports->insert_last(this->ports, entry); } /** @@ -257,6 +257,8 @@ pa_tnc_attr_t *ietf_attr_port_filter_create_from_data(chunk_t data) .pa_tnc_attribute = { .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, diff --git a/src/libimcv/ietf/ietf_attr_product_info.c b/src/libimcv/ietf/ietf_attr_product_info.c index dcc0e0294..115f00130 100644 --- a/src/libimcv/ietf/ietf_attr_product_info.c +++ b/src/libimcv/ietf/ietf_attr_product_info.c @@ -17,7 +17,7 @@ #include <pa_tnc/pa_tnc_msg.h> #include <bio/bio_writer.h> #include <bio/bio_reader.h> -#include <debug.h> +#include <utils/debug.h> typedef struct private_ietf_attr_product_info_t private_ietf_attr_product_info_t; @@ -73,7 +73,7 @@ struct private_ietf_attr_product_info_t { /** * Product Name */ - char *product_name; + chunk_t product_name; /** * Reference count @@ -109,18 +109,15 @@ METHOD(pa_tnc_attr_t, build, void, private_ietf_attr_product_info_t *this) { bio_writer_t *writer; - chunk_t product_name; if (this->value.ptr) { return; } - 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); + writer->write_data (writer, this->product_name); this->value = chunk_clone(writer->get_buf(writer)); writer->destroy(writer); @@ -144,9 +141,14 @@ METHOD(pa_tnc_attr_t, process, status_t, 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'; + if (!this->product_vendor_id && this->product_id) + { + DBG1(DBG_TNC, "IETF product information vendor ID is 0 " + "but product ID is not 0"); + *offset = 3; + return FAILED; + } + this->product_name = chunk_clone(product_name); return SUCCESS; } @@ -163,13 +165,13 @@ METHOD(pa_tnc_attr_t, destroy, void, { if (ref_put(&this->ref)) { - free(this->product_name); + free(this->product_name.ptr); free(this->value.ptr); free(this); } } -METHOD(ietf_attr_product_info_t, get_info, char*, +METHOD(ietf_attr_product_info_t, get_info, chunk_t, private_ietf_attr_product_info_t *this, pen_t *vendor_id, u_int16_t *id) { if (vendor_id) @@ -187,7 +189,7 @@ METHOD(ietf_attr_product_info_t, get_info, char*, * Described in header. */ pa_tnc_attr_t *ietf_attr_product_info_create(pen_t vendor_id, u_int16_t id, - char *name) + chunk_t name) { private_ietf_attr_product_info_t *this; @@ -208,7 +210,7 @@ pa_tnc_attr_t *ietf_attr_product_info_create(pen_t vendor_id, u_int16_t id, .type = { PEN_IETF, IETF_ATTR_PRODUCT_INFORMATION }, .product_vendor_id = vendor_id, .product_id = id, - .product_name = strdup(name), + .product_name = chunk_clone(name), .ref = 1, ); @@ -227,6 +229,8 @@ pa_tnc_attr_t *ietf_attr_product_info_create_from_data(chunk_t data) .pa_tnc_attribute = { .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, diff --git a/src/libimcv/ietf/ietf_attr_product_info.h b/src/libimcv/ietf/ietf_attr_product_info.h index f1dfc3e83..dfaa67d6c 100644 --- a/src/libimcv/ietf/ietf_attr_product_info.h +++ b/src/libimcv/ietf/ietf_attr_product_info.h @@ -45,8 +45,8 @@ struct ietf_attr_product_info_t { * @param id Product ID * @return Product Name */ - char* (*get_info)(ietf_attr_product_info_t *this, - pen_t *vendor_id, u_int16_t *id); + chunk_t (*get_info)(ietf_attr_product_info_t *this, + pen_t *vendor_id, u_int16_t *id); }; @@ -55,7 +55,7 @@ struct ietf_attr_product_info_t { * */ pa_tnc_attr_t* ietf_attr_product_info_create(pen_t vendor_id, u_int16_t id, - char *name); + chunk_t name); /** * Creates an ietf_attr_product_info_t object from received data diff --git a/src/libimcv/ietf/ietf_attr_remediation_instr.c b/src/libimcv/ietf/ietf_attr_remediation_instr.c new file mode 100644 index 000000000..f3b4e83dd --- /dev/null +++ b/src/libimcv/ietf/ietf_attr_remediation_instr.c @@ -0,0 +1,363 @@ +/* + * 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 "ietf_attr_remediation_instr.h" + +#include <pa_tnc/pa_tnc_msg.h> +#include <bio/bio_writer.h> +#include <bio/bio_reader.h> +#include <utils/debug.h> + +typedef struct private_ietf_attr_remediation_instr_t private_ietf_attr_remediation_instr_t; + +/** + * PA-TNC Remediation Instructions type (see section 4.2.10 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 | Remediation Parameters Vendor ID | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Remediation Parameters Type | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Remediation Parameters (Variable Length) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +#define REMEDIATION_INSTR_MIN_SIZE 8 +#define REMEDIATION_INSTR_RESERVED 0x00 + +/** + * IETF Remediation Parameters URI type (see section 4.2.10.1 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 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Remediation URI (Variable Length) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +*/ + +/** + * IETF Remediation Parameters String type (see section 4.2.10.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 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Remediation String Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Remediation String (Variable Length) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Lang Code Len | Remediation String Lang Code (Variable Len) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +/** + * Private data of an ietf_attr_remediation_instr_t object. + */ +struct private_ietf_attr_remediation_instr_t { + + /** + * Public members of ietf_attr_remediation_instr_t + */ + ietf_attr_remediation_instr_t public; + + /** + * Vendor-specific attribute type + */ + pen_type_t type; + + /** + * Attribute value + */ + chunk_t value; + + /** + * Noskip flag + */ + bool noskip_flag; + + /** + * Remediation Parameters Type + */ + pen_type_t parameters_type; + + /** + * Remediation Parameters + */ + chunk_t parameters; + + /** + * Remediation String + */ + chunk_t string; + + /** + * Remediation Language Code + */ + chunk_t lang_code; + + /** + * Reference count + */ + refcount_t ref; +}; + +METHOD(pa_tnc_attr_t, get_type, pen_type_t, + private_ietf_attr_remediation_instr_t *this) +{ + return this->type; +} + +METHOD(pa_tnc_attr_t, get_value, chunk_t, + private_ietf_attr_remediation_instr_t *this) +{ + return this->value; +} + +METHOD(pa_tnc_attr_t, get_noskip_flag, bool, + private_ietf_attr_remediation_instr_t *this) +{ + return this->noskip_flag; +} + +METHOD(pa_tnc_attr_t, set_noskip_flag,void, + private_ietf_attr_remediation_instr_t *this, bool noskip) +{ + this->noskip_flag = noskip; +} + +METHOD(pa_tnc_attr_t, build, void, + private_ietf_attr_remediation_instr_t *this) +{ + bio_writer_t *writer; + + if (this->value.ptr) + { + return; + } + + writer = bio_writer_create(REMEDIATION_INSTR_MIN_SIZE); + writer->write_uint8 (writer, REMEDIATION_INSTR_RESERVED); + writer->write_uint24(writer, this->parameters_type.vendor_id); + writer->write_uint32(writer, this->parameters_type.type); + writer->write_data (writer, this->parameters); + + this->value = chunk_clone(writer->get_buf(writer)); + writer->destroy(writer); +} + +METHOD(pa_tnc_attr_t, process, status_t, + private_ietf_attr_remediation_instr_t *this, u_int32_t *offset) +{ + bio_reader_t *reader; + u_int8_t reserved; + status_t status = SUCCESS; + u_char *pos; + + *offset = 0; + + if (this->value.len < REMEDIATION_INSTR_MIN_SIZE) + { + DBG1(DBG_TNC, "insufficient data for IETF remediation instructions"); + return FAILED; + } + reader = bio_reader_create(this->value); + reader->read_uint8 (reader, &reserved); + reader->read_uint24(reader, &this->parameters_type.vendor_id); + reader->read_uint32(reader, &this->parameters_type.type); + reader->read_data (reader, reader->remaining(reader), &this->parameters); + + this->parameters = chunk_clone(this->parameters); + reader->destroy(reader); + + if (this->parameters_type.vendor_id == PEN_IETF && + this->parameters_type.type == IETF_REMEDIATION_PARAMETERS_STRING) + { + reader = bio_reader_create(this->parameters); + status = FAILED; + *offset = 8; + + if (!reader->read_data32(reader, &this->string)) + { + DBG1(DBG_TNC, "insufficient data for IETF remediation string"); + goto end; + } + pos = memchr(this->string.ptr, '\0', this->string.len); + if (pos) + { + DBG1(DBG_TNC, "nul termination in IETF remediation string"); + *offset += 1 + (pos - this->string.ptr); + goto end; + } + *offset += 4 + this->string.len; + + if (!reader->read_data8(reader, &this->lang_code)) + { + DBG1(DBG_TNC, "insufficient data for IETF remediation lang code"); + goto end; + } + status = SUCCESS; + +end: + reader->destroy(reader); + } + return status; +} + +METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*, + private_ietf_attr_remediation_instr_t *this) +{ + ref_get(&this->ref); + return &this->public.pa_tnc_attribute; +} + +METHOD(pa_tnc_attr_t, destroy, void, + private_ietf_attr_remediation_instr_t *this) +{ + if (ref_put(&this->ref)) + { + free(this->parameters.ptr); + free(this->value.ptr); + free(this); + } +} + +METHOD(ietf_attr_remediation_instr_t, get_parameters_type, pen_type_t, + private_ietf_attr_remediation_instr_t *this) +{ + return this->parameters_type; +} + +METHOD(ietf_attr_remediation_instr_t, get_parameters, chunk_t, + private_ietf_attr_remediation_instr_t *this) +{ + return this->parameters; +} + +METHOD(ietf_attr_remediation_instr_t, get_uri, chunk_t, + private_ietf_attr_remediation_instr_t *this) +{ + return this->parameters; +} + +METHOD(ietf_attr_remediation_instr_t, get_string, chunk_t, + private_ietf_attr_remediation_instr_t *this, chunk_t *lang_code) +{ + if (lang_code) + { + *lang_code = this->lang_code; + } + return this->string; +} + +/** + * Described in header. + */ +pa_tnc_attr_t *ietf_attr_remediation_instr_create(pen_type_t parameters_type, + chunk_t parameters) +{ + private_ietf_attr_remediation_instr_t *this; + + INIT(this, + .public = { + .pa_tnc_attribute = { + .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_parameters_type = _get_parameters_type, + .get_parameters = _get_parameters, + .get_uri = _get_uri, + .get_string = _get_string, + }, + .type = { PEN_IETF, IETF_ATTR_REMEDIATION_INSTRUCTIONS }, + .parameters_type = parameters_type, + .parameters = chunk_clone(parameters), + .ref = 1, + ); + + return &this->public.pa_tnc_attribute; +} + +/** + * Described in header. + */ +pa_tnc_attr_t *ietf_attr_remediation_instr_create_from_uri(chunk_t uri) +{ + pen_type_t type = { PEN_IETF, IETF_REMEDIATION_PARAMETERS_URI }; + + return ietf_attr_remediation_instr_create(type, uri); +} + +/** + * Described in header. + */ +pa_tnc_attr_t *ietf_attr_remediation_instr_create_from_string(chunk_t string, + chunk_t lang_code) +{ + pa_tnc_attr_t *attr; + bio_writer_t *writer; + pen_type_t type = { PEN_IETF, IETF_REMEDIATION_PARAMETERS_STRING }; + + /* limit language code to 255 octets */ + lang_code.len = min(255, lang_code.len); + + writer = bio_writer_create(4 + string.len + 1 + lang_code.len); + writer->write_data32(writer, string); + writer->write_data8 (writer, lang_code); + + attr = ietf_attr_remediation_instr_create(type, writer->get_buf(writer)); + writer->destroy(writer); + + return attr; +} + +/** + * Described in header. + */ +pa_tnc_attr_t *ietf_attr_remediation_instr_create_from_data(chunk_t data) +{ + private_ietf_attr_remediation_instr_t *this; + + INIT(this, + .public = { + .pa_tnc_attribute = { + .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_parameters_type = _get_parameters_type, + .get_parameters = _get_parameters, + .get_uri = _get_uri, + .get_string = _get_string, + }, + .type = { PEN_IETF, IETF_ATTR_REMEDIATION_INSTRUCTIONS }, + .value = chunk_clone(data), + .ref = 1, + ); + + return &this->public.pa_tnc_attribute; +} + diff --git a/src/libimcv/ietf/ietf_attr_remediation_instr.h b/src/libimcv/ietf/ietf_attr_remediation_instr.h new file mode 100644 index 000000000..473280c33 --- /dev/null +++ b/src/libimcv/ietf/ietf_attr_remediation_instr.h @@ -0,0 +1,109 @@ +/* + * 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_remediation_instrt ietf_attr_remediation_instr + * @{ @ingroup ietf + */ + +#ifndef IETF_ATTR_REMEDIATION_INSTR_H_ +#define IETF_ATTR_REMEDIATION_INSTR_H_ + +typedef struct ietf_attr_remediation_instr_t ietf_attr_remediation_instr_t; +typedef enum ietf_remediation_parameters_t ietf_remediation_parameters_t; + +#include "ietf_attr.h" +#include "pa_tnc/pa_tnc_attr.h" + +enum ietf_remediation_parameters_t { + IETF_REMEDIATION_PARAMETERS_URI = 1, + IETF_REMEDIATION_PARAMETERS_STRING = 2 +}; + +/** + * Class implementing the IETF PA-TNC Remediation Instructions attribute. + * + */ +struct ietf_attr_remediation_instr_t { + + /** + * Public PA-TNC attribute interface + */ + pa_tnc_attr_t pa_tnc_attribute; + + /** + * Get the Remediation Parameters Type (Vendor ID and Type) + * + * @return Remediation Parameters Type + */ + pen_type_t (*get_parameters_type)(ietf_attr_remediation_instr_t *this); + + /** + * Get the Remediation Parameters + * + * @return Remediation Parameters + */ + chunk_t (*get_parameters)(ietf_attr_remediation_instr_t *this); + + /** + * Get the Remediation URI + * + * @return Remediation URI + */ + chunk_t (*get_uri)(ietf_attr_remediation_instr_t *this); + + /** + * Get the Remediation String + * + * @param lang_code Optional Language Code + * @return Remediation String + */ + chunk_t (*get_string)(ietf_attr_remediation_instr_t *this, + chunk_t *lang_code); +}; + +/** + * Creates a general ietf_attr_remediation_instr_t object + * + * @param parameters_type Remediation Parameters Type + * @param parameters Remediation Parameters + */ +pa_tnc_attr_t* ietf_attr_remediation_instr_create(pen_type_t parameters_type, + chunk_t parameters); + +/** + * Creates an ietf_attr_remediation_instr_t object of Remediation URI Type + * + * @param uri Remediation URI + */ +pa_tnc_attr_t* ietf_attr_remediation_instr_create_from_uri(chunk_t uri); + +/** + * Creates an ietf_attr_remediation_instr_t object of Remediation String Type + * + * @param string Remediation String + * @param lang_code Remediation String Language Code + */ +pa_tnc_attr_t* ietf_attr_remediation_instr_create_from_string(chunk_t string, + chunk_t lang_code); + +/** + * Creates an ietf_attr_remediation_instr_t object from received data + * + * @param value unparsed attribute value + */ +pa_tnc_attr_t* ietf_attr_remediation_instr_create_from_data(chunk_t value); + +#endif /** IETF_ATTR_REMEDIATION_INSTR_H_ @}*/ diff --git a/src/libimcv/ietf/ietf_attr_string_version.c b/src/libimcv/ietf/ietf_attr_string_version.c new file mode 100644 index 000000000..8f4129eac --- /dev/null +++ b/src/libimcv/ietf/ietf_attr_string_version.c @@ -0,0 +1,300 @@ +/* + * 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 "ietf_attr_string_version.h" + +#include <pa_tnc/pa_tnc_msg.h> +#include <bio/bio_writer.h> +#include <bio/bio_reader.h> +#include <utils/debug.h> + +typedef struct private_ietf_attr_string_version_t private_ietf_attr_string_version_t; + +/** + * PA-TNC String Version type (see section 4.2.4 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 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Version Len | Product Version Number (Variable Length) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Build Num Len | Internal Build Number (Variable Length) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Config. Len | Configuration Version Number (Variable Length)| + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +#define STRING_VERSION_MIN_SIZE 3 + +/** + * Private data of an ietf_attr_string_version_t object. + */ +struct private_ietf_attr_string_version_t { + + /** + * Public members of ietf_attr_string_version_t + */ + ietf_attr_string_version_t public; + + /** + * Vendor-specific attribute type + */ + pen_type_t type; + + /** + * Attribute value + */ + chunk_t value; + + /** + * Noskip flag + */ + bool noskip_flag; + + /** + * Product Version Number + */ + chunk_t version; + + /** + * Internal Build Number + */ + chunk_t build; + + /** + * Configuration Version Number + */ + chunk_t config; + + /** + * Reference count + */ + refcount_t ref; +}; + +METHOD(pa_tnc_attr_t, get_type, pen_type_t, + private_ietf_attr_string_version_t *this) +{ + return this->type; +} + +METHOD(pa_tnc_attr_t, get_value, chunk_t, + private_ietf_attr_string_version_t *this) +{ + return this->value; +} + +METHOD(pa_tnc_attr_t, get_noskip_flag, bool, + private_ietf_attr_string_version_t *this) +{ + return this->noskip_flag; +} + +METHOD(pa_tnc_attr_t, set_noskip_flag,void, + private_ietf_attr_string_version_t *this, bool noskip) +{ + this->noskip_flag = noskip; +} + +METHOD(pa_tnc_attr_t, build, void, + private_ietf_attr_string_version_t *this) +{ + bio_writer_t *writer; + + if (this->value.ptr) + { + return; + } + + writer = bio_writer_create(STRING_VERSION_MIN_SIZE); + writer->write_data8(writer, this->version); + writer->write_data8(writer, this->build); + writer->write_data8(writer, this->config); + + this->value = chunk_clone(writer->get_buf(writer)); + writer->destroy(writer); +} + +METHOD(pa_tnc_attr_t, process, status_t, + private_ietf_attr_string_version_t *this, u_int32_t *offset) +{ + bio_reader_t *reader; + status_t status = FAILED; + chunk_t version, build, config; + u_char *pos; + + *offset = 0; + + if (this->value.len < STRING_VERSION_MIN_SIZE) + { + DBG1(DBG_TNC, "insufficient data for IETF string version"); + return FAILED; + } + reader = bio_reader_create(this->value); + + if (!reader->read_data8(reader, &version)) + { + DBG1(DBG_TNC, "insufficient data for IETF product version number"); + goto end; + + } + pos = memchr(version.ptr, '\0', version.len); + if (pos) + { + DBG1(DBG_TNC, "nul termination in IETF product version number"); + *offset += 1 + (pos - version.ptr); + goto end; + } + *offset += 1 + version.len; + + if (!reader->read_data8(reader, &build)) + { + DBG1(DBG_TNC, "insufficient data for IETF internal build number"); + goto end; + + } + pos = memchr(build.ptr, '\0', build.len); + if (pos) + { + DBG1(DBG_TNC, "nul termination in IETF internal build number"); + *offset += 1 + (pos - build.ptr); + goto end; + } + *offset += 1 + build.len; + + if (!reader->read_data8(reader, &config)) + { + DBG1(DBG_TNC, "insufficient data for IETF configuration version number"); + goto end; + + } + pos = memchr(config.ptr, '\0', config.len); + if (pos) + { + DBG1(DBG_TNC, "nul termination in IETF configuration version number"); + *offset += 1 + (pos - config.ptr); + goto end; + } + + this->version = chunk_clone(version); + this->build = chunk_clone(build); + this->config = chunk_clone(config); + status = SUCCESS; + +end: + reader->destroy(reader); + return status; +} + +METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*, + private_ietf_attr_string_version_t *this) +{ + ref_get(&this->ref); + return &this->public.pa_tnc_attribute; +} + +METHOD(pa_tnc_attr_t, destroy, void, + private_ietf_attr_string_version_t *this) +{ + if (ref_put(&this->ref)) + { + free(this->version.ptr); + free(this->build.ptr); + free(this->config.ptr); + free(this->value.ptr); + free(this); + } +} + +METHOD(ietf_attr_string_version_t, get_version, chunk_t, + private_ietf_attr_string_version_t *this, chunk_t *build, chunk_t *config) +{ + if (build) + { + *build = this->build; + } + if (config) + { + *config = this->config; + } + return this->version; +} + +/** + * Described in header. + */ +pa_tnc_attr_t *ietf_attr_string_version_create(chunk_t version, chunk_t build, + chunk_t config) +{ + private_ietf_attr_string_version_t *this; + + /* limit version numbers to 255 octets */ + version.len = min(255, version.len); + build.len = min(255, build.len); + config.len = min(255, config.len); + + INIT(this, + .public = { + .pa_tnc_attribute = { + .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_version = _get_version, + }, + .type = { PEN_IETF, IETF_ATTR_STRING_VERSION }, + .version = chunk_clone(version), + .build = chunk_clone(build), + .config = chunk_clone(config), + .ref = 1, + ); + + return &this->public.pa_tnc_attribute; +} + +/** + * Described in header. + */ +pa_tnc_attr_t *ietf_attr_string_version_create_from_data(chunk_t data) +{ + private_ietf_attr_string_version_t *this; + + INIT(this, + .public = { + .pa_tnc_attribute = { + .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_version = _get_version, + }, + .type = { PEN_IETF, IETF_ATTR_STRING_VERSION }, + .value = chunk_clone(data), + .ref = 1, + ); + + return &this->public.pa_tnc_attribute; +} + diff --git a/src/libimcv/ietf/ietf_attr_string_version.h b/src/libimcv/ietf/ietf_attr_string_version.h new file mode 100644 index 000000000..5ffbea8e0 --- /dev/null +++ b/src/libimcv/ietf/ietf_attr_string_version.h @@ -0,0 +1,67 @@ +/* + * 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_string_versiont ietf_attr_string_version + * @{ @ingroup ietf + */ + +#ifndef IETF_ATTR_STRING_VERSION_H_ +#define IETF_ATTR_STRING_VERSION_H_ + +typedef struct ietf_attr_string_version_t ietf_attr_string_version_t; + +#include "ietf_attr.h" +#include "pa_tnc/pa_tnc_attr.h" + + +/** + * Class implementing the IETF PA-TNC String Version attribute. + * + */ +struct ietf_attr_string_version_t { + + /** + * Public PA-TNC attribute interface + */ + pa_tnc_attr_t pa_tnc_attribute; + + /** + * Gets the Product Version Number and optionally the Internal Build + * and Configuration Version Numbers + * + * @param build Internal Build Number (if build != NULL) + * @param config Configuration Version Number (if config != NULL) + * @return Product Version Number + */ + chunk_t (*get_version)(ietf_attr_string_version_t *this, chunk_t *build, + chunk_t *config); +}; + +/** + * Creates an ietf_attr_string_version_t object + * + */ +pa_tnc_attr_t* ietf_attr_string_version_create(chunk_t version, chunk_t build, + chunk_t config); + +/** + * Creates an ietf_attr_string_version_t object from received data + * + * @param value unparsed attribute value + */ +pa_tnc_attr_t* ietf_attr_string_version_create_from_data(chunk_t value); + +#endif /** IETF_ATTR_STRING_VERSION_H_ @}*/ |