diff options
author | Romain Francoise <rfrancoise@debian.org> | 2014-10-21 19:28:38 +0200 |
---|---|---|
committer | Romain Francoise <rfrancoise@debian.org> | 2014-10-21 19:28:38 +0200 |
commit | 2b8de74ff4c334c25e89988c4a401b24b5bcf03d (patch) | |
tree | 10fb49ca94bfd0c8b8a583412281abfc0186836e /src/libimcv/ietf | |
parent | 81c63b0eed39432878f78727f60a1e7499645199 (diff) | |
download | vyos-strongswan-2b8de74ff4c334c25e89988c4a401b24b5bcf03d.tar.gz vyos-strongswan-2b8de74ff4c334c25e89988c4a401b24b5bcf03d.zip |
Import upstream release 5.2.1
Diffstat (limited to 'src/libimcv/ietf')
26 files changed, 505 insertions, 154 deletions
diff --git a/src/libimcv/ietf/ietf_attr.c b/src/libimcv/ietf/ietf_attr.c index 2f3819898..67269af53 100644 --- a/src/libimcv/ietf/ietf_attr.c +++ b/src/libimcv/ietf/ietf_attr.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011-2012 Andreas Steffen + * Copyright (C) 2011-2014 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -47,34 +47,35 @@ ENUM(ietf_attr_names, IETF_ATTR_TESTING, IETF_ATTR_FACTORY_DEFAULT_PWD_ENABLED, /** * See header */ -pa_tnc_attr_t* ietf_attr_create_from_data(u_int32_t type, chunk_t value) +pa_tnc_attr_t* ietf_attr_create_from_data(u_int32_t type, size_t length, + chunk_t value) { switch (type) { case IETF_ATTR_ATTRIBUTE_REQUEST: - return ietf_attr_attr_request_create_from_data(value); + return ietf_attr_attr_request_create_from_data(length, value); case IETF_ATTR_PRODUCT_INFORMATION: - return ietf_attr_product_info_create_from_data(value); + return ietf_attr_product_info_create_from_data(length, value); case IETF_ATTR_NUMERIC_VERSION: - return ietf_attr_numeric_version_create_from_data(value); + return ietf_attr_numeric_version_create_from_data(length, value); case IETF_ATTR_STRING_VERSION: - return ietf_attr_string_version_create_from_data(value); + return ietf_attr_string_version_create_from_data(length, value); case IETF_ATTR_OPERATIONAL_STATUS: - return ietf_attr_op_status_create_from_data(value); + return ietf_attr_op_status_create_from_data(length, value); case IETF_ATTR_PORT_FILTER: - return ietf_attr_port_filter_create_from_data(value); + return ietf_attr_port_filter_create_from_data(length, value); case IETF_ATTR_INSTALLED_PACKAGES: - return ietf_attr_installed_packages_create_from_data(value); + return ietf_attr_installed_packages_create_from_data(length, value); case IETF_ATTR_PA_TNC_ERROR: - return ietf_attr_pa_tnc_error_create_from_data(value); + return ietf_attr_pa_tnc_error_create_from_data(length, value); case IETF_ATTR_ASSESSMENT_RESULT: - return ietf_attr_assess_result_create_from_data(value); + return ietf_attr_assess_result_create_from_data(length, value); case IETF_ATTR_REMEDIATION_INSTRUCTIONS: - return ietf_attr_remediation_instr_create_from_data(value); + return ietf_attr_remediation_instr_create_from_data(length, value); case IETF_ATTR_FORWARDING_ENABLED: - return ietf_attr_fwd_enabled_create_from_data(value); + return ietf_attr_fwd_enabled_create_from_data(length, value); case IETF_ATTR_FACTORY_DEFAULT_PWD_ENABLED: - return ietf_attr_default_pwd_enabled_create_from_data(value); + return ietf_attr_default_pwd_enabled_create_from_data(length, value); case IETF_ATTR_TESTING: case IETF_ATTR_RESERVED: default: diff --git a/src/libimcv/ietf/ietf_attr.h b/src/libimcv/ietf/ietf_attr.h index d22175d94..169ed78e8 100644 --- a/src/libimcv/ietf/ietf_attr.h +++ b/src/libimcv/ietf/ietf_attr.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 Andreas Steffen + * Copyright (C) 2011-2014 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -56,8 +56,10 @@ extern enum_name_t *ietf_attr_names; * Create an IETF PA-TNC attribute from data * * @param type attribute type - * @param value attribute value + * @param length attribute length + * @param value attribute value or segment */ -pa_tnc_attr_t* ietf_attr_create_from_data(u_int32_t type, chunk_t value); +pa_tnc_attr_t* ietf_attr_create_from_data(u_int32_t type, size_t length, + chunk_t value); #endif /** IETF_ATTR_H_ @}*/ diff --git a/src/libimcv/ietf/ietf_attr_assess_result.c b/src/libimcv/ietf/ietf_attr_assess_result.c index 55226e3bb..1cffdcaae 100644 --- a/src/libimcv/ietf/ietf_attr_assess_result.c +++ b/src/libimcv/ietf/ietf_attr_assess_result.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Andreas Steffen + * Copyright (C) 2012-2014 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -50,7 +50,12 @@ struct private_ietf_attr_assess_result_t { pen_type_t type; /** - * Attribute value + * Length of attribute value + */ + size_t length; + + /** + * Attribute value or segment */ chunk_t value; @@ -107,6 +112,7 @@ METHOD(pa_tnc_attr_t, build, void, writer = bio_writer_create(ASSESS_RESULT_SIZE); writer->write_uint32(writer, this->result); this->value = writer->extract_buf(writer); + this->length = this->value.len; writer->destroy(writer); } @@ -115,10 +121,15 @@ METHOD(pa_tnc_attr_t, process, status_t, { bio_reader_t *reader; + *offset = 0; + + if (this->value.len < this->length) + { + return NEED_MORE; + } if (this->value.len < ASSESS_RESULT_SIZE) { DBG1(DBG_TNC, "insufficient data for IETF assessment result"); - *offset = 0; return FAILED; } reader = bio_reader_create(this->value); @@ -128,6 +139,12 @@ METHOD(pa_tnc_attr_t, process, status_t, return SUCCESS; } +METHOD(pa_tnc_attr_t, add_segment, void, + private_ietf_attr_assess_result_t *this, chunk_t segment) +{ + this->value = chunk_cat("mc", this->value, segment); +} + METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*, private_ietf_attr_assess_result_t *this) { @@ -167,6 +184,7 @@ pa_tnc_attr_t *ietf_attr_assess_result_create(u_int32_t result) .set_noskip_flag = _set_noskip_flag, .build = _build, .process = _process, + .add_segment = _add_segment, .get_ref = _get_ref, .destroy = _destroy, }, @@ -183,7 +201,8 @@ pa_tnc_attr_t *ietf_attr_assess_result_create(u_int32_t result) /** * Described in header. */ -pa_tnc_attr_t *ietf_attr_assess_result_create_from_data(chunk_t data) +pa_tnc_attr_t *ietf_attr_assess_result_create_from_data(size_t length, + chunk_t data) { private_ietf_attr_assess_result_t *this; @@ -196,12 +215,14 @@ pa_tnc_attr_t *ietf_attr_assess_result_create_from_data(chunk_t data) .set_noskip_flag = _set_noskip_flag, .build = _build, .process = _process, + .add_segment = _add_segment, .get_ref = _get_ref, .destroy = _destroy, }, .get_result = _get_result, }, .type = { PEN_IETF, IETF_ATTR_ASSESSMENT_RESULT }, + .length = length, .value = chunk_clone(data), .ref = 1, ); diff --git a/src/libimcv/ietf/ietf_attr_assess_result.h b/src/libimcv/ietf/ietf_attr_assess_result.h index e94b57b88..b1a5166dc 100644 --- a/src/libimcv/ietf/ietf_attr_assess_result.h +++ b/src/libimcv/ietf/ietf_attr_assess_result.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Andreas Steffen + * Copyright (C) 2012-2014 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -56,8 +56,10 @@ pa_tnc_attr_t* ietf_attr_assess_result_create(u_int32_t result); /** * Creates an ietf_attr_assess_result_t object from received data * - * @param value unparsed attribute value + * @param length Total length of attribute value + * @param value Unparsed attribute value (might be a segment) */ -pa_tnc_attr_t* ietf_attr_assess_result_create_from_data(chunk_t value); +pa_tnc_attr_t* ietf_attr_assess_result_create_from_data(size_t length, + chunk_t value); #endif /** IETF_ATTR_ASSESS_RESULT_H_ @}*/ diff --git a/src/libimcv/ietf/ietf_attr_attr_request.c b/src/libimcv/ietf/ietf_attr_attr_request.c index 3b4fd26cd..3862a0aa8 100644 --- a/src/libimcv/ietf/ietf_attr_attr_request.c +++ b/src/libimcv/ietf/ietf_attr_attr_request.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Andreas Steffen + * Copyright (C) 2012-2014 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -59,7 +59,12 @@ struct private_ietf_attr_attr_request_t { pen_type_t type; /** - * Attribute value + * Length of attribute value + */ + size_t length; + + /** + * Attribute value or segment */ chunk_t value; @@ -126,6 +131,7 @@ METHOD(pa_tnc_attr_t, build, void, enumerator->destroy(enumerator); this->value = writer->extract_buf(writer); + this->length = this->value.len; writer->destroy(writer); } @@ -150,11 +156,17 @@ METHOD(pa_tnc_attr_t, process, status_t, u_int8_t reserved; int count; + *offset = 0; + + if (this->value.len < this->length) + { + return NEED_MORE; + } + count = this->value.len / ATTR_REQUEST_ENTRY_SIZE; if (this->value.len != ATTR_REQUEST_ENTRY_SIZE * count) { DBG1(DBG_TNC, "incorrect attribute length for IETF attribute request"); - *offset = 0; return FAILED; } @@ -184,6 +196,12 @@ METHOD(pa_tnc_attr_t, process, status_t, return SUCCESS; } +METHOD(pa_tnc_attr_t, add_segment, void, + private_ietf_attr_attr_request_t *this, chunk_t segment) +{ + this->value = chunk_cat("mc", this->value, segment); +} + METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*, private_ietf_attr_attr_request_t *this) { @@ -224,6 +242,7 @@ pa_tnc_attr_t *ietf_attr_attr_request_create(pen_t vendor_id, u_int32_t type) .set_noskip_flag = _set_noskip_flag, .build = _build, .process = _process, + .add_segment = _add_segment, .get_ref = _get_ref, .destroy = _destroy, }, @@ -246,7 +265,8 @@ pa_tnc_attr_t *ietf_attr_attr_request_create(pen_t vendor_id, u_int32_t type) /** * Described in header. */ -pa_tnc_attr_t *ietf_attr_attr_request_create_from_data(chunk_t data) +pa_tnc_attr_t *ietf_attr_attr_request_create_from_data(size_t length, + chunk_t data) { private_ietf_attr_attr_request_t *this; @@ -259,6 +279,7 @@ pa_tnc_attr_t *ietf_attr_attr_request_create_from_data(chunk_t data) .set_noskip_flag = _set_noskip_flag, .build = _build, .process = _process, + .add_segment = _add_segment, .get_ref = _get_ref, .destroy = _destroy, }, @@ -266,6 +287,7 @@ pa_tnc_attr_t *ietf_attr_attr_request_create_from_data(chunk_t data) .create_enumerator = _create_enumerator, }, .type = { PEN_IETF, IETF_ATTR_ATTRIBUTE_REQUEST }, + .length = length, .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 fc9e08676..47b038605 100644 --- a/src/libimcv/ietf/ietf_attr_attr_request.h +++ b/src/libimcv/ietf/ietf_attr_attr_request.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Andreas Steffen + * Copyright (C) 2012-2014 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -62,10 +62,10 @@ struct ietf_attr_attr_request_t { pa_tnc_attr_t* ietf_attr_attr_request_create(pen_t vendor_id, u_int32_t type); /** - * Creates an ietf_attr_attr_request_t object from received data - * - * @param value unparsed attribute value + * @param length Total length of attribute value + * @param value Unparsed attribute value (might be a segment) */ -pa_tnc_attr_t* ietf_attr_attr_request_create_from_data(chunk_t value); +pa_tnc_attr_t* ietf_attr_attr_request_create_from_data(size_t length, + chunk_t value); #endif /** IETF_ATTR_ATTR_REQUEST_H_ @}*/ diff --git a/src/libimcv/ietf/ietf_attr_default_pwd_enabled.c b/src/libimcv/ietf/ietf_attr_default_pwd_enabled.c index 2c6b3d542..ee5864d29 100644 --- a/src/libimcv/ietf/ietf_attr_default_pwd_enabled.c +++ b/src/libimcv/ietf/ietf_attr_default_pwd_enabled.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Andreas Steffen + * Copyright (C) 2012-2014 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -50,7 +50,12 @@ struct private_ietf_attr_default_pwd_enabled_t { pen_type_t type; /** - * Attribute value + * Length of attribute value + */ + size_t length; + + /** + * Attribute value or segment */ chunk_t value; @@ -107,6 +112,7 @@ METHOD(pa_tnc_attr_t, build, void, writer->write_uint32(writer, this->status); this->value = writer->extract_buf(writer); + this->length = this->value.len; writer->destroy(writer); } @@ -118,6 +124,10 @@ METHOD(pa_tnc_attr_t, process, status_t, *offset = 0; + if (this->value.len < this->length) + { + return NEED_MORE; + } if (this->value.len != DEFAULT_PWD_ENABLED_SIZE) { DBG1(DBG_TNC, "incorrect size for IETF factory default password " @@ -139,6 +149,12 @@ METHOD(pa_tnc_attr_t, process, status_t, return SUCCESS; } +METHOD(pa_tnc_attr_t, add_segment, void, + private_ietf_attr_default_pwd_enabled_t *this, chunk_t segment) +{ + this->value = chunk_cat("mc", this->value, segment); +} + METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*, private_ietf_attr_default_pwd_enabled_t *this) { @@ -178,6 +194,7 @@ pa_tnc_attr_t *ietf_attr_default_pwd_enabled_create(bool status) .set_noskip_flag = _set_noskip_flag, .build = _build, .process = _process, + .add_segment = _add_segment, .get_ref = _get_ref, .destroy = _destroy, }, @@ -194,7 +211,8 @@ pa_tnc_attr_t *ietf_attr_default_pwd_enabled_create(bool status) /** * Described in header. */ -pa_tnc_attr_t *ietf_attr_default_pwd_enabled_create_from_data(chunk_t data) +pa_tnc_attr_t *ietf_attr_default_pwd_enabled_create_from_data(size_t length, + chunk_t data) { private_ietf_attr_default_pwd_enabled_t *this; @@ -207,12 +225,14 @@ pa_tnc_attr_t *ietf_attr_default_pwd_enabled_create_from_data(chunk_t data) .set_noskip_flag = _set_noskip_flag, .build = _build, .process = _process, + .add_segment = _add_segment, .get_ref = _get_ref, .destroy = _destroy, }, .get_status = _get_status, }, .type = { PEN_IETF, IETF_ATTR_FACTORY_DEFAULT_PWD_ENABLED }, + .length = length, .value = chunk_clone(data), .ref = 1, ); diff --git a/src/libimcv/ietf/ietf_attr_default_pwd_enabled.h b/src/libimcv/ietf/ietf_attr_default_pwd_enabled.h index 6fe1a02b1..3999590d4 100644 --- a/src/libimcv/ietf/ietf_attr_default_pwd_enabled.h +++ b/src/libimcv/ietf/ietf_attr_default_pwd_enabled.h @@ -56,8 +56,10 @@ 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 + * @param length Total length of attribute value + * @param value Unparsed attribute value (might be a segment) */ -pa_tnc_attr_t* ietf_attr_default_pwd_enabled_create_from_data(chunk_t value); +pa_tnc_attr_t* ietf_attr_default_pwd_enabled_create_from_data(size_t length, + 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 index a906b2258..c00a5efc2 100644 --- a/src/libimcv/ietf/ietf_attr_fwd_enabled.c +++ b/src/libimcv/ietf/ietf_attr_fwd_enabled.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Andreas Steffen + * Copyright (C) 2012-2014 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -50,7 +50,12 @@ struct private_ietf_attr_fwd_enabled_t { pen_type_t type; /** - * Attribute value + * Length of attribute value + */ + size_t length; + + /** + * Attribute value or segment */ chunk_t value; @@ -107,6 +112,7 @@ METHOD(pa_tnc_attr_t, build, void, writer->write_uint32(writer, this->fwd_status); this->value = writer->extract_buf(writer); + this->length = this->value.len; writer->destroy(writer); } @@ -118,6 +124,10 @@ METHOD(pa_tnc_attr_t, process, status_t, *offset = 0; + if (this->value.len < this->length) + { + return NEED_MORE; + } if (this->value.len != FORWARDING_ENABLED_SIZE) { DBG1(DBG_TNC, "incorrect size for IETF forwarding enabled attribute"); @@ -138,6 +148,12 @@ METHOD(pa_tnc_attr_t, process, status_t, return SUCCESS; } +METHOD(pa_tnc_attr_t, add_segment, void, + private_ietf_attr_fwd_enabled_t *this, chunk_t segment) +{ + this->value = chunk_cat("mc", this->value, segment); +} + METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*, private_ietf_attr_fwd_enabled_t *this) { @@ -177,6 +193,7 @@ pa_tnc_attr_t *ietf_attr_fwd_enabled_create(os_fwd_status_t fwd_status) .set_noskip_flag = _set_noskip_flag, .build = _build, .process = _process, + .add_segment = _add_segment, .get_ref = _get_ref, .destroy = _destroy, }, @@ -193,7 +210,8 @@ pa_tnc_attr_t *ietf_attr_fwd_enabled_create(os_fwd_status_t fwd_status) /** * Described in header. */ -pa_tnc_attr_t *ietf_attr_fwd_enabled_create_from_data(chunk_t data) +pa_tnc_attr_t *ietf_attr_fwd_enabled_create_from_data(size_t length, + chunk_t data) { private_ietf_attr_fwd_enabled_t *this; @@ -206,12 +224,14 @@ pa_tnc_attr_t *ietf_attr_fwd_enabled_create_from_data(chunk_t data) .set_noskip_flag = _set_noskip_flag, .build = _build, .process = _process, + .add_segment = _add_segment, .get_ref = _get_ref, .destroy = _destroy, }, .get_status = _get_status, }, .type = { PEN_IETF, IETF_ATTR_FORWARDING_ENABLED }, + .length = length, .value = chunk_clone(data), .ref = 1, ); diff --git a/src/libimcv/ietf/ietf_attr_fwd_enabled.h b/src/libimcv/ietf/ietf_attr_fwd_enabled.h index 41714380e..c4b6c1547 100644 --- a/src/libimcv/ietf/ietf_attr_fwd_enabled.h +++ b/src/libimcv/ietf/ietf_attr_fwd_enabled.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Andreas Steffen + * Copyright (C) 2012-14 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -57,8 +57,10 @@ 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 + * @param length Total length of attribute value + * @param value Unparsed attribute value (might be a segment) */ -pa_tnc_attr_t* ietf_attr_fwd_enabled_create_from_data(chunk_t value); +pa_tnc_attr_t* ietf_attr_fwd_enabled_create_from_data(size_t length, + 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 index f33f643af..39eea555a 100644 --- a/src/libimcv/ietf/ietf_attr_installed_packages.c +++ b/src/libimcv/ietf/ietf_attr_installed_packages.c @@ -57,16 +57,36 @@ struct private_ietf_attr_installed_packages_t { pen_type_t type; /** - * Attribute value + * Length of attribute value + */ + size_t length; + + /** + * Offset up to which attribute value has been processed + */ + size_t offset; + + /** + * Current position of attribute value pointer */ chunk_t value; /** + * Contains complete attribute or current segment + */ + chunk_t segment; + + /** * Noskip flag */ bool noskip_flag; /** + * Number of Installed Packages in attribute + */ + uint16_t count; + + /** * List of Installed Package entries */ linked_list_t *packages; @@ -143,6 +163,8 @@ METHOD(pa_tnc_attr_t, build, void, enumerator->destroy(enumerator); this->value = writer->extract_buf(writer); + this->segment = this->value; + this->length = this->value.len; writer->destroy(writer); } @@ -151,72 +173,91 @@ METHOD(pa_tnc_attr_t, process, status_t, { bio_reader_t *reader; package_entry_t *entry; - status_t status = FAILED; + status_t status = NEED_MORE; chunk_t name, version; - u_int16_t reserved, count; + u_int16_t reserved; u_char *pos; - *offset = 0; - - if (this->value.len < IETF_INSTALLED_PACKAGES_MIN_SIZE) - { - DBG1(DBG_TNC, "insufficient data for IETF installed packages"); - return FAILED; + if (this->offset == 0) + { + if (this->length < IETF_INSTALLED_PACKAGES_MIN_SIZE) + { + DBG1(DBG_TNC, "insufficient data for %N/%N", pen_names, PEN_IETF, + ietf_attr_names, this->type.type); + *offset = this->offset; + return FAILED; + } + if (this->value.len < IETF_INSTALLED_PACKAGES_MIN_SIZE) + { + return NEED_MORE; + } + reader = bio_reader_create(this->value); + reader->read_uint16(reader, &reserved); + reader->read_uint16(reader, &this->count); + this->offset = IETF_INSTALLED_PACKAGES_MIN_SIZE; + this->value = reader->peek(reader); + reader->destroy(reader); } + reader = bio_reader_create(this->value); - reader->read_uint16(reader, &reserved); - reader->read_uint16(reader, &count); - *offset = IETF_INSTALLED_PACKAGES_MIN_SIZE; - while (reader->remaining(reader)) + while (this->count) { - if (!reader->read_data8(reader, &name)) + if (!reader->read_data8(reader, &name) || + !reader->read_data8(reader, &version)) { - 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"); + *offset = this->offset + 1 + (pos - name.ptr); + status = FAILED; 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); + *offset = this->offset + 1 + name.len + 1 + (pos - version.ptr); + status = FAILED; goto end; } - *offset += 1 + version.len; + this->offset += this->value.len - reader->remaining(reader); + this->value = reader->peek(reader); entry = malloc_thing(package_entry_t); entry->name = chunk_clone(name); entry->version = chunk_clone(version); this->packages->insert_last(this->packages, entry); + + /* at least one tag ID was processed */ + status = SUCCESS; + this->count--; } - if (count != this->packages->get_count(this->packages)) + if (this->length != this->offset) { - DBG1(DBG_TNC, "IETF installed package count unequal to " - "number of included packages"); - goto end; + DBG1(DBG_TNC, "inconsistent length for %N/%N", pen_names, PEN_IETF, + ietf_attr_names, this->type.type); + *offset = this->offset; + status = FAILED; } - status = SUCCESS; end: reader->destroy(reader); return status; } +METHOD(pa_tnc_attr_t, add_segment, void, + private_ietf_attr_installed_packages_t *this, chunk_t segment) +{ + this->value = chunk_cat("cc", this->value, segment); + chunk_free(&this->segment); + this->segment = this->value; +} + METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*, private_ietf_attr_installed_packages_t *this) { @@ -230,7 +271,7 @@ METHOD(pa_tnc_attr_t, destroy, void, if (ref_put(&this->ref)) { this->packages->destroy_function(this->packages, (void*)free_package_entry); - free(this->value.ptr); + free(this->segment.ptr); free(this); } } @@ -269,6 +310,23 @@ METHOD(ietf_attr_installed_packages_t, create_enumerator, enumerator_t*, (void*)package_filter, NULL, NULL); } +METHOD(ietf_attr_installed_packages_t, get_count, uint16_t, + private_ietf_attr_installed_packages_t *this) +{ + return this->count; +} + +METHOD(ietf_attr_installed_packages_t, clear_packages, void, + private_ietf_attr_installed_packages_t *this) +{ + package_entry_t *entry; + + while (this->packages->remove_first(this->packages,(void**)&entry) == SUCCESS) + { + free_package_entry(entry); + } +} + /** * Described in header. */ @@ -285,11 +343,14 @@ pa_tnc_attr_t *ietf_attr_installed_packages_create(void) .set_noskip_flag = _set_noskip_flag, .build = _build, .process = _process, + .add_segment = _add_segment, .get_ref = _get_ref, .destroy = _destroy, }, .add = _add, .create_enumerator = _create_enumerator, + .get_count = _get_count, + .clear_packages = _clear_packages, }, .type = { PEN_IETF, IETF_ATTR_INSTALLED_PACKAGES }, .packages = linked_list_create(), @@ -300,9 +361,11 @@ pa_tnc_attr_t *ietf_attr_installed_packages_create(void) } /** - * Described in header. + * Described in header. .length = length, + */ -pa_tnc_attr_t *ietf_attr_installed_packages_create_from_data(chunk_t data) +pa_tnc_attr_t *ietf_attr_installed_packages_create_from_data(size_t length, + chunk_t data) { private_ietf_attr_installed_packages_t *this; @@ -315,18 +378,25 @@ pa_tnc_attr_t *ietf_attr_installed_packages_create_from_data(chunk_t data) .set_noskip_flag = _set_noskip_flag, .build = _build, .process = _process, + .add_segment = _add_segment, .get_ref = _get_ref, .destroy = _destroy, }, .add = _add, .create_enumerator = _create_enumerator, + .get_count = _get_count, + .clear_packages = _clear_packages, }, .type = {PEN_IETF, IETF_ATTR_INSTALLED_PACKAGES }, - .value = chunk_clone(data), + .length = length, + .segment = chunk_clone(data), .packages = linked_list_create(), .ref = 1, ); + /* received either complete attribute value or first segment */ + this->value = this->segment; + 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 index e19d0f47b..9f7b7cbcf 100644 --- a/src/libimcv/ietf/ietf_attr_installed_packages.h +++ b/src/libimcv/ietf/ietf_attr_installed_packages.h @@ -56,6 +56,18 @@ struct ietf_attr_installed_packages_t { */ enumerator_t* (*create_enumerator)(ietf_attr_installed_packages_t *this); + /** + * Number of Installed Packages still missing + * + * @return Number of missing installed packages + */ + uint16_t (*get_count)(ietf_attr_installed_packages_t *this); + + /** + * Remove all Installed Packages from list + */ + void (*clear_packages)(ietf_attr_installed_packages_t *this); + }; /** @@ -67,8 +79,10 @@ 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 + * @param length Total length of attribute value + * @param value Unparsed attribute value (might be a segment) */ -pa_tnc_attr_t* ietf_attr_installed_packages_create_from_data(chunk_t value); +pa_tnc_attr_t* ietf_attr_installed_packages_create_from_data(size_t length, + 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 index 739256457..c8fd6c1ca 100644 --- a/src/libimcv/ietf/ietf_attr_numeric_version.c +++ b/src/libimcv/ietf/ietf_attr_numeric_version.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Andreas Steffen + * Copyright (C) 2012-2014 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -56,7 +56,12 @@ struct private_ietf_attr_numeric_version_t { pen_type_t type; /** - * Attribute value + * Length of attribute value + */ + size_t length; + + /** + * Attribute value or segment */ chunk_t value; @@ -138,6 +143,7 @@ METHOD(pa_tnc_attr_t, build, void, writer->write_uint16(writer, this->service_pack_minor); this->value = writer->extract_buf(writer); + this->length = this->value.len; writer->destroy(writer); } @@ -146,10 +152,15 @@ METHOD(pa_tnc_attr_t, process, status_t, { bio_reader_t *reader; + *offset = 0; + + if (this->value.len < this->length) + { + return NEED_MORE; + } 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); @@ -163,6 +174,12 @@ METHOD(pa_tnc_attr_t, process, status_t, return SUCCESS; } +METHOD(pa_tnc_attr_t, add_segment, void, + private_ietf_attr_numeric_version_t *this, chunk_t segment) +{ + this->value = chunk_cat("mc", this->value, segment); +} + METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*, private_ietf_attr_numeric_version_t *this) { @@ -231,6 +248,7 @@ pa_tnc_attr_t *ietf_attr_numeric_version_create(u_int32_t major, u_int32_t minor .set_noskip_flag = _set_noskip_flag, .build = _build, .process = _process, + .add_segment = _add_segment, .get_ref = _get_ref, .destroy = _destroy, }, @@ -253,7 +271,8 @@ pa_tnc_attr_t *ietf_attr_numeric_version_create(u_int32_t major, u_int32_t minor /** * Described in header. */ -pa_tnc_attr_t *ietf_attr_numeric_version_create_from_data(chunk_t data) +pa_tnc_attr_t *ietf_attr_numeric_version_create_from_data(size_t length, + chunk_t data) { private_ietf_attr_numeric_version_t *this; @@ -266,6 +285,7 @@ pa_tnc_attr_t *ietf_attr_numeric_version_create_from_data(chunk_t data) .set_noskip_flag = _set_noskip_flag, .build = _build, .process = _process, + .add_segment = _add_segment, .get_ref = _get_ref, .destroy = _destroy, }, @@ -274,6 +294,7 @@ pa_tnc_attr_t *ietf_attr_numeric_version_create_from_data(chunk_t data) .get_service_pack = _get_service_pack, }, .type = { PEN_IETF, IETF_ATTR_NUMERIC_VERSION }, + .length = length, .value = chunk_clone(data), .ref = 1, ); diff --git a/src/libimcv/ietf/ietf_attr_numeric_version.h b/src/libimcv/ietf/ietf_attr_numeric_version.h index bbda6b895..34393c673 100644 --- a/src/libimcv/ietf/ietf_attr_numeric_version.h +++ b/src/libimcv/ietf/ietf_attr_numeric_version.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Andreas Steffen + * Copyright (C) 2012-14 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -77,8 +77,10 @@ pa_tnc_attr_t* ietf_attr_numeric_version_create(u_int32_t major, u_int32_t minor /** * Creates an ietf_attr_numeric_version_t object from received data * - * @param value unparsed attribute value + * @param length Total length of attribute value + * @param value Unparsed attribute value (might be a segment) */ -pa_tnc_attr_t* ietf_attr_numeric_version_create_from_data(chunk_t value); +pa_tnc_attr_t* ietf_attr_numeric_version_create_from_data(size_t length, + 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 index 23530684a..d061a52f9 100644 --- a/src/libimcv/ietf/ietf_attr_op_status.c +++ b/src/libimcv/ietf/ietf_attr_op_status.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Andreas Steffen + * Copyright (C) 2012-2014 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -76,7 +76,12 @@ struct private_ietf_attr_op_status_t { pen_type_t type; /** - * Attribute value + * Length of attribute value + */ + size_t length; + + /** + * Attribute value or segment */ chunk_t value; @@ -154,6 +159,7 @@ METHOD(pa_tnc_attr_t, build, void, writer->write_data (writer, chunk_create(last_use, 20)); this->value = writer->extract_buf(writer); + this->length = this->value.len; writer->destroy(writer); } @@ -167,6 +173,10 @@ METHOD(pa_tnc_attr_t, process, status_t, *offset = 0; + if (this->value.len < this->length) + { + return NEED_MORE; + } if (this->value.len != OP_STATUS_SIZE) { DBG1(DBG_TNC, "incorrect size for IETF operational status"); @@ -212,6 +222,12 @@ METHOD(pa_tnc_attr_t, process, status_t, return SUCCESS; } +METHOD(pa_tnc_attr_t, add_segment, void, + private_ietf_attr_op_status_t *this, chunk_t segment) +{ + this->value = chunk_cat("mc", this->value, segment); +} + METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*, private_ietf_attr_op_status_t *this) { @@ -264,6 +280,7 @@ pa_tnc_attr_t *ietf_attr_op_status_create(u_int8_t status, u_int8_t result, .set_noskip_flag = _set_noskip_flag, .build = _build, .process = _process, + .add_segment = _add_segment, .get_ref = _get_ref, .destroy = _destroy, }, @@ -284,7 +301,7 @@ pa_tnc_attr_t *ietf_attr_op_status_create(u_int8_t status, u_int8_t result, /** * Described in header. */ -pa_tnc_attr_t *ietf_attr_op_status_create_from_data(chunk_t data) +pa_tnc_attr_t *ietf_attr_op_status_create_from_data(size_t length, chunk_t data) { private_ietf_attr_op_status_t *this; @@ -297,6 +314,7 @@ pa_tnc_attr_t *ietf_attr_op_status_create_from_data(chunk_t data) .set_noskip_flag = _set_noskip_flag, .build = _build, .process = _process, + .add_segment = _add_segment, .get_ref = _get_ref, .destroy = _destroy, }, diff --git a/src/libimcv/ietf/ietf_attr_op_status.h b/src/libimcv/ietf/ietf_attr_op_status.h index b70fab608..f19185f0a 100644 --- a/src/libimcv/ietf/ietf_attr_op_status.h +++ b/src/libimcv/ietf/ietf_attr_op_status.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Andreas Steffen + * Copyright (C) 2012-14 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -100,8 +100,10 @@ pa_tnc_attr_t* ietf_attr_op_status_create(u_int8_t status, u_int8_t result, /** * Creates an ietf_attr_op_status_t object from received data * - * @param value unparsed attribute value + * @param length Total length of attribute value + * @param value Unparsed attribute value (might be a segment) */ -pa_tnc_attr_t* ietf_attr_op_status_create_from_data(chunk_t value); +pa_tnc_attr_t* ietf_attr_op_status_create_from_data(size_t length, + 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 5f20f8958..0dbb4aaef 100644 --- a/src/libimcv/ietf/ietf_attr_pa_tnc_error.c +++ b/src/libimcv/ietf/ietf_attr_pa_tnc_error.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011-2012 Andreas Steffen + * Copyright (C) 2011-2014 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -113,7 +113,12 @@ struct private_ietf_attr_pa_tnc_error_t { pen_type_t type; /** - * Attribute value + * Length of attribute value + */ + size_t length; + + /** + * Attribute value or segment */ chunk_t value; @@ -133,14 +138,19 @@ struct private_ietf_attr_pa_tnc_error_t { chunk_t msg_info; /** - * First 8 bytes of unsupported PA-TNC attribute + * Flags of unsupported PA-TNC attribute + */ + uint8_t flags; + + /** + * Vendor ID and type of unsupported PA-TNC attribute */ - chunk_t attr_info; + pen_type_t unsupported_type; /** * PA-TNC error offset */ - u_int32_t error_offset; + uint32_t error_offset; /** * Reference count @@ -200,26 +210,35 @@ METHOD(pa_tnc_attr_t, build, void, writer->write_uint16(writer, PA_ERROR_VERSION_RESERVED); break; case PA_ERROR_ATTR_TYPE_NOT_SUPPORTED: - writer->write_data(writer, this->attr_info); + writer->write_uint8 (writer, this->flags); + writer->write_uint24(writer, this->unsupported_type.vendor_id); + writer->write_uint32(writer, this->unsupported_type.type); break; default: break; } } this->value = writer->extract_buf(writer); + this->length = this->value.len; writer->destroy(writer); } METHOD(pa_tnc_attr_t, process, status_t, - private_ietf_attr_pa_tnc_error_t *this, u_int32_t *offset) + private_ietf_attr_pa_tnc_error_t *this, uint32_t *offset) { bio_reader_t *reader; - u_int8_t reserved; + uint8_t reserved; + uint32_t vendor_id, type; + *offset = 0; + + if (this->value.len < this->length) + { + return NEED_MORE; + } 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); @@ -250,8 +269,7 @@ METHOD(pa_tnc_attr_t, process, status_t, } break; case PA_ERROR_ATTR_TYPE_NOT_SUPPORTED: - if (!reader->read_data(reader, PA_ERROR_ATTR_INFO_SIZE, - &this->attr_info)) + if (reader->remaining(reader) < PA_ERROR_ATTR_INFO_SIZE) { reader->destroy(reader); DBG1(DBG_TNC, "insufficient data for unsupported attribute " @@ -259,7 +277,10 @@ METHOD(pa_tnc_attr_t, process, status_t, *offset = PA_ERROR_HEADER_SIZE + PA_ERROR_MSG_INFO_SIZE; return FAILED; } - this->attr_info = chunk_clone(this->attr_info); + reader->read_uint8 (reader, &this->flags); + reader->read_uint24(reader, &vendor_id); + reader->read_uint32(reader, &type); + this->unsupported_type = pen_type_create(vendor_id, type); break; default: break; @@ -275,6 +296,12 @@ METHOD(pa_tnc_attr_t, process, status_t, return SUCCESS; } +METHOD(pa_tnc_attr_t, add_segment, void, + private_ietf_attr_pa_tnc_error_t *this, chunk_t segment) +{ + this->value = chunk_cat("mc", this->value, segment); +} + METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*, private_ietf_attr_pa_tnc_error_t *this) { @@ -289,7 +316,6 @@ METHOD(pa_tnc_attr_t, destroy, void, { free(this->value.ptr); free(this->msg_info.ptr); - free(this->attr_info.ptr); free(this); } } @@ -306,19 +332,24 @@ METHOD(ietf_attr_pa_tnc_error_t, get_msg_info, chunk_t, return this->msg_info; } -METHOD(ietf_attr_pa_tnc_error_t, get_attr_info, chunk_t, - private_ietf_attr_pa_tnc_error_t *this) +METHOD(ietf_attr_pa_tnc_error_t, get_unsupported_attr, pen_type_t, + private_ietf_attr_pa_tnc_error_t *this, uint8_t *flags) { - return this->attr_info; + if (flags) + { + *flags = this->flags; + } + return this->unsupported_type; } -METHOD(ietf_attr_pa_tnc_error_t, set_attr_info, void, - private_ietf_attr_pa_tnc_error_t *this, chunk_t attr_info) +METHOD(ietf_attr_pa_tnc_error_t, set_unsupported_attr, void, + private_ietf_attr_pa_tnc_error_t *this, uint8_t flags, pen_type_t type) { - this->attr_info = chunk_clone(attr_info); + this->flags = flags; + this->unsupported_type = type; } -METHOD(ietf_attr_pa_tnc_error_t, get_offset, u_int32_t, +METHOD(ietf_attr_pa_tnc_error_t, get_offset, uint32_t, private_ietf_attr_pa_tnc_error_t *this) { return this->error_offset; @@ -340,13 +371,14 @@ static private_ietf_attr_pa_tnc_error_t* create_generic() .set_noskip_flag = _set_noskip_flag, .build = _build, .process = _process, + .add_segment = _add_segment, .get_ref = _get_ref, .destroy = _destroy, }, .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_unsupported_attr = _get_unsupported_attr, + .set_unsupported_attr = _set_unsupported_attr, .get_offset = _get_offset, }, .type = { PEN_IETF, IETF_ATTR_PA_TNC_ERROR }, @@ -385,7 +417,7 @@ pa_tnc_attr_t *ietf_attr_pa_tnc_error_create(pen_type_t error_code, */ pa_tnc_attr_t *ietf_attr_pa_tnc_error_create_with_offset(pen_type_t error_code, chunk_t msg_info, - u_int32_t error_offset) + uint32_t error_offset) { private_ietf_attr_pa_tnc_error_t *this; @@ -403,11 +435,13 @@ pa_tnc_attr_t *ietf_attr_pa_tnc_error_create_with_offset(pen_type_t error_code, /** * Described in header. */ -pa_tnc_attr_t *ietf_attr_pa_tnc_error_create_from_data(chunk_t data) +pa_tnc_attr_t *ietf_attr_pa_tnc_error_create_from_data(size_t length, + chunk_t data) { private_ietf_attr_pa_tnc_error_t *this; this = create_generic(); + this->length = length; this->value = chunk_clone(data); 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 index faa38f8f9..b1df1945a 100644 --- a/src/libimcv/ietf/ietf_attr_pa_tnc_error.h +++ b/src/libimcv/ietf/ietf_attr_pa_tnc_error.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011-2012 Andreas Steffen + * Copyright (C) 2011-2014 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -69,25 +69,29 @@ struct ietf_attr_pa_tnc_error_t { chunk_t (*get_msg_info)(ietf_attr_pa_tnc_error_t *this); /** - * Get first 8 bytes of unsupported PA-TNC attribute + * Get flags, vendor ID and type of unsupported PA-TNC attribute * - * @return PA-TNC attribute info + * @param flags PA-TNC attribute flags + * @return PA-TNC attribute vendor ID and type */ - chunk_t (*get_attr_info)(ietf_attr_pa_tnc_error_t *this); + pen_type_t (*get_unsupported_attr)(ietf_attr_pa_tnc_error_t *this, + uint8_t *flags); /** - * Set first 8 bytes of unsupported PA-TNC attribute + * Set flags, vendor ID and type of unsupported PA-TNC attribute * - * @param attr_info PA-TNC message info + * @param flags PA-TNC attribute flags + * @param attr_info PA-TNC attribute vendor ID and type */ - void (*set_attr_info)(ietf_attr_pa_tnc_error_t *this, chunk_t attr_info); + void (*set_unsupported_attr)(ietf_attr_pa_tnc_error_t *this, uint8_t flags, + pen_type_t type); /** * Get the PA-TNC error offset * * @return PA-TNC error offset */ - u_int32_t (*get_offset)(ietf_attr_pa_tnc_error_t *this); + uint32_t (*get_offset)(ietf_attr_pa_tnc_error_t *this); }; @@ -111,13 +115,15 @@ pa_tnc_attr_t* ietf_attr_pa_tnc_error_create(pen_type_t error_code, */ pa_tnc_attr_t* ietf_attr_pa_tnc_error_create_with_offset(pen_type_t error_code, chunk_t header, - u_int32_t error_offset); + uint32_t error_offset); /** * Creates an ietf_attr_pa_tnc_error_t object from received data * - * @param value unparsed attribute value + * @param length Total length of attribute value + * @param value Unparsed attribute value (might be a segment) */ -pa_tnc_attr_t* ietf_attr_pa_tnc_error_create_from_data(chunk_t value); +pa_tnc_attr_t* ietf_attr_pa_tnc_error_create_from_data(size_t length, + 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 index 1d516a51f..46824406a 100644 --- a/src/libimcv/ietf/ietf_attr_port_filter.c +++ b/src/libimcv/ietf/ietf_attr_port_filter.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2011 Andreas Steffen, HSR Hochschule fuer Technik Rapperswil + * Copyright (C) 2011-2014 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 @@ -63,7 +64,12 @@ struct private_ietf_attr_port_filter_t { pen_type_t type; /** - * Attribute value + * Length of attribute value + */ + size_t length; + + /** + * Attribute value or segment */ chunk_t value; @@ -131,6 +137,7 @@ METHOD(pa_tnc_attr_t, build, void, enumerator->destroy(enumerator); this->value = writer->extract_buf(writer); + this->length = this->value.len; writer->destroy(writer); } @@ -141,11 +148,16 @@ METHOD(pa_tnc_attr_t, process, status_t, port_entry_t *entry; u_int8_t blocked; + *offset = 0; + + if (this->value.len < this->length) + { + return NEED_MORE; + } 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); @@ -164,6 +176,12 @@ METHOD(pa_tnc_attr_t, process, status_t, return SUCCESS; } +METHOD(pa_tnc_attr_t, add_segment, void, + private_ietf_attr_port_filter_t *this, chunk_t segment) +{ + this->value = chunk_cat("mc", this->value, segment); +} + METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*, private_ietf_attr_port_filter_t *this) { @@ -231,6 +249,7 @@ pa_tnc_attr_t *ietf_attr_port_filter_create(void) .set_noskip_flag = _set_noskip_flag, .build = _build, .process = _process, + .add_segment = _add_segment, .get_ref = _get_ref, .destroy = _destroy, }, @@ -248,7 +267,8 @@ pa_tnc_attr_t *ietf_attr_port_filter_create(void) /** * Described in header. */ -pa_tnc_attr_t *ietf_attr_port_filter_create_from_data(chunk_t data) +pa_tnc_attr_t *ietf_attr_port_filter_create_from_data(size_t length, + chunk_t data) { private_ietf_attr_port_filter_t *this; @@ -261,6 +281,7 @@ pa_tnc_attr_t *ietf_attr_port_filter_create_from_data(chunk_t data) .set_noskip_flag = _set_noskip_flag, .build = _build, .process = _process, + .add_segment = _add_segment, .get_ref = _get_ref, .destroy = _destroy, }, @@ -268,6 +289,7 @@ pa_tnc_attr_t *ietf_attr_port_filter_create_from_data(chunk_t data) .create_port_enumerator = _create_port_enumerator, }, .type = {PEN_IETF, IETF_ATTR_PORT_FILTER }, + .length = length, .value = chunk_clone(data), .ports = linked_list_create(), .ref = 1, diff --git a/src/libimcv/ietf/ietf_attr_port_filter.h b/src/libimcv/ietf/ietf_attr_port_filter.h index 93b696e45..d383b19a2 100644 --- a/src/libimcv/ietf/ietf_attr_port_filter.h +++ b/src/libimcv/ietf/ietf_attr_port_filter.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 Andreas Steffen + * Copyright (C) 2011-2014 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -67,8 +67,10 @@ 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 + * @param length Total length of attribute value + * @param value Unparsed attribute value (might be a segment) */ -pa_tnc_attr_t* ietf_attr_port_filter_create_from_data(chunk_t value); +pa_tnc_attr_t* ietf_attr_port_filter_create_from_data(size_t length, + 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 index a107c27d3..37c89e9e5 100644 --- a/src/libimcv/ietf/ietf_attr_product_info.c +++ b/src/libimcv/ietf/ietf_attr_product_info.c @@ -1,5 +1,6 @@ /* - * Copyright (C) 2011 Andreas Steffen, HSR Hochschule fuer Technik Rapperswil + * Copyright (C) 2011-2014 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 @@ -51,7 +52,12 @@ struct private_ietf_attr_product_info_t { pen_type_t type; /** - * Attribute value + * Length of attribute value + */ + size_t length; + + /** + * Attribute value or segment */ chunk_t value; @@ -120,6 +126,7 @@ METHOD(pa_tnc_attr_t, build, void, writer->write_data (writer, this->product_name); this->value = writer->extract_buf(writer); + this->length = this->value.len; writer->destroy(writer); } @@ -129,10 +136,15 @@ METHOD(pa_tnc_attr_t, process, status_t, bio_reader_t *reader; chunk_t product_name; + *offset = 0; + + if (this->value.len < this->length) + { + return NEED_MORE; + } 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); @@ -153,6 +165,12 @@ METHOD(pa_tnc_attr_t, process, status_t, return SUCCESS; } +METHOD(pa_tnc_attr_t, add_segment, void, + private_ietf_attr_product_info_t *this, chunk_t segment) +{ + this->value = chunk_cat("mc", this->value, segment); +} + METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*, private_ietf_attr_product_info_t *this) { @@ -202,6 +220,7 @@ pa_tnc_attr_t *ietf_attr_product_info_create(pen_t vendor_id, u_int16_t id, .set_noskip_flag = _set_noskip_flag, .build = _build, .process = _process, + .add_segment = _add_segment, .get_ref = _get_ref, .destroy = _destroy, }, @@ -220,7 +239,8 @@ pa_tnc_attr_t *ietf_attr_product_info_create(pen_t vendor_id, u_int16_t id, /** * Described in header. */ -pa_tnc_attr_t *ietf_attr_product_info_create_from_data(chunk_t data) +pa_tnc_attr_t *ietf_attr_product_info_create_from_data(size_t length, + chunk_t data) { private_ietf_attr_product_info_t *this; @@ -233,12 +253,14 @@ pa_tnc_attr_t *ietf_attr_product_info_create_from_data(chunk_t data) .set_noskip_flag = _set_noskip_flag, .build = _build, .process = _process, + .add_segment = _add_segment, .get_ref = _get_ref, .destroy = _destroy, }, .get_info = _get_info, }, .type = { PEN_IETF, IETF_ATTR_PRODUCT_INFORMATION }, + .length = length, .value = chunk_clone(data), .ref = 1, ); diff --git a/src/libimcv/ietf/ietf_attr_product_info.h b/src/libimcv/ietf/ietf_attr_product_info.h index d0b2d2a84..5151b5808 100644 --- a/src/libimcv/ietf/ietf_attr_product_info.h +++ b/src/libimcv/ietf/ietf_attr_product_info.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 Andreas Steffen + * Copyright (C) 2011-2014 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -60,8 +60,10 @@ pa_tnc_attr_t* ietf_attr_product_info_create(pen_t vendor_id, u_int16_t id, /** * Creates an ietf_attr_product_info_t object from received data * - * @param value unparsed attribute value + * @param length Total length of attribute value + * @param value Unparsed attribute value (might be a segment) */ -pa_tnc_attr_t* ietf_attr_product_info_create_from_data(chunk_t value); +pa_tnc_attr_t* ietf_attr_product_info_create_from_data(size_t length, + chunk_t value); #endif /** IETF_ATTR_PRODUCT_INFO_H_ @}*/ diff --git a/src/libimcv/ietf/ietf_attr_remediation_instr.c b/src/libimcv/ietf/ietf_attr_remediation_instr.c index 5d85e5d89..64070374e 100644 --- a/src/libimcv/ietf/ietf_attr_remediation_instr.c +++ b/src/libimcv/ietf/ietf_attr_remediation_instr.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Andreas Steffen + * Copyright (C) 2012-2014 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -79,7 +79,12 @@ struct private_ietf_attr_remediation_instr_t { pen_type_t type; /** - * Attribute value + * Length of attribute value + */ + size_t length; + + /** + * Attribute value or segment */ chunk_t value; @@ -155,6 +160,7 @@ METHOD(pa_tnc_attr_t, build, void, writer->write_data (writer, this->parameters); this->value = writer->extract_buf(writer); + this->length = this->value.len; writer->destroy(writer); } @@ -168,6 +174,10 @@ METHOD(pa_tnc_attr_t, process, status_t, *offset = 0; + if (this->value.len < this->length) + { + return NEED_MORE; + } if (this->value.len < REMEDIATION_INSTR_MIN_SIZE) { DBG1(DBG_TNC, "insufficient data for IETF remediation instructions"); @@ -218,6 +228,12 @@ end: return status; } +METHOD(pa_tnc_attr_t, add_segment, void, + private_ietf_attr_remediation_instr_t *this, chunk_t segment) +{ + this->value = chunk_cat("mc", this->value, segment); +} + METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*, private_ietf_attr_remediation_instr_t *this) { @@ -275,6 +291,7 @@ pa_tnc_attr_t *ietf_attr_remediation_instr_create(pen_type_t parameters_type, .set_noskip_flag = _set_noskip_flag, .build = _build, .process = _process, + .add_segment = _add_segment, .get_ref = _get_ref, .destroy = _destroy, }, @@ -328,7 +345,8 @@ pa_tnc_attr_t *ietf_attr_remediation_instr_create_from_string(chunk_t string, /** * Described in header. */ -pa_tnc_attr_t *ietf_attr_remediation_instr_create_from_data(chunk_t data) +pa_tnc_attr_t *ietf_attr_remediation_instr_create_from_data(size_t length, + chunk_t data) { private_ietf_attr_remediation_instr_t *this; @@ -341,6 +359,7 @@ pa_tnc_attr_t *ietf_attr_remediation_instr_create_from_data(chunk_t data) .set_noskip_flag = _set_noskip_flag, .build = _build, .process = _process, + .add_segment = _add_segment, .get_ref = _get_ref, .destroy = _destroy, }, @@ -350,6 +369,7 @@ pa_tnc_attr_t *ietf_attr_remediation_instr_create_from_data(chunk_t data) .get_string = _get_string, }, .type = { PEN_IETF, IETF_ATTR_REMEDIATION_INSTRUCTIONS }, + .length = length, .value = chunk_clone(data), .ref = 1, ); diff --git a/src/libimcv/ietf/ietf_attr_remediation_instr.h b/src/libimcv/ietf/ietf_attr_remediation_instr.h index 5c7c8891b..bc03e995a 100644 --- a/src/libimcv/ietf/ietf_attr_remediation_instr.h +++ b/src/libimcv/ietf/ietf_attr_remediation_instr.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Andreas Steffen + * Copyright (C) 2012-2014 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -102,8 +102,10 @@ pa_tnc_attr_t* ietf_attr_remediation_instr_create_from_string(chunk_t string, /** * Creates an ietf_attr_remediation_instr_t object from received data * - * @param value unparsed attribute value + * @param length Total length of attribute value + * @param value Unparsed attribute value (might be a segment) */ -pa_tnc_attr_t* ietf_attr_remediation_instr_create_from_data(chunk_t value); +pa_tnc_attr_t* ietf_attr_remediation_instr_create_from_data(size_t length, + 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 index 68adde612..c46200b8f 100644 --- a/src/libimcv/ietf/ietf_attr_string_version.c +++ b/src/libimcv/ietf/ietf_attr_string_version.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Andreas Steffen + * Copyright (C) 2012-2014 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -54,7 +54,12 @@ struct private_ietf_attr_string_version_t { pen_type_t type; /** - * Attribute value + * Length of attribute value + */ + size_t length; + + /** + * Attribute value or segment */ chunk_t value; @@ -124,6 +129,7 @@ METHOD(pa_tnc_attr_t, build, void, writer->write_data8(writer, this->config); this->value = writer->extract_buf(writer); + this->length = this->value.len; writer->destroy(writer); } @@ -137,6 +143,10 @@ METHOD(pa_tnc_attr_t, process, status_t, *offset = 0; + if (this->value.len < this->length) + { + return NEED_MORE; + } if (this->value.len < STRING_VERSION_MIN_SIZE) { DBG1(DBG_TNC, "insufficient data for IETF string version"); @@ -198,6 +208,12 @@ end: return status; } +METHOD(pa_tnc_attr_t, add_segment, void, + private_ietf_attr_string_version_t *this, chunk_t segment) +{ + this->value = chunk_cat("mc", this->value, segment); +} + METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*, private_ietf_attr_string_version_t *this) { @@ -254,6 +270,7 @@ pa_tnc_attr_t *ietf_attr_string_version_create(chunk_t version, chunk_t build, .set_noskip_flag = _set_noskip_flag, .build = _build, .process = _process, + .add_segment = _add_segment, .get_ref = _get_ref, .destroy = _destroy, }, @@ -272,7 +289,8 @@ pa_tnc_attr_t *ietf_attr_string_version_create(chunk_t version, chunk_t build, /** * Described in header. */ -pa_tnc_attr_t *ietf_attr_string_version_create_from_data(chunk_t data) +pa_tnc_attr_t *ietf_attr_string_version_create_from_data(size_t length, + chunk_t data) { private_ietf_attr_string_version_t *this; @@ -285,12 +303,14 @@ pa_tnc_attr_t *ietf_attr_string_version_create_from_data(chunk_t data) .set_noskip_flag = _set_noskip_flag, .build = _build, .process = _process, + .add_segment = _add_segment, .get_ref = _get_ref, .destroy = _destroy, }, .get_version = _get_version, }, .type = { PEN_IETF, IETF_ATTR_STRING_VERSION }, + .length = length, .value = chunk_clone(data), .ref = 1, ); diff --git a/src/libimcv/ietf/ietf_attr_string_version.h b/src/libimcv/ietf/ietf_attr_string_version.h index 9ccc1f0ee..432ed4a0f 100644 --- a/src/libimcv/ietf/ietf_attr_string_version.h +++ b/src/libimcv/ietf/ietf_attr_string_version.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Andreas Steffen + * Copyright (C) 2012-2014 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -60,8 +60,10 @@ pa_tnc_attr_t* ietf_attr_string_version_create(chunk_t version, chunk_t build, /** * Creates an ietf_attr_string_version_t object from received data * - * @param value unparsed attribute value + * @param length Total length of attribute value + * @param value Unparsed attribute value (might be a segment) */ -pa_tnc_attr_t* ietf_attr_string_version_create_from_data(chunk_t value); +pa_tnc_attr_t* ietf_attr_string_version_create_from_data(size_t length, + chunk_t value); #endif /** IETF_ATTR_STRING_VERSION_H_ @}*/ |