refactored PA-TNC message handling by IMCs
authorAndreas Steffen <andreas.steffen@strongswan.org>
Wed, 17 Oct 2012 07:58:00 +0000 (09:58 +0200)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Wed, 17 Oct 2012 08:02:53 +0000 (10:02 +0200)
15 files changed:
src/libimcv/Makefile.am
src/libimcv/imc/imc_agent.c
src/libimcv/imc/imc_agent.h
src/libimcv/imc/imc_msg.c [new file with mode: 0644]
src/libimcv/imc/imc_msg.h [new file with mode: 0644]
src/libimcv/plugins/imc_os/imc_os.c
src/libimcv/plugins/imc_os/imc_os_state.c
src/libimcv/plugins/imc_scanner/imc_scanner.c
src/libimcv/plugins/imc_scanner/imc_scanner_state.c
src/libimcv/plugins/imc_test/imc_test.c
src/libimcv/plugins/imc_test/imc_test_state.c
src/libpts/plugins/imc_attestation/imc_attestation.c
src/libpts/plugins/imc_attestation/imc_attestation_process.c
src/libpts/plugins/imc_attestation/imc_attestation_process.h
src/libpts/plugins/imc_attestation/imc_attestation_state.c

index a331870..34746a8 100644 (file)
@@ -8,6 +8,7 @@ libimcv_la_LIBADD = $(top_builddir)/src/libtncif/libtncif.la
 libimcv_la_SOURCES = \
        imcv.h imcv.c \
        imc/imc_agent.h imc/imc_agent.c imc/imc_state.h \
+       imc/imc_msg.h imc/imc_msg.c \
        imv/imv_agent.h imv/imv_agent.c imv/imv_state.h \
        ietf/ietf_attr.h ietf/ietf_attr.c \
        ietf/ietf_attr_assess_result.h ietf/ietf_attr_assess_result.c \
index 1ba91cc..911a5b0 100644 (file)
@@ -95,45 +95,6 @@ struct private_imc_agent_t {
                                                                        TNC_UInt32 type_count);
 
        /**
-        * Call when an IMC-IMC message is to be sent
-        *
-        * @param imc_id                        IMC ID assigned by TNCC
-        * @param connection_id         network connection ID assigned by TNCC
-        * @param msg                           message to send
-        * @param msg_len                       message length in bytes
-        * @param msg_type                      message type
-        * @return                                      TNC result code
-        */
-       TNC_Result (*send_message)(TNC_IMCID imc_id,
-                                                          TNC_ConnectionID connection_id,
-                                                          TNC_BufferReference msg,
-                                                          TNC_UInt32 msg_len,
-                                                          TNC_MessageType msg_type);
-
-
-       /**
-        * Call when an IMC-IMC message is to be sent with long message types
-        *
-        * @param imc_id                        IMC ID assigned by TNCC
-        * @param connection_id         network connection ID assigned by TNCC
-        * @param msg_flags                     message flags
-        * @param msg                           message to send
-        * @param msg_len                       message length in bytes
-        * @param msg_vid                       message vendor ID
-        * @param msg_subtype           message subtype
-        * @param dst_imc_id            destination IMV ID
-        * @return                                      TNC result code
-        */
-       TNC_Result (*send_message_long)(TNC_IMCID imc_id,
-                                                                       TNC_ConnectionID connection_id,
-                                                                       TNC_UInt32 msg_flags,
-                                                                       TNC_BufferReference msg,
-                                                                       TNC_UInt32 msg_len,
-                                                                       TNC_VendorID msg_vid,
-                                                                       TNC_MessageSubtype msg_subtype,
-                                                                       TNC_UInt32 dst_imv_id);
-
-       /**
         * Get the value of an attribute associated with a connection
         * or with the TNCC as a whole.
         *
@@ -205,14 +166,14 @@ METHOD(imc_agent_t, bind_functions, TNC_Result,
                this->public.request_handshake_retry = NULL;
        }
        if (bind_function(this->id, "TNC_TNCC_SendMessage",
-                       (void**)&this->send_message) != TNC_RESULT_SUCCESS)
+                       (void**)&this->public.send_message) != TNC_RESULT_SUCCESS)
        {
-               this->send_message = NULL;
+               this->public.send_message = NULL;
        }
        if (bind_function(this->id, "TNC_TNCC_SendMessageLong",
-                       (void**)&this->send_message_long) != TNC_RESULT_SUCCESS)
+                       (void**)&this->public.send_message_long) != TNC_RESULT_SUCCESS)
        {
-               this->send_message_long = NULL;
+               this->public.send_message_long = NULL;
        }
        if (bind_function(this->id, "TNC_TNCC_GetAttribute",
                        (void**)&this->get_attribute) != TNC_RESULT_SUCCESS)
@@ -494,167 +455,16 @@ METHOD(imc_agent_t, get_state, bool,
        return TRUE;
 }
 
-METHOD(imc_agent_t, send_message, TNC_Result,
-       private_imc_agent_t *this, TNC_ConnectionID connection_id, bool excl,
-       TNC_UInt32 src_imc_id, TNC_UInt32 dst_imv_id, TNC_VendorID msg_vid,
-       TNC_MessageSubtype msg_subtype, linked_list_t *attr_list)
+METHOD(imc_agent_t, get_name, const char*,
+       private_imc_agent_t *this)
 {
-       TNC_MessageType type;
-       TNC_UInt32 msg_flags;
-       TNC_Result result = TNC_RESULT_FATAL;
-       imc_state_t *state;
-       pa_tnc_attr_t *attr;
-       pa_tnc_msg_t *pa_tnc_msg;
-       chunk_t msg;
-       enumerator_t *enumerator;
-       bool attr_added;
-
-       state = find_connection(this, connection_id);
-       if (!state)
-       {
-               DBG1(DBG_IMV, "IMC %u \"%s\" has no state for Connection ID %u",
-                                         this->id, this->name, connection_id);
-               return TNC_RESULT_FATAL;
-       }
-
-       while (attr_list->get_count(attr_list))
-       {
-               pa_tnc_msg = pa_tnc_msg_create(state->get_max_msg_len(state));
-               attr_added = FALSE;
-
-               enumerator = attr_list->create_enumerator(attr_list);
-               while (enumerator->enumerate(enumerator, &attr))
-               {
-                       if (pa_tnc_msg->add_attribute(pa_tnc_msg, attr))
-                       {
-                               attr_added = TRUE;
-                       }
-                       else
-                       {
-                               if (attr_added)
-                               {
-                                       break;
-                               }
-                               else
-                               {
-                                       DBG1(DBG_IMC, "PA-TNC attribute too large to send, deleted");
-                                       attr->destroy(attr);
-                               }
-                       }
-                       attr_list->remove_at(attr_list, enumerator);
-               }
-               enumerator->destroy(enumerator);
-
-               /* build and send the PA-TNC message via the IF-IMC interface */
-               if (!pa_tnc_msg->build(pa_tnc_msg))
-               {
-                       pa_tnc_msg->destroy(pa_tnc_msg);
-                       return TNC_RESULT_FATAL;
-               }
-               msg = pa_tnc_msg->get_encoding(pa_tnc_msg);
-
-               if (state->has_long(state) && this->send_message_long)
-               {
-                       if (!src_imc_id)
-                       {
-                               src_imc_id = this->id;
-                       }
-                       msg_flags = excl ? TNC_MESSAGE_FLAGS_EXCLUSIVE : 0;
-
-                       result = this->send_message_long(src_imc_id, connection_id,
-                                                               msg_flags, msg.ptr, msg.len, msg_vid,
-                                                               msg_subtype, dst_imv_id);
-               }
-               else if (this->send_message)
-               {
-                       type = msg_vid << 8 | msg_subtype;
-
-                       result = this->send_message(this->id, connection_id, msg.ptr,
-                                                               msg.len, type);
-               }
-
-               pa_tnc_msg->destroy(pa_tnc_msg);
-
-               if (result != TNC_RESULT_SUCCESS)
-               {
-                       break;
-               }
-       }
-       return result;
+       return  this->name;
 }
 
