diff options
Diffstat (limited to 'src/libimcv/imc/imc_agent.c')
-rw-r--r-- | src/libimcv/imc/imc_agent.c | 272 |
1 files changed, 52 insertions, 220 deletions
diff --git a/src/libimcv/imc/imc_agent.c b/src/libimcv/imc/imc_agent.c index 8d1e70716..161623477 100644 --- a/src/libimcv/imc/imc_agent.c +++ b/src/libimcv/imc/imc_agent.c @@ -18,7 +18,7 @@ #include <tncif_names.h> -#include <debug.h> +#include <utils/debug.h> #include <threading/rwlock.h> typedef struct private_imc_agent_t private_imc_agent_t; @@ -39,14 +39,14 @@ struct private_imc_agent_t { const char *name; /** - * message vendor ID of IMC + * message types registered by IMC */ - TNC_VendorID vendor_id; + pen_type_t *supported_types; /** - * message subtype of IMC + * number of message types registered by IMC */ - TNC_MessageSubtype subtype; + u_int32_t type_count; /** * ID of IMC as assigned by TNCC @@ -95,45 +95,6 @@ struct private_imc_agent_t { TNC_UInt32 type_count); /** - * Call when an IMC-IMC message is to be sent - * - * @param imc_id IMC ID assigned by TNCC - * @param connection_id network connection ID assigned by TNCC - * @param msg message to send - * @param msg_len message length in bytes - * @param msg_type message type - * @return TNC result code - */ - TNC_Result (*send_message)(TNC_IMCID imc_id, - TNC_ConnectionID connection_id, - TNC_BufferReference msg, - TNC_UInt32 msg_len, - TNC_MessageType msg_type); - - - /** - * Call when an IMC-IMC message is to be sent with long message types - * - * @param imc_id IMC ID assigned by TNCC - * @param connection_id network connection ID assigned by TNCC - * @param msg_flags message flags - * @param msg message to send - * @param msg_len message length in bytes - * @param msg_vid message vendor ID - * @param msg_subtype message subtype - * @param dst_imc_id destination IMV ID - * @return TNC result code - */ - TNC_Result (*send_message_long)(TNC_IMCID imc_id, - TNC_ConnectionID connection_id, - TNC_UInt32 msg_flags, - TNC_BufferReference msg, - TNC_UInt32 msg_len, - TNC_VendorID msg_vid, - TNC_MessageSubtype msg_subtype, - TNC_UInt32 dst_imv_id); - - /** * Get the value of an attribute associated with a connection * or with the TNCC as a whole. * @@ -205,14 +166,14 @@ METHOD(imc_agent_t, bind_functions, TNC_Result, this->public.request_handshake_retry = NULL; } if (bind_function(this->id, "TNC_TNCC_SendMessage", - (void**)&this->send_message) != TNC_RESULT_SUCCESS) + (void**)&this->public.send_message) != TNC_RESULT_SUCCESS) { - this->send_message = NULL; + this->public.send_message = NULL; } if (bind_function(this->id, "TNC_TNCC_SendMessageLong", - (void**)&this->send_message_long) != TNC_RESULT_SUCCESS) + (void**)&this->public.send_message_long) != TNC_RESULT_SUCCESS) { - this->send_message_long = NULL; + this->public.send_message_long = NULL; } if (bind_function(this->id, "TNC_TNCC_GetAttribute", (void**)&this->get_attribute) != TNC_RESULT_SUCCESS) @@ -234,17 +195,37 @@ METHOD(imc_agent_t, bind_functions, TNC_Result, if (this->report_message_types_long) { - this->report_message_types_long(this->id, &this->vendor_id, - &this->subtype, 1); + TNC_VendorIDList vendor_id_list; + TNC_MessageSubtypeList subtype_list; + int i; + + vendor_id_list = malloc(this->type_count * sizeof(TNC_UInt32)); + subtype_list = malloc(this->type_count * sizeof(TNC_UInt32)); + + for (i = 0; i < this->type_count; i++) + { + vendor_id_list[i] = this->supported_types[i].vendor_id; + subtype_list[i] = this->supported_types[i].type; + } + this->report_message_types_long(this->id, vendor_id_list, subtype_list, + this->type_count); + free(vendor_id_list); + free(subtype_list); } - else if (this->report_message_types && - this->vendor_id <= TNC_VENDORID_ANY && - this->subtype <= TNC_SUBTYPE_ANY) + else if (this->report_message_types) { - TNC_MessageType type; + TNC_MessageTypeList type_list; + int i; + + type_list = malloc(this->type_count * sizeof(TNC_UInt32)); - type = (this->vendor_id << 8) | this->subtype; - this->report_message_types(this->id, &type, 1); + for (i = 0; i < this->type_count; i++) + { + type_list[i] = (this->supported_types[i].vendor_id << 8) | + (this->supported_types[i].type & 0xff); + } + this->report_message_types(this->id, type_list, this->type_count); + free(type_list); } return TNC_RESULT_SUCCESS; } @@ -372,7 +353,7 @@ METHOD(imc_agent_t, create_state, TNC_Result, has_long = get_bool_attribute(this, conn_id, TNC_ATTRIBUTEID_HAS_LONG_TYPES); has_excl = get_bool_attribute(this, conn_id, TNC_ATTRIBUTEID_HAS_EXCLUSIVE); has_soh = get_bool_attribute(this, conn_id, TNC_ATTRIBUTEID_HAS_SOH); - tnccs_p = get_str_attribute(this, conn_id, TNC_ATTRIBUTEID_IFTNCCS_PROTOCOL); + tnccs_p = get_str_attribute(this, conn_id, TNC_ATTRIBUTEID_IFTNCCS_PROTOCOL); tnccs_v = get_str_attribute(this, conn_id, TNC_ATTRIBUTEID_IFTNCCS_VERSION); t_p = get_str_attribute(this, conn_id, TNC_ATTRIBUTEID_IFT_PROTOCOL); t_v = get_str_attribute(this, conn_id, TNC_ATTRIBUTEID_IFT_VERSION); @@ -427,7 +408,7 @@ METHOD(imc_agent_t, change_state, TNC_Result, case TNC_CONNECTION_STATE_ACCESS_ISOLATED: case TNC_CONNECTION_STATE_ACCESS_NONE: state = find_connection(this, connection_id); - + if (!state) { DBG1(DBG_IMC, "IMC %u \"%s\" has no state for Connection ID %u", @@ -455,7 +436,7 @@ METHOD(imc_agent_t, change_state, TNC_Result, DBG1(DBG_IMC, "IMC %u \"%s\" was notified of unknown state %u " "for Connection ID %u", this->id, this->name, new_state, connection_id); - return TNC_RESULT_INVALID_PARAMETER; + return TNC_RESULT_INVALID_PARAMETER; } return TNC_RESULT_SUCCESS; } @@ -474,165 +455,16 @@ METHOD(imc_agent_t, get_state, bool, return TRUE; } -METHOD(imc_agent_t, send_message, TNC_Result, - private_imc_agent_t *this, TNC_ConnectionID connection_id, bool excl, - TNC_UInt32 src_imc_id, TNC_UInt32 dst_imv_id, linked_list_t *attr_list) +METHOD(imc_agent_t, get_name, const char*, + private_imc_agent_t *this) { - TNC_MessageType type; - TNC_UInt32 msg_flags; - TNC_Result result = TNC_RESULT_FATAL; - imc_state_t *state; - pa_tnc_attr_t *attr; - pa_tnc_msg_t *pa_tnc_msg; - chunk_t msg; - enumerator_t *enumerator; - bool attr_added; - - state = find_connection(this, connection_id); - if (!state) - { - DBG1(DBG_IMV, "IMC %u \"%s\" has no state for Connection ID %u", - this->id, this->name, connection_id); - return TNC_RESULT_FATAL; - } - - while (attr_list->get_count(attr_list)) - { - pa_tnc_msg = pa_tnc_msg_create(state->get_max_msg_len(state)); - attr_added = FALSE; - - enumerator = attr_list->create_enumerator(attr_list); - while (enumerator->enumerate(enumerator, &attr)) - { - if (pa_tnc_msg->add_attribute(pa_tnc_msg, attr)) - { - attr_added = TRUE; - } - else - { - if (attr_added) - { - break; - } - else - { - DBG1(DBG_IMC, "PA-TNC attribute too large to send, deleted"); - attr->destroy(attr); - } - } - attr_list->remove_at(attr_list, enumerator); - } - enumerator->destroy(enumerator); - - /* build and send the PA-TNC message via the IF-IMC interface */ - if (!pa_tnc_msg->build(pa_tnc_msg)) - { - pa_tnc_msg->destroy(pa_tnc_msg); - return TNC_RESULT_FATAL; - } - msg = pa_tnc_msg->get_encoding(pa_tnc_msg); - - if (state->has_long(state) && this->send_message_long) - { - if (!src_imc_id) - { - src_imc_id = this->id; - } - msg_flags = excl ? TNC_MESSAGE_FLAGS_EXCLUSIVE : 0; - - result = this->send_message_long(src_imc_id, connection_id, - msg_flags, msg.ptr, msg.len, this->vendor_id, - this->subtype, dst_imv_id); - } - else if (this->send_message) - { - type = (this->vendor_id << 8) | this->subtype; - - result = this->send_message(this->id, connection_id, msg.ptr, - msg.len, type); - } - - pa_tnc_msg->destroy(pa_tnc_msg); - - if (result != TNC_RESULT_SUCCESS) - { - break; - } - } - return result; + return this->name; } -METHOD(imc_agent_t, receive_message, TNC_Result, - private_imc_agent_t *this, imc_state_t *state, chunk_t msg, - TNC_VendorID msg_vid, TNC_MessageSubtype msg_subtype, - TNC_UInt32 src_imv_id, TNC_UInt32 dst_imc_id, pa_tnc_msg_t **pa_tnc_msg) +METHOD(imc_agent_t, get_id, TNC_IMCID, + private_imc_agent_t *this) { - pa_tnc_msg_t *pa_msg; - pa_tnc_attr_t *error_attr; - linked_list_t *error_attr_list; - enumerator_t *enumerator; - TNC_UInt32 src_imc_id, dst_imv_id; - TNC_ConnectionID connection_id; - TNC_Result result; - - connection_id = state->get_connection_id(state); - - if (state->has_long(state)) - { - if (dst_imc_id != TNC_IMCID_ANY) - { - DBG2(DBG_IMC, "IMC %u \"%s\" received message for Connection ID %u " - "from IMV %u to IMC %u", this->id, this->name, - connection_id, src_imv_id, dst_imc_id); - } - else - { - DBG2(DBG_IMC, "IMC %u \"%s\" received message for Connection ID %u " - "from IMV %u", this->id, this->name, connection_id, - src_imv_id); - } - } - else - { - DBG2(DBG_IMC, "IMC %u \"%s\" received message for Connection ID %u", - this->id, this->name, connection_id); - } - - *pa_tnc_msg = NULL; - pa_msg = pa_tnc_msg_create_from_data(msg); - - switch (pa_msg->process(pa_msg)) - { - case SUCCESS: - *pa_tnc_msg = pa_msg; - break; - case VERIFY_ERROR: - /* extract and copy by refence all error attributes */ - error_attr_list = linked_list_create(); - - enumerator = pa_msg->create_error_enumerator(pa_msg); - while (enumerator->enumerate(enumerator, &error_attr)) - { - error_attr_list->insert_last(error_attr_list, - error_attr->get_ref(error_attr)); - } - enumerator->destroy(enumerator); - - src_imc_id = (dst_imc_id == TNC_IMCID_ANY) ? this->id : dst_imc_id; - dst_imv_id = state->has_excl(state) ? src_imv_id : TNC_IMVID_ANY; - - result = send_message(this, connection_id, state->has_excl(state), - src_imc_id, dst_imv_id, error_attr_list); - - error_attr_list->destroy(error_attr_list); - pa_msg->destroy(pa_msg); - return result; - case FAILED: - default: - pa_msg->destroy(pa_msg); - return TNC_RESULT_FATAL; - } - return TNC_RESULT_SUCCESS; + return this->id; } METHOD(imc_agent_t, reserve_additional_ids, TNC_Result, @@ -697,7 +529,7 @@ METHOD(imc_agent_t, destroy, void, * Described in header. */ imc_agent_t *imc_agent_create(const char *name, - pen_t vendor_id, u_int32_t subtype, + pen_type_t *supported_types, u_int32_t type_count, TNC_IMCID id, TNC_Version *actual_version) { private_imc_agent_t *this; @@ -715,22 +547,22 @@ imc_agent_t *imc_agent_create(const char *name, .delete_state = _delete_state, .change_state = _change_state, .get_state = _get_state, - .send_message = _send_message, - .receive_message = _receive_message, + .get_name = _get_name, + .get_id = _get_id, .reserve_additional_ids = _reserve_additional_ids, .count_additional_ids = _count_additional_ids, .create_id_enumerator = _create_id_enumerator, .destroy = _destroy, }, .name = name, - .vendor_id = vendor_id, - .subtype = subtype, + .supported_types = supported_types, + .type_count = type_count, .id = id, .additional_ids = linked_list_create(), .connections = linked_list_create(), .connection_lock = rwlock_create(RWLOCK_TYPE_DEFAULT), ); - + *actual_version = TNC_IFIMC_VERSION_1; DBG1(DBG_IMC, "IMC %u \"%s\" initialized", this->id, this->name); |