added IETF standard error handling method
authorAndreas Steffen <andreas.steffen@strongswan.org>
Sun, 11 Dec 2011 08:41:40 +0000 (09:41 +0100)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Sun, 11 Dec 2011 08:41:40 +0000 (09:41 +0100)
src/libimcv/pa_tnc/pa_tnc_msg.c
src/libimcv/pa_tnc/pa_tnc_msg.h
src/libimcv/plugins/imc_scanner/imc_scanner.c
src/libimcv/plugins/imc_test/imc_test.c
src/libimcv/plugins/imv_scanner/imv_scanner.c
src/libimcv/plugins/imv_test/imv_test.c
src/libpts/plugins/imc_attestation/imc_attestation.c
src/libpts/plugins/imv_attestation/imv_attestation.c

index f8d3b9d..b5df0a5 100644 (file)
@@ -311,6 +311,63 @@ err:
        return VERIFY_ERROR;
 }
 
+METHOD(pa_tnc_msg_t, process_ietf_std_errors, bool,
+       private_pa_tnc_msg_t *this)
+{
+       enumerator_t *enumerator;
+       pa_tnc_attr_t *attr;
+       bool fatal_error = FALSE;
+
+       enumerator = this->attributes->create_enumerator(this->attributes);
+       while (enumerator->enumerate(enumerator, &attr))
+       {
+               if (attr->get_vendor_id(attr) == PEN_IETF &&
+                       attr->get_type(attr) == IETF_ATTR_PA_TNC_ERROR)
+               {
+                       ietf_attr_pa_tnc_error_t *error_attr;
+                       pen_t error_vendor_id;
+                       pa_tnc_error_code_t error_code;
+                       chunk_t msg_info, attr_info;
+                       u_int32_t offset;
+
+                       error_attr = (ietf_attr_pa_tnc_error_t*)attr;
+                       error_vendor_id = error_attr->get_vendor_id(error_attr);
+                       error_code = error_attr->get_error_code(error_attr);
+                       msg_info = error_attr->get_msg_info(error_attr);
+
+                       /* skip errors from non-IETF namespaces */
+                       if (error_vendor_id != PEN_IETF)
+                       {
+                               continue;
+                       }
+                       DBG1(DBG_IMC, "received PA-TNC error '%N' concerning message "
+                                "0x%08x/0x%08x", pa_tnc_error_code_names, error_code,
+                                untoh32(msg_info.ptr), untoh32(msg_info.ptr + 4));
+
+                       switch (error_code)
+                       {
+                               case PA_ERROR_INVALID_PARAMETER:
+                                       offset = error_attr->get_offset(error_attr);
+                                       DBG1(DBG_IMC, "  occurred at offset of %u bytes", offset);
+                                       break;
+                               case PA_ERROR_ATTR_TYPE_NOT_SUPPORTED:
+                                       attr_info = error_attr->get_attr_info(error_attr);
+                                       DBG1(DBG_IMC, "  unsupported attribute %#B", &attr_info);
+                                       break;
+                               default:
+                                       break;
+                       }
+
+                       /* remove the processed IETF standard error attribute */
+                       this->attributes->remove_at(this->attributes, enumerator);
+                       fatal_error = TRUE;
+               }
+       }
+       enumerator->destroy(enumerator);
+
+       return fatal_error;
+}
+
 METHOD(pa_tnc_msg_t, create_attribute_enumerator, enumerator_t*,
        private_pa_tnc_msg_t *this)
 {
@@ -347,6 +404,7 @@ pa_tnc_msg_t *pa_tnc_msg_create_from_data(chunk_t data)
                        .add_attribute = _add_attribute,
                        .build = _build,
                        .process = _process,
+                       .process_ietf_std_errors = _process_ietf_std_errors,
                        .create_attribute_enumerator = _create_attribute_enumerator,
                        .create_error_enumerator = _create_error_enumerator,
                        .destroy = _destroy,
index bff9546..c3ce829 100644 (file)
@@ -62,6 +62,13 @@ struct pa_tnc_msg_t {
        status_t (*process)(pa_tnc_msg_t *this);
 
        /**
+        * Process and remove all IETF standard error PA-TNC attributes
+        *
+        * @return                                      TRUE if at least one error attribute processed
+        */
+       bool (*process_ietf_std_errors)(pa_tnc_msg_t *this);
+
+       /**
         * Enumerates over all PA-TNC attributes
         *
         * @return                              return attribute enumerator
index 4cdf2bd..a54aafe 100644 (file)
@@ -270,9 +270,8 @@ static TNC_Result receive_message(TNC_IMCID imc_id,
        pa_tnc_msg_t *pa_tnc_msg;
        pa_tnc_attr_t *attr;
        imc_state_t *state;
-       enumerator_t *enumerator;
        TNC_Result result;
-       bool fatal_error = FALSE;
+       bool fatal_error;
 
        if (!imc_scanner)
        {
@@ -296,43 +295,8 @@ static TNC_Result receive_message(TNC_IMCID imc_id,
                return result;
        }
 
-       /* analyze PA-TNC attributes */
-       enumerator = pa_tnc_msg->create_attribute_enumerator(pa_tnc_msg);
-       while (enumerator->enumerate(enumerator, &attr))
-       {
-               ietf_attr_pa_tnc_error_t *error_attr;
-               pa_tnc_error_code_t error_code;
-               chunk_t msg_info, attr_info;
-               u_int32_t offset;
-
-               if (attr->get_vendor_id(attr) != PEN_IETF &&
-                       attr->get_type(attr) != IETF_ATTR_PA_TNC_ERROR)
-               {
-                       continue;
-               }
-
-               error_attr = (ietf_attr_pa_tnc_error_t*)attr;
-               error_code = error_attr->get_error_code(error_attr);
-               msg_info = error_attr->get_msg_info(error_attr);
-               DBG1(DBG_IMC, "received PA-TNC error '%N' concerning message %#B",
-                        pa_tnc_error_code_names, error_code, &msg_info);
-
-               switch (error_code)
-               {
-                       case PA_ERROR_INVALID_PARAMETER:
-                               offset = error_attr->get_offset(error_attr);
-                               DBG1(DBG_IMC, "  occurred at offset of %u bytes", offset);
-                               break;
-                       case PA_ERROR_ATTR_TYPE_NOT_SUPPORTED:
-                               attr_info = error_attr->get_attr_info(error_attr);
-                               DBG1(DBG_IMC, "  unsupported attribute %#B", &attr_info);
-                               break;
-                       default:
-                               break;
-               }
-               fatal_error = TRUE;
-       }
-       enumerator->destroy(enumerator);
+       /* preprocess any IETF standard error attributes */
+       fatal_error = pa_tnc_msg->process_ietf_std_errors(pa_tnc_msg);
        pa_tnc_msg->destroy(pa_tnc_msg);
 
        /* if no error occurred then always return the same response */
index 732a625..b7858c5 100644 (file)
@@ -279,41 +279,15 @@ static TNC_Result receive_message(TNC_IMCID imc_id,
                return result;
        }
 
+       /* 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))
        {
-               if (attr->get_vendor_id(attr) == PEN_IETF &&
-                       attr->get_type(attr) == IETF_ATTR_PA_TNC_ERROR)
-               {
-                       ietf_attr_pa_tnc_error_t *error_attr;
-                       pa_tnc_error_code_t error_code;
-                       chunk_t msg_info, attr_info;
-                       u_int32_t offset;
-
-                       error_attr = (ietf_attr_pa_tnc_error_t*)attr;
-                       error_code = error_attr->get_error_code(error_attr);
-                       msg_info = error_attr->get_msg_info(error_attr);
-
-                       DBG1(DBG_IMC, "received PA-TNC error '%N' concerning message %#B",
-                                pa_tnc_error_code_names, error_code, &msg_info);
-                       switch (error_code)
-                       {
-                               case PA_ERROR_INVALID_PARAMETER:
-                                       offset = error_attr->get_offset(error_attr);
-                                       DBG1(DBG_IMC, "  occurred at offset of %u bytes", offset);
-                                       break;
-                               case PA_ERROR_ATTR_TYPE_NOT_SUPPORTED:
-                                       attr_info = error_attr->get_attr_info(error_attr);
-                                       DBG1(DBG_IMC, "  unsupported attribute %#B", &attr_info);
-                                       break;
-                               default:
-                                       break;
-                       }
-                       fatal_error = TRUE;
-               }
-               else if (attr->get_vendor_id(attr) == PEN_ITA &&
-                                attr->get_type(attr) == ITA_ATTR_COMMAND)
+               if (attr->get_vendor_id(attr) == PEN_ITA &&
+                       attr->get_type(attr) == ITA_ATTR_COMMAND)
                {
                        ita_attr_command_t *ita_attr;
                        char *command;
index 0b2187a..8455115 100644 (file)
@@ -189,7 +189,7 @@ static TNC_Result receive_message(TNC_IMVID imv_id,
        imv_state_t *state;
        enumerator_t *enumerator;
        TNC_Result result;
-       bool fatal_error = FALSE;
+       bool fatal_error;
 
        if (!imv_scanner)
        {
@@ -213,44 +213,15 @@ static TNC_Result receive_message(TNC_IMVID imv_id,
                return result;
        }
 
+       /* 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))
        {
-               if (attr->get_vendor_id(attr) != PEN_IETF)
-               {
-                       continue;
-               }
-
-               if (attr->get_type(attr) == IETF_ATTR_PA_TNC_ERROR)
-               {
-                       ietf_attr_pa_tnc_error_t *error_attr;
-                       pa_tnc_error_code_t error_code;
-                       chunk_t msg_info, attr_info;
-                       u_int32_t offset;
-
-                       error_attr = (ietf_attr_pa_tnc_error_t*)attr;
-                       error_code = error_attr->get_error_code(error_attr);
-                       msg_info = error_attr->get_msg_info(error_attr);
-                       DBG1(DBG_IMV, "received PA-TNC error '%N' concerning message %#B",
-                                pa_tnc_error_code_names, error_code, &msg_info);
-
-                       switch (error_code)
-                       {
-                               case PA_ERROR_INVALID_PARAMETER:
-                                       offset = error_attr->get_offset(error_attr);
-                                       DBG1(DBG_IMV, "  occurred at offset of %u bytes", offset);
-                                       break;
-                               case PA_ERROR_ATTR_TYPE_NOT_SUPPORTED:
-                                       attr_info = error_attr->get_attr_info(error_attr);
-                                       DBG1(DBG_IMV, "  unsupported attribute %#B", &attr_info);
-                                       break;
-                               default:
-                                       break;
-                       }
-                       fatal_error = TRUE;
-               }
-               else if (attr->get_type(attr) == IETF_ATTR_PORT_FILTER)
+               if (attr->get_vendor_id(attr) == PEN_IETF &&
+                       attr->get_type(attr) == IETF_ATTR_PORT_FILTER)
                {
                        ietf_attr_port_filter_t *attr_port_filter;
                        enumerator_t *enumerator;
index d19c7c0..be5aa98 100644 (file)
@@ -140,7 +140,7 @@ static TNC_Result receive_message(TNC_IMVID imv_id,
        imv_test_state_t *imv_test_state;
        enumerator_t *enumerator;
        TNC_Result result;
-       bool fatal_error = FALSE, retry = FALSE;
+       bool fatal_error, retry = FALSE;
 
        if (!imv_test)
        {
@@ -164,41 +164,15 @@ static TNC_Result receive_message(TNC_IMVID imv_id,
                return result;
        }
 
+       /* 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))
        {
-               if (attr->get_vendor_id(attr) == PEN_IETF &&
-                       attr->get_type(attr) == IETF_ATTR_PA_TNC_ERROR)
-               {
-                       ietf_attr_pa_tnc_error_t *error_attr;
-                       pa_tnc_error_code_t error_code;
-                       chunk_t msg_info, attr_info;
-                       u_int32_t offset;
-
-                       error_attr = (ietf_attr_pa_tnc_error_t*)attr;
-                       error_code = error_attr->get_error_code(error_attr);
-                       msg_info = error_attr->get_msg_info(error_attr);
-
-                       DBG1(DBG_IMV, "received PA-TNC error '%N' concerning message %#B",
-                                pa_tnc_error_code_names, error_code, &msg_info);
-                       switch (error_code)
-                       {
-                               case PA_ERROR_INVALID_PARAMETER:
-                                       offset = error_attr->get_offset(error_attr);
-                                       DBG1(DBG_IMV, "  occurred at offset of %u bytes", offset);
-                                       break;
-                               case PA_ERROR_ATTR_TYPE_NOT_SUPPORTED:
-                                       attr_info = error_attr->get_attr_info(error_attr);
-                                       DBG1(DBG_IMV, "  unsupported attribute %#B", &attr_info);
-                                       break;
-                               default:
-                                       break;
-                       }
-                       fatal_error = TRUE;
-               }
-               else if (attr->get_vendor_id(attr) == PEN_ITA &&
-                                attr->get_type(attr) == ITA_ATTR_COMMAND)
+               if (attr->get_vendor_id(attr) == PEN_ITA &&
+                       attr->get_type(attr) == ITA_ATTR_COMMAND)
                {
                        ita_attr_command_t *ita_attr;
                        char *command;
index 683cf98..4f77ba0 100644 (file)
@@ -205,8 +205,11 @@ static TNC_Result receive_message(TNC_IMCID imc_id,
                return result;
        }
        
+       /* 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();
-       result = TNC_RESULT_SUCCESS;
 
        /* analyze PA-TNC attributes */
        enumerator = pa_tnc_msg->create_attribute_enumerator(pa_tnc_msg);
@@ -216,30 +219,24 @@ static TNC_Result receive_message(TNC_IMCID imc_id,
                        attr->get_type(attr) == IETF_ATTR_PA_TNC_ERROR)
                {
                        ietf_attr_pa_tnc_error_t *error_attr;
+                       pen_t error_vendor_id;
                        pa_tnc_error_code_t error_code;
-                       chunk_t msg_info, attr_info;
-                       u_int32_t offset;
+                       chunk_t msg_info;
 
                        error_attr = (ietf_attr_pa_tnc_error_t*)attr;
-                       error_code = error_attr->get_error_code(error_attr);
-                       msg_info = error_attr->get_msg_info(error_attr);
+                       error_vendor_id = error_attr->get_vendor_id(error_attr);
 
-                       DBG1(DBG_IMC, "received PA-TNC error '%N' concerning message %#B",
-                                pa_tnc_error_code_names, error_code, &msg_info);
-                       switch (error_code)
+                       if (error_vendor_id == PEN_TCG)
                        {
-                               case PA_ERROR_INVALID_PARAMETER:
-                                       offset = error_attr->get_offset(error_attr);
-                                       DBG1(DBG_IMC, "  occurred at offset of %u bytes", offset);
-                                       break;
-                               case PA_ERROR_ATTR_TYPE_NOT_SUPPORTED:
-                                       attr_info = error_attr->get_attr_info(error_attr);
-                                       DBG1(DBG_IMC, "  unsupported attribute %#B", &attr_info);
-                                       break;
-                               default:
-                                       break;
+                               error_code = error_attr->get_error_code(error_attr);
+                               msg_info = error_attr->get_msg_info(error_attr);
+
+                               DBG1(DBG_IMC, "received TCG-PTS error '%N'",
+                                        pts_error_code_names, error_code);
+                               DBG1(DBG_IMC, "error information: %B", &msg_info);
+
+                               result = TNC_RESULT_FATAL;
                        }
-                       result = TNC_RESULT_FATAL;
                }
                else if (attr->get_vendor_id(attr) == PEN_TCG)
                {
index 7803fb6..cd6f5b5 100644 (file)
@@ -239,8 +239,11 @@ static TNC_Result receive_message(TNC_IMVID imv_id,
                return result;
        }
 
+       /* 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();
-       result = TNC_RESULT_SUCCESS;
 
        /* analyze PA-TNC attributes */
        enumerator = pa_tnc_msg->create_attribute_enumerator(pa_tnc_msg);
@@ -253,43 +256,22 @@ static TNC_Result receive_message(TNC_IMVID imv_id,
                                ietf_attr_pa_tnc_error_t *error_attr;
                                pen_t error_vendor_id;
                                pa_tnc_error_code_t error_code;
-                               chunk_t msg_info, attr_info;
-                               u_int32_t offset;
+                               chunk_t msg_info;
 
                                error_attr = (ietf_attr_pa_tnc_error_t*)attr;
                                error_vendor_id = error_attr->get_vendor_id(error_attr);
-                               error_code = error_attr->get_error_code(error_attr);
-                               msg_info = error_attr->get_msg_info(error_attr);
 
-                               if (error_vendor_id == PEN_IETF)
-                               {
-                                       DBG1(DBG_IMV, "received PA-TNC error '%N' "
-                                                                 "concerning message %#B",
-                                                pa_tnc_error_code_names, error_code, &msg_info);
-
-                                       switch (error_code)
-                                       {
-                                               case PA_ERROR_INVALID_PARAMETER:
-                                                       offset = error_attr->get_offset(error_attr);
-                                                       DBG1(DBG_IMV, "  occurred at offset of %u bytes",
-                                                                offset);
-                                                       break;
-                                               case PA_ERROR_ATTR_TYPE_NOT_SUPPORTED:
-                                                       attr_info = error_attr->get_attr_info(error_attr);
-                                                       DBG1(DBG_IMV, "  unsupported attribute %#B",
-                                                                &attr_info);
-                                                       break;
-                                               default:
-                                                       break;
-                                       }
-                               }
-                               else if (error_vendor_id == PEN_TCG)
+                               if (error_vendor_id == PEN_TCG)
                                {
+                                       error_code = error_attr->get_error_code(error_attr);
+                                       msg_info = error_attr->get_msg_info(error_attr);
+
                                        DBG1(DBG_IMV, "received TCG-PTS error '%N'",
                                                 pts_error_code_names, error_code);
                                        DBG1(DBG_IMV, "error information: %B", &msg_info);
+
+                                       result = TNC_RESULT_FATAL;
                                }
-                               result = TNC_RESULT_FATAL;
                        }
                        else if (attr->get_type(attr) == IETF_ATTR_PRODUCT_INFORMATION)
                        {