-METHOD(imc_agent_t, receive_message, TNC_Result,
-       private_imc_agent_t *this, imc_state_t *state, chunk_t msg,
-       TNC_VendorID msg_vid, TNC_MessageSubtype msg_subtype,
-       TNC_UInt32 src_imv_id, TNC_UInt32 dst_imc_id, pa_tnc_msg_t **pa_tnc_msg)
+METHOD(imc_agent_t, get_id, TNC_IMCID,
+       private_imc_agent_t *this)
 {
-       pa_tnc_msg_t *pa_msg;
-       pa_tnc_attr_t *error_attr;
-       linked_list_t *error_attr_list;
-       enumerator_t *enumerator;
-       TNC_UInt32 src_imc_id, dst_imv_id;
-       TNC_ConnectionID connection_id;
-       TNC_Result result;
-
-       connection_id = state->get_connection_id(state);
-
-       if (state->has_long(state))
-       {
-               if (dst_imc_id != TNC_IMCID_ANY)
-               {
-                       DBG2(DBG_IMC, "IMC %u \"%s\" received message for Connection ID %u "
-                                                 "from IMV %u to IMC %u", this->id, this->name,
-                                                  connection_id, src_imv_id, dst_imc_id);
-               }
-               else
-               {
-                       DBG2(DBG_IMC, "IMC %u \"%s\" received message for Connection ID %u "
-                                                 "from IMV %u", this->id, this->name, connection_id,
-                                                  src_imv_id);
-               }
-       }
-       else
-       {
-               DBG2(DBG_IMC, "IMC %u \"%s\" received message for Connection ID %u",
-                                          this->id, this->name, connection_id);
-       }
-
-       *pa_tnc_msg = NULL;
-       pa_msg = pa_tnc_msg_create_from_data(msg);
-
-       switch (pa_msg->process(pa_msg))
-       {
-               case SUCCESS:
-                       *pa_tnc_msg = pa_msg;
-                       break;
-               case VERIFY_ERROR:
-                       /* extract and copy by refence all error attributes */
-                       error_attr_list = linked_list_create();
-
-                       enumerator = pa_msg->create_error_enumerator(pa_msg);
-                       while (enumerator->enumerate(enumerator, &error_attr))
-                       {
-                               error_attr_list->insert_last(error_attr_list,
-                                                                                        error_attr->get_ref(error_attr));
-                       }
-                       enumerator->destroy(enumerator);
-
-                       src_imc_id = (dst_imc_id == TNC_IMCID_ANY) ? this->id : dst_imc_id;
-                       dst_imv_id = state->has_excl(state) ? src_imv_id : TNC_IMVID_ANY;
-
-                       result = send_message(this, connection_id, state->has_excl(state),
-                                                                 src_imc_id, dst_imv_id, msg_vid, msg_subtype,
-                                                                 error_attr_list);
-
-                       error_attr_list->destroy(error_attr_list);
-                       pa_msg->destroy(pa_msg);
-                       return result;
-               case FAILED:
-               default:
-                       pa_msg->destroy(pa_msg);
-                       return TNC_RESULT_FATAL;
-       }
-       return TNC_RESULT_SUCCESS;
+       return  this->id;
 }
 
 METHOD(imc_agent_t, reserve_additional_ids, TNC_Result,
@@ -737,8 +547,8 @@ imc_agent_t *imc_agent_create(const char *name,
                        .delete_state = _delete_state,
                        .change_state = _change_state,
                        .get_state = _get_state,
-                       .send_message = _send_message,
-                       .receive_message = _receive_message,
+                       .get_name = _get_name,
+                       .get_id = _get_id,
                        .reserve_additional_ids = _reserve_additional_ids,
                        .count_additional_ids = _count_additional_ids,
                        .create_id_enumerator = _create_id_enumerator,
index 4e2947d..7c36136 100644 (file)
@@ -51,6 +51,44 @@ struct imc_agent_t {
                                                                                  TNC_RetryReason reason);
 
        /**
+        * Call when an IMC-IMC message is to be sent
+        *
+        * @param imc_id                        IMC ID assigned by TNCC
+        * @param connection_id         network connection ID assigned by TNCC
+        * @param msg                           message to send
+        * @param msg_len                       message length in bytes
+        * @param msg_type                      message type
+        * @return                                      TNC result code
+        */
+       TNC_Result (*send_message)(TNC_IMCID imc_id,
+                                                          TNC_ConnectionID connection_id,
+                                                          TNC_BufferReference msg,
+                                                          TNC_UInt32 msg_len,
+                                                          TNC_MessageType msg_type);
+
+       /**
+        * Call when an IMC-IMC message is to be sent with long message types
+        *
+        * @param imc_id                        IMC ID assigned by TNCC
+        * @param connection_id         network connection ID assigned by TNCC
+        * @param msg_flags                     message flags
+        * @param msg                           message to send
+        * @param msg_len                       message length in bytes
+        * @param msg_vid                       message vendor ID
+        * @param msg_subtype           message subtype
+        * @param dst_imc_id            destination IMV ID
+        * @return                                      TNC result code
+        */
+       TNC_Result (*send_message_long)(TNC_IMCID imc_id,
+                                                                       TNC_ConnectionID connection_id,
+                                                                       TNC_UInt32 msg_flags,
+                                                                       TNC_BufferReference msg,
+                                                                       TNC_UInt32 msg_len,
+                                                                       TNC_VendorID msg_vid,
+                                                                       TNC_MessageSubtype msg_subtype,
+                                                                       TNC_UInt32 dst_imv_id);
+
+       /**
         * Bind TNCC functions
         *
         * @param bind_function         function offered by the TNCC
@@ -100,43 +138,18 @@ struct imc_agent_t {
                                          TNC_ConnectionID connection_id, imc_state_t **state);
 
        /**
-        * Call when an PA-TNC message is to be sent
+        * Get IMC name
         *
-        * @param connection_id         network connection ID assigned by TNCC
-        * @param excl                          exclusive flag
-        * @param src_imc_id            IMC ID to be set as source
-        * @param dst_imv_id            IMV ID to be set as destination
-        * @param msg_vid                       message vendor ID
-        * @param msg_subtype           message subtype
-        * @param attr_list                     list of PA-TNC attributes to send
-        * @return                                      TNC result code
+        * return                                       IMC name
         */
-       TNC_Result (*send_message)(imc_agent_t *this,
-                                                          TNC_ConnectionID connection_id, bool excl,
-                                                          TNC_UInt32 src_imc_id, TNC_UInt32 dst_imv_id,
-                                                          TNC_VendorID msg_vid,
-                                                          TNC_MessageSubtype msg_subtype,
-                                                          linked_list_t *attr_list);
+       const char* (*get_name)(imc_agent_t *this);
 
        /**
-        * Call when a PA-TNC message was received
+        * Get base IMC ID
         *
-        * @param state                         state for current connection
-        * @param msg                           received unparsed message
-        * @param msg_vid                       message vendorID of the received message
-        * @param msg_subtype           message subtype of the received message
-        * @param src_imv_id            source IMV ID
-        * @param dst_imc_id            destination IMC ID
-        * @param pa_tnc_message        parsed PA-TNC message or NULL if an error occurred
-        * @return                                      TNC result code
+        * return                                       base IMC ID
         */
-       TNC_Result (*receive_message)(imc_agent_t *this,
-                                                                 imc_state_t *state, chunk_t msg,
-                                                                 TNC_VendorID msg_vid,
-                                                                 TNC_MessageSubtype msg_subtype,
-                                                                 TNC_UInt32 src_imv_id,
-                                                                 TNC_UInt32 dst_imc_id,
-                                                                 pa_tnc_msg_t **pa_tnc_msg);
+       TNC_IMCID (*get_id)(imc_agent_t *this);
 
        /**
         * Reserve additional IMC IDs from TNCC
diff --git a/src/libimcv/imc/imc_msg.c b/src/libimcv/imc/imc_msg.c
new file mode 100644 (file)
index 0000000..e21c985
--- /dev/null
@@ -0,0 +1,392 @@
+/*
+ * Copyright (C) 2012 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+#include "imc_msg.h"
+
+#include "ietf/ietf_attr.h"
+#include "ietf/ietf_attr_assess_result.h"
+
+#include <tncif_names.h>
+
+#include <pen/pen.h>
+#include <utils/linked_list.h>
+#include <debug.h>
+
+typedef struct private_imc_msg_t private_imc_msg_t;
+
+/**
+ * Private data of a imc_msg_t object.
+ *
+ */
+struct private_imc_msg_t {
+
+       /**
+        * Public imc_msg_t interface.
+        */
+       imc_msg_t public;
+
+       /**
+        * Connection ID 
+        */
+       TNC_ConnectionID connection_id;
+
+       /**
+        * source ID 
+        */
+       TNC_UInt32 src_id; 
+
+       /**
+        * destination ID 
+        */
+       TNC_UInt32 dst_id; 
+
+       /**
+        * PA-TNC message type 
+        */
+       pen_type_t msg_type; 
+
+       /**
+        * List of PA-TNC attributes to be sent
+        */
+       linked_list_t *attr_list;
+
+       /**
+        * PA-TNC message 
+        */
+       pa_tnc_msg_t *pa_msg;
+
+       /**
+        * Assigned IMC agent 
+        */
+       imc_agent_t *agent;
+
+       /**
+        * Assigned IMC state 
+        */
+       imc_state_t *state;
+};
+
+METHOD(imc_msg_t, get_src_id, TNC_UInt32,
+       private_imc_msg_t *this)
+{
+       return this->src_id;
+}
+
+METHOD(imc_msg_t, get_dst_id, TNC_UInt32,
+       private_imc_msg_t *this)
+{
+       return this->dst_id;
+}
+
+METHOD(imc_msg_t, send_, TNC_Result,
+       private_imc_msg_t *this, bool excl)
+{
+       pa_tnc_msg_t *pa_tnc_msg;
+       pa_tnc_attr_t *attr;
+       TNC_UInt32 msg_flags;
+       TNC_MessageType msg_type;
+       bool attr_added;
+       chunk_t msg;
+       enumerator_t *enumerator;
+       TNC_Result result;
+
+       while (this->attr_list->get_count(this->attr_list))
+       {
+               pa_tnc_msg = pa_tnc_msg_create(this->state->get_max_msg_len(this->state));
+               attr_added = FALSE;
+
+               enumerator = this->attr_list->create_enumerator(this->attr_list);
+               while (enumerator->enumerate(enumerator, &attr))
+               {
+                       if (pa_tnc_msg->add_attribute(pa_tnc_msg, attr))
+                       {
+                               attr_added = TRUE;
+                       }
+                       else
+                       {
+                               if (attr_added)
+                               {
+                                       break;
+                               }
+                               else
+                               {
+                                       DBG1(DBG_IMC, "PA-TNC attribute too large to send, deleted");
+                                       attr->destroy(attr);
+                               }
+                       }
+                       this->attr_list->remove_at(this->attr_list, enumerator);
+               }
+               enumerator->destroy(enumerator);
+
+               /* build and send the PA-TNC message via the IF-IMC interface */
+               if (!pa_tnc_msg->build(pa_tnc_msg))
+               {
+                       pa_tnc_msg->destroy(pa_tnc_msg);
+                       return TNC_RESULT_FATAL;
+               }
+               msg = pa_tnc_msg->get_encoding(pa_tnc_msg);
+               DBG3(DBG_IMC, "created PA-TNC message: %B", &msg);
+
+               if (this->state->has_long(this->state) && this->agent->send_message_long)
+               {
+                       excl = excl && this->state->has_excl(this->state) && 
+                                                  this->dst_id != TNC_IMVID_ANY;
+                       msg_flags = excl ? TNC_MESSAGE_FLAGS_EXCLUSIVE : 0;
+                       result = this->agent->send_message_long(this->src_id,
+                                                       this->connection_id, msg_flags, msg.ptr, msg.len,
+                                                       this->msg_type.vendor_id, this->msg_type.type,
+                                                       this->dst_id);
+               }
+               else if (this->agent->send_message)
+               {
+                       msg_type = (this->msg_type.vendor_id << 8) |
+                                          (this->msg_type.type & 0x000000ff);
+                       result = this->agent->send_message(this->src_id, this->connection_id,
+                                                                                          msg.ptr, msg.len, msg_type);
+               }
+
+               pa_tnc_msg->destroy(pa_tnc_msg);
+
+               if (result != TNC_RESULT_SUCCESS)
+               {
+                       break;
+               }
+       }
+       return result;
+}
+
+METHOD(imc_msg_t, receive, TNC_Result,
+       private_imc_msg_t *this, bool *fatal_error)
+{
+       enumerator_t *enumerator;
+       pa_tnc_attr_t *attr;
+       pen_type_t attr_type;
+       chunk_t msg;
+
+       if (this->state->has_long(this->state))
+       {
+               if (this->dst_id != TNC_IMCID_ANY)
+               {
+                       DBG2(DBG_IMC, "IMC %u \"%s\" received message for Connection ID %u "
+                                                 "from IMV %u to IMC %u",
+                                                  this->agent->get_id(this->agent),
+                                                  this->agent->get_name(this->agent),
+                                                  this->connection_id, this->src_id, this->dst_id);
+               }
+               else
+               {
+                       DBG2(DBG_IMC, "IMC %u \"%s\" received message for Connection ID %u "
+                                                 "from IMV %u", this->agent->get_id(this->agent),
+                                                  this->agent->get_name(this->agent),
+                                                  this->connection_id, this->src_id);
+               }
+       }
+       else
+       {
+               DBG2(DBG_IMC, "IMC %u \"%s\" received message for Connection ID %u",
+                                          this->agent->get_id(this->agent),
+                                          this->agent->get_name(this->agent),
+                                          this->connection_id);
+       }
+       msg = this->pa_msg->get_encoding(this->pa_msg);
+       DBG3(DBG_IMC, "%B", &msg);
+
+       switch (this->pa_msg->process(this->pa_msg))
+       {
+               case SUCCESS:
+                       break;
+               case VERIFY_ERROR:
+               {
+                       imc_msg_t *error_msg;
+                       TNC_Result result;
+
+                       error_msg = imc_msg_create_as_reply(&this->public);
+
+                       /* extract and copy by reference all error attributes */
+                       enumerator = this->pa_msg->create_error_enumerator(this->pa_msg);
+                       while (enumerator->enumerate(enumerator, &attr))
+                       {
+                               error_msg->add_attribute(error_msg, attr->get_ref(attr));
+                       }
+                       enumerator->destroy(enumerator);
+
+                       /* 
+                        * send the PA-TNC message containing all error attributes
+                        * with the excl flag set
+                        */
+                       result = error_msg->send(error_msg, TRUE);
+                       error_msg->destroy(error_msg);
+                       return result;
+               }
+               case FAILED:
+               default:
+                       return TNC_RESULT_FATAL;
+       }
+
+       /* preprocess any received IETF standard error attributes */
+       *fatal_error = this->pa_msg->process_ietf_std_errors(this->pa_msg);
+
+       /* preprocess any received IETF assessment result attribute */
+       enumerator = this->pa_msg->create_attribute_enumerator(this->pa_msg);
+       while (enumerator->enumerate(enumerator, &attr))
+       {
+               attr_type = attr->get_type(attr);
+               
+               if (attr_type.vendor_id == PEN_IETF &&
+                       attr_type.type == IETF_ATTR_ASSESSMENT_RESULT)
+               {
+                       ietf_attr_assess_result_t *attr_cast;
+                       TNC_UInt32 target_imc_id;
+                       TNC_IMV_Evaluation_Result result;
+
+                       attr_cast = (ietf_attr_assess_result_t*)attr;
+                       result =  attr_cast->get_result(attr_cast);
+                       target_imc_id = (this->dst_id != TNC_IMCID_ANY) ?
+                                                        this->dst_id : this->agent->get_id(this->agent); 
+                       this->state->set_result(this->state, target_imc_id, result);
+
+                       DBG1(DBG_IMC, "set assessment result for IMC %u to '%N'",
+                                target_imc_id, TNC_IMV_Evaluation_Result_names, result);
+               }
+       }
+       enumerator->destroy(enumerator);
+               
+       return TNC_RESULT_SUCCESS;
+}
+
+METHOD(imc_msg_t, add_attribute, void,
+       private_imc_msg_t *this, pa_tnc_attr_t *attr)
+{
+       this->attr_list->insert_last(this->attr_list, attr);
+}
+
+METHOD(imc_msg_t, create_attribute_enumerator, enumerator_t*,
+       private_imc_msg_t *this)
+{
+       return this->pa_msg->create_attribute_enumerator(this->pa_msg);
+}
+
+METHOD(imc_msg_t, destroy, void,
+       private_imc_msg_t *this)
+{
+       this->attr_list->destroy_offset(this->attr_list,
+                                                                       offsetof(pa_tnc_attr_t, destroy));
+       DESTROY_IF(this->pa_msg);
+       free(this);
+}
+
+/**
+ * See header
+ */
+imc_msg_t *imc_msg_create(imc_agent_t *agent, imc_state_t *state,
+                                                 TNC_ConnectionID connection_id,
+                                                 TNC_UInt32 src_id, TNC_UInt32 dst_id,
+                                                 pen_type_t msg_type)
+{
+       private_imc_msg_t *this;
+
+       INIT(this,
+               .public = {
+                       .get_src_id = _get_src_id,
+                       .get_dst_id = _get_dst_id,
+                       .send = _send_,
+                       .receive = _receive,
+                       .add_attribute = _add_attribute,
+                       .create_attribute_enumerator = _create_attribute_enumerator,
+                       .destroy = _destroy,
+               },
+               .connection_id = connection_id,
+               .src_id = src_id,
+               .dst_id = dst_id,
+               .msg_type = msg_type,
+               .attr_list = linked_list_create(),
+               .agent = agent,
+               .state = state,
+       );
+
+       return &this->public;
+}
+
+/**
+ * See header
+ */
+imc_msg_t* imc_msg_create_as_reply(imc_msg_t *msg)
+{
+       private_imc_msg_t *in;
+       TNC_UInt32 src_id;
+
+       in = (private_imc_msg_t*)msg;
+       src_id = (in->dst_id != TNC_IMCID_ANY) ? 
+                         in->dst_id : in->agent->get_id(in->agent);
+
+       return imc_msg_create(in->agent, in->state, in->connection_id, src_id,
+                                                 in->src_id, in->msg_type);
+}
+
+/**
+ * See header
+ */
+imc_msg_t *imc_msg_create_from_data(imc_agent_t *agent, imc_state_t *state,
+                                                                       TNC_ConnectionID connection_id,
+                                                                       TNC_MessageType msg_type,
+                                                                       chunk_t msg)
+{
+       TNC_VendorID msg_vid;
+       TNC_MessageSubtype msg_subtype;
+
+       msg_vid = msg_type >> 8;
+       msg_subtype = msg_type & TNC_SUBTYPE_ANY;
+
+       return imc_msg_create_from_long_data(agent, state, connection_id,
+                                                               TNC_IMVID_ANY, agent->get_id(agent),  
+                                                               msg_vid, msg_subtype, msg);
+}
+
+/**
+ * See header
+ */
+imc_msg_t *imc_msg_create_from_long_data(imc_agent_t *agent, imc_state_t *state,
+                                                                                TNC_ConnectionID connection_id,
+                                                                                TNC_UInt32 src_id,
+                                                                                TNC_UInt32 dst_id,
+                                                                                TNC_VendorID msg_vid,
+                                                                                TNC_MessageSubtype msg_subtype,
+                                                                                chunk_t msg)
+{
+       private_imc_msg_t *this;
+
+       INIT(this,
+               .public = {
+                       .get_src_id = _get_src_id,
+                       .get_dst_id = _get_dst_id,
+                       .send = _send_,
+                       .receive = _receive,
+                       .add_attribute = _add_attribute,
+                       .create_attribute_enumerator = _create_attribute_enumerator,
+                       .destroy = _destroy,
+               },
+               .connection_id = connection_id,
+               .src_id = src_id,
+               .dst_id = dst_id,
+               .msg_type = pen_type_create(msg_vid, msg_subtype),
+               .attr_list = linked_list_create(),
+               .pa_msg = pa_tnc_msg_create_from_data(msg),
+               .agent = agent,
+               .state = state,
+       );
+
+       return &this->public;
+}
+
diff --git a/src/libimcv/imc/imc_msg.h b/src/libimcv/imc/imc_msg.h
new file mode 100644 (file)
index 0000000..42cdd68
--- /dev/null
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2012 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup imc_msg imc_msg
+ * @{ @ingroup libimcv
+ */
+
+#ifndef IMC_MSG_H_
+#define IMC_MSG_H_
+
+#include <imc/imc_agent.h>
+
+typedef struct imc_msg_t imc_msg_t;
+
+#include <library.h>
+
+/**
+ * Interface for a PA-TNC message handled by an IMC.
+ *
+ */
+struct imc_msg_t {
+
+       /**
+        * Get source ID of PA-TNC message
+        *
+        * @return                                      src ID
+        */
+       TNC_UInt32 (*get_src_id)(imc_msg_t *this);
+
+       /**
+        * Get destination ID of PA-TNC message
+        *
+        * @return                                      destination ID
+        */
+       TNC_UInt32 (*get_dst_id)(imc_msg_t *this);
+
+       /**
+        * Sends one or multiple PA-TNC messages
+        *
+        * @param excl                          set the excl message flag if supported
+        * @return                                      TNC result code
+        */
+       TNC_Result (*send)(imc_msg_t *this, bool excl);
+
+       /**
+        * Processes a received PA-TNC message
+        *
+        * @param fatal_error           TRUE if IMV sent a fatal error message
+        * @return                                      TNC result code
+        */
+       TNC_Result (*receive)(imc_msg_t *this, bool *fatal_error);
+
+       /**
+        * Add a PA-TNC attribute to the send queue
+        *
+        * @param attr                          PA-TNC attribute to be added
+        */
+       void (*add_attribute)(imc_msg_t *this, pa_tnc_attr_t *attr);
+       
+       /**
+        * Enumerator over PA-TNC attributes contained in the PA-TNC message
+        *
+        * @return                                      PA-TNC attribute enumerator
+        */
+       enumerator_t* (*create_attribute_enumerator)(imc_msg_t *this);
+
+       /**
+        * Destroys a imc_msg_t object.
+        */
+       void (*destroy)(imc_msg_t *this);
+};
+
+/**
+ * Create a wrapper for an outbound message
+ *
+ * @param agent                                        IMC agent responsible for the message
+ * @param state                                        IMC state for the given connection ID
+ * @param connection_id                        connection ID
+ * @param src_id                               source IMC ID
+ * @param dst_id                               destination IMV ID
+ * @param msg_type                             PA-TNC message type
+ */
+imc_msg_t* imc_msg_create(imc_agent_t *agent, imc_state_t *state,
+                                                 TNC_ConnectionID connection_id,
+                                                 TNC_UInt32 src_id, TNC_UInt32 dst_id,
+                                                 pen_type_t msg_type);
+
+/**
+ * Create a wrapper for an outbound message based on a received message
+ *
+ * @param msg                                  received message the reply is based on
+ */
+imc_msg_t* imc_msg_create_as_reply(imc_msg_t *msg);
+
+/**
+ * Create a wrapper around message data received via the legacy IF-IMC interface
+ *
+ * @param agent                                        IMC agent responsible for the message
+ * @param state                                        IMC state for the given connection ID
+ * @param connection_id                        connection ID
+ * @param msg_type                             PA-TNC message type
+ * @param msg                                  received PA-TNC message blob
+ */
+imc_msg_t* imc_msg_create_from_data(imc_agent_t *agent, imc_state_t *state,
+                                                                       TNC_ConnectionID connection_id,
+                                                                       TNC_MessageType msg_type,
+                                                                       chunk_t msg); 
+
+/**
+ * Create a wrapper around message data received via the long IF-IMC interface
+ *
+ * @param agent                                        IMC agent responsible for the message
+ * @param state                                        IMC state for the given connection ID
+ * @param connection_id                        connection ID
+ * @param src_id                               source IMV ID
+ * @param dst_id                               destination IMC ID
+ * @param msg_flags                            PA-TNC message flags
+ * @param msg_vid                              PA-TNC message vendor ID
+ * @param msg_subtype                  PA-TNC subtype
+ * @param msg                                  received PA-TNC message blob
+ */
+imc_msg_t* imc_msg_create_from_long_data(imc_agent_t *agent, imc_state_t *state,
+                                                                                TNC_ConnectionID connection_id,
+                                                                                TNC_UInt32 src_id, TNC_UInt32 dst_id,
+                                                                                TNC_VendorID msg_vid,
+                                                                                TNC_MessageSubtype msg_subtype,
+                                                                                chunk_t msg); 
+
+#endif /** IMC_MSG_H_ @}*/
index d141488..f4fffa0 100644 (file)
 #include "imc_os_state.h"
 
 #include <imc/imc_agent.h>
+#include <imc/imc_msg.h>
 #include <pa_tnc/pa_tnc_msg.h>
 #include <ietf/ietf_attr.h>
-#include <ietf/ietf_attr_assess_result.h>
 #include <ietf/ietf_attr_attr_request.h>
 #include <ietf/ietf_attr_default_pwd_enabled.h>
 #include <ietf/ietf_attr_fwd_enabled.h>
 #include <ietf/ietf_attr_installed_packages.h>
 #include <ietf/ietf_attr_op_status.h>
-#include <ietf/ietf_attr_pa_tnc_error.h>
 #include <ietf/ietf_attr_product_info.h>
 #include <ietf/ietf_attr_string_version.h>
 #include <os_info/os_info.h>
@@ -120,30 +119,30 @@ TNC_Result TNC_IMC_NotifyConnectionChange(TNC_IMCID imc_id,
 /**
  * Add IETF Product Information attribute to the send queue
  */
-static void add_product_info(linked_list_t *attr_list)
+static void add_product_info(imc_msg_t *msg)
 {
        pa_tnc_attr_t *attr;
 
        attr = ietf_attr_product_info_create(PEN_IETF, 0, os->get_name(os));
-       attr_list->insert_last(attr_list, attr);
+       msg->add_attribute(msg, attr);
 }
 
 /**
  * Add IETF String Version attribute to the send queue
  */
-static void add_string_version(linked_list_t *attr_list)
+static void add_string_version(imc_msg_t *msg)
 {
        pa_tnc_attr_t *attr;
 
        attr = ietf_attr_string_version_create(os->get_version(os),
                                                                                   chunk_empty, chunk_empty);
-       attr_list->insert_last(attr_list, attr);
+       msg->add_attribute(msg, attr);
 }
 
 /**
  * Add IETF Operational Status attribute to the send queue
  */
-static void add_op_status(linked_list_t *attr_list)
+static void add_op_status(imc_msg_t *msg)
 {
        pa_tnc_attr_t *attr;
        time_t uptime, last_boot;
@@ -156,13 +155,13 @@ static void add_op_status(linked_list_t *attr_list)
        }
        attr = ietf_attr_op_status_create(OP_STATUS_OPERATIONAL,
                                                                          OP_RESULT_SUCCESSFUL, last_boot);
-       attr_list->insert_last(attr_list, attr);
+       msg->add_attribute(msg, attr);
 }
 
 /**
  * Add IETF Forwarding Enabled attribute to the send queue
  */
-static void add_fwd_enabled(linked_list_t *attr_list)
+static void add_fwd_enabled(imc_msg_t *msg)
 {
        pa_tnc_attr_t *attr;
        os_fwd_status_t fwd_status;
@@ -171,25 +170,25 @@ static void add_fwd_enabled(linked_list_t *attr_list)
        DBG1(DBG_IMC, "IPv4 forwarding status: %N",
                                   os_fwd_status_names, fwd_status);
        attr = ietf_attr_fwd_enabled_create(fwd_status);
-       attr_list->insert_last(attr_list, attr);
+       msg->add_attribute(msg, attr);
 }
 
 /**
  * Add IETF Factory Default Password Enabled attribute to the send queue
  */
-static void add_default_pwd_enabled(linked_list_t *attr_list)
+static void add_default_pwd_enabled(imc_msg_t *msg)
 {
        pa_tnc_attr_t *attr;
 
        DBG1(DBG_IMC, "factory default password: disabled");
        attr = ietf_attr_default_pwd_enabled_create(FALSE);
-       attr_list->insert_last(attr_list, attr);
+       msg->add_attribute(msg, attr);
 }
 
 /**
  * Add an IETF Installed Packages attribute to the send queue
  */
-static void add_installed_packages(linked_list_t *attr_list)
+static void add_installed_packages(imc_msg_t *msg)
 {
        pa_tnc_attr_t *attr;
        ietf_attr_installed_packages_t *attr_cast;
@@ -202,7 +201,7 @@ static void add_installed_packages(linked_list_t *attr_list)
        attr_cast = (ietf_attr_installed_packages_t*)attr;
        attr_cast->add(attr_cast, libc_name, libc_version);
        attr_cast->add(attr_cast, selinux_name, selinux_version);
-       attr_list->insert_last(attr_list, attr);
+       msg->add_attribute(msg, attr);
 }
 
 /**
@@ -211,6 +210,8 @@ static void add_installed_packages(linked_list_t *attr_list)
 TNC_Result TNC_IMC_BeginHandshake(TNC_IMCID imc_id,
                                                                  TNC_ConnectionID connection_id)
 {
+       imc_state_t *state;
+       imc_msg_t *out_msg;
        TNC_Result result = TNC_RESULT_SUCCESS;
 
        if (!imc_os)
@@ -218,75 +219,48 @@ TNC_Result TNC_IMC_BeginHandshake(TNC_IMCID imc_id,
                DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
                return TNC_RESULT_NOT_INITIALIZED;
        }
-
+       if (!imc_os->get_state(imc_os, connection_id, &state))
+       {
+               return TNC_RESULT_FATAL;
+       }
        if (lib->settings->get_bool(lib->settings,
                                                                "libimcv.plugins.imc-os.send_info", TRUE))
        {
-               linked_list_t *attr_list;
-
-               attr_list = linked_list_create();
-               add_product_info(attr_list);
-               add_string_version(attr_list);
-               add_op_status(attr_list);
-               add_fwd_enabled(attr_list);
-               add_default_pwd_enabled(attr_list);
-               result = imc_os->send_message(imc_os, connection_id, FALSE, 0,
-                                       TNC_IMVID_ANY, PEN_IETF, PA_SUBTYPE_IETF_OPERATING_SYSTEM,
-                                       attr_list);
-               attr_list->destroy(attr_list);
+               out_msg = imc_msg_create(imc_os, state, connection_id, imc_id,
+                                                                TNC_IMVID_ANY, msg_types[0]);
+               add_product_info(out_msg);
+               add_string_version(out_msg);
+               add_op_status(out_msg);
+               add_fwd_enabled(out_msg);
+               add_default_pwd_enabled(out_msg);
+
+               /* send PA-TNC message with the excl flag not set */
+               result = out_msg->send(out_msg, FALSE);
+               out_msg->destroy(out_msg);
        }
 
        return result;
 }
 
-static TNC_Result receive_message(TNC_IMCID imc_id,
-                                                                 TNC_ConnectionID connection_id,
-                                                                 TNC_UInt32 msg_flags,
-                                                                 chunk_t msg,
-                                                                 TNC_VendorID msg_vid,
-                                                                 TNC_MessageSubtype msg_subtype,
-                                                                 TNC_UInt32 src_imv_id,
-                                                                 TNC_UInt32 dst_imc_id)
+static TNC_Result receive_message(imc_msg_t *in_msg)
 {
-       pa_tnc_msg_t *pa_tnc_msg;
+       imc_msg_t *out_msg;
+       enumerator_t *enumerator;
        pa_tnc_attr_t *attr;
        pen_type_t attr_type;
-       linked_list_t *attr_list;
-       imc_state_t *state;
-       enumerator_t *enumerator;
        TNC_Result result;
-       TNC_UInt32 target_imc_id;
-       bool fatal_error;
-
-       if (!imc_os)
-       {
-               DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
-               return TNC_RESULT_NOT_INITIALIZED;
-       }
-
-       /* get current IMC state */
-       if (!imc_os->get_state(imc_os, connection_id, &state))
-       {
-               return TNC_RESULT_FATAL;
-       }
+       bool fatal_error = FALSE;
 
-       /* parse received PA-TNC message and automatically handle any errors */
-       result = imc_os->receive_message(imc_os, state, msg, msg_vid,
-                                                       msg_subtype, src_imv_id, dst_imc_id, &pa_tnc_msg);
-
-       /* no parsed PA-TNC attributes available if an error occurred */
-       if (!pa_tnc_msg)
+       /* parse received PA-TNC message and handle local and remote errors */
+       result = in_msg->receive(in_msg, &fatal_error);
+       if (result != TNC_RESULT_SUCCESS)
        {
                return result;
        }
-       target_imc_id = (dst_imc_id == TNC_IMCID_ANY) ? imc_id : dst_imc_id;
-
-       /* preprocess any IETF standard error attributes */
-       fatal_error = pa_tnc_msg->process_ietf_std_errors(pa_tnc_msg);
+       out_msg = imc_msg_create_as_reply(in_msg);
 
        /* analyze PA-TNC attributes */
-       attr_list = linked_list_create();
-       enumerator = pa_tnc_msg->create_attribute_enumerator(pa_tnc_msg);
+       enumerator = in_msg->create_attribute_enumerator(in_msg);
        while (enumerator->enumerate(enumerator, &attr))
        {
                attr_type = attr->get_type(attr);
@@ -313,22 +287,22 @@ static TNC_Result receive_message(TNC_IMCID imc_id,
                                switch (entry->type)
                                {
                                        case IETF_ATTR_PRODUCT_INFORMATION:
-                                               add_product_info(attr_list);
+                                               add_product_info(out_msg);
                                                break;
                                        case IETF_ATTR_STRING_VERSION:
-                                               add_string_version(attr_list);
+                                               add_string_version(out_msg);
                                                break;
                                        case IETF_ATTR_OPERATIONAL_STATUS:
-                                               add_op_status(attr_list);
+                                               add_op_status(out_msg);
                                                break;
                                        case IETF_ATTR_FORWARDING_ENABLED:
-                                               add_fwd_enabled(attr_list);
+                                               add_fwd_enabled(out_msg);
                                                break;
                                        case IETF_ATTR_FACTORY_DEFAULT_PWD_ENABLED:
-                                               add_default_pwd_enabled(attr_list);
+                                               add_default_pwd_enabled(out_msg);
                                                break;
                                        case IETF_ATTR_INSTALLED_PACKAGES:
-                                               add_installed_packages(attr_list);
+                                               add_installed_packages(out_msg);
                                                break;
                                        default:
                                                break;
@@ -336,35 +310,18 @@ static TNC_Result receive_message(TNC_IMCID imc_id,
                        }
                        e->destroy(e); 
                }
-               else if (attr_type.type == IETF_ATTR_ASSESSMENT_RESULT)
-               {
-                       ietf_attr_assess_result_t *attr_cast;
-
-                       attr_cast = (ietf_attr_assess_result_t*)attr;
-                       state->set_result(state, target_imc_id,
-                                                         attr_cast->get_result(attr_cast));
-               }
        }
        enumerator->destroy(enumerator);
-       pa_tnc_msg->destroy(pa_tnc_msg);
 
        if (fatal_error)
        {
-               attr_list->destroy_offset(attr_list, offsetof(pa_tnc_attr_t, destroy));
-               return TNC_RESULT_FATAL;
-       }
-
-       if (attr_list->get_count(attr_list))
-       {
-               result = imc_os->send_message(imc_os, connection_id, TRUE, imc_id,
-                                               src_imv_id, PEN_IETF, PA_SUBTYPE_IETF_OPERATING_SYSTEM,
-                                               attr_list);
+               result = TNC_RESULT_FATAL;
        }
        else
        {
-               result = TNC_RESULT_SUCCESS;
+               result = out_msg->send(out_msg, TRUE);
        }
-       attr_list->destroy(attr_list);
+       out_msg->destroy(out_msg);
 
        return result;
 }
@@ -379,14 +336,25 @@ TNC_Result TNC_IMC_ReceiveMessage(TNC_IMCID imc_id,
                                                                  TNC_UInt32 msg_len,
                                                                  TNC_MessageType msg_type)
 {
-       TNC_VendorID msg_vid;
-       TNC_MessageSubtype msg_subtype;
+       imc_state_t *state;
+       imc_msg_t *in_msg;
+       TNC_Result result;
 
-       msg_vid = msg_type >> 8;
-       msg_subtype = msg_type & TNC_SUBTYPE_ANY;
+       if (!imc_os)
+       {
+               DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
+               return TNC_RESULT_NOT_INITIALIZED;
+       }
+       if (!imc_os->get_state(imc_os, connection_id, &state))
+       {
+               return TNC_RESULT_FATAL;
+       }
+       in_msg = imc_msg_create_from_data(imc_os, state, connection_id, msg_type,
+                                                                         chunk_create(msg, msg_len));
+       result = receive_message(in_msg);
+       in_msg->destroy(in_msg);
 
-       return receive_message(imc_id, connection_id, 0, chunk_create(msg, msg_len),
-                                                  msg_vid,     msg_subtype, 0, TNC_IMCID_ANY);
+       return result;
 }
 
 /**
@@ -402,9 +370,26 @@ TNC_Result TNC_IMC_ReceiveMessageLong(TNC_IMCID imc_id,
                                                                          TNC_UInt32 src_imv_id,
                                                                          TNC_UInt32 dst_imc_id)
 {
-       return receive_message(imc_id, connection_id, msg_flags,
-                                                  chunk_create(msg, msg_len), msg_vid, msg_subtype,
-                                                  src_imv_id, dst_imc_id);
+       imc_state_t *state;
+       imc_msg_t *in_msg;
+       TNC_Result result;
+
+       if (!imc_os)
+       {
+               DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
+               return TNC_RESULT_NOT_INITIALIZED;
+       }
+       if (!imc_os->get_state(imc_os, connection_id, &state))
+       {
+               return TNC_RESULT_FATAL;
+       }
+       in_msg = imc_msg_create_from_long_data(imc_os, state, connection_id,
+                                                               src_imv_id, dst_imc_id,msg_vid, msg_subtype,
+                                                               chunk_create(msg, msg_len));
+       result =receive_message(in_msg);
+       in_msg->destroy(in_msg);
+
+       return result;
 }
 
 /**
index 5ad7379..859e1f8 100644 (file)
@@ -109,8 +109,6 @@ METHOD(imc_state_t, set_result, void,
        private_imc_os_state_t *this, TNC_IMCID id,
        TNC_IMV_Evaluation_Result result)
 {
-       DBG1(DBG_IMC, "set assessment result for IMC %u to '%N'",
-                id, TNC_IMV_Evaluation_Result_names, result);
        this->result = result;
 }
 
index d82d1fa..c3bfab6 100644 (file)
 #include "imc_scanner_state.h"
 
 #include <imc/imc_agent.h>
+#include <imc/imc_msg.h>
 #include <pa_tnc/pa_tnc_msg.h>
 #include <ietf/ietf_attr.h>
-#include <ietf/ietf_attr_pa_tnc_error.h>
 #include <ietf/ietf_attr_port_filter.h>
-#include <ietf/ietf_attr_assess_result.h>
 
 #include <tncif_pa_subtypes.h>
 
@@ -229,12 +228,10 @@ end:
        return success;
 }
 
-static TNC_Result send_message(TNC_ConnectionID connection_id)
+static TNC_Result send_message(imc_msg_t *out_msg)
 {
-       linked_list_t *attr_list;
        pa_tnc_attr_t *attr;
        ietf_attr_port_filter_t *attr_port_filter;
-       TNC_Result result;
 
        attr = ietf_attr_port_filter_create();
        attr->set_noskip_flag(attr, TRUE);
@@ -244,14 +241,10 @@ static TNC_Result send_message(TNC_ConnectionID connection_id)
                attr->destroy(attr);
                return TNC_RESULT_FATAL;
        }
-       attr_list = linked_list_create();
-       attr_list->insert_last(attr_list, attr);
-       result = imc_scanner->send_message(imc_scanner, connection_id, FALSE, 0,
-                                                       TNC_IMVID_ANY, PEN_ITA, PA_SUBTYPE_ITA_SCANNER,
-                                                       attr_list);
-       attr_list->destroy(attr_list);
+       out_msg->add_attribute(out_msg, attr);
 
-       return result;
+       /* send PA-TNC message with the excl flag not set */
+       return out_msg->send(out_msg, FALSE);
 }
 
 /**
@@ -260,85 +253,39 @@ static TNC_Result send_message(TNC_ConnectionID connection_id)
 TNC_Result TNC_IMC_BeginHandshake(TNC_IMCID imc_id,
                                                                  TNC_ConnectionID connection_id)
 {
-       if (!imc_scanner)
-       {
-               DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
-               return TNC_RESULT_NOT_INITIALIZED;
-       }
-       return send_message(connection_id);
-}
-
-static TNC_Result receive_message(TNC_IMCID imc_id,
-                                                                 TNC_ConnectionID connection_id,
-                                                                 TNC_UInt32 msg_flags,
-                                                                 chunk_t msg,
-                                                                 TNC_VendorID msg_vid,
-                                                                 TNC_MessageSubtype msg_subtype,
-                                                                 TNC_UInt32 src_imv_id,
-                                                                 TNC_UInt32 dst_imc_id)
-{
-       pa_tnc_msg_t *pa_tnc_msg;
-       pa_tnc_attr_t *attr;
-       pen_type_t attr_type;
        imc_state_t *state;
-       enumerator_t *enumerator;
+       imc_msg_t *out_msg;
        TNC_Result result;
-       TNC_UInt32 target_imc_id;
-       bool fatal_error;
 
        if (!imc_scanner)
        {
                DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
                return TNC_RESULT_NOT_INITIALIZED;
        }
-
-       /* get current IMC state */
        if (!imc_scanner->get_state(imc_scanner, connection_id, &state))
        {
                return TNC_RESULT_FATAL;
        }
+       out_msg = imc_msg_create(imc_scanner, state, connection_id, imc_id,
+                                                        TNC_IMVID_ANY, msg_types[0]);
+       result = send_message(out_msg);
+       out_msg->destroy(out_msg);
 
-       /* parse received PA-TNC message and automatically handle any errors */
-       result = imc_scanner->receive_message(imc_scanner, state, msg, msg_vid,
-                                                       msg_subtype, src_imv_id, dst_imc_id, &pa_tnc_msg);
-
-       /* no parsed PA-TNC attributes available if an error occurred */
-       if (!pa_tnc_msg)
-       {
-               return result;
-       }
-       target_imc_id = (dst_imc_id == TNC_IMCID_ANY) ? imc_id : dst_imc_id;
-
-       /* preprocess any IETF standard error attributes */
-       fatal_error = pa_tnc_msg->process_ietf_std_errors(pa_tnc_msg);
-
-       /* analyze PA-TNC attributes */
-       enumerator = pa_tnc_msg->create_attribute_enumerator(pa_tnc_msg);
-       while (enumerator->enumerate(enumerator, &attr))
-       {
-               attr_type = attr->get_type(attr);
-
-               if (attr_type.vendor_id == PEN_IETF &&
-                       attr_type.type == IETF_ATTR_ASSESSMENT_RESULT)
-               {
-                       ietf_attr_assess_result_t *ietf_attr;
+       return result;
+}
 
-                       ietf_attr = (ietf_attr_assess_result_t*)attr;
-                       state->set_result(state, target_imc_id,
-                                                         ietf_attr->get_result(ietf_attr));
-               }
-       }
-       enumerator->destroy(enumerator);
-       pa_tnc_msg->destroy(pa_tnc_msg);
+static TNC_Result receive_message(imc_msg_t *in_msg)
+{
+       TNC_Result result;
+       bool fatal_error = FALSE;
 
-       if (fatal_error)
+       /* parse received PA-TNC message and handle local and remote errors */
+       result = in_msg->receive(in_msg, &fatal_error);
+       if (result != TNC_RESULT_SUCCESS)
        {
-               return TNC_RESULT_FATAL;
+               return result;
        }
-
-       /* if no assessment result is known then repeat the measurement */
-       return state->get_result(state, target_imc_id, NULL) ?
-                  TNC_RESULT_SUCCESS : send_message(connection_id);
+       return fatal_error ? TNC_RESULT_FATAL : TNC_RESULT_SUCCESS;
 }
 
 /**
@@ -351,14 +298,26 @@ TNC_Result TNC_IMC_ReceiveMessage(TNC_IMCID imc_id,
                                                                  TNC_UInt32 msg_len,
                                                                  TNC_MessageType msg_type)
 {
-       TNC_VendorID msg_vid;
-       TNC_MessageSubtype msg_subtype;
+       imc_state_t *state;
+       imc_msg_t *in_msg;
+       TNC_Result result;
 
-       msg_vid = msg_type >> 8;
-       msg_subtype = msg_type & TNC_SUBTYPE_ANY;
+       if (!imc_scanner)
+       {
+               DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
+               return TNC_RESULT_NOT_INITIALIZED;
+       }
+       if (!imc_scanner->get_state(imc_scanner, connection_id, &state))
+       {
+               return TNC_RESULT_FATAL;
+       }
+
+       in_msg = imc_msg_create_from_data(imc_scanner, state, connection_id,
+                                                                         msg_type, chunk_create(msg, msg_len));
+       result = receive_message(in_msg);
+       in_msg->destroy(in_msg);
 
-       return receive_message(imc_id, connection_id, 0, chunk_create(msg, msg_len),
-                                                  msg_vid,     msg_subtype, 0, TNC_IMCID_ANY);
+       return result;
 }
 
 /**
@@ -374,9 +333,26 @@ TNC_Result TNC_IMC_ReceiveMessageLong(TNC_IMCID imc_id,
                                                                          TNC_UInt32 src_imv_id,
                                                                          TNC_UInt32 dst_imc_id)
 {
-       return receive_message(imc_id, connection_id, msg_flags,
-                                                  chunk_create(msg, msg_len), msg_vid, msg_subtype,
-                                                  src_imv_id, dst_imc_id);
+       imc_state_t *state;
+       imc_msg_t *in_msg;
+       TNC_Result result;
+
+       if (!imc_scanner)
+       {
+               DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
+               return TNC_RESULT_NOT_INITIALIZED;
+       }
+       if (!imc_scanner->get_state(imc_scanner, connection_id, &state))
+       {
+               return TNC_RESULT_FATAL;
+       }
+       in_msg = imc_msg_create_from_long_data(imc_scanner, state, connection_id,
+                                                               src_imv_id, dst_imc_id, msg_vid, msg_subtype,
+                                                               chunk_create(msg, msg_len));
+       result =receive_message(in_msg);
+       in_msg->destroy(in_msg);
+
+       return result;
 }
 
 /**
index 991b24a..d47c4ec 100644 (file)
@@ -109,8 +109,6 @@ METHOD(imc_state_t, set_result, void,
        private_imc_scanner_state_t *this, TNC_IMCID id,
        TNC_IMV_Evaluation_Result result)
 {
-       DBG1(DBG_IMC, "set assessment result for IMC %u to '%N'",
-                id, TNC_IMV_Evaluation_Result_names, result);
        this->result = result;
 }
 
index b8ee137..68352e1 100644 (file)
 #include "imc_test_state.h"
 
 #include <imc/imc_agent.h>
+#include <imc/imc_msg.h>
 #include <pa_tnc/pa_tnc_msg.h>
 #include <ietf/ietf_attr.h>
-#include <ietf/ietf_attr_pa_tnc_error.h>
-#include <ietf/ietf_attr_assess_result.h>
 #include <ita/ita_attr.h>
 #include <ita/ita_attr_command.h>
 #include <ita/ita_attr_dummy.h>
@@ -182,37 +181,24 @@ TNC_Result TNC_IMC_NotifyConnectionChange(TNC_IMCID imc_id,
        }
 }
 
-static TNC_Result send_message(imc_state_t *state, TNC_UInt32 src_imc_id,
-                                                                                                  TNC_UInt32 dst_imv_id)
+static TNC_Result send_message(imc_state_t *state, imc_msg_t *out_msg)
 {
        imc_test_state_t *test_state;
-       linked_list_t *attr_list;
        pa_tnc_attr_t *attr;
-       bool excl;
-       TNC_ConnectionID connection_id;
-       TNC_Result result;
 
-       attr_list = linked_list_create();
-       connection_id = state->get_connection_id(state);
        test_state = (imc_test_state_t*)state;
-
        if (test_state->get_dummy_size(test_state))
        {
                attr = ita_attr_dummy_create(test_state->get_dummy_size(test_state));
                attr->set_noskip_flag(attr, TRUE);
-               attr_list->insert_last(attr_list, attr);
+               out_msg->add_attribute(out_msg, attr);
        }
        attr = ita_attr_command_create(test_state->get_command(test_state));
        attr->set_noskip_flag(attr, TRUE);
-       attr_list->insert_last(attr_list, attr);
+       out_msg->add_attribute(out_msg, attr);
 
-       excl = dst_imv_id != TNC_IMVID_ANY;
-       result = imc_test->send_message(imc_test, connection_id, excl, src_imc_id,
-                                                                       dst_imv_id, PEN_ITA, PA_SUBTYPE_ITA_TEST,
-                                                                       attr_list);
-       attr_list->destroy(attr_list);
-
-       return result;
+       /* send PA-TNC message with the excl flag set */
+       return out_msg->send(out_msg, TRUE);
 }
 
 /**
@@ -222,6 +208,7 @@ TNC_Result TNC_IMC_BeginHandshake(TNC_IMCID imc_id,
                                                                  TNC_ConnectionID connection_id)
 {
        imc_state_t *state;
+       imc_msg_t *out_msg;
        enumerator_t *enumerator;
        void *pointer;
        TNC_UInt32 additional_id;
@@ -232,15 +219,16 @@ TNC_Result TNC_IMC_BeginHandshake(TNC_IMCID imc_id,
                DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
                return TNC_RESULT_NOT_INITIALIZED;
        }
-
-       /* get current IMC state */
        if (!imc_test->get_state(imc_test, connection_id, &state))
        {
                return TNC_RESULT_FATAL;
        }
 
        /* send PA message for primary IMC ID */
