implemented server-initiated handshake retry in IMC/IMV Test pair
authorAndreas Steffen <andreas.steffen@strongswan.org>
Thu, 23 Jun 2011 13:23:53 +0000 (15:23 +0200)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Thu, 23 Jun 2011 13:23:53 +0000 (15:23 +0200)
src/libimcv/plugins/imc_test/imc_test.c
src/libimcv/plugins/imc_test/imc_test_state.c
src/libimcv/plugins/imc_test/imc_test_state.h
src/libimcv/plugins/imv_test/imv_test.c

index 9efdc72..4c7c2d1 100644 (file)
@@ -20,8 +20,9 @@
 #include <ietf/ietf_attr_pa_tnc_error.h>
 #include <ita/ita_attr_command.h>
 
-#include <pen/pen.h>
+#include <tncif_names.h>
 
+#include <pen/pen.h>
 #include <debug.h>
 
 /* IMC definitions */
@@ -86,8 +87,32 @@ TNC_Result TNC_IMC_NotifyConnectionChange(TNC_IMCID imc_id,
                                                                "libimcv.plugins.imc-test.retry", FALSE);
                        state = imc_test_state_create(connection_id, command, retry);
                        return imc_test->create_state(imc_test, state);
+
+               case TNC_CONNECTION_STATE_HANDSHAKE:
+                       /* get current IMC state and update it */
+                       if (!imc_test->get_state(imc_test, connection_id, &state))
+                       {
+                               return TNC_RESULT_FATAL;
+                       }
+                       state->change_state(state, new_state);
+                       DBG2(DBG_IMC, "IMC %u \"%s\" changed state of Connection ID %u to '%N'",
+                                                 imc_id, imc_name, connection_id,
+                                                 TNC_Connection_State_names, new_state);
+                       test_state = (imc_test_state_t*)state;
+
+                       /* is it the first handshake or a retry ? */
+                       if (!test_state->is_first_handshake(test_state))
+                       {
+                               command = lib->settings->get_str(lib->settings,
+                                                               "libimcv.plugins.imc-test.retry_command",
+                                                               test_state->get_command(test_state));
+                               test_state->set_command(test_state, command);
+                       }
+                       return TNC_RESULT_SUCCESS;
+
                case TNC_CONNECTION_STATE_DELETE:
                        return imc_test->delete_state(imc_test, connection_id);
+
                case TNC_CONNECTION_STATE_ACCESS_ISOLATED:
                case TNC_CONNECTION_STATE_ACCESS_NONE:
                        /* get current IMC state and update it */
@@ -96,19 +121,19 @@ TNC_Result TNC_IMC_NotifyConnectionChange(TNC_IMCID imc_id,
                                return TNC_RESULT_FATAL;
                        }
                        state->change_state(state, new_state);
+                       DBG2(DBG_IMC, "IMC %u \"%s\" changed state of Connection ID %u to '%N'",
+                                                 imc_id, imc_name, connection_id,
+                                                 TNC_Connection_State_names, new_state);
                        test_state = (imc_test_state_t*)state;
 
                        /* do a handshake retry? */
                        if (test_state->do_handshake_retry(test_state))
                        {
-                               command = lib->settings->get_str(lib->settings,
-                                                               "libimcv.plugins.imc-test.retry_command",
-                                                               test_state->get_command(test_state));
-                               test_state->set_command(test_state, command);
                                return imc_test->request_handshake_retry(imc_id, connection_id,
                                                                        TNC_RETRY_REASON_IMC_REMEDIATION_COMPLETE);
                        }
                        return TNC_RESULT_SUCCESS;
+
                default:
                        return imc_test->change_state(imc_test, connection_id, new_state);
        }
