diff options
author | Romain Francoise <rfrancoise@debian.org> | 2014-10-21 19:28:38 +0200 |
---|---|---|
committer | Romain Francoise <rfrancoise@debian.org> | 2014-10-21 19:28:38 +0200 |
commit | 2b8de74ff4c334c25e89988c4a401b24b5bcf03d (patch) | |
tree | 10fb49ca94bfd0c8b8a583412281abfc0186836e /src/libimcv/imv | |
parent | 81c63b0eed39432878f78727f60a1e7499645199 (diff) | |
download | vyos-strongswan-2b8de74ff4c334c25e89988c4a401b24b5bcf03d.tar.gz vyos-strongswan-2b8de74ff4c334c25e89988c4a401b24b5bcf03d.zip |
Import upstream release 5.2.1
Diffstat (limited to 'src/libimcv/imv')
-rw-r--r-- | src/libimcv/imv/data.sql | 35 | ||||
-rw-r--r-- | src/libimcv/imv/imv_agent.c | 26 | ||||
-rw-r--r-- | src/libimcv/imv/imv_agent.h | 10 | ||||
-rw-r--r-- | src/libimcv/imv/imv_msg.c | 238 | ||||
-rw-r--r-- | src/libimcv/imv/imv_msg.h | 6 | ||||
-rw-r--r-- | src/libimcv/imv/imv_os_info.h | 2 | ||||
-rw-r--r-- | src/libimcv/imv/imv_state.h | 8 |
7 files changed, 303 insertions, 22 deletions
diff --git a/src/libimcv/imv/data.sql b/src/libimcv/imv/data.sql index b45cad487..425748f59 100644 --- a/src/libimcv/imv/data.sql +++ b/src/libimcv/imv/data.sql @@ -306,6 +306,23 @@ INSERT INTO products ( /* 51 */ 'Android 4.4.4' ); +INSERT INTO products ( /* 52 */ + name +) VALUES ( + 'Debian 7.6 i686' +); + +INSERT INTO products ( /* 53 */ + name +) VALUES ( + 'Debian 7.6 x86_64' +); +INSERT INTO products ( /* 54 */ + name +) VALUES ( + 'Debian 7.6 armv6l' +); + /* Directories */ INSERT INTO directories ( /* 1 */ @@ -777,6 +794,12 @@ INSERT INTO groups_product_defaults ( INSERT INTO groups_product_defaults ( group_id, product_id ) VALUES ( + 4, 52 +); + +INSERT INTO groups_product_defaults ( + group_id, product_id +) VALUES ( 5, 2 ); @@ -825,6 +848,12 @@ INSERT INTO groups_product_defaults ( INSERT INTO groups_product_defaults ( group_id, product_id ) VALUES ( + 5, 53 +); + +INSERT INTO groups_product_defaults ( + group_id, product_id +) VALUES ( 6, 9 ); @@ -1026,6 +1055,12 @@ INSERT INTO groups_product_defaults ( 14, 48 ); +INSERT INTO groups_product_defaults ( + group_id, product_id +) VALUES ( + 14, 54 +); + /* Policies */ INSERT INTO policies ( /* 1 */ diff --git a/src/libimcv/imv/imv_agent.c b/src/libimcv/imv/imv_agent.c index a46455d47..6b24f4b28 100644 --- a/src/libimcv/imv/imv_agent.c +++ b/src/libimcv/imv/imv_agent.c @@ -65,6 +65,11 @@ struct private_imv_agent_t { linked_list_t *additional_ids; /** + * list of non-fatal unsupported PA-TNC attribute types + */ + linked_list_t *non_fatal_attr_types; + + /** * list of TNCS connection entries */ linked_list_t *connections; @@ -772,11 +777,29 @@ METHOD(imv_agent_t, provide_recommendation, TNC_Result, return this->provide_recommendation(this->id, connection_id, rec, eval); } +METHOD(imv_agent_t, add_non_fatal_attr_type, void, + private_imv_agent_t *this, pen_type_t type) +{ + pen_type_t *type_p; + + type_p = malloc_thing(pen_type_t); + *type_p = type; + this->non_fatal_attr_types->insert_last(this->non_fatal_attr_types, type_p); +} + +METHOD(imv_agent_t, get_non_fatal_attr_types, linked_list_t*, + private_imv_agent_t *this) +{ + return this->non_fatal_attr_types; +} + METHOD(imv_agent_t, destroy, void, private_imv_agent_t *this) { DBG1(DBG_IMV, "IMV %u \"%s\" terminated", this->id, this->name); this->additional_ids->destroy(this->additional_ids); + this->non_fatal_attr_types->destroy_function(this->non_fatal_attr_types, + free); this->connections->destroy_offset(this->connections, offsetof(imv_state_t, destroy)); this->connection_lock->destroy(this->connection_lock); @@ -815,6 +838,8 @@ imv_agent_t *imv_agent_create(const char *name, .create_id_enumerator = _create_id_enumerator, .create_language_enumerator = _create_language_enumerator, .provide_recommendation = _provide_recommendation, + .add_non_fatal_attr_type = _add_non_fatal_attr_type, + .get_non_fatal_attr_types = _get_non_fatal_attr_types, .destroy = _destroy, }, .name = name, @@ -822,6 +847,7 @@ imv_agent_t *imv_agent_create(const char *name, .type_count = type_count, .id = id, .additional_ids = linked_list_create(), + .non_fatal_attr_types = linked_list_create(), .connections = linked_list_create(), .connection_lock = rwlock_create(RWLOCK_TYPE_DEFAULT), ); diff --git a/src/libimcv/imv/imv_agent.h b/src/libimcv/imv/imv_agent.h index 47ce770bc..1f6a10b7c 100644 --- a/src/libimcv/imv/imv_agent.h +++ b/src/libimcv/imv/imv_agent.h @@ -189,6 +189,16 @@ struct imv_agent_t { TNC_Result (*provide_recommendation)(imv_agent_t *this, imv_state_t* state); /** + * Add an item to the list of non-fatal unsupported PA-TNC attribute types + */ + void (*add_non_fatal_attr_type)(imv_agent_t *this, pen_type_t type); + + /** + * Get a list of non-fatal unsupported PA-TNC attribute types + */ + linked_list_t* (*get_non_fatal_attr_types)(imv_agent_t *this); + + /** * Destroys an imv_agent_t object */ void (*destroy)(imv_agent_t *this); diff --git a/src/libimcv/imv/imv_msg.c b/src/libimcv/imv/imv_msg.c index e7181750c..fdf63325d 100644 --- a/src/libimcv/imv/imv_msg.c +++ b/src/libimcv/imv/imv_msg.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Andreas Steffen + * Copyright (C) 2012-2014 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -18,8 +18,12 @@ #include "ietf/ietf_attr.h" #include "ietf/ietf_attr_assess_result.h" #include "ietf/ietf_attr_remediation_instr.h" +#include "tcg/seg/tcg_seg_attr_max_size.h" +#include "tcg/seg/tcg_seg_attr_seg_env.h" +#include "tcg/seg/tcg_seg_attr_next_seg.h" #include <tncif_names.h> +#include <tncif_pa_subtypes.h> #include <pen/pen.h> #include <collections/linked_list.h> @@ -121,11 +125,18 @@ METHOD(imv_msg_t, send_, TNC_Result, pa_tnc_attr_t *attr; TNC_UInt32 msg_flags; TNC_MessageType msg_type; - bool attr_added; + bool attr_added, oversize; chunk_t msg; + seg_contract_t *contract; + seg_contract_manager_t *contracts; enumerator_t *enumerator; TNC_Result result = TNC_RESULT_SUCCESS; + /* Get IF-M segmentation contract for this subtype if any */ + contracts = this->state->get_contracts(this->state); + contract = contracts->get_contract(contracts, this->msg_type, + FALSE, this->dst_id); + while (this->attr_list->get_count(this->attr_list)) { pa_tnc_msg = pa_tnc_msg_create(this->state->get_max_msg_len(this->state)); @@ -134,6 +145,17 @@ METHOD(imv_msg_t, send_, TNC_Result, enumerator = this->attr_list->create_enumerator(this->attr_list); while (enumerator->enumerate(enumerator, &attr)) { + if (contract && contract->check_size(contract, attr, &oversize)) + { + if (oversize) + { + /* TODO generate SWID error msg */ + } + else + { + attr = contract->first_segment(contract, attr); + } + } if (pa_tnc_msg->add_attribute(pa_tnc_msg, attr)) { attr_added = TRUE; @@ -246,8 +268,11 @@ METHOD(imv_msg_t, send_assessment, TNC_Result, } METHOD(imv_msg_t, receive, TNC_Result, - private_imv_msg_t *this, bool *fatal_error) + private_imv_msg_t *this, imv_msg_t *out_msg, bool *fatal_error) { + TNC_Result result = TNC_RESULT_SUCCESS; + TNC_UInt32 target_imv_id; + linked_list_t *non_fatal_types; enumerator_t *enumerator; pa_tnc_attr_t *attr; chunk_t msg; @@ -286,36 +311,211 @@ METHOD(imv_msg_t, receive, TNC_Result, break; case VERIFY_ERROR: { - imv_msg_t *error_msg; - TNC_Result result; - - error_msg = imv_msg_create_as_reply(&this->public); - /* extract and copy by reference all error attributes */ enumerator = this->pa_msg->create_error_enumerator(this->pa_msg); while (enumerator->enumerate(enumerator, &attr)) { - error_msg->add_attribute(error_msg, attr->get_ref(attr)); + out_msg->add_attribute(out_msg, attr->get_ref(attr)); } enumerator->destroy(enumerator); - - /* - * send the PA-TNC message containing all error attributes - * with the excl flag set - */ - result = error_msg->send(error_msg, TRUE); - error_msg->destroy(error_msg); - return result; } case FAILED: default: return TNC_RESULT_FATAL; } + /* determine target IMV ID */ + target_imv_id = (this->dst_id != TNC_IMVID_ANY) ? + this->dst_id : this->agent->get_id(this->agent); + + /* process IF-M segmentation attributes */ + enumerator = this->pa_msg->create_attribute_enumerator(this->pa_msg); + while (enumerator->enumerate(enumerator, &attr)) + { + uint32_t max_attr_size, max_seg_size, my_max_attr_size, my_max_seg_size; + seg_contract_manager_t *contracts; + seg_contract_t *contract; + char buf[BUF_LEN]; + pen_type_t type; + + type = attr->get_type(attr); + + if (type.vendor_id != PEN_TCG) + { + continue; + } + + contracts = this->state->get_contracts(this->state); + + switch (type.type) + { + case TCG_SEG_MAX_ATTR_SIZE_REQ: + { + tcg_seg_attr_max_size_t *attr_cast; + + attr_cast = (tcg_seg_attr_max_size_t*)attr; + attr_cast->get_attr_size(attr_cast, &max_attr_size, + &max_seg_size); + contract = contracts->get_contract(contracts, this->msg_type, + FALSE, this->src_id); + if (contract) + { + contract->set_max_size(contract, max_attr_size, + max_seg_size); + } + else + { + contract = seg_contract_create(this->msg_type, max_attr_size, + max_seg_size, FALSE, this->src_id, FALSE); + contract->set_responder(contract, target_imv_id); + contracts->add_contract(contracts, contract); + } + contract->get_info_string(contract, buf, BUF_LEN, TRUE); + DBG2(DBG_IMV, "%s", buf); + + /* Determine maximum PA-TNC attribute segment size */ + my_max_seg_size = this->state->get_max_msg_len(this->state) + - PA_TNC_HEADER_SIZE + - PA_TNC_ATTR_HEADER_SIZE + - TCG_SEG_ATTR_SEG_ENV_HEADER + - PA_TNC_ATTR_HEADER_SIZE + - TCG_SEG_ATTR_MAX_SIZE_SIZE; + + /* If segmentation is possible select lower segment size */ + if (max_seg_size != SEG_CONTRACT_NO_FRAGMENTATION && + max_seg_size > my_max_seg_size) + { + max_seg_size = my_max_seg_size; + contract->set_max_size(contract, max_attr_size, + max_seg_size); + DBG2(DBG_IMV, " lowered maximum segment size to %u bytes", + max_seg_size); + } + + /* Add Maximum Attribute Size Response attribute */ + attr = tcg_seg_attr_max_size_create(max_attr_size, + max_seg_size, FALSE); + out_msg->add_attribute(out_msg, attr); + break; + } + case TCG_SEG_MAX_ATTR_SIZE_RESP: + { + tcg_seg_attr_max_size_t *attr_cast; + + attr_cast = (tcg_seg_attr_max_size_t*)attr; + attr_cast->get_attr_size(attr_cast, &max_attr_size, + &max_seg_size); + contract = contracts->get_contract(contracts, this->msg_type, + TRUE, this->src_id); + if (!contract) + { + contract = contracts->get_contract(contracts, this->msg_type, + TRUE, TNC_IMCID_ANY); + if (contract) + { + contract = contract->clone(contract); + contract->set_responder(contract, this->src_id); + contracts->add_contract(contracts, contract); + } + } + if (contract) + { + contract->get_max_size(contract, &my_max_attr_size, + &my_max_seg_size); + if (my_max_seg_size != SEG_CONTRACT_NO_FRAGMENTATION && + my_max_seg_size > max_seg_size) + { + my_max_seg_size = max_seg_size; + contract->set_max_size(contract, my_max_attr_size, + my_max_seg_size); + } + contract->get_info_string(contract, buf, BUF_LEN, FALSE); + DBG2(DBG_IMV, "%s", buf); + } + else + { + /* TODO no request pending */ + DBG1(DBG_IMV, "no contract for this PA message type found"); + } + break; + } + case TCG_SEG_ATTR_SEG_ENV: + { + tcg_seg_attr_seg_env_t *seg_env_attr; + pa_tnc_attr_t *error; + uint32_t base_attr_id; + bool more; + + seg_env_attr = (tcg_seg_attr_seg_env_t*)attr; + base_attr_id = seg_env_attr->get_base_attr_id(seg_env_attr); + + contract = contracts->get_contract(contracts, this->msg_type, + TRUE, this->src_id); + if (!contract) + { + DBG2(DBG_IMV, "no contract for received attribute segment " + "with base attribute ID %u", base_attr_id); + continue; + } + attr = contract->add_segment(contract, attr, &error, &more); + if (error) + { + out_msg->add_attribute(out_msg, error); + } + if (attr) + { + this->pa_msg->add_attribute(this->pa_msg, attr); + } + if (more) + { + /* Send Next Segment Request */ + attr = tcg_seg_attr_next_seg_create(base_attr_id, FALSE); + out_msg->add_attribute(out_msg, attr); + } + break; + } + case TCG_SEG_NEXT_SEG_REQ: + { + tcg_seg_attr_next_seg_t *attr_cast; + uint32_t base_attr_id; + + attr_cast = (tcg_seg_attr_next_seg_t*)attr; + base_attr_id = attr_cast->get_base_attr_id(attr_cast); + + contract = contracts->get_contract(contracts, this->msg_type, + FALSE, this->src_id); + if (!contract) + { + /* TODO no contract - generate error message */ + DBG1(DBG_IMV, "no contract for received next segment " + "request with base attribute ID %u", base_attr_id); + continue; + } + attr = contract->next_segment(contract, base_attr_id); + if (attr) + { + out_msg->add_attribute(out_msg, attr); + } + else + { + /* TODO no more segments - generate error message */ + DBG1(DBG_IMV, "no more segments found for " + "base attribute ID %u", base_attr_id); + } + break; + } + default: + break; + } + } + enumerator->destroy(enumerator); + /* preprocess any received IETF standard error attributes */ - *fatal_error = this->pa_msg->process_ietf_std_errors(this->pa_msg); + non_fatal_types = this->agent->get_non_fatal_attr_types(this->agent); + *fatal_error = this->pa_msg->process_ietf_std_errors(this->pa_msg, + non_fatal_types); - return TNC_RESULT_SUCCESS; + return result; } METHOD(imv_msg_t, get_attribute_count, int, diff --git a/src/libimcv/imv/imv_msg.h b/src/libimcv/imv/imv_msg.h index dfec169cc..43b91e908 100644 --- a/src/libimcv/imv/imv_msg.h +++ b/src/libimcv/imv/imv_msg.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 Andreas Steffen + * Copyright (C) 2012-2014 Andreas Steffen * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -79,10 +79,12 @@ struct imv_msg_t { /** * Processes a received PA-TNC message * + * @param out_msg outgoing PA-TN message * @param fatal_error TRUE if IMC sent a fatal error message * @return TNC result code */ - TNC_Result (*receive)(imv_msg_t *this, bool *fatal_error); + TNC_Result (*receive)(imv_msg_t *this, imv_msg_t *out_msg, + bool *fatal_error); /** * Add a PA-TNC attribute to the send queue diff --git a/src/libimcv/imv/imv_os_info.h b/src/libimcv/imv/imv_os_info.h index b68a17ee7..7cd609a22 100644 --- a/src/libimcv/imv/imv_os_info.h +++ b/src/libimcv/imv/imv_os_info.h @@ -15,7 +15,7 @@ /** * @defgroup imv_os_info imv_os_info - * @{ @ingroup libimcv + * @{ @ingroup libimcv_imv */ #ifndef IMV_OS_INFO_H_ diff --git a/src/libimcv/imv/imv_state.h b/src/libimcv/imv/imv_state.h index d11d15e0d..30ed612b3 100644 --- a/src/libimcv/imv/imv_state.h +++ b/src/libimcv/imv/imv_state.h @@ -23,6 +23,7 @@ #define IMV_STATE_H_ #include "imv_session.h" +#include "seg/seg_contract_manager.h" #include <tncifimv.h> @@ -108,6 +109,13 @@ struct imv_state_t { imv_session_t* (*get_session)(imv_state_t *this); /** + * Get attribute segmentation contracts associated with TNCCS Connection + * + * @return Contracts associated with TNCCS Connection + */ + seg_contract_manager_t* (*get_contracts)(imv_state_t *this); + + /** * Change the connection state * * @param new_state new connection state |