-       result = send_message(state, imc_id, TNC_IMVID_ANY);
+       out_msg = imc_msg_create(imc_test, state, connection_id, imc_id,
+                                                        TNC_IMVID_ANY, msg_types[0]);
+       result = send_message(state, out_msg);
+       out_msg->destroy(out_msg);
 
        /* Exit if there are no additional IMC IDs */
        if (!imc_test->count_additional_ids(imc_test))
@@ -263,93 +251,60 @@ TNC_Result TNC_IMC_BeginHandshake(TNC_IMCID imc_id,
        {
                /* interpret pointer as scalar value */
                additional_id = (TNC_UInt32)pointer;
-               result = send_message(state, additional_id, TNC_IMVID_ANY);     
+               out_msg = imc_msg_create(imc_test, state, connection_id, additional_id,
+                                                                TNC_IMVID_ANY, msg_types[0]);
+               result = send_message(state, out_msg);
+               out_msg->destroy(out_msg);
        }
        enumerator->destroy(enumerator);
 
        return result;
 }
 
-static TNC_Result receive_message(TNC_IMCID imc_id,
-                                                                 TNC_ConnectionID connection_id,
-                                                                 TNC_UInt32 msg_flags,
-                                                                 chunk_t msg,
-                                                                 TNC_VendorID msg_vid,
-                                                                 TNC_MessageSubtype msg_subtype,
-                                                                 TNC_UInt32 src_imv_id,
-                                                                 TNC_UInt32 dst_imc_id)
+static TNC_Result receive_message(imc_state_t *state, imc_msg_t *in_msg)
 {
-       pa_tnc_msg_t *pa_tnc_msg;
+       imc_msg_t *out_msg;
+       enumerator_t *enumerator;
        pa_tnc_attr_t *attr;
        pen_type_t attr_type;
-       imc_state_t *state;
-       enumerator_t *enumerator;
        TNC_Result result;
-       TNC_UInt32 target_imc_id;
        bool fatal_error = FALSE;
 
-       if (!imc_test)
-       {
-               DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
-               return TNC_RESULT_NOT_INITIALIZED;
-       }
-
-       /* get current IMC state */
-       if (!imc_test->get_state(imc_test, connection_id, &state))
-       {
-               return TNC_RESULT_FATAL;
-       }
-
-       /* parse received PA-TNC message and automatically handle any errors */ 
-       result = imc_test->receive_message(imc_test, state, msg, msg_vid,
-                                                       msg_subtype, src_imv_id, dst_imc_id, &pa_tnc_msg);
-
-       /* no parsed PA-TNC attributes available if an error occurred */
-       if (!pa_tnc_msg)
+       /* parse received PA-TNC message and handle local and remote errors */
+       result = in_msg->receive(in_msg, &fatal_error);
+       if (result != TNC_RESULT_SUCCESS)
        {
                return result;
        }
-       target_imc_id = (dst_imc_id == TNC_IMCID_ANY) ? imc_id : dst_imc_id;
-
-       /* preprocess any IETF standard error attributes */
-       fatal_error = pa_tnc_msg->process_ietf_std_errors(pa_tnc_msg);
 
        /* analyze PA-TNC attributes */
-       enumerator = pa_tnc_msg->create_attribute_enumerator(pa_tnc_msg);
+       enumerator = in_msg->create_attribute_enumerator(in_msg);
        while (enumerator->enumerate(enumerator, &attr))
        {
                attr_type = attr->get_type(attr);
 
-               if (attr_type.vendor_id == PEN_IETF)
+               if (attr_type.vendor_id != PEN_ITA)
                {
-                       ietf_attr_assess_result_t *ietf_attr;
-
-                       ietf_attr = (ietf_attr_assess_result_t*)attr;
-                       state->set_result(state, target_imc_id,
-                                                         ietf_attr->get_result(ietf_attr));
+                       continue;
                }
-               else if (attr_type.vendor_id == PEN_ITA)
+               if (attr_type.type == ITA_ATTR_COMMAND)
                {
-                       if (attr_type.type == ITA_ATTR_COMMAND)
-                       {
-                               ita_attr_command_t *ita_attr;
+                       ita_attr_command_t *ita_attr;
 
-                               ita_attr = (ita_attr_command_t*)attr;
-                               DBG1(DBG_IMC, "received command '%s'",
-                                        ita_attr->get_command(ita_attr));
-                       }
-                       else if (attr_type.type == ITA_ATTR_DUMMY)
-                       {
-                               ita_attr_dummy_t *ita_attr;
+                       ita_attr = (ita_attr_command_t*)attr;
+                       DBG1(DBG_IMC, "received command '%s'",
+                                ita_attr->get_command(ita_attr));
+               }
+               else if (attr_type.type == ITA_ATTR_DUMMY)
+               {
+                       ita_attr_dummy_t *ita_attr;
 
-                               ita_attr = (ita_attr_dummy_t*)attr;
-                               DBG1(DBG_IMC, "received dummy attribute value (%d bytes)",
-                                        ita_attr->get_size(ita_attr));
-                       }
+                       ita_attr = (ita_attr_dummy_t*)attr;
+                       DBG1(DBG_IMC, "received dummy attribute value (%d bytes)",
+                                ita_attr->get_size(ita_attr));
                }
        }
        enumerator->destroy(enumerator);
-       pa_tnc_msg->destroy(pa_tnc_msg);
 
        if (fatal_error)
        {
@@ -357,8 +312,15 @@ static TNC_Result receive_message(TNC_IMCID imc_id,
        }
 
        /* if no assessment result is known then repeat the measurement */
-       return state->get_result(state, target_imc_id, NULL) ?
-                  TNC_RESULT_SUCCESS : send_message(state, dst_imc_id, src_imv_id);
+       if (state->get_result(state, in_msg->get_dst_id(in_msg), NULL))
+       {
+               return TNC_RESULT_SUCCESS;
+       }
+       out_msg = imc_msg_create_as_reply(in_msg);
+       result = send_message(state, out_msg);
+       out_msg->destroy(out_msg);
+
+       return result;
 }
 
 /**
@@ -370,14 +332,26 @@ TNC_Result TNC_IMC_ReceiveMessage(TNC_IMCID imc_id,
                                                                  TNC_UInt32 msg_len,
                                                                  TNC_MessageType msg_type)
 {
-       TNC_VendorID msg_vid;
-       TNC_MessageSubtype msg_subtype;
+       imc_state_t *state;
+       imc_msg_t *in_msg;
+       TNC_Result result;
+
+       if (!imc_test)
+       {
+               DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
+               return TNC_RESULT_NOT_INITIALIZED;
+       }
+       if (!imc_test->get_state(imc_test, connection_id, &state))
+       {
+               return TNC_RESULT_FATAL;
+       }
 
-       msg_vid = msg_type >> 8;
-       msg_subtype = msg_type & TNC_SUBTYPE_ANY;
+       in_msg = imc_msg_create_from_data(imc_test, state, connection_id, msg_type,
+                                                                         chunk_create(msg, msg_len));
+       result = receive_message(state, in_msg);
+       in_msg->destroy(in_msg);
 
-       return receive_message(imc_id, connection_id, 0, chunk_create(msg, msg_len),
-                                                  msg_vid,     msg_subtype, 0, TNC_IMCID_ANY);
+       return result;
 }
 
 /**
@@ -393,9 +367,26 @@ TNC_Result TNC_IMC_ReceiveMessageLong(TNC_IMCID imc_id,
                                                                          TNC_UInt32 src_imv_id,
                                                                          TNC_UInt32 dst_imc_id)
 {
-       return receive_message(imc_id, connection_id, msg_flags,
-                                                  chunk_create(msg, msg_len), msg_vid, msg_subtype,
-                                                  src_imv_id, dst_imc_id);
+       imc_state_t *state;
+       imc_msg_t *in_msg;
+       TNC_Result result;
+
+       if (!imc_test)
+       {
+               DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
+               return TNC_RESULT_NOT_INITIALIZED;
+       }
+       if (!imc_test->get_state(imc_test, connection_id, &state))
+       {
+               return TNC_RESULT_FATAL;
+       }
+       in_msg = imc_msg_create_from_long_data(imc_test, state, connection_id,
+                                                               src_imv_id, dst_imc_id, msg_vid, msg_subtype,
+                                                               chunk_create(msg, msg_len));
+       result =receive_message(state, in_msg);
+       in_msg->destroy(in_msg);
+
+       return result;
 }
 
 /**
index e70eb14..7d2db7c 100644 (file)
@@ -144,9 +144,6 @@ METHOD(imc_state_t, set_result, void,
        entry_t *entry;
        bool found = FALSE;
 
-       DBG1(DBG_IMC, "set assessment result for IMC %u to '%N'",
-                id, TNC_IMV_Evaluation_Result_names, result);
-
        enumerator = this->results->create_enumerator(this->results);
        while (enumerator->enumerate(enumerator, &entry))
        {
index a2b118d..ee3d5c8 100644 (file)
@@ -17,6 +17,7 @@
 #include "imc_attestation_process.h"
 
 #include <imc/imc_agent.h>
+#include <imc/imc_msg.h>
 #include <pa_tnc/pa_tnc_msg.h>
 #include <ietf/ietf_attr.h>
 #include <ietf/ietf_attr_pa_tnc_error.h>
@@ -147,57 +148,26 @@ TNC_Result TNC_IMC_BeginHandshake(TNC_IMCID imc_id,
        return TNC_RESULT_SUCCESS;
 }
 
-static TNC_Result receive_message(TNC_IMCID imc_id,
-                                                                 TNC_ConnectionID connection_id,
-                                                                 TNC_UInt32 msg_flags,
-                                                                 chunk_t msg,
-                                                                 TNC_VendorID msg_vid,
-                                                                 TNC_MessageSubtype msg_subtype,
-                                                                 TNC_UInt32 src_imv_id,
-                                                                 TNC_UInt32 dst_imc_id)
+static TNC_Result receive_message(imc_state_t *state, imc_msg_t *in_msg)
 {
-       pa_tnc_msg_t *pa_tnc_msg;
-       pa_tnc_attr_t *attr;
-       pen_type_t type;
-       linked_list_t *attr_list;
-       imc_state_t *state;
+       imc_msg_t *out_msg;
        imc_attestation_state_t *attestation_state;
        enumerator_t *enumerator;
+       pa_tnc_attr_t *attr;
+       pen_type_t type;
        TNC_Result result;
-       TNC_UInt32 target_imc_id;
-
-       if (!imc_attestation)
-       {
-               DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
-               return TNC_RESULT_NOT_INITIALIZED;
-       }
-
-       /* get current IMC state */
-       if (!imc_attestation->get_state(imc_attestation, connection_id, &state))
-       {
-               return TNC_RESULT_FATAL;
-       }
-       attestation_state = (imc_attestation_state_t*)state;
+       bool fatal_error = FALSE;
 
-       /* parse received PA-TNC message and automatically handle any errors */
-       result = imc_attestation->receive_message(imc_attestation, state, msg,
-                                       msg_vid, msg_subtype, src_imv_id, dst_imc_id, &pa_tnc_msg);
-
-       /* no parsed PA-TNC attributes available if an error occurred */
-       if (!pa_tnc_msg)
+       /* parse received PA-TNC message and handle local and remote errors */
+       result = in_msg->receive(in_msg, &fatal_error);
+       if (result != TNC_RESULT_SUCCESS)
        {
                return result;
        }
-       target_imc_id = (dst_imc_id == TNC_IMCID_ANY) ? imc_id : dst_imc_id;
-       
-       /* preprocess any IETF standard error attributes */
-       result = pa_tnc_msg->process_ietf_std_errors(pa_tnc_msg) ?
-                                       TNC_RESULT_FATAL : TNC_RESULT_SUCCESS;
-
-       attr_list = linked_list_create();
+       out_msg = imc_msg_create_as_reply(in_msg);
 
        /* analyze PA-TNC attributes */
-       enumerator = pa_tnc_msg->create_attribute_enumerator(pa_tnc_msg);
+       enumerator = in_msg->create_attribute_enumerator(in_msg);
        while (enumerator->enumerate(enumerator, &attr))
        {
                type = attr->get_type(attr);
@@ -224,18 +194,12 @@ static TNC_Result receive_message(TNC_IMCID imc_id,
                                        result = TNC_RESULT_FATAL;
                                }
                        }
-                       else if (type.type == IETF_ATTR_ASSESSMENT_RESULT)
-                       {
-                               ietf_attr_assess_result_t *ietf_attr;
-
-                               ietf_attr = (ietf_attr_assess_result_t*)attr;
-                               state->set_result(state, target_imc_id,
-                                                                 ietf_attr->get_result(ietf_attr));
-                       }
                }
                else if (type.vendor_id == PEN_TCG)
                {
-                       if (!imc_attestation_process(attr, attr_list, attestation_state,
+                       attestation_state = (imc_attestation_state_t*)state;
+
+                       if (!imc_attestation_process(attr, out_msg, attestation_state,
                                supported_algorithms, supported_dh_groups))
                        {
                                result = TNC_RESULT_FATAL;
@@ -244,15 +208,13 @@ static TNC_Result receive_message(TNC_IMCID imc_id,
                }
        }
        enumerator->destroy(enumerator);
-       pa_tnc_msg->destroy(pa_tnc_msg);
 
-       if (result == TNC_RESULT_SUCCESS && attr_list->get_count(attr_list))
+       if (result == TNC_RESULT_SUCCESS)
        {
-               result = imc_attestation->send_message(imc_attestation, connection_id,
-                                               FALSE, 0, TNC_IMVID_ANY, PEN_TCG, PA_SUBTYPE_TCG_PTS,
-                                               attr_list);
+               /* send PA-TNC message with the excl flag set */
+               result = out_msg->send(out_msg, TRUE);
        }
-       attr_list->destroy(attr_list);
+       out_msg->destroy(out_msg);
 
        return result;
 }
@@ -266,14 +228,26 @@ TNC_Result TNC_IMC_ReceiveMessage(TNC_IMCID imc_id,
                                                                  TNC_UInt32 msg_len,
                                                                  TNC_MessageType msg_type)
 {
-       TNC_VendorID msg_vid;
-       TNC_MessageSubtype msg_subtype;
+       imc_state_t *state;
+       imc_msg_t *in_msg;
+       TNC_Result result;
 
-       msg_vid = msg_type >> 8;
-       msg_subtype = msg_type & TNC_SUBTYPE_ANY;
+       if (!imc_attestation)
+       {
+               DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
+               return TNC_RESULT_NOT_INITIALIZED;
+       }
+       if (!imc_attestation->get_state(imc_attestation, connection_id, &state))
+       {
+               return TNC_RESULT_FATAL;
+       }
+
+       in_msg = imc_msg_create_from_data(imc_attestation, state, connection_id,
+                                                                         msg_type, chunk_create(msg, msg_len));
+       result = receive_message(state, in_msg);
+       in_msg->destroy(in_msg);
 
-       return receive_message(imc_id, connection_id, 0, chunk_create(msg, msg_len),
-                                                  msg_vid,     msg_subtype, 0, TNC_IMCID_ANY);
+       return result;
 }
 
 /**
@@ -289,9 +263,26 @@ TNC_Result TNC_IMC_ReceiveMessageLong(TNC_IMCID imc_id,
                                                                          TNC_UInt32 src_imv_id,
                                                                          TNC_UInt32 dst_imc_id)
 {
-       return receive_message(imc_id, connection_id, msg_flags,
-                                                  chunk_create(msg, msg_len), msg_vid, msg_subtype,
-                                                  src_imv_id, dst_imc_id);
+       imc_state_t *state;
+       imc_msg_t *in_msg;
+       TNC_Result result;
+
+       if (!imc_attestation)
+       {
+               DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
+               return TNC_RESULT_NOT_INITIALIZED;
+       }
+       if (!imc_attestation->get_state(imc_attestation, connection_id, &state))
+       {
+               return TNC_RESULT_FATAL;
+       }
+       in_msg = imc_msg_create_from_long_data(imc_attestation, state, connection_id,
+                                                               src_imv_id, dst_imc_id, msg_vid, msg_subtype,
+                                                               chunk_create(msg, msg_len));
+       result =receive_message(state, in_msg);
+       in_msg->destroy(in_msg);
+
+       return result;
 }
 
 /**
index bd2fa64..8ee02e4 100644 (file)
@@ -48,7 +48,7 @@
 
 #define DEFAULT_NONCE_LEN              20
 
-bool imc_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
+bool imc_attestation_process(pa_tnc_attr_t *attr, imc_msg_t *msg,
                                                         imc_attestation_state_t *attestation_state,
                                                         pts_meas_algorithms_t supported_algorithms,
                                                         pts_dh_group_t supported_dh_groups)
@@ -76,7 +76,7 @@ bool imc_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
 
                        /* Send PTS Protocol Capabilities attribute */
                        attr = tcg_pts_attr_proto_caps_create(imc_caps & imv_caps, FALSE);
-                       attr_list->insert_last(attr_list, attr);
+                       msg->add_attribute(msg, attr);
                        break;
                }
                case TCG_PTS_MEAS_ALGO:
@@ -91,14 +91,14 @@ bool imc_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
                        if (selected_algorithm == PTS_MEAS_ALGO_NONE)
                        {
                                attr = pts_hash_alg_error_create(supported_algorithms);
-                               attr_list->insert_last(attr_list, attr);
+                               msg->add_attribute(msg, attr);
                                break;
                        }
 
                        /* Send Measurement Algorithm Selection attribute */
                        pts->set_meas_algorithm(pts, selected_algorithm);
                        attr = tcg_pts_attr_meas_algo_create(selected_algorithm, TRUE);
-                       attr_list->insert_last(attr_list, attr);
+                       msg->add_attribute(msg, attr);
                        break;
                }
                case TCG_PTS_DH_NONCE_PARAMS_REQ:
