Determine type of unsupported PA-TNC attribute in error message
authorAndreas Steffen <andreas.steffen@strongswan.org>
Wed, 16 Jul 2014 13:56:09 +0000 (15:56 +0200)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Wed, 16 Jul 2014 13:57:15 +0000 (15:57 +0200)
src/libimcv/ietf/ietf_attr_pa_tnc_error.c
src/libimcv/ietf/ietf_attr_pa_tnc_error.h
src/libimcv/pa_tnc/pa_tnc_msg.c

index 5f20f89..f299df2 100644 (file)
@@ -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;
 
index faa38f8..47588d5 100644 (file)
@@ -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
index 77d383b..fa4ee00 100644 (file)
@@ -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;