From: Andreas Steffen Date: Wed, 16 Jul 2014 13:56:09 +0000 (+0200) Subject: Determine type of unsupported PA-TNC attribute in error message X-Git-Tag: 5.2.1dr1~121 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3b96147353a2cacc25aa7a33f398edad04b29255;p=thirdparty%2Fstrongswan.git Determine type of unsupported PA-TNC attribute in error message --- diff --git a/src/libimcv/ietf/ietf_attr_pa_tnc_error.c b/src/libimcv/ietf/ietf_attr_pa_tnc_error.c index 5f20f89587..f299df22a7 100644 --- a/src/libimcv/ietf/ietf_attr_pa_tnc_error.c +++ b/src/libimcv/ietf/ietf_attr_pa_tnc_error.c @@ -133,14 +133,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 */ - chunk_t attr_info; + uint8_t flags; + + /** + * Vendor ID and type of unsupported PA-TNC attribute + */ + pen_type_t unsupported_type; /** * PA-TNC error offset */ - u_int32_t error_offset; + uint32_t error_offset; /** * Reference count @@ -200,7 +205,9 @@ 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; @@ -211,10 +218,11 @@ METHOD(pa_tnc_attr_t, build, void, } 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; if (this->value.len < PA_ERROR_HEADER_SIZE) { @@ -250,8 +258,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 +266,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; @@ -289,7 +299,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 +315,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; @@ -345,8 +359,8 @@ static private_ietf_attr_pa_tnc_error_t* create_generic() }, .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 +399,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; diff --git a/src/libimcv/ietf/ietf_attr_pa_tnc_error.h b/src/libimcv/ietf/ietf_attr_pa_tnc_error.h index faa38f8f92..47588d55e8 100644 --- a/src/libimcv/ietf/ietf_attr_pa_tnc_error.h +++ b/src/libimcv/ietf/ietf_attr_pa_tnc_error.h @@ -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,7 +115,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 header, - u_int32_t error_offset); + uint32_t error_offset); /** * Creates an ietf_attr_pa_tnc_error_t object from received data diff --git a/src/libimcv/pa_tnc/pa_tnc_msg.c b/src/libimcv/pa_tnc/pa_tnc_msg.c index 77d383b931..fa4ee008e5 100644 --- a/src/libimcv/pa_tnc/pa_tnc_msg.c +++ b/src/libimcv/pa_tnc/pa_tnc_msg.c @@ -236,13 +236,12 @@ METHOD(pa_tnc_msg_t, process, status_t, pen_t vendor_id; uint8_t flags; uint32_t type, length; - chunk_t value, attr_info; + chunk_t value; pa_tnc_attr_t *attr; enum_name_t *pa_attr_names; ietf_attr_pa_tnc_error_t *error_attr; + pen_type_t unsupported_type; - attr_info = reader->peek(reader); - attr_info.len = PA_TNC_ATTR_INFO_SIZE; reader->read_uint8 (reader, &flags); reader->read_uint24(reader, &vendor_id); reader->read_uint32(reader, &type); @@ -297,23 +296,21 @@ METHOD(pa_tnc_msg_t, process, status_t, vendor_id, type, value); if (!attr) { - if (flags & PA_TNC_ATTR_FLAG_NOSKIP) - { - DBG1(DBG_TNC, "unsupported PA-TNC attribute with NOSKIP flag"); - error_code = pen_type_create(PEN_IETF, - PA_ERROR_ATTR_TYPE_NOT_SUPPORTED); - error = ietf_attr_pa_tnc_error_create(error_code, - this->encoding); - error_attr = (ietf_attr_pa_tnc_error_t*)error; - error_attr->set_attr_info(error_attr, attr_info); - goto err; - } - else + if (!(flags & PA_TNC_ATTR_FLAG_NOSKIP)) { DBG1(DBG_TNC, "skipping unsupported PA-TNC attribute"); offset += length; continue; } + + DBG1(DBG_TNC, "unsupported PA-TNC attribute with NOSKIP flag"); + unsupported_type = pen_type_create(vendor_id, type); + error_code = pen_type_create(PEN_IETF, + PA_ERROR_ATTR_TYPE_NOT_SUPPORTED); + error = ietf_attr_pa_tnc_error_create(error_code, this->encoding); + error_attr = (ietf_attr_pa_tnc_error_t*)error; + error_attr->set_unsupported_attr(error_attr, flags, unsupported_type); + goto err; } if (attr->process(attr, &attr_offset) != SUCCESS) @@ -355,8 +352,10 @@ METHOD(pa_tnc_msg_t, process_ietf_std_errors, bool, private_pa_tnc_msg_t *this) { enumerator_t *enumerator; + enum_name_t *pa_attr_names; pa_tnc_attr_t *attr; - pen_type_t type; + pen_type_t type, unsupported_type; + uint8_t flags; bool fatal_error = FALSE; enumerator = this->attributes->create_enumerator(this->attributes); @@ -368,7 +367,7 @@ METHOD(pa_tnc_msg_t, process_ietf_std_errors, bool, { ietf_attr_pa_tnc_error_t *error_attr; pen_type_t error_code; - chunk_t msg_info, attr_info; + chunk_t msg_info; uint32_t offset; error_attr = (ietf_attr_pa_tnc_error_t*)attr; @@ -391,8 +390,28 @@ METHOD(pa_tnc_msg_t, process_ietf_std_errors, bool, DBG1(DBG_TNC, " occurred at offset of %u bytes", offset); break; case PA_ERROR_ATTR_TYPE_NOT_SUPPORTED: - attr_info = error_attr->get_attr_info(error_attr); - DBG1(DBG_TNC, " unsupported attribute %#B", &attr_info); + unsupported_type = + error_attr->get_unsupported_attr(error_attr, &flags); + pa_attr_names = + imcv_pa_tnc_attributes->get_names(imcv_pa_tnc_attributes, + unsupported_type.vendor_id); + if (pa_attr_names) + { + DBG1(DBG_TNC, " unsupported attribute type '%N/%N' " + "0x%06x/0x%08x, flags 0x%02x", + pen_names, unsupported_type.vendor_id, + pa_attr_names, unsupported_type.type, + unsupported_type.vendor_id, unsupported_type.type, + flags); + } + else + { + DBG1(DBG_TNC, " unsupported attribute type '%N' " + "0x%06x/0x%08x, flags 0x%02x", + pen_names, unsupported_type.vendor_id, + unsupported_type.vendor_id, unsupported_type.type, + flags); + } break; default: break;