@@ -118,7 +118,7 @@ bool imc_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
                                (min_nonce_len > 0 && nonce_len < min_nonce_len))
                        {
                                attr = pts_dh_nonce_error_create(nonce_len, PTS_MAX_NONCE_LEN);
-                               attr_list->insert_last(attr_list, attr);
+                               msg->add_attribute(msg, attr);
                                break;
                        }
 
@@ -128,7 +128,7 @@ bool imc_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
                        if (selected_dh_group == PTS_DH_GROUP_NONE)
                        {
                                attr = pts_dh_group_error_create(supported_dh_groups);
-                               attr_list->insert_last(attr_list, attr);
+                               msg->add_attribute(msg, attr);
                                break;
                        }
 
@@ -142,7 +142,7 @@ bool imc_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
                        /* Send DH Nonce Parameters Response attribute */
                        attr = tcg_pts_attr_dh_nonce_params_resp_create(selected_dh_group,
                                         supported_algorithms, responder_nonce, responder_value);
-                       attr_list->insert_last(attr_list, attr);
+                       msg->add_attribute(msg, attr);
                        break;
                }
                case TCG_PTS_DH_NONCE_FINISH:
@@ -190,13 +190,13 @@ bool imc_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
                        {
                                attr_info = attr->get_value(attr);
                                attr = ietf_attr_pa_tnc_error_create(error_code, attr_info);
-                               attr_list->insert_last(attr_list, attr);
+                               msg->add_attribute(msg, attr);
                                break;
                        }
 
                        /* Send TPM Version Info attribute */
                        attr = tcg_pts_attr_tpm_version_info_create(tpm_version_info);
