mirror of
https://github.com/strongswan/strongswan.git
synced 2025-10-06 00:00:47 -04:00
imv-swima: Support subscriptions
This commit is contained in:
parent
f649a13cc6
commit
37c12f98b0
@ -143,7 +143,7 @@ static bool create_session(private_imv_database_t *this, imv_session_t *session)
|
||||
}
|
||||
|
||||
/* create a new session entry */
|
||||
created = session->get_creation_time(session);
|
||||
created = time(NULL);
|
||||
conn_id = session->get_connection_id(session);
|
||||
this->db->execute(this->db, &session_id,
|
||||
"INSERT INTO sessions (time, connection, product, device) "
|
||||
@ -161,6 +161,7 @@ static bool create_session(private_imv_database_t *this, imv_session_t *session)
|
||||
return FALSE;
|
||||
}
|
||||
session->set_session_id(session, session_id, pid, did);
|
||||
session->set_creation_time(session, created);
|
||||
|
||||
enumerator = session->create_ar_identities_enumerator(session);
|
||||
while (enumerator->enumerate(enumerator, &tnc_id))
|
||||
|
@ -121,6 +121,12 @@ METHOD(imv_session_t, get_connection_id, TNC_ConnectionID,
|
||||
return this->conn_id;
|
||||
}
|
||||
|
||||
METHOD(imv_session_t, set_creation_time, void,
|
||||
private_imv_session_t *this, time_t created)
|
||||
{
|
||||
this->created = created;
|
||||
}
|
||||
|
||||
METHOD(imv_session_t, get_creation_time, time_t,
|
||||
private_imv_session_t *this)
|
||||
{
|
||||
@ -259,7 +265,7 @@ METHOD(imv_session_t, destroy, void,
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
imv_session_t *imv_session_create(TNC_ConnectionID conn_id, time_t created,
|
||||
imv_session_t *imv_session_create(TNC_ConnectionID conn_id,
|
||||
linked_list_t *ar_identities)
|
||||
{
|
||||
private_imv_session_t *this;
|
||||
@ -269,6 +275,7 @@ imv_session_t *imv_session_create(TNC_ConnectionID conn_id, time_t created,
|
||||
.set_session_id = _set_session_id,
|
||||
.get_session_id = _get_session_id,
|
||||
.get_connection_id = _get_connection_id,
|
||||
.set_creation_time = _set_creation_time,
|
||||
.get_creation_time = _get_creation_time,
|
||||
.create_ar_identities_enumerator = _create_ar_identities_enumerator,
|
||||
.get_os_info = _get_os_info,
|
||||
@ -286,7 +293,6 @@ imv_session_t *imv_session_create(TNC_ConnectionID conn_id, time_t created,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.conn_id = conn_id,
|
||||
.created = created,
|
||||
.ar_identities = ar_identities,
|
||||
.os_info = imv_os_info_create(),
|
||||
.workitems = linked_list_create(),
|
||||
|
@ -62,6 +62,13 @@ struct imv_session_t {
|
||||
*/
|
||||
TNC_ConnectionID (*get_connection_id)(imv_session_t *this);
|
||||
|
||||
/**
|
||||
* Set session creation time
|
||||
*
|
||||
* @param created Session creation time
|
||||
*/
|
||||
void (*set_creation_time)(imv_session_t *this, time_t created);
|
||||
|
||||
/**
|
||||
* Get session creation time
|
||||
*
|
||||
@ -170,10 +177,9 @@ struct imv_session_t {
|
||||
* Create an imv_session_t instance
|
||||
*
|
||||
* @param id Associated Connection ID
|
||||
* @param created Session creation time
|
||||
* @param ar_identities List of Access Requestor identities
|
||||
*/
|
||||
imv_session_t* imv_session_create(TNC_ConnectionID id, time_t created,
|
||||
linked_list_t *ar_identities);
|
||||
imv_session_t* imv_session_create(TNC_ConnectionID id,
|
||||
linked_list_t *ar_identities);
|
||||
|
||||
#endif /** IMV_SESSION_H_ @}*/
|
||||
|
@ -51,7 +51,6 @@ METHOD(imv_session_manager_t, add_session, imv_session_t*,
|
||||
enumerator_t *enumerator;
|
||||
tncif_identity_t *tnc_id;
|
||||
imv_session_t *current, *session = NULL;
|
||||
time_t created;
|
||||
|
||||
this->mutex->lock(this->mutex);
|
||||
|
||||
@ -105,8 +104,7 @@ METHOD(imv_session_manager_t, add_session, imv_session_t*,
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
/* create a new session entry */
|
||||
created = time(NULL);
|
||||
session = imv_session_create(conn_id, created, ar_identities);
|
||||
session = imv_session_create(conn_id, ar_identities);
|
||||
this->sessions->insert_last(this->sessions, session);
|
||||
|
||||
this->mutex->unlock(this->mutex);
|
||||
|
@ -90,12 +90,19 @@ METHOD(imv_agent_if_t, notify_connection_change, TNC_Result,
|
||||
TNC_ConnectionState new_state)
|
||||
{
|
||||
imv_state_t *state;
|
||||
imv_swima_state_t *swima_state;
|
||||
|
||||
switch (new_state)
|
||||
{
|
||||
case TNC_CONNECTION_STATE_CREATE:
|
||||
state = imv_swima_state_create(id);
|
||||
return this->agent->create_state(this->agent, state);
|
||||
case TNC_CONNECTION_STATE_HANDSHAKE:
|
||||
this->agent->change_state(this->agent, id, new_state, &state);
|
||||
state->set_action_flags(state, 0);
|
||||
swima_state = (imv_swima_state_t*)state;
|
||||
swima_state->set_handshake_state(swima_state, IMV_SWIMA_STATE_INIT);
|
||||
return TNC_RESULT_SUCCESS;
|
||||
case TNC_CONNECTION_STATE_DELETE:
|
||||
return this->agent->delete_state(this->agent, id);
|
||||
default:
|
||||
@ -187,11 +194,17 @@ static TNC_Result receive_msg(private_imv_swima_agent_t *this,
|
||||
}
|
||||
description = reader->peek(reader);
|
||||
if (description.len)
|
||||
{
|
||||
{
|
||||
DBG1(DBG_IMV, " description: %.*s", description.len,
|
||||
description.ptr);
|
||||
}
|
||||
reader->destroy(reader);
|
||||
if (error_code.type == PA_ERROR_SWIMA_SUBSCRIPTION_DENIED)
|
||||
{
|
||||
swima_state->set_subscription(swima_state, FALSE);
|
||||
DBG1(DBG_IMV, "SWIMA subscription %u cleared",
|
||||
swima_state->get_request_id(swima_state));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IETF_ATTR_SW_ID_INVENTORY:
|
||||
@ -474,7 +487,7 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result,
|
||||
seg_contract_t *contract;
|
||||
seg_contract_manager_t *contracts;
|
||||
swima_inventory_t *targets;
|
||||
uint32_t earliest_eid = 0;
|
||||
uint32_t old_request_id = 0, earliest_eid = 0;
|
||||
char buf[BUF_LEN];
|
||||
|
||||
enumerator = session->create_workitem_enumerator(session);
|
||||
@ -487,7 +500,13 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result,
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
earliest_eid = workitem->get_arg_int(workitem);
|
||||
request_id = workitem->get_id(workitem);
|
||||
workitem->set_imv_id(workitem, imv_id);
|
||||
no_workitems = FALSE;
|
||||
old_request_id = swima_state->get_request_id(swima_state);
|
||||
|
||||
flags = IETF_SWIMA_ATTR_REQ_FLAG_NONE;
|
||||
if (strchr(workitem->get_arg_str(workitem), 'R'))
|
||||
{
|
||||
@ -496,47 +515,57 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result,
|
||||
if (strchr(workitem->get_arg_str(workitem), 'S'))
|
||||
{
|
||||
flags |= IETF_SWIMA_ATTR_REQ_FLAG_S;
|
||||
swima_state->set_subscription(swima_state, TRUE);
|
||||
if (!old_request_id)
|
||||
{
|
||||
DBG1(DBG_IMV, "SWIMA subscription %u requested",
|
||||
request_id);
|
||||
}
|
||||
}
|
||||
if (strchr(workitem->get_arg_str(workitem), 'C'))
|
||||
{
|
||||
flags |= IETF_SWIMA_ATTR_REQ_FLAG_C;
|
||||
swima_state->set_subscription(swima_state, FALSE);
|
||||
}
|
||||
earliest_eid = workitem->get_arg_int(workitem);
|
||||
|
||||
/* Determine maximum PA-TNC attribute segment size */
|
||||
max_seg_size = state->get_max_msg_len(state)
|
||||
- PA_TNC_HEADER_SIZE
|
||||
- PA_TNC_ATTR_HEADER_SIZE
|
||||
- TCG_SEG_ATTR_SEG_ENV_HEADER;
|
||||
if (!old_request_id)
|
||||
{
|
||||
/* Determine maximum PA-TNC attribute segment size */
|
||||
max_seg_size = state->get_max_msg_len(state)
|
||||
- PA_TNC_HEADER_SIZE
|
||||
- PA_TNC_ATTR_HEADER_SIZE
|
||||
- TCG_SEG_ATTR_SEG_ENV_HEADER;
|
||||
|
||||
/* Announce support of PA-TNC segmentation to IMC */
|
||||
contract = seg_contract_create(msg_types[0], max_attr_size,
|
||||
max_seg_size, TRUE, imv_id, FALSE);
|
||||
contract->get_info_string(contract, buf, BUF_LEN, TRUE);
|
||||
DBG2(DBG_IMV, "%s", buf);
|
||||
contracts = state->get_contracts(state);
|
||||
contracts->add_contract(contracts, contract);
|
||||
attr = tcg_seg_attr_max_size_create(max_attr_size,
|
||||
max_seg_size, TRUE);
|
||||
out_msg->add_attribute(out_msg, attr);
|
||||
/* Announce support of PA-TNC segmentation to IMC */
|
||||
contract = seg_contract_create(msg_types[0], max_attr_size,
|
||||
max_seg_size, TRUE, imv_id, FALSE);
|
||||
contract->get_info_string(contract, buf, BUF_LEN, TRUE);
|
||||
DBG2(DBG_IMV, "%s", buf);
|
||||
contracts = state->get_contracts(state);
|
||||
contracts->add_contract(contracts, contract);
|
||||
attr = tcg_seg_attr_max_size_create(max_attr_size,
|
||||
max_seg_size, TRUE);
|
||||
out_msg->add_attribute(out_msg, attr);
|
||||
}
|
||||
|
||||
/* Issue a SWID request */
|
||||
request_id = workitem->get_id(workitem);
|
||||
swima_state->set_request_id(swima_state, request_id);
|
||||
attr = ietf_swima_attr_req_create(flags, request_id);
|
||||
if (!old_request_id ||
|
||||
!swima_state->get_subscription(swima_state))
|
||||
{
|
||||
/* Issue a SWID request */
|
||||
swima_state->set_request_id(swima_state, request_id);
|
||||
attr = ietf_swima_attr_req_create(flags, request_id);
|
||||
|
||||
/* Request software identifier events */
|
||||
targets = swima_inventory_create();
|
||||
targets->set_eid(targets, earliest_eid, 0);
|
||||
cast_attr = (ietf_swima_attr_req_t*)attr;
|
||||
cast_attr->set_targets(cast_attr, targets);
|
||||
targets->destroy(targets);
|
||||
/* Request software identifier events */
|
||||
targets = swima_inventory_create();
|
||||
targets->set_eid(targets, earliest_eid, 0);
|
||||
cast_attr = (ietf_swima_attr_req_t*)attr;
|
||||
cast_attr->set_targets(cast_attr, targets);
|
||||
targets->destroy(targets);
|
||||
|
||||
out_msg->add_attribute(out_msg, attr);
|
||||
workitem->set_imv_id(workitem, imv_id);
|
||||
no_workitems = FALSE;
|
||||
DBG2(DBG_IMV, "IMV %d issues sw request %d with earliest eid %d",
|
||||
imv_id, request_id, earliest_eid);
|
||||
out_msg->add_attribute(out_msg, attr);
|
||||
DBG2(DBG_IMV, "IMV %d issues sw request %d with earliest "
|
||||
"eid %d", imv_id, request_id, earliest_eid);
|
||||
}
|
||||
break;
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
@ -565,7 +594,7 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result,
|
||||
TNC_IMV_Action_Recommendation rec;
|
||||
char result_str[BUF_LEN], *format = NULL, *cmd = NULL, *command;
|
||||
char *target_str, *error_str = "";
|
||||
int sw_id_count, tag_count, i, res;
|
||||
int sw_id_count, tag_count, i, res, written;
|
||||
json_object *jrequest, *jresponse, *jvalue;
|
||||
ietf_swima_attr_req_t *cast_attr;
|
||||
swima_inventory_t *targets;
|
||||
@ -617,16 +646,24 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result,
|
||||
&tag_count);
|
||||
if (format)
|
||||
{
|
||||
snprintf(result_str, BUF_LEN, format,
|
||||
written = snprintf(result_str, BUF_LEN, format,
|
||||
sw_id_count, (sw_id_count == 1) ? "" : "s",
|
||||
tag_count, (tag_count == 1) ? "" : "s");
|
||||
}
|
||||
else
|
||||
{
|
||||
snprintf(result_str, BUF_LEN, "received %d SWID tag"
|
||||
"%s", tag_count, (tag_count == 1) ? "" : "s");
|
||||
written = snprintf(result_str, BUF_LEN,
|
||||
"received %d SWID tag%s",
|
||||
tag_count, (tag_count == 1) ? "" : "s");
|
||||
|
||||
}
|
||||
if (swima_state->get_subscription(swima_state) &&
|
||||
written > 0 && written < BUF_LEN)
|
||||
{
|
||||
snprintf(result_str + written, BUF_LEN - written,
|
||||
" from subscription %u",
|
||||
swima_state->get_request_id(swima_state));
|
||||
}
|
||||
session->remove_workitem(session, enumerator);
|
||||
|
||||
eval = TNC_IMV_EVALUATION_RESULT_COMPLIANT;
|
||||
|
@ -100,6 +100,11 @@ struct private_imv_swima_state_t {
|
||||
*/
|
||||
imv_remediation_string_t *remediation_string;
|
||||
|
||||
/**
|
||||
* Has a subscription been established?
|
||||
*/
|
||||
bool has_subscription;
|
||||
|
||||
/**
|
||||
* SWID Tag Request ID
|
||||
*/
|
||||
@ -177,7 +182,16 @@ METHOD(imv_state_t, get_max_msg_len, uint32_t,
|
||||
METHOD(imv_state_t, set_action_flags, void,
|
||||
private_imv_swima_state_t *this, uint32_t flags)
|
||||
{
|
||||
this->action_flags |= flags;
|
||||
if (flags == 0)
|
||||
{
|
||||
/* reset action flags */
|
||||
this->action_flags = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* add flags */
|
||||
this->action_flags |= flags;
|
||||
}
|
||||
}
|
||||
|
||||
METHOD(imv_state_t, get_action_flags, uint32_t,
|
||||
@ -426,6 +440,18 @@ METHOD(imv_swima_state_t, get_imc_id, TNC_UInt32,
|
||||
return this->imc_id;
|
||||
}
|
||||
|
||||
METHOD(imv_swima_state_t, set_subscription, void,
|
||||
private_imv_swima_state_t *this, bool set)
|
||||
{
|
||||
this->has_subscription = set;
|
||||
}
|
||||
|
||||
METHOD(imv_swima_state_t, get_subscription, bool,
|
||||
private_imv_swima_state_t *this)
|
||||
{
|
||||
return this->has_subscription;
|
||||
}
|
||||
|
||||
/**
|
||||
* Described in header.
|
||||
*/
|
||||
@ -467,6 +493,8 @@ imv_state_t *imv_swima_state_create(TNC_ConnectionID connection_id)
|
||||
.set_count = _set_count,
|
||||
.get_count = _get_count,
|
||||
.get_imc_id = _get_imc_id,
|
||||
.set_subscription = _set_subscription,
|
||||
.get_subscription = _get_subscription,
|
||||
},
|
||||
.state = TNC_CONNECTION_STATE_CREATE,
|
||||
.rec = TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION,
|
||||
|
@ -141,6 +141,20 @@ struct imv_swima_state_t {
|
||||
* @return SWID IMC ID
|
||||
*/
|
||||
TNC_UInt32 (*get_imc_id)(imv_swima_state_t *this);
|
||||
|
||||
/**
|
||||
* Set or clear a subscription
|
||||
*
|
||||
* @param set TRUE sets and FALSE clears a subscripton
|
||||
*/
|
||||
void (*set_subscription)(imv_swima_state_t *this, bool set);
|
||||
|
||||
/**
|
||||
* Get the subscription status
|
||||
*
|
||||
* @return TRUE if subscription is set
|
||||
*/
|
||||
bool (*get_subscription)(imv_swima_state_t *this);
|
||||
};
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user