imv-swima: Support subscriptions
This commit is contained in:
@@ -143,7 +143,7 @@ static bool create_session(private_imv_database_t *this, imv_session_t *session)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* create a new session entry */
|
/* create a new session entry */
|
||||||
created = session->get_creation_time(session);
|
created = time(NULL);
|
||||||
conn_id = session->get_connection_id(session);
|
conn_id = session->get_connection_id(session);
|
||||||
this->db->execute(this->db, &session_id,
|
this->db->execute(this->db, &session_id,
|
||||||
"INSERT INTO sessions (time, connection, product, device) "
|
"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;
|
return FALSE;
|
||||||
}
|
}
|
||||||
session->set_session_id(session, session_id, pid, did);
|
session->set_session_id(session, session_id, pid, did);
|
||||||
|
session->set_creation_time(session, created);
|
||||||
|
|
||||||
enumerator = session->create_ar_identities_enumerator(session);
|
enumerator = session->create_ar_identities_enumerator(session);
|
||||||
while (enumerator->enumerate(enumerator, &tnc_id))
|
while (enumerator->enumerate(enumerator, &tnc_id))
|
||||||
|
|||||||
@@ -121,6 +121,12 @@ METHOD(imv_session_t, get_connection_id, TNC_ConnectionID,
|
|||||||
return this->conn_id;
|
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,
|
METHOD(imv_session_t, get_creation_time, time_t,
|
||||||
private_imv_session_t *this)
|
private_imv_session_t *this)
|
||||||
{
|
{
|
||||||
@@ -259,7 +265,7 @@ METHOD(imv_session_t, destroy, void,
|
|||||||
/**
|
/**
|
||||||
* See header
|
* 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)
|
linked_list_t *ar_identities)
|
||||||
{
|
{
|
||||||
private_imv_session_t *this;
|
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,
|
.set_session_id = _set_session_id,
|
||||||
.get_session_id = _get_session_id,
|
.get_session_id = _get_session_id,
|
||||||
.get_connection_id = _get_connection_id,
|
.get_connection_id = _get_connection_id,
|
||||||
|
.set_creation_time = _set_creation_time,
|
||||||
.get_creation_time = _get_creation_time,
|
.get_creation_time = _get_creation_time,
|
||||||
.create_ar_identities_enumerator = _create_ar_identities_enumerator,
|
.create_ar_identities_enumerator = _create_ar_identities_enumerator,
|
||||||
.get_os_info = _get_os_info,
|
.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,
|
.destroy = _destroy,
|
||||||
},
|
},
|
||||||
.conn_id = conn_id,
|
.conn_id = conn_id,
|
||||||
.created = created,
|
|
||||||
.ar_identities = ar_identities,
|
.ar_identities = ar_identities,
|
||||||
.os_info = imv_os_info_create(),
|
.os_info = imv_os_info_create(),
|
||||||
.workitems = linked_list_create(),
|
.workitems = linked_list_create(),
|
||||||
|
|||||||
@@ -62,6 +62,13 @@ struct imv_session_t {
|
|||||||
*/
|
*/
|
||||||
TNC_ConnectionID (*get_connection_id)(imv_session_t *this);
|
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
|
* Get session creation time
|
||||||
*
|
*
|
||||||
@@ -170,10 +177,9 @@ struct imv_session_t {
|
|||||||
* Create an imv_session_t instance
|
* Create an imv_session_t instance
|
||||||
*
|
*
|
||||||
* @param id Associated Connection ID
|
* @param id Associated Connection ID
|
||||||
* @param created Session creation time
|
|
||||||
* @param ar_identities List of Access Requestor identities
|
* @param ar_identities List of Access Requestor identities
|
||||||
*/
|
*/
|
||||||
imv_session_t* imv_session_create(TNC_ConnectionID id, time_t created,
|
imv_session_t* imv_session_create(TNC_ConnectionID id,
|
||||||
linked_list_t *ar_identities);
|
linked_list_t *ar_identities);
|
||||||
|
|
||||||
#endif /** IMV_SESSION_H_ @}*/
|
#endif /** IMV_SESSION_H_ @}*/
|
||||||
|
|||||||
@@ -51,7 +51,6 @@ METHOD(imv_session_manager_t, add_session, imv_session_t*,
|
|||||||
enumerator_t *enumerator;
|
enumerator_t *enumerator;
|
||||||
tncif_identity_t *tnc_id;
|
tncif_identity_t *tnc_id;
|
||||||
imv_session_t *current, *session = NULL;
|
imv_session_t *current, *session = NULL;
|
||||||
time_t created;
|
|
||||||
|
|
||||||
this->mutex->lock(this->mutex);
|
this->mutex->lock(this->mutex);
|
||||||
|
|
||||||
@@ -105,8 +104,7 @@ METHOD(imv_session_manager_t, add_session, imv_session_t*,
|
|||||||
enumerator->destroy(enumerator);
|
enumerator->destroy(enumerator);
|
||||||
|
|
||||||
/* create a new session entry */
|
/* create a new session entry */
|
||||||
created = time(NULL);
|
session = imv_session_create(conn_id, ar_identities);
|
||||||
session = imv_session_create(conn_id, created, ar_identities);
|
|
||||||
this->sessions->insert_last(this->sessions, session);
|
this->sessions->insert_last(this->sessions, session);
|
||||||
|
|
||||||
this->mutex->unlock(this->mutex);
|
this->mutex->unlock(this->mutex);
|
||||||
|
|||||||
@@ -90,12 +90,19 @@ METHOD(imv_agent_if_t, notify_connection_change, TNC_Result,
|
|||||||
TNC_ConnectionState new_state)
|
TNC_ConnectionState new_state)
|
||||||
{
|
{
|
||||||
imv_state_t *state;
|
imv_state_t *state;
|
||||||
|
imv_swima_state_t *swima_state;
|
||||||
|
|
||||||
switch (new_state)
|
switch (new_state)
|
||||||
{
|
{
|
||||||
case TNC_CONNECTION_STATE_CREATE:
|
case TNC_CONNECTION_STATE_CREATE:
|
||||||
state = imv_swima_state_create(id);
|
state = imv_swima_state_create(id);
|
||||||
return this->agent->create_state(this->agent, state);
|
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:
|
case TNC_CONNECTION_STATE_DELETE:
|
||||||
return this->agent->delete_state(this->agent, id);
|
return this->agent->delete_state(this->agent, id);
|
||||||
default:
|
default:
|
||||||
@@ -192,6 +199,12 @@ static TNC_Result receive_msg(private_imv_swima_agent_t *this,
|
|||||||
description.ptr);
|
description.ptr);
|
||||||
}
|
}
|
||||||
reader->destroy(reader);
|
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;
|
break;
|
||||||
}
|
}
|
||||||
case IETF_ATTR_SW_ID_INVENTORY:
|
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_t *contract;
|
||||||
seg_contract_manager_t *contracts;
|
seg_contract_manager_t *contracts;
|
||||||
swima_inventory_t *targets;
|
swima_inventory_t *targets;
|
||||||
uint32_t earliest_eid = 0;
|
uint32_t old_request_id = 0, earliest_eid = 0;
|
||||||
char buf[BUF_LEN];
|
char buf[BUF_LEN];
|
||||||
|
|
||||||
enumerator = session->create_workitem_enumerator(session);
|
enumerator = session->create_workitem_enumerator(session);
|
||||||
@@ -488,6 +501,12 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result,
|
|||||||
continue;
|
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;
|
flags = IETF_SWIMA_ATTR_REQ_FLAG_NONE;
|
||||||
if (strchr(workitem->get_arg_str(workitem), 'R'))
|
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'))
|
if (strchr(workitem->get_arg_str(workitem), 'S'))
|
||||||
{
|
{
|
||||||
flags |= IETF_SWIMA_ATTR_REQ_FLAG_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'))
|
if (strchr(workitem->get_arg_str(workitem), 'C'))
|
||||||
{
|
{
|
||||||
flags |= IETF_SWIMA_ATTR_REQ_FLAG_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 */
|
if (!old_request_id)
|
||||||
max_seg_size = state->get_max_msg_len(state)
|
{
|
||||||
- PA_TNC_HEADER_SIZE
|
/* Determine maximum PA-TNC attribute segment size */
|
||||||
- PA_TNC_ATTR_HEADER_SIZE
|
max_seg_size = state->get_max_msg_len(state)
|
||||||
- TCG_SEG_ATTR_SEG_ENV_HEADER;
|
- PA_TNC_HEADER_SIZE
|
||||||
|
- PA_TNC_ATTR_HEADER_SIZE
|
||||||
|
- TCG_SEG_ATTR_SEG_ENV_HEADER;
|
||||||
|
|
||||||
/* Announce support of PA-TNC segmentation to IMC */
|
/* Announce support of PA-TNC segmentation to IMC */
|
||||||
contract = seg_contract_create(msg_types[0], max_attr_size,
|
contract = seg_contract_create(msg_types[0], max_attr_size,
|
||||||
max_seg_size, TRUE, imv_id, FALSE);
|
max_seg_size, TRUE, imv_id, FALSE);
|
||||||
contract->get_info_string(contract, buf, BUF_LEN, TRUE);
|
contract->get_info_string(contract, buf, BUF_LEN, TRUE);
|
||||||
DBG2(DBG_IMV, "%s", buf);
|
DBG2(DBG_IMV, "%s", buf);
|
||||||
contracts = state->get_contracts(state);
|
contracts = state->get_contracts(state);
|
||||||
contracts->add_contract(contracts, contract);
|
contracts->add_contract(contracts, contract);
|
||||||
attr = tcg_seg_attr_max_size_create(max_attr_size,
|
attr = tcg_seg_attr_max_size_create(max_attr_size,
|
||||||
max_seg_size, TRUE);
|
max_seg_size, TRUE);
|
||||||
out_msg->add_attribute(out_msg, attr);
|
out_msg->add_attribute(out_msg, attr);
|
||||||
|
}
|
||||||
|
|
||||||
/* Issue a SWID request */
|
if (!old_request_id ||
|
||||||
request_id = workitem->get_id(workitem);
|
!swima_state->get_subscription(swima_state))
|
||||||
swima_state->set_request_id(swima_state, request_id);
|
{
|
||||||
attr = ietf_swima_attr_req_create(flags, request_id);
|
/* 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 */
|
/* Request software identifier events */
|
||||||
targets = swima_inventory_create();
|
targets = swima_inventory_create();
|
||||||
targets->set_eid(targets, earliest_eid, 0);
|
targets->set_eid(targets, earliest_eid, 0);
|
||||||
cast_attr = (ietf_swima_attr_req_t*)attr;
|
cast_attr = (ietf_swima_attr_req_t*)attr;
|
||||||
cast_attr->set_targets(cast_attr, targets);
|
cast_attr->set_targets(cast_attr, targets);
|
||||||
targets->destroy(targets);
|
targets->destroy(targets);
|
||||||
|
|
||||||
out_msg->add_attribute(out_msg, attr);
|
out_msg->add_attribute(out_msg, attr);
|
||||||
workitem->set_imv_id(workitem, imv_id);
|
DBG2(DBG_IMV, "IMV %d issues sw request %d with earliest "
|
||||||
no_workitems = FALSE;
|
"eid %d", imv_id, request_id, earliest_eid);
|
||||||
DBG2(DBG_IMV, "IMV %d issues sw request %d with earliest eid %d",
|
}
|
||||||
imv_id, request_id, earliest_eid);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
enumerator->destroy(enumerator);
|
enumerator->destroy(enumerator);
|
||||||
@@ -565,7 +594,7 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result,
|
|||||||
TNC_IMV_Action_Recommendation rec;
|
TNC_IMV_Action_Recommendation rec;
|
||||||
char result_str[BUF_LEN], *format = NULL, *cmd = NULL, *command;
|
char result_str[BUF_LEN], *format = NULL, *cmd = NULL, *command;
|
||||||
char *target_str, *error_str = "";
|
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;
|
json_object *jrequest, *jresponse, *jvalue;
|
||||||
ietf_swima_attr_req_t *cast_attr;
|
ietf_swima_attr_req_t *cast_attr;
|
||||||
swima_inventory_t *targets;
|
swima_inventory_t *targets;
|
||||||
@@ -617,16 +646,24 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result,
|
|||||||
&tag_count);
|
&tag_count);
|
||||||
if (format)
|
if (format)
|
||||||
{
|
{
|
||||||
snprintf(result_str, BUF_LEN, format,
|
written = snprintf(result_str, BUF_LEN, format,
|
||||||
sw_id_count, (sw_id_count == 1) ? "" : "s",
|
sw_id_count, (sw_id_count == 1) ? "" : "s",
|
||||||
tag_count, (tag_count == 1) ? "" : "s");
|
tag_count, (tag_count == 1) ? "" : "s");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
snprintf(result_str, BUF_LEN, "received %d SWID tag"
|
written = snprintf(result_str, BUF_LEN,
|
||||||
"%s", tag_count, (tag_count == 1) ? "" : "s");
|
"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);
|
session->remove_workitem(session, enumerator);
|
||||||
|
|
||||||
eval = TNC_IMV_EVALUATION_RESULT_COMPLIANT;
|
eval = TNC_IMV_EVALUATION_RESULT_COMPLIANT;
|
||||||
|
|||||||
@@ -100,6 +100,11 @@ struct private_imv_swima_state_t {
|
|||||||
*/
|
*/
|
||||||
imv_remediation_string_t *remediation_string;
|
imv_remediation_string_t *remediation_string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Has a subscription been established?
|
||||||
|
*/
|
||||||
|
bool has_subscription;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SWID Tag Request ID
|
* 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,
|
METHOD(imv_state_t, set_action_flags, void,
|
||||||
private_imv_swima_state_t *this, uint32_t flags)
|
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,
|
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;
|
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.
|
* Described in header.
|
||||||
*/
|
*/
|
||||||
@@ -467,6 +493,8 @@ imv_state_t *imv_swima_state_create(TNC_ConnectionID connection_id)
|
|||||||
.set_count = _set_count,
|
.set_count = _set_count,
|
||||||
.get_count = _get_count,
|
.get_count = _get_count,
|
||||||
.get_imc_id = _get_imc_id,
|
.get_imc_id = _get_imc_id,
|
||||||
|
.set_subscription = _set_subscription,
|
||||||
|
.get_subscription = _get_subscription,
|
||||||
},
|
},
|
||||||
.state = TNC_CONNECTION_STATE_CREATE,
|
.state = TNC_CONNECTION_STATE_CREATE,
|
||||||
.rec = TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION,
|
.rec = TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION,
|
||||||
|
|||||||
@@ -141,6 +141,20 @@ struct imv_swima_state_t {
|
|||||||
* @return SWID IMC ID
|
* @return SWID IMC ID
|
||||||
*/
|
*/
|
||||||
TNC_UInt32 (*get_imc_id)(imv_swima_state_t *this);
|
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);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user