-                       attr_list->insert_last(attr_list, attr);
+                       msg->add_attribute(msg, attr);
                        break;
                }
                case TCG_PTS_GET_AIK:
@@ -212,7 +212,7 @@ bool imc_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
 
                        /* Send AIK attribute */
                        attr = tcg_pts_attr_aik_create(aik);
-                       attr_list->insert_last(attr_list, attr);
+                       msg->add_attribute(msg, attr);
                        break;
                }
                case TCG_PTS_REQ_FILE_MEAS:
@@ -237,7 +237,7 @@ bool imc_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
                        {
                                error_code = pen_type_create(PEN_TCG, pts_error);
                                attr = ietf_attr_pa_tnc_error_create(error_code, attr_info);
-                               attr_list->insert_last(attr_list, attr);
+                               msg->add_attribute(msg, attr);
                                break;
                        }
                        else if (!valid_path)
@@ -250,7 +250,7 @@ bool imc_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
                                error_code = pen_type_create(PEN_TCG,
                                                                                         TCG_PTS_INVALID_DELIMITER);
                                attr = ietf_attr_pa_tnc_error_create(error_code, attr_info);
-                               attr_list->insert_last(attr_list, attr);
+                               msg->add_attribute(msg, attr);
                                break;
                        }
 
@@ -268,7 +268,7 @@ bool imc_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
                        }
                        attr = tcg_pts_attr_file_meas_create(measurements);
                        attr->set_noskip_flag(attr, TRUE);
