From 96d0ff123796634f6bdd690fb97ca672e31302c8 Mon Sep 17 00:00:00 2001 From: Andreas Steffen Date: Wed, 15 Jun 2011 13:09:19 +0200 Subject: [PATCH] implemented handshake retry on the client side --- src/libimcv/plugins/imc_test/imc_test.c | 42 +++++++++++++++-- src/libimcv/plugins/imc_test/imc_test_state.c | 46 ++++++++++++++++++- src/libimcv/plugins/imc_test/imc_test_state.h | 27 ++++++++++- 3 files changed, 107 insertions(+), 8 deletions(-) diff --git a/src/libimcv/plugins/imc_test/imc_test.c b/src/libimcv/plugins/imc_test/imc_test.c index e89008f87..9efdc72c6 100644 --- a/src/libimcv/plugins/imc_test/imc_test.c +++ b/src/libimcv/plugins/imc_test/imc_test.c @@ -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); diff --git a/src/libimcv/plugins/imc_test/imc_test_state.c b/src/libimcv/plugins/imc_test/imc_test_state.c index 1b60f3260..ade1fc15b 100644 --- a/src/libimcv/plugins/imc_test/imc_test_state.c +++ b/src/libimcv/plugins/imc_test/imc_test_state.c @@ -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; diff --git a/src/libimcv/plugins/imc_test/imc_test_state.h b/src/libimcv/plugins/imc_test/imc_test_state.h index 6d2dc5e7a..edcd81dbb 100644 --- a/src/libimcv/plugins/imc_test/imc_test_state.h +++ b/src/libimcv/plugins/imc_test/imc_test_state.h @@ -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_ @}*/