summaryrefslogtreecommitdiff
path: root/src/libimcv/pa_tnc
diff options
context:
space:
mode:
Diffstat (limited to 'src/libimcv/pa_tnc')
-rw-r--r--src/libimcv/pa_tnc/pa_tnc_attr.h13
-rw-r--r--src/libimcv/pa_tnc/pa_tnc_attr_manager.c161
-rw-r--r--src/libimcv/pa_tnc/pa_tnc_attr_manager.h26
-rw-r--r--src/libimcv/pa_tnc/pa_tnc_msg.c221
-rw-r--r--src/libimcv/pa_tnc/pa_tnc_msg.h6
5 files changed, 276 insertions, 151 deletions
diff --git a/src/libimcv/pa_tnc/pa_tnc_attr.h b/src/libimcv/pa_tnc/pa_tnc_attr.h
index 1e0c339c9..be0bef32e 100644
--- a/src/libimcv/pa_tnc/pa_tnc_attr.h
+++ b/src/libimcv/pa_tnc/pa_tnc_attr.h
@@ -26,8 +26,12 @@ typedef struct pa_tnc_attr_t pa_tnc_attr_t;
#include <library.h>
#include <pen/pen.h>
+#define PA_TNC_ATTR_INFO_SIZE 8
#define PA_TNC_ATTR_HEADER_SIZE 12
+#define PA_TNC_ATTR_FLAG_NONE 0x00
+#define PA_TNC_ATTR_FLAG_NOSKIP (1<<7)
+
/**
* Interface for an RFC 5792 PA-TNC Posture Attribute.
*
@@ -70,12 +74,19 @@ struct pa_tnc_attr_t {
/**
* Process the value of an PA-TNC attribute to extract its parameters
*
- * @param relative error offset within attribute body
+ * @param offset relative error offset within attribute body
* @return result status
*/
status_t (*process)(pa_tnc_attr_t *this, uint32_t *offset);
/**
+ * Add a data segment to an attribute allowing incremental processing
+ *
+ * @param segment data segment to be appended
+ */
+ void (*add_segment)(pa_tnc_attr_t *this, chunk_t segment);
+
+ /**
* Get a new reference to the PA-TNC attribute
*
* @return this, with an increased refcount
diff --git a/src/libimcv/pa_tnc/pa_tnc_attr_manager.c b/src/libimcv/pa_tnc/pa_tnc_attr_manager.c
index 900a55716..522213bd5 100644
--- a/src/libimcv/pa_tnc/pa_tnc_attr_manager.c
+++ b/src/libimcv/pa_tnc/pa_tnc_attr_manager.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Andreas Steffen
+ * Copyright (C) 2011-2014 Andreas Steffen
*
* HSR Hochschule fuer Technik Rapperswil
*
@@ -16,6 +16,10 @@
#include "pa_tnc_attr_manager.h"
+#include "imcv.h"
+#include "pa_tnc_attr.h"
+#include "ietf/ietf_attr_pa_tnc_error.h"
+
#include <collections/linked_list.h>
#include <utils/debug.h>
@@ -100,14 +104,102 @@ METHOD(pa_tnc_attr_manager_t, get_names, enum_name_t*,
return attr_names;
}
+/**
+ * PA-TNC attribute
+ *
+ * 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Flags | PA-TNC Attribute Vendor ID |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | PA-TNC Attribute Type |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | PA-TNC Attribute Length |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Attribute Value (Variable Length) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
METHOD(pa_tnc_attr_manager_t, create, pa_tnc_attr_t*,
- private_pa_tnc_attr_manager_t *this, pen_t vendor_id, u_int32_t type,
- chunk_t value)
+ private_pa_tnc_attr_manager_t *this, bio_reader_t *reader, bool segmented,
+ uint32_t *offset, chunk_t msg_info, pa_tnc_attr_t **error)
{
+ uint8_t flags;
+ uint32_t type, length, value_len;
+ chunk_t value;
+ ietf_attr_pa_tnc_error_t *error_attr;
+ pen_t vendor_id;
+ pen_type_t unsupported_type;
+ pen_type_t error_code = { PEN_IETF, PA_ERROR_INVALID_PARAMETER };
+ enum_name_t *pa_attr_names;
+ pa_tnc_attr_t *attr = NULL;
enumerator_t *enumerator;
entry_t *entry;
- pa_tnc_attr_t *attr = NULL;
+ /* properly initialize error return argument in case of no error */
+ *error = NULL;
+
+ if (reader->remaining(reader) < PA_TNC_ATTR_HEADER_SIZE)
+ {
+ DBG1(DBG_TNC, "insufficient bytes for PA-TNC attribute header");
+ *error = ietf_attr_pa_tnc_error_create_with_offset(error_code,
+ msg_info, *offset);
+ return NULL;
+ }
+ reader->read_uint8 (reader, &flags);
+ reader->read_uint24(reader, &vendor_id);
+ reader->read_uint32(reader, &type);
+ reader->read_uint32(reader, &length);
+
+ pa_attr_names = imcv_pa_tnc_attributes->get_names(imcv_pa_tnc_attributes,
+ vendor_id);
+ if (pa_attr_names)
+ {
+ DBG2(DBG_TNC, "processing PA-TNC attribute type '%N/%N' "
+ "0x%06x/0x%08x", pen_names, vendor_id,
+ pa_attr_names, type, vendor_id, type);
+ }
+ else
+ {
+ DBG2(DBG_TNC, "processing PA-TNC attribute type '%N' "
+ "0x%06x/0x%08x", pen_names, vendor_id,
+ vendor_id, type);
+ }
+
+ if (length < PA_TNC_ATTR_HEADER_SIZE)
+ {
+ DBG1(DBG_TNC, "%u bytes too small for PA-TNC attribute length",
+ length);
+ *error = ietf_attr_pa_tnc_error_create_with_offset(error_code,
+ msg_info, *offset + PA_TNC_ATTR_INFO_SIZE);
+ return NULL;
+ }
+ length -= PA_TNC_ATTR_HEADER_SIZE;
+ value_len = segmented ? reader->remaining(reader) : length;
+
+ if (!reader->read_data(reader, value_len, &value))
+ {
+ DBG1(DBG_TNC, "insufficient bytes for PA-TNC attribute value");
+ *error = ietf_attr_pa_tnc_error_create_with_offset(error_code,
+ msg_info, *offset + PA_TNC_ATTR_INFO_SIZE);
+ return NULL;
+ }
+ DBG3(DBG_TNC, "%B", &value);
+
+ if (vendor_id == PEN_RESERVED)
+ {
+ *error = ietf_attr_pa_tnc_error_create_with_offset(error_code,
+ msg_info, *offset + 1);
+ return NULL;
+ }
+ if (type == IETF_ATTR_RESERVED)
+ {
+ *error = ietf_attr_pa_tnc_error_create_with_offset(error_code,
+ msg_info, *offset + 4);
+ return NULL;
+ }
+
+ /* check if the attribute type is registered */
enumerator = this->list->create_enumerator(this->list);
while (enumerator->enumerate(enumerator, &entry))
{
@@ -115,13 +207,71 @@ METHOD(pa_tnc_attr_manager_t, create, pa_tnc_attr_t*,
{
if (entry->attr_create)
{
- attr = entry->attr_create(type, value);
+ attr = entry->attr_create(type, length, value);
}
break;
}
}
enumerator->destroy(enumerator);
+ if (!attr)
+ {
+ if (!(flags & PA_TNC_ATTR_FLAG_NOSKIP))
+ {
+ DBG1(DBG_TNC, "skipping unsupported PA-TNC attribute");
+ (*offset) += PA_TNC_ATTR_HEADER_SIZE + length;
+ return NULL;
+ }
+
+ 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, msg_info);
+ error_attr = (ietf_attr_pa_tnc_error_t*)(*error);
+ error_attr->set_unsupported_attr(error_attr, flags, unsupported_type);
+ return NULL;
+ }
+ (*offset) += PA_TNC_ATTR_HEADER_SIZE;
+
+ return attr;
+}
+
+METHOD(pa_tnc_attr_manager_t, construct, pa_tnc_attr_t*,
+ private_pa_tnc_attr_manager_t *this, pen_t vendor_id, uint32_t type,
+ chunk_t value)
+{
+ enum_name_t *pa_attr_names;
+ pa_tnc_attr_t *attr = NULL;
+ enumerator_t *enumerator;
+ entry_t *entry;
+
+ pa_attr_names = imcv_pa_tnc_attributes->get_names(imcv_pa_tnc_attributes,
+ vendor_id);
+ if (pa_attr_names)
+ {
+ DBG2(DBG_TNC, "generating PA-TNC attribute type '%N/%N' "
+ "0x%06x/0x%08x", pen_names, vendor_id,
+ pa_attr_names, type, vendor_id, type);
+ }
+ else
+ {
+ DBG2(DBG_TNC, "generating PA-TNC attribute type '%N' "
+ "0x%06x/0x%08x", pen_names, vendor_id,
+ vendor_id, type);
+ }
+ enumerator = this->list->create_enumerator(this->list);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (entry->vendor_id == vendor_id)
+ {
+ if (entry->attr_create)
+ {
+ attr = entry->attr_create(type, value.len, value);
+ }
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
return attr;
}
@@ -145,6 +295,7 @@ pa_tnc_attr_manager_t *pa_tnc_attr_manager_create(void)
.remove_vendor = _remove_vendor,
.get_names = _get_names,
.create = _create,
+ .construct = _construct,
.destroy = _destroy,
},
.list = linked_list_create(),
diff --git a/src/libimcv/pa_tnc/pa_tnc_attr_manager.h b/src/libimcv/pa_tnc/pa_tnc_attr_manager.h
index 121be7f90..8607feede 100644
--- a/src/libimcv/pa_tnc/pa_tnc_attr_manager.h
+++ b/src/libimcv/pa_tnc/pa_tnc_attr_manager.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
@@ -26,8 +26,10 @@ typedef struct pa_tnc_attr_manager_t pa_tnc_attr_manager_t;
#include "pa_tnc_attr.h"
#include <library.h>
+#include <bio/bio_reader.h>
-typedef pa_tnc_attr_t* (*pa_tnc_attr_create_t)(u_int32_t type, chunk_t value);
+typedef pa_tnc_attr_t* (*pa_tnc_attr_create_t)(u_int32_t type, size_t length,
+ chunk_t value);
/**
* Manages PA-TNC attributes for arbitrary PENs
@@ -61,15 +63,29 @@ struct pa_tnc_attr_manager_t {
enum_name_t* (*get_names)(pa_tnc_attr_manager_t *this, pen_t vendor_id);
/**
- * Create a PA-TNC attribute object from data for a given vendor ID and type
+ * Create and pre-parse a PA-TNC attribute object from data
+ *
+ * @param reader PA-TNC attribute as encoded data
+ * @param segmented TRUE if attribute is segmented
+ * @param offset Offset in bytes where an error has been found
+ * @param msg_info Message info added to an error attribute
+ * @param error Error attribute if an error occurred
+ * @return PA-TNC attribute object if supported, NULL else
+ */
+ pa_tnc_attr_t* (*create)(pa_tnc_attr_manager_t *this, bio_reader_t *reader,
+ bool segmented, uint32_t *offset, chunk_t msg_info,
+ pa_tnc_attr_t **error);
+
+ /**
+ * Generically construct a PA-TNC attribute from type and data
*
* @param vendor_id Private Enterprise Number (PEN)
* @param type PA-TNC attribute type
* @param value PA-TNC attribute value as encoded data
* @return PA-TNC attribute object if supported, NULL else
*/
- pa_tnc_attr_t* (*create)(pa_tnc_attr_manager_t *this, pen_t vendor_id,
- u_int32_t type, chunk_t value);
+ pa_tnc_attr_t* (*construct)(pa_tnc_attr_manager_t *this, pen_t vendor_id,
+ uint32_t type, chunk_t value);
/**
* Destroys a pa_tnc_attr_manager_t object.
diff --git a/src/libimcv/pa_tnc/pa_tnc_msg.c b/src/libimcv/pa_tnc/pa_tnc_msg.c
index 77d383b93..d9b441707 100644
--- a/src/libimcv/pa_tnc/pa_tnc_msg.c
+++ b/src/libimcv/pa_tnc/pa_tnc_msg.c
@@ -40,26 +40,6 @@ typedef struct private_pa_tnc_msg_t private_pa_tnc_msg_t;
#define PA_TNC_RESERVED 0x000000
/**
- * PA-TNC attribute
- *
- * 1 2 3
- * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | Flags | PA-TNC Attribute Vendor ID |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | PA-TNC Attribute Type |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | PA-TNC Attribute Length |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- * | Attribute Value (Variable Length) |
- * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- */
-
-#define PA_TNC_ATTR_FLAG_NONE 0x00
-#define PA_TNC_ATTR_FLAG_NOSKIP (1<<7)
-#define PA_TNC_ATTR_INFO_SIZE 8
-
-/**
* Private data of a pa_tnc_msg_t object.
*
*/
@@ -96,6 +76,11 @@ struct private_pa_tnc_msg_t {
size_t max_msg_len;
/**
+ * TRUE if attribute was extracted from data
+ */
+ bool from_data;
+
+ /**
* Encoded message
*/
chunk_t encoding;
@@ -113,17 +98,19 @@ METHOD(pa_tnc_msg_t, add_attribute, bool,
chunk_t attr_value;
size_t attr_len;
- attr->build(attr);
- attr_value = attr->get_value(attr);
- attr_len = PA_TNC_ATTR_HEADER_SIZE + attr_value.len;
-
- if (this->max_msg_len && this->msg_len + attr_len > this->max_msg_len)
+ if (!this->from_data)
{
- /* attribute just does not fit into this message */
- return FALSE;
- }
- this->msg_len += attr_len;
+ attr->build(attr);
+ attr_value = attr->get_value(attr);
+ attr_len = PA_TNC_ATTR_HEADER_SIZE + attr_value.len;
+ if (this->max_msg_len && this->msg_len + attr_len > this->max_msg_len)
+ {
+ /* attribute just does not fit into this message */
+ return FALSE;
+ }
+ this->msg_len += attr_len;
+ }
this->attributes->insert_last(this->attributes, attr);
return TRUE;
}
@@ -201,7 +188,9 @@ METHOD(pa_tnc_msg_t, process, status_t,
private_pa_tnc_msg_t *this)
{
bio_reader_t *reader;
- pa_tnc_attr_t *error;
+ pa_tnc_attr_t *attr, *error;
+ pen_type_t attr_type;
+ chunk_t attr_value;
uint8_t version;
uint32_t reserved, offset, attr_offset;
pen_type_t error_code = { PEN_IETF, PA_ERROR_INVALID_PARAMETER };
@@ -231,119 +220,38 @@ METHOD(pa_tnc_msg_t, process, status_t,
offset = PA_TNC_HEADER_SIZE;
/* pre-process PA-TNC attributes */
- while (reader->remaining(reader) >= PA_TNC_ATTR_HEADER_SIZE)
+ while (reader->remaining(reader) > 0)
{
- pen_t vendor_id;
- uint8_t flags;
- uint32_t type, length;
- chunk_t value, attr_info;
- pa_tnc_attr_t *attr;
- enum_name_t *pa_attr_names;
- ietf_attr_pa_tnc_error_t *error_attr;
-
- 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);
- reader->read_uint32(reader, &length);
-
- pa_attr_names = imcv_pa_tnc_attributes->get_names(imcv_pa_tnc_attributes,
- vendor_id);
- if (pa_attr_names)
- {
- DBG2(DBG_TNC, "processing PA-TNC attribute type '%N/%N' "
- "0x%06x/0x%08x", pen_names, vendor_id,
- pa_attr_names, type, vendor_id, type);
- }
- else
- {
- DBG2(DBG_TNC, "processing PA-TNC attribute type '%N' "
- "0x%06x/0x%08x", pen_names, vendor_id,
- vendor_id, type);
- }
-
- if (length < PA_TNC_ATTR_HEADER_SIZE)
- {
- DBG1(DBG_TNC, "%u bytes too small for PA-TNC attribute length",
- length);
- error = ietf_attr_pa_tnc_error_create_with_offset(error_code,
- this->encoding, offset + PA_TNC_ATTR_INFO_SIZE);
- goto err;
- }
-
- if (!reader->read_data(reader, length - PA_TNC_ATTR_HEADER_SIZE, &value))
- {
- DBG1(DBG_TNC, "insufficient bytes for PA-TNC attribute value");
- error = ietf_attr_pa_tnc_error_create_with_offset(error_code,
- this->encoding, offset + PA_TNC_ATTR_INFO_SIZE);
- goto err;
- }
- DBG3(DBG_TNC, "%B", &value);
-
- if (vendor_id == PEN_RESERVED)
- {
- error = ietf_attr_pa_tnc_error_create_with_offset(error_code,
- this->encoding, offset + 1);
- goto err;
- }
- if (type == IETF_ATTR_RESERVED)
- {
- error = ietf_attr_pa_tnc_error_create_with_offset(error_code,
- this->encoding, offset + 4);
- goto err;
- }
attr = imcv_pa_tnc_attributes->create(imcv_pa_tnc_attributes,
- vendor_id, type, value);
+ reader, FALSE, &offset, this->encoding, &error);
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
- {
- DBG1(DBG_TNC, "skipping unsupported PA-TNC attribute");
- offset += length;
- continue;
- }
+ goto err;
}
+ attr_value = attr->get_value(attr);
+ attr_type = attr->get_type(attr);
if (attr->process(attr, &attr_offset) != SUCCESS)
{
attr->destroy(attr);
- if (vendor_id == PEN_IETF && type == IETF_ATTR_PA_TNC_ERROR)
+
+ if (attr_type.vendor_id == PEN_IETF &&
+ attr_type.type == IETF_ATTR_PA_TNC_ERROR)
{
- /* error while processing a PA-TNC error attribute - abort */
- reader->destroy(reader);
- return FAILED;
+ /* suppress error while processing a PA-TNC error attribute */
+ offset += attr_value.len;
+ continue;
}
- error_code = pen_type_create(PEN_IETF,
- PA_ERROR_INVALID_PARAMETER);
+ error_code = pen_type_create(PEN_IETF, PA_ERROR_INVALID_PARAMETER);
error = ietf_attr_pa_tnc_error_create_with_offset(error_code,
- this->encoding,
- offset + PA_TNC_ATTR_HEADER_SIZE + attr_offset);
+ this->encoding, offset + attr_offset);
goto err;
}
+ offset += attr_value.len;
this->attributes->insert_last(this->attributes, attr);
- offset += length;
}
-
- if (reader->remaining(reader) == 0)
- {
- reader->destroy(reader);
- return SUCCESS;
- }
- DBG1(DBG_TNC, "insufficient bytes for PA-TNC attribute header");
- error = ietf_attr_pa_tnc_error_create_with_offset(error_code,
- this->encoding, offset);
+ reader->destroy(reader);
+ return SUCCESS;
err:
reader->destroy(reader);
@@ -352,24 +260,27 @@ err:
}
METHOD(pa_tnc_msg_t, process_ietf_std_errors, bool,
- private_pa_tnc_msg_t *this)
+ private_pa_tnc_msg_t *this, linked_list_t *non_fatal_types)
{
- enumerator_t *enumerator;
+ enumerator_t *e1, *e2;
+ 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);
- while (enumerator->enumerate(enumerator, &attr))
+ e1 = this->attributes->create_enumerator(this->attributes);
+ while (e1->enumerate(e1, &attr))
{
type = attr->get_type(attr);
if (type.vendor_id == PEN_IETF && type.type == IETF_ATTR_PA_TNC_ERROR)
{
ietf_attr_pa_tnc_error_t *error_attr;
- pen_type_t error_code;
- chunk_t msg_info, attr_info;
+ pen_type_t error_code, *non_fatal_type;
+ chunk_t msg_info;
uint32_t offset;
+ bool fatal_current_error = TRUE;
error_attr = (ietf_attr_pa_tnc_error_t*)attr;
error_code = error_attr->get_error_code(error_attr);
@@ -391,16 +302,49 @@ 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);
+ }
+ e2 = non_fatal_types->create_enumerator(non_fatal_types);
+ while (e2->enumerate(e2, &non_fatal_type))
+ {
+ if (pen_type_equals(unsupported_type, *non_fatal_type))
+ {
+ fatal_current_error = FALSE;
+ break;
+ }
+ }
+ e2->destroy(e2);
break;
default:
break;
}
- fatal_error = TRUE;
+ if (fatal_current_error)
+ {
+ fatal_error = TRUE;
+ }
}
}
- enumerator->destroy(enumerator);
+ e1->destroy(e1);
return fatal_error;
}
@@ -476,6 +420,7 @@ pa_tnc_msg_t *pa_tnc_msg_create_from_data(chunk_t data)
.encoding = chunk_clone(data),
.attributes = linked_list_create(),
.errors = linked_list_create(),
+ .from_data = TRUE,
);
return &this->public;
diff --git a/src/libimcv/pa_tnc/pa_tnc_msg.h b/src/libimcv/pa_tnc/pa_tnc_msg.h
index 84814b92b..57ff1a04c 100644
--- a/src/libimcv/pa_tnc/pa_tnc_msg.h
+++ b/src/libimcv/pa_tnc/pa_tnc_msg.h
@@ -68,9 +68,11 @@ struct pa_tnc_msg_t {
/**
* Process all IETF standard error PA-TNC attributes
*
- * @return TRUE if at least one error attribute processed
+ * @param non_fatal_types list of non fatal unsupported attribute types
+ * @return TRUE if at least one fatal error processed
*/
- bool (*process_ietf_std_errors)(pa_tnc_msg_t *this);
+ bool (*process_ietf_std_errors)(pa_tnc_msg_t *this,
+ linked_list_t *non_fatal_types);
/**
* Enumerates over all PA-TNC attributes