-                       attr_list->insert_last(attr_list, attr);
+                       msg->add_attribute(msg, attr);
                        break;
                }
                case TCG_PTS_REQ_FILE_META:
@@ -291,7 +291,7 @@ bool imc_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
                        {
                                error_code = pen_type_create(PEN_TCG, pts_error);
                                attr = ietf_attr_pa_tnc_error_create(error_code, attr_info);
-                               attr_list->insert_last(attr_list, attr);
+                               msg->add_attribute(msg, attr);
                                break;
                        }
                        else if (!valid_path)
@@ -303,7 +303,7 @@ bool imc_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
                                error_code = pen_type_create(PEN_TCG,
                                                                                         TCG_PTS_INVALID_DELIMITER);
                                attr = ietf_attr_pa_tnc_error_create(error_code, attr_info);
-                               attr_list->insert_last(attr_list, attr);
+                               msg->add_attribute(msg, attr);
                                break;
                        }
                        /* Get File Metadata and send them to PTS-IMV */
@@ -319,8 +319,7 @@ bool imc_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
                        }
                        attr = tcg_pts_attr_unix_file_meta_create(metadata);
                        attr->set_noskip_flag(attr, TRUE);
-                       attr_list->insert_last(attr_list, attr);
-
+                       msg->add_attribute(msg, attr);
                        break;
                }
                case TCG_PTS_REQ_FUNC_COMP_EVID:
