implemented handshake retry on the client side
authorAndreas Steffen <andreas.steffen@strongswan.org>
Wed, 15 Jun 2011 11:09:19 +0000 (13:09 +0200)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Wed, 15 Jun 2011 11:09:41 +0000 (13:09 +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

index e89008f..9efdc72 100644 (file)
@@ -68,6 +68,9 @@ TNC_Result TNC_IMC_NotifyConnectionChange(TNC_IMCID imc_id,
                                                                                  TNC_ConnectionState new_state)
 {
        imc_state_t *state;
+       imc_test_state_t *test_state;
+       char *command;
+       bool retry;
 
        if (!imc_test)
        {
@@ -77,10 +80,35 @@ TNC_Result TNC_IMC_NotifyConnectionChange(TNC_IMCID imc_id,
        switch (new_state)
        {
                case TNC_CONNECTION_STATE_CREATE:
-                       state = imc_test_state_create(connection_id);
+                       command = lib->settings->get_str(lib->settings,
+                                                "libimcv.plugins.imc-test.command", "none");
+                       retry = lib->settings->get_bool(lib->settings,
+                                                               "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_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 */
+                       if (!imc_test->get_state(imc_test, connection_id, &state))
+                       {
+                               return TNC_RESULT_FATAL;
+                       }
+                       state->change_state(state, 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);
        }
@@ -90,12 +118,16 @@ static TNC_Result send_message(TNC_ConnectionID connection_id)
 {
        pa_tnc_msg_t *msg;
        pa_tnc_attr_t *attr;
-       char *command;
+       imc_state_t *state;
+       imc_test_state_t *test_state;
        TNC_Result result;
 
-       command = lib->settings->get_str(lib->settings,
-                                                "libimcv.plugins.imc-test.command", "none");
-       attr = ita_attr_command_create(command);
+       if (!imc_test->get_state(imc_test, connection_id, &state))
+       {
+               return TNC_RESULT_FATAL;
+       }
+       test_state = (imc_test_state_t*)state;
+       attr = ita_attr_command_create(test_state->get_command(test_state));
        attr->set_noskip_flag(attr, TRUE);
        msg = pa_tnc_msg_create();
        msg->add_attribute(msg, attr);
index 1b60f32..ade1fc1 100644 (file)
@@ -38,6 +38,15 @@ struct private_imc_test_state_t {
         */
        TNC_ConnectionState state;
 
+       /**
+        * Command to transmit to IMV
+        */
+       char *command;
+
+       /**
+        * Do a handshake retry
+        */
+       bool handshake_retry;
 };
 
 METHOD(imc_state_t, get_connection_id, TNC_ConnectionID,
@@ -55,13 +64,43 @@ METHOD(imc_state_t, change_state, void,
 METHOD(imc_state_t, destroy, void,
        private_imc_test_state_t *this)
 {
+       free(this->command);
        free(this);
 }
 
+METHOD(imc_test_state_t, get_command, char*,
+       private_imc_test_state_t *this)
+{
+       return this->command;
+}
+
+METHOD(imc_test_state_t, set_command, void,
+       private_imc_test_state_t *this, char* command)
+{
+       char *old_command;
+
+       old_command = this->command;
+       this->command = strdup(command);
+       free(old_command);
+}
+
+METHOD(imc_test_state_t, do_handshake_retry, bool,
+       private_imc_test_state_t *this)
+{
+       bool retry;
+
+       /* test and reset handshake_retry flag */
+       retry = this->handshake_retry;
+       this->handshake_retry = FALSE;
+       return retry;
+}
+
+
 /**
  * Described in header.
  */
-imc_state_t *imc_test_state_create(TNC_ConnectionID connection_id)
+imc_state_t *imc_test_state_create(TNC_ConnectionID connection_id,
+                                                                  char *command, bool retry)
 {
        private_imc_test_state_t *this;
 
@@ -72,9 +111,14 @@ imc_state_t *imc_test_state_create(TNC_ConnectionID connection_id)
                                .change_state = _change_state,
                                .destroy = _destroy,
                        },
+                       .get_command = _get_command,
+                       .set_command = _set_command,
+                       .do_handshake_retry = _do_handshake_retry,
                },
                .state = TNC_CONNECTION_STATE_CREATE,
                .connection_id = connection_id,
+               .command = strdup(command),
+               .handshake_retry = retry,
        );
        
        return &this->public.interface;
index 6d2dc5e..edcd81d 100644 (file)
@@ -35,14 +35,37 @@ struct imc_test_state_t {
         * imc_state_t interface
         */
        imc_state_t interface;
+
+       /**
+        * get the command to send to IMV
+        *
+        * @return                              commmand to send to IMV
+        */
+       char* (*get_command)(imc_test_state_t *this);
+
+       /**
+        * set the command to send to IMV
+        *
+        * @param command               commmand to send to IMV
+        */
+       void (*set_command)(imc_test_state_t *this, char *command);
+
+       /**
+        * Test and reset the retry handshake flag
+        *
+        * @return                              TRUE if a handshake retry should be done
+        */
+       bool (*do_handshake_retry)(imc_test_state_t *this);
 };
 
 /**
  * Create an imc_test_state_t instance
  *
  * @param id           connection ID
- * @param rounds       total number of IMC re-measurements
+ * @param command      command to send to IMV
+ * @param retry                TRUE if a handshake retry should be done
  */
-imc_state_t* imc_test_state_create(TNC_ConnectionID id);
+imc_state_t* imc_test_state_create(TNC_ConnectionID id, char* command,
+                                                                  bool retry);
 
 #endif /** IMC_TEST_STATE_H_ @}*/