index ade1fc1..cc7e18a 100644 (file)
@@ -44,6 +44,11 @@ struct private_imc_test_state_t {
        char *command;
 
        /**
+        * Is it the first handshake?
+        */
+       bool first_handshake;
+
+       /**
         * Do a handshake retry
         */
        bool handshake_retry;
@@ -84,6 +89,17 @@ METHOD(imc_test_state_t, set_command, void,
        free(old_command);
 }
 
+METHOD(imc_test_state_t, is_first_handshake, bool,
+       private_imc_test_state_t *this)
+{
+       bool first;
+
+       /* test and reset first_handshake flag */
+       first= this->first_handshake;
+       this->first_handshake = FALSE;
+       return first;
+}
+
 METHOD(imc_test_state_t, do_handshake_retry, bool,
        private_imc_test_state_t *this)
 {
@@ -95,7 +111,6 @@ METHOD(imc_test_state_t, do_handshake_retry, bool,
        return retry;
 }
 
-
 /**
  * Described in header.
  */
@@ -113,11 +128,13 @@ imc_state_t *imc_test_state_create(TNC_ConnectionID connection_id,
                        },
                        .get_command = _get_command,
                        .set_command = _set_command,
+                       .is_first_handshake = _is_first_handshake,
                        .do_handshake_retry = _do_handshake_retry,
                },
                .state = TNC_CONNECTION_STATE_CREATE,
                .connection_id = connection_id,
                .command = strdup(command),
+               .first_handshake = TRUE,
                .handshake_retry = retry,
        );
        
index edcd81d..384285a 100644 (file)
@@ -51,6 +51,13 @@ struct imc_test_state_t {
        void (*set_command)(imc_test_state_t *this, char *command);
 
        /**
+        * Test and reset the first handshake flag
+        *
+        * @return                              TRUE if first handshake
+        */
+       bool (*is_first_handshake)(imc_test_state_t *this);
+
+       /**
         * Test and reset the retry handshake flag
         *
         * @return                              TRUE if a handshake retry should be done
index ca798bb..f2230a4 100644 (file)
@@ -20,8 +20,9 @@
 #include <ietf/ietf_attr_pa_tnc_error.h>
 #include <ita/ita_attr_command.h>
 
-#include <pen/pen.h>
+#include <tncif_names.h>
 
+#include <pen/pen.h>
 #include <debug.h>
 
 /* IMV definitions */
@@ -89,9 +90,14 @@ TNC_Result TNC_IMV_NotifyConnectionChange(TNC_IMVID imv_id,
                                return TNC_RESULT_FATAL;
                        }
                        state->change_state(state, new_state);
+                       DBG2(DBG_IMV, "IMV %u \"%s\" changed state of Connection ID %u to '%N'",
+                                                 imv_id, imv_name, connection_id,
+                                                 TNC_Connection_State_names, new_state);
+                       test_state = (imv_test_state_t*)state;
+
+                       /* set the number of measurement rounds */
                        rounds = lib->settings->get_int(lib->settings,
                                                                "libimcv.plugins.imv-test.rounds", 0);
-                       test_state = (imv_test_state_t*)state;
                        test_state->set_rounds(test_state, rounds);
                        return TNC_RESULT_SUCCESS;
                default:
@@ -131,7 +137,7 @@ TNC_Result TNC_IMV_ReceiveMessage(TNC_IMVID imv_id,
        imv_test_state_t *imv_test_state;
        enumerator_t *enumerator;
        TNC_Result result;
-       bool fatal_error = FALSE;
+       bool fatal_error = FALSE, retry = FALSE;
 
        if (!imv_test)
        {
@@ -211,6 +217,10 @@ TNC_Result TNC_IMV_ReceiveMessage(TNC_IMVID imv_id,
                                                                TNC_IMV_ACTION_RECOMMENDATION_NO_ACCESS,
                                                                TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MAJOR);                    
                        }
+                       else if (streq(command, "retry"))
+                       {
+                               retry = TRUE;
+                       }
                        else
                        {
                                DBG1(DBG_IMV, "unsupported ITA Command '%s'", command);
@@ -231,6 +241,13 @@ TNC_Result TNC_IMV_ReceiveMessage(TNC_IMVID imv_id,
                return imv_test->provide_recommendation(imv_test, connection_id);
        }
 
+       /* request a handshake retry ? */
+       if (retry)
+       {
+               return imv_test->request_handshake_retry(imv_id, connection_id,
+                                                               TNC_RETRY_REASON_IMV_SERIOUS_EVENT);
+       }
+       
        /* repeat the measurement ? */
        imv_test_state = (imv_test_state_t*)state;
        if (imv_test_state->another_round(imv_test_state))