@@ -353,7 +352,7 @@ bool imc_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
                                        error_code = pen_type_create(PEN_TCG,
                                                                                                 TCG_PTS_UNABLE_DET_TTC); 
                                        attr = ietf_attr_pa_tnc_error_create(error_code, attr_info);
-                                       attr_list->insert_last(attr_list, attr);
+                                       msg->add_attribute(msg, attr);
                                        break;
                                }
                                if (flags & PTS_REQ_FUNC_COMP_EVID_VER &&
@@ -362,7 +361,7 @@ bool imc_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
                                        error_code = pen_type_create(PEN_TCG,
                                                                                                 TCG_PTS_UNABLE_LOCAL_VAL);
                                        attr = ietf_attr_pa_tnc_error_create(error_code, attr_info);
-                                       attr_list->insert_last(attr_list, attr);
+                                       msg->add_attribute(msg, attr);
                                        break;
                                }
                                if (flags & PTS_REQ_FUNC_COMP_EVID_CURR &&
@@ -371,7 +370,7 @@ bool imc_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
                                        error_code = pen_type_create(PEN_TCG,
                                                                                                 TCG_PTS_UNABLE_CUR_EVID);
                                        attr = ietf_attr_pa_tnc_error_create(error_code, attr_info);
-                                       attr_list->insert_last(attr_list, attr);
+                                       msg->add_attribute(msg, attr);
                                        break;
                                }
                                if (flags & PTS_REQ_FUNC_COMP_EVID_PCR &&
@@ -380,7 +379,7 @@ bool imc_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
                                        error_code = pen_type_create(PEN_TCG,
                                                                                                 TCG_PTS_UNABLE_DET_PCR);
                                        attr = ietf_attr_pa_tnc_error_create(error_code, attr_info);
-                                       attr_list->insert_last(attr_list, attr);
+                                       msg->add_attribute(msg, attr);
                                        break;
                                }
                                if (depth > 0)
