mirror of
https://github.com/strongswan/strongswan.git
synced 2025-12-15 00:00:26 -05:00
upgraded Test IMC/IMV pair to fully support multple IMC IDs
This commit is contained in:
parent
6f04ccff5e
commit
63179fd459
@ -607,6 +607,9 @@ List of TCP ports that can be open or must be closed
|
||||
.BR libimcv.plugins.imv-scanner.udp_ports
|
||||
List of UDP ports that can be open or must be closed
|
||||
.TP
|
||||
.BR libimcv.plugins.imc-test.additional_ids " [0]"
|
||||
Number of additional IMC IDs
|
||||
.TP
|
||||
.BR libimcv.plugins.imc-test.command " [none]"
|
||||
Command to be sent to the Test IMV
|
||||
.TP
|
||||
|
||||
@ -83,6 +83,7 @@ TNC_Result TNC_IMC_NotifyConnectionChange(TNC_IMCID imc_id,
|
||||
DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
|
||||
return TNC_RESULT_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
switch (new_state)
|
||||
{
|
||||
case TNC_CONNECTION_STATE_CREATE:
|
||||
@ -91,6 +92,7 @@ TNC_Result TNC_IMC_NotifyConnectionChange(TNC_IMCID imc_id,
|
||||
retry = lib->settings->get_bool(lib->settings,
|
||||
"libimcv.plugins.imc-test.retry", FALSE);
|
||||
state = imc_test_state_create(connection_id, command, retry);
|
||||
test_state = (imc_test_state_t*)state;
|
||||
|
||||
result = imc_test->create_state(imc_test, state);
|
||||
if (result != TNC_RESULT_SUCCESS)
|
||||
@ -112,7 +114,6 @@ TNC_Result TNC_IMC_NotifyConnectionChange(TNC_IMCID imc_id,
|
||||
"multiple IMC IDs", imc_id, imc_name);
|
||||
return TNC_RESULT_SUCCESS;
|
||||
}
|
||||
test_state = (imc_test_state_t*)state;
|
||||
|
||||
while (additional_ids-- > 0)
|
||||
{
|
||||
@ -178,52 +179,28 @@ TNC_Result TNC_IMC_NotifyConnectionChange(TNC_IMCID imc_id,
|
||||
}
|
||||
}
|
||||
|
||||
static TNC_Result send_message(TNC_ConnectionID connection_id)
|
||||
static TNC_Result send_message(imc_state_t *state, TNC_UInt32 src_imc_id,
|
||||
TNC_UInt32 dst_imv_id)
|
||||
{
|
||||
imc_test_state_t *test_state;
|
||||
pa_tnc_msg_t *msg;
|
||||
pa_tnc_attr_t *attr;
|
||||
imc_state_t *state;
|
||||
imc_test_state_t *test_state;
|
||||
enumerator_t *enumerator;
|
||||
void *pointer;
|
||||
TNC_UInt32 imc_id;
|
||||
bool excl;
|
||||
TNC_ConnectionID connection_id;
|
||||
TNC_Result result;
|
||||
|
||||
if (!imc_test->get_state(imc_test, connection_id, &state))
|
||||
{
|
||||
return TNC_RESULT_FATAL;
|
||||
}
|
||||
connection_id = state->get_connection_id(state);
|
||||
test_state = (imc_test_state_t*)state;
|
||||
|
||||
/* send PA message for primary IMC ID */
|
||||
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);
|
||||
msg->build(msg);
|
||||
result = imc_test->send_message(imc_test, connection_id, FALSE, 0,
|
||||
TNC_IMVID_ANY, msg->get_encoding(msg));
|
||||
excl = dst_imv_id != TNC_IMVID_ANY;
|
||||
result = imc_test->send_message(imc_test, connection_id, excl, src_imc_id,
|
||||
dst_imv_id, msg->get_encoding(msg));
|
||||
msg->destroy(msg);
|
||||
|
||||
/* send PA messages for additional IMC IDs */
|
||||
enumerator = test_state->create_id_enumerator(test_state);
|
||||
while (result == TNC_RESULT_SUCCESS &&
|
||||
enumerator->enumerate(enumerator, &pointer))
|
||||
{
|
||||
/* interpret pointer as scalar value */
|
||||
imc_id = (TNC_UInt32)pointer;
|
||||
|
||||
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);
|
||||
msg->build(msg);
|
||||
result = imc_test->send_message(imc_test, connection_id, FALSE, imc_id,
|
||||
TNC_IMVID_ANY, msg->get_encoding(msg));
|
||||
msg->destroy(msg);
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -233,12 +210,41 @@ static TNC_Result send_message(TNC_ConnectionID connection_id)
|
||||
TNC_Result TNC_IMC_BeginHandshake(TNC_IMCID imc_id,
|
||||
TNC_ConnectionID connection_id)
|
||||
{
|
||||
imc_state_t *state;
|
||||
imc_test_state_t *test_state;
|
||||
enumerator_t *enumerator;
|
||||
void *pointer;
|
||||
TNC_UInt32 additional_id;
|
||||
TNC_Result result;
|
||||
|
||||
if (!imc_test)
|
||||
{
|
||||
DBG1(DBG_IMC, "IMC \"%s\" has not been initialized", imc_name);
|
||||
return TNC_RESULT_NOT_INITIALIZED;
|
||||
}
|
||||
return send_message(connection_id);
|
||||
|
||||
/* get current IMC state */
|
||||
if (!imc_test->get_state(imc_test, connection_id, &state))
|
||||
{
|
||||
return TNC_RESULT_FATAL;
|
||||
}
|
||||
test_state = (imc_test_state_t*)state;
|
||||
|
||||
/* send PA message for primary IMC ID */
|
||||
result = send_message(state, imc_id, TNC_IMVID_ANY);
|
||||
|
||||
/* send PA messages for additional IMC IDs */
|
||||
enumerator = test_state->create_id_enumerator(test_state);
|
||||
while (result == TNC_RESULT_SUCCESS &&
|
||||
enumerator->enumerate(enumerator, &pointer))
|
||||
{
|
||||
/* interpret pointer as scalar value */
|
||||
additional_id = (TNC_UInt32)pointer;
|
||||
result = send_message(state, additional_id, TNC_IMVID_ANY);
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static TNC_Result receive_message(TNC_IMCID imc_id,
|
||||
@ -300,7 +306,8 @@ static TNC_Result receive_message(TNC_IMCID imc_id,
|
||||
pa_tnc_msg->destroy(pa_tnc_msg);
|
||||
|
||||
/* if no error occurred then always return the same response */
|
||||
return fatal_error ? TNC_RESULT_FATAL : send_message(connection_id);
|
||||
return fatal_error ? TNC_RESULT_FATAL :
|
||||
send_message(state, dst_imc_id, src_imv_id);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -71,9 +71,6 @@ TNC_Result TNC_IMV_NotifyConnectionChange(TNC_IMVID imv_id,
|
||||
TNC_ConnectionState new_state)
|
||||
{
|
||||
imv_state_t *state;
|
||||
imv_test_state_t *test_state;
|
||||
TNC_Result result;
|
||||
int rounds;
|
||||
|
||||
if (!imv_test)
|
||||
{
|
||||
@ -87,44 +84,12 @@ TNC_Result TNC_IMV_NotifyConnectionChange(TNC_IMVID imv_id,
|
||||
return imv_test->create_state(imv_test, state);
|
||||
case TNC_CONNECTION_STATE_DELETE:
|
||||
return imv_test->delete_state(imv_test, connection_id);
|
||||
case TNC_CONNECTION_STATE_HANDSHAKE:
|
||||
/* get updated IMV state */
|
||||
result = imv_test->change_state(imv_test, connection_id,
|
||||
new_state, &state);
|
||||
if (result != TNC_RESULT_SUCCESS)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
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->set_rounds(test_state, rounds);
|
||||
return TNC_RESULT_SUCCESS;
|
||||
default:
|
||||
return imv_test->change_state(imv_test, connection_id,
|
||||
new_state, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static TNC_Result send_message(TNC_ConnectionID connection_id)
|
||||
{
|
||||
pa_tnc_msg_t *msg;
|
||||
pa_tnc_attr_t *attr;
|
||||
TNC_Result result;
|
||||
|
||||
attr = ita_attr_command_create("repeat");
|
||||
msg = pa_tnc_msg_create();
|
||||
msg->add_attribute(msg, attr);
|
||||
msg->build(msg);
|
||||
result = imv_test->send_message(imv_test, connection_id, FALSE, 0,
|
||||
TNC_IMCID_ANY, msg->get_encoding(msg));
|
||||
msg->destroy(msg);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static TNC_Result receive_message(TNC_IMVID imv_id,
|
||||
TNC_ConnectionID connection_id,
|
||||
TNC_UInt32 msg_flags,
|
||||
@ -137,9 +102,10 @@ static TNC_Result receive_message(TNC_IMVID imv_id,
|
||||
pa_tnc_msg_t *pa_tnc_msg;
|
||||
pa_tnc_attr_t *attr;
|
||||
imv_state_t *state;
|
||||
imv_test_state_t *imv_test_state;
|
||||
imv_test_state_t *test_state;
|
||||
enumerator_t *enumerator;
|
||||
TNC_Result result;
|
||||
int rounds;
|
||||
bool fatal_error, retry = FALSE;
|
||||
|
||||
if (!imv_test)
|
||||
@ -153,6 +119,7 @@ static TNC_Result receive_message(TNC_IMVID imv_id,
|
||||
{
|
||||
return TNC_RESULT_FATAL;
|
||||
}
|
||||
test_state = (imv_test_state_t*)state;
|
||||
|
||||
/* parse received PA-TNC message and automatically handle any errors */
|
||||
result = imv_test->receive_message(imv_test, state, msg, msg_vid,
|
||||
@ -167,6 +134,11 @@ static TNC_Result receive_message(TNC_IMVID imv_id,
|
||||
/* preprocess any IETF standard error attributes */
|
||||
fatal_error = pa_tnc_msg->process_ietf_std_errors(pa_tnc_msg);
|
||||
|
||||
/* add any new IMC and set its number of rounds */
|
||||
rounds = lib->settings->get_int(lib->settings,
|
||||
"libimcv.plugins.imv-test.rounds", 0);
|
||||
test_state->add_imc(test_state, src_imc_id, rounds);
|
||||
|
||||
/* analyze PA-TNC attributes */
|
||||
enumerator = pa_tnc_msg->create_attribute_enumerator(pa_tnc_msg);
|
||||
while (enumerator->enumerate(enumerator, &attr))
|
||||
@ -225,15 +197,23 @@ static TNC_Result receive_message(TNC_IMVID imv_id,
|
||||
/* request a handshake retry ? */
|
||||
if (retry)
|
||||
{
|
||||
test_state->set_rounds(test_state, rounds);
|
||||
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))
|
||||
if (test_state->another_round(test_state, src_imc_id))
|
||||
{
|
||||
return send_message(connection_id);
|
||||
attr = ita_attr_command_create("repeat");
|
||||
pa_tnc_msg = pa_tnc_msg_create();
|
||||
pa_tnc_msg->add_attribute(pa_tnc_msg, attr);
|
||||
pa_tnc_msg->build(pa_tnc_msg);
|
||||
result = imv_test->send_message(imv_test, connection_id, TRUE, imv_id,
|
||||
src_imc_id, pa_tnc_msg->get_encoding(pa_tnc_msg));
|
||||
pa_tnc_msg->destroy(pa_tnc_msg);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
return imv_test->provide_recommendation(imv_test, connection_id);
|
||||
|
||||
@ -15,6 +15,7 @@
|
||||
#include "imv_test_state.h"
|
||||
|
||||
#include <utils/lexparser.h>
|
||||
#include <utils/linked_list.h>
|
||||
#include <debug.h>
|
||||
|
||||
typedef struct private_imv_test_state_t private_imv_test_state_t;
|
||||
@ -60,12 +61,22 @@ struct private_imv_test_state_t {
|
||||
TNC_IMV_Evaluation_Result eval;
|
||||
|
||||
/**
|
||||
* IMC-IMV round-trip count
|
||||
* List of IMCs
|
||||
*/
|
||||
int rounds;
|
||||
linked_list_t *imcs;
|
||||
|
||||
};
|
||||
|
||||
typedef struct imc_entry_t imc_entry_t;
|
||||
|
||||
/**
|
||||
* Define an internal IMC entry
|
||||
*/
|
||||
struct imc_entry_t {
|
||||
TNC_UInt32 imc_id;
|
||||
int rounds;
|
||||
};
|
||||
|
||||
typedef struct entry_t entry_t;
|
||||
|
||||
/**
|
||||
@ -180,19 +191,73 @@ METHOD(imv_state_t, get_reason_string, bool,
|
||||
METHOD(imv_state_t, destroy, void,
|
||||
private_imv_test_state_t *this)
|
||||
{
|
||||
this->imcs->destroy_function(this->imcs, free);
|
||||
free(this);
|
||||
}
|
||||
|
||||
METHOD(imv_test_state_t, add_imc, void,
|
||||
private_imv_test_state_t *this, TNC_UInt32 imc_id, int rounds)
|
||||
{
|
||||
enumerator_t *enumerator;
|
||||
imc_entry_t *imc_entry;
|
||||
bool found = FALSE;
|
||||
|
||||
enumerator = this->imcs->create_enumerator(this->imcs);
|
||||
while (enumerator->enumerate(enumerator, &imc_entry))
|
||||
{
|
||||
if (imc_entry->imc_id == imc_id)
|
||||
{
|
||||
found = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
if (!found)
|
||||
{
|
||||
imc_entry = malloc_thing(imc_entry_t);
|
||||
imc_entry->imc_id = imc_id;
|
||||
imc_entry->rounds = rounds;
|
||||
this->imcs->insert_last(this->imcs, imc_entry);
|
||||
}
|
||||
}
|
||||
|
||||
METHOD(imv_test_state_t, set_rounds, void,
|
||||
private_imv_test_state_t *this, int rounds)
|
||||
{
|
||||
this->rounds = rounds;
|
||||
enumerator_t *enumerator;
|
||||
imc_entry_t *imc_entry;
|
||||
|
||||
enumerator = this->imcs->create_enumerator(this->imcs);
|
||||
while (enumerator->enumerate(enumerator, &imc_entry))
|
||||
{
|
||||
imc_entry->rounds = rounds;
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
}
|
||||
|
||||
METHOD(imv_test_state_t, another_round, bool,
|
||||
private_imv_test_state_t *this)
|
||||
private_imv_test_state_t *this, TNC_UInt32 imc_id)
|
||||
{
|
||||
return (this->rounds-- > 0);
|
||||
enumerator_t *enumerator;
|
||||
imc_entry_t *imc_entry;
|
||||
bool not_finished = FALSE;
|
||||
|
||||
enumerator = this->imcs->create_enumerator(this->imcs);
|
||||
while (enumerator->enumerate(enumerator, &imc_entry))
|
||||
{
|
||||
if (imc_entry->rounds > 0)
|
||||
{
|
||||
not_finished = TRUE;
|
||||
}
|
||||
if (imc_entry->imc_id == imc_id)
|
||||
{
|
||||
imc_entry->rounds--;
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
return not_finished;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -215,6 +280,7 @@ imv_state_t *imv_test_state_create(TNC_ConnectionID connection_id)
|
||||
.get_reason_string = _get_reason_string,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.add_imc = _add_imc,
|
||||
.set_rounds = _set_rounds,
|
||||
.another_round = _another_round,
|
||||
},
|
||||
@ -222,6 +288,7 @@ imv_state_t *imv_test_state_create(TNC_ConnectionID connection_id)
|
||||
.rec = TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION,
|
||||
.eval = TNC_IMV_EVALUATION_RESULT_DONT_KNOW,
|
||||
.connection_id = connection_id,
|
||||
.imcs = linked_list_create(),
|
||||
);
|
||||
|
||||
return &this->public.interface;
|
||||
|
||||
@ -36,6 +36,14 @@ struct imv_test_state_t {
|
||||
*/
|
||||
imv_state_t interface;
|
||||
|
||||
/**
|
||||
* Add an IMC
|
||||
*
|
||||
* @param imc_id ID of the IMC to be added
|
||||
* @param rounds number of re-measurement rounds
|
||||
*/
|
||||
void (*add_imc)(imv_test_state_t *this, TNC_UInt32 imc_id, int rounds);
|
||||
|
||||
/**
|
||||
* Set the IMC-IMV round-trip count
|
||||
*
|
||||
@ -46,9 +54,10 @@ struct imv_test_state_t {
|
||||
/**
|
||||
* Check and decrease IMC-IMV round-trip count
|
||||
*
|
||||
* @param imc_id ID of the IMC to be checked
|
||||
* @return new connection state
|
||||
*/
|
||||
bool (*another_round)(imv_test_state_t *this);
|
||||
bool (*another_round)(imv_test_state_t *this, TNC_UInt32 imc_id);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@ -14,6 +14,7 @@ libimcv {
|
||||
plugins {
|
||||
imc-test {
|
||||
command = allow
|
||||
additional_ids = 2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -17,6 +17,7 @@ libimcv {
|
||||
plugins {
|
||||
imc-test {
|
||||
command = isolate
|
||||
additional_ids = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user