summaryrefslogtreecommitdiff
path: root/src/libimcv/imv
diff options
context:
space:
mode:
authorRomain Francoise <rfrancoise@debian.org>2014-10-21 19:28:38 +0200
committerRomain Francoise <rfrancoise@debian.org>2014-10-21 19:28:38 +0200
commit2b8de74ff4c334c25e89988c4a401b24b5bcf03d (patch)
tree10fb49ca94bfd0c8b8a583412281abfc0186836e /src/libimcv/imv
parent81c63b0eed39432878f78727f60a1e7499645199 (diff)
downloadvyos-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.sql35
-rw-r--r--src/libimcv/imv/imv_agent.c26
-rw-r--r--src/libimcv/imv/imv_agent.h10
-rw-r--r--src/libimcv/imv/imv_msg.c238
-rw-r--r--src/libimcv/imv/imv_msg.h6
-rw-r--r--src/libimcv/imv/imv_os_info.h2
-rw-r--r--src/libimcv/imv/imv_state.h8
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