@@ -425,7 +424,7 @@ bool imc_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
                        while (attestation_state->next_evidence(attestation_state, &evid))
                        {
                                attr = tcg_pts_attr_simple_comp_evid_create(evid);
-                               attr_list->insert_last(attr_list, attr);
+                               msg->add_attribute(msg, attr);
                        }
 
                        use_quote2 = lib->settings->get_bool(lib->settings,
@@ -443,7 +442,7 @@ bool imc_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
 
                        attr = tcg_pts_attr_simple_evid_final_create(flags,
                                                                comp_hash_algorithm, pcr_composite, quote_sig);
-                       attr_list->insert_last(attr_list, attr);
+                       msg->add_attribute(msg, attr);
                        break;
                }
                /* TODO: Not implemented yet */
index b6dca1f..5ada104 100644 (file)
@@ -26,6 +26,7 @@
 
 #include <library.h>
 
+#include <imc/imc_msg.h>
 #include <pa_tnc/pa_tnc_attr.h>
 
 #include <pts/pts_dh_group.h>
  * Process a TCG PTS attribute
  *
  * @param attr                                 PA-TNC attribute to be processed
- * @param attr_list                            list with PA-TNC error attributes
+ * @param msg                                  outbound PA-TNC message to be assembled
  * @param attestation_state            attestation state of a given connection
  * @param supported_algorithms supported PTS measurement algorithms
  * @param supported_dh_groups  supported DH groups
  * @return                                             TRUE if successful
  */
-bool imc_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
+bool imc_attestation_process(pa_tnc_attr_t *attr, imc_msg_t *msg,
                                                         imc_attestation_state_t *attestation_state,
                                                         pts_meas_algorithms_t supported_algorithms,
                                                         pts_dh_group_t supported_dh_groups);
index 23cbd84..b3d3510 100644 (file)
@@ -129,8 +129,6 @@ METHOD(imc_state_t, set_result, void,
        private_imc_attestation_state_t *this, TNC_IMCID id,
        TNC_IMV_Evaluation_Result result)
 {
-       DBG1(DBG_IMC, "set assessment result for IMC %u to '%N'",
-                id, TNC_IMV_Evaluation_Result_names, result);
        this->result = result;
 }