From: Andreas Steffen Date: Fri, 23 May 2014 13:21:38 +0000 (+0200) Subject: Implemented SWID REST API X-Git-Tag: 5.2.0dr5~24 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=344c9f91f355c4f94c82ef1a2564115f7fee8748;p=thirdparty%2Fstrongswan.git Implemented SWID REST API --- diff --git a/src/libpts/plugins/imv_swid/Makefile.am b/src/libpts/plugins/imv_swid/Makefile.am index 29c05e0ab8..fc4350f85b 100644 --- a/src/libpts/plugins/imv_swid/Makefile.am +++ b/src/libpts/plugins/imv_swid/Makefile.am @@ -12,10 +12,12 @@ imcv_LTLIBRARIES = imv-swid.la imv_swid_la_LIBADD = \ $(top_builddir)/src/libimcv/libimcv.la \ $(top_builddir)/src/libpts/libpts.la \ - $(top_builddir)/src/libstrongswan/libstrongswan.la + $(top_builddir)/src/libstrongswan/libstrongswan.la \ + -ljson imv_swid_la_SOURCES = \ imv_swid.c imv_swid_state.h imv_swid_state.c \ - imv_swid_agent.h imv_swid_agent.c + imv_swid_agent.h imv_swid_agent.c \ + imv_swid_rest.h imv_swid_rest.c imv_swid_la_LDFLAGS = -module -avoid-version -no-undefined diff --git a/src/libpts/plugins/imv_swid/imv_swid_agent.c b/src/libpts/plugins/imv_swid/imv_swid_agent.c index fdf1dcf25c..f5a343af21 100644 --- a/src/libpts/plugins/imv_swid/imv_swid_agent.c +++ b/src/libpts/plugins/imv_swid/imv_swid_agent.c @@ -13,8 +13,12 @@ * for more details. */ +#define _GNU_SOURCE +#include + #include "imv_swid_agent.h" #include "imv_swid_state.h" +#include "imv_swid_rest.h" #include "libpts.h" #include "swid/swid_error.h" @@ -67,6 +71,11 @@ struct private_imv_swid_agent_t { */ imv_agent_t *agent; + /** + * REST API to strongTNC manager + */ + imv_swid_rest_t *rest_api; + }; METHOD(imv_agent_if_t, bind_functions, TNC_Result, @@ -101,7 +110,6 @@ static TNC_Result receive_msg(private_imv_swid_agent_t *this, { imv_swid_state_t *swid_state; imv_msg_t *out_msg; - imv_session_t *session; enumerator_t *enumerator; pa_tnc_attr_t *attr; TNC_Result result; @@ -115,20 +123,15 @@ static TNC_Result receive_msg(private_imv_swid_agent_t *this, } swid_state = (imv_swid_state_t*)state; - session = state->get_session(state); /* analyze PA-TNC attributes */ enumerator = in_msg->create_attribute_enumerator(in_msg); while (enumerator->enumerate(enumerator, &attr)) { - pen_type_t type; - uint32_t request_id, last_eid, eid_epoch; + uint32_t request_id = 0, last_eid, eid_epoch; swid_inventory_t *inventory; - int tag_count; - char *tag_item; - imv_workitem_t *workitem, *found = NULL; - enumerator_t *et, *ew; - + pen_type_t type; + type = attr->get_type(attr); if (type.vendor_id == PEN_IETF && type.type == IETF_ATTR_PA_TNC_ERROR) @@ -137,7 +140,7 @@ static TNC_Result receive_msg(private_imv_swid_agent_t *this, pen_type_t error_code; chunk_t msg_info, description; bio_reader_t *reader; - uint32_t request_id = 0, max_attr_size; + uint32_t max_attr_size; bool success; error_attr = (ietf_attr_pa_tnc_error_t*)attr; @@ -200,8 +203,7 @@ static TNC_Result receive_msg(private_imv_swid_agent_t *this, case TCG_SWID_TAG_ID_INVENTORY: { tcg_swid_attr_tag_id_inv_t *attr_cast; - swid_tag_id_t *tag_id; - chunk_t tag_creator, unique_sw_id; + int tag_id_count; state->set_action_flags(state, IMV_SWID_ATTR_TAG_ID_INV); @@ -209,26 +211,21 @@ static TNC_Result receive_msg(private_imv_swid_agent_t *this, request_id = attr_cast->get_request_id(attr_cast); last_eid = attr_cast->get_last_eid(attr_cast, &eid_epoch); inventory = attr_cast->get_inventory(attr_cast); - tag_item = "tag ID"; - DBG2(DBG_IMV, "received SWID %s inventory for request %d " - "at eid %d of epoch 0x%08x", tag_item, - request_id, last_eid, eid_epoch); + tag_id_count = inventory->get_count(inventory); + + DBG2(DBG_IMV, "received SWID tag ID inventory with %d items " + "for request %d at eid %d of epoch 0x%08x", + tag_id_count, request_id, last_eid, eid_epoch); - et = inventory->create_enumerator(inventory); - while (et->enumerate(et, &tag_id)) + if (request_id == swid_state->get_request_id(swid_state)) { - tag_creator = tag_id->get_tag_creator(tag_id); - unique_sw_id = tag_id->get_unique_sw_id(tag_id, NULL); - DBG3(DBG_IMV, " %.*s_%.*s", - tag_creator.len, tag_creator.ptr, - unique_sw_id.len, unique_sw_id.ptr); + swid_state->set_swid_inventory(swid_state, inventory); + swid_state->set_count(swid_state, tag_id_count, 0); } - et->destroy(et); - - if (request_id == 0) + else { - /* TODO handle subscribed messages */ - break; + DBG1(DBG_IMV, "no workitem found for SWID tag ID inventory " + "with request ID %d", request_id); } break; } @@ -237,6 +234,10 @@ static TNC_Result receive_msg(private_imv_swid_agent_t *this, tcg_swid_attr_tag_inv_t *attr_cast; swid_tag_t *tag; chunk_t tag_encoding; + json_object *jarray, *jstring; + char *tag_str; + int tag_count; + enumerator_t *e; state->set_action_flags(state, IMV_SWID_ATTR_TAG_INV); @@ -244,51 +245,50 @@ static TNC_Result receive_msg(private_imv_swid_agent_t *this, request_id = attr_cast->get_request_id(attr_cast); last_eid = attr_cast->get_last_eid(attr_cast, &eid_epoch); inventory = attr_cast->get_inventory(attr_cast); - tag_item = "tag"; - DBG2(DBG_IMV, "received SWID %s inventory for request %d " - "at eid %d of epoch 0x%08x", tag_item, - request_id, last_eid, eid_epoch); + tag_count = inventory->get_count(inventory); + + DBG2(DBG_IMV, "received SWID tag inventory with %d items for " + "request %d at eid %d of epoch 0x%08x", + tag_count, request_id, last_eid, eid_epoch); - et = inventory->create_enumerator(inventory); - while (et->enumerate(et, &tag)) + + if (request_id == swid_state->get_request_id(swid_state)) { - tag_encoding = tag->get_encoding(tag); - DBG3(DBG_IMV, "%.*s", tag_encoding.len, tag_encoding.ptr); - } - et->destroy(et); + swid_state->set_count(swid_state, 0, tag_count); - if (request_id == 0) + if (this->rest_api) + { + jarray = json_object_new_array(); + + e = inventory->create_enumerator(inventory); + while (e->enumerate(e, &tag)) + { + tag_encoding = tag->get_encoding(tag); + tag_str = strndup(tag_encoding.ptr, tag_encoding.len); + DBG3(DBG_IMV, "%s", tag_str); + jstring = json_object_new_string(tag_str); + json_object_array_add(jarray, jstring); + free(tag_str); + } + e->destroy(e); + + if (this->rest_api->post(this->rest_api, + "swid/add-tags/", jarray, NULL) != SUCCESS) + { + DBG1(DBG_IMV, "error in REST API add-tags request"); + } + json_object_put(jarray); + } + } + else { - /* TODO handle subscribed messages */ - break; + DBG1(DBG_IMV, "no workitem found for SWID tag inventory " + "with request ID %d", request_id); } - break; } default: continue; } - - ew = session->create_workitem_enumerator(session); - while (ew->enumerate(ew, &workitem)) - { - if (workitem->get_id(workitem) == request_id) - { - found = workitem; - break; - } - } - if (found) - { - /* accumulate the swid tag [ID] count */ - tag_count = inventory->get_count(inventory); - swid_state->set_count(swid_state, tag_count); - } - else - { - DBG1(DBG_IMV, "no workitem found for SWID %s inventory " - "with request ID %d", tag_item, request_id); - } - ew->destroy(ew); } enumerator->destroy(enumerator); @@ -382,7 +382,7 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result, return TNC_RESULT_SUCCESS; } - /* create an empty out message - we might need it */ + /* Create an empty out message - we might need it */ out_msg = imv_msg_create(this->agent, state, id, imv_id, TNC_IMCID_ANY, msg_types[0]); @@ -403,6 +403,7 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result, return this->agent->provide_recommendation(this->agent, state); } + /* Look for SWID tag workitem and create SWID tag request */ if (handshake_state == IMV_SWID_STATE_INIT && session->get_policy_started(session)) { @@ -431,13 +432,14 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result, flags |= TCG_SWID_ATTR_REQ_FLAG_C; } request_id = workitem->get_id(workitem); - + swid_state->set_request_id(swid_state, request_id); attr = tcg_swid_attr_req_create(flags, request_id, 0); out_msg->add_attribute(out_msg, attr); workitem->set_imv_id(workitem, imv_id); no_workitems = FALSE; DBG2(DBG_IMV, "IMV %d issues SWID request %d", imv_id, request_id); + break; } enumerator->destroy(enumerator); @@ -462,30 +464,140 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result, { TNC_IMV_Evaluation_Result eval; TNC_IMV_Action_Recommendation rec; - char result_str[BUF_LEN], *tag_item; - int tag_count; - - enumerator = session->create_workitem_enumerator(session); - while (enumerator->enumerate(enumerator, &workitem)) + char result_str[BUF_LEN], *error_str = "", *command; + char *target, *separator; + int tag_id_count, tag_count, i; + chunk_t tag_creator, unique_sw_id; + json_object *jrequest, *jresponse, *jvalue; + tcg_swid_attr_req_t *cast_attr; + swid_tag_id_t *tag_id; + status_t status = SUCCESS; + + if (this->rest_api) { - if (workitem->get_type(workitem) == IMV_WORKITEM_SWID_TAGS) + if (asprintf(&command, "sessions/%d/swid_measurement/", + session->get_session_id(session, NULL, NULL)) < 0) { - swid_state->get_count(swid_state, &tag_count); - tag_item = (received & IMV_SWID_ATTR_TAG_INV) ? "" : " ID"; - snprintf(result_str, BUF_LEN, "received inventory of %d " - "SWID tag%s%s", tag_count, tag_item, - (tag_count == 1) ? "" : "s"); - session->remove_workitem(session, enumerator); - - eval = TNC_IMV_EVALUATION_RESULT_COMPLIANT; - rec = workitem->set_result(workitem, result_str, eval); - state->update_recommendation(state, rec, eval); - imcv_db->finalize_workitem(imcv_db, workitem); - workitem->destroy(workitem); + error_str = "allocation of command string failed"; + status = FAILED; + } + else + { + jrequest = swid_state->get_swid_inventory(swid_state); + status = this->rest_api->post(this->rest_api, command, + jrequest, &jresponse); + if (status == FAILED) + { + error_str = "error in REST API swid_measurement request"; + } + free(command); + } + } + + switch (status) + { + case SUCCESS: + enumerator = session->create_workitem_enumerator(session); + while (enumerator->enumerate(enumerator, &workitem)) + { + if (workitem->get_type(workitem) == IMV_WORKITEM_SWID_TAGS) + { + swid_state->get_count(swid_state, &tag_id_count, + &tag_count); + snprintf(result_str, BUF_LEN, "received inventory of " + "%d SWID tag ID%s and %d SWID tag%s", + tag_id_count, (tag_id_count == 1) ? "" : "s", + tag_count, (tag_count == 1) ? "" : "s"); + session->remove_workitem(session, enumerator); + + eval = TNC_IMV_EVALUATION_RESULT_COMPLIANT; + rec = workitem->set_result(workitem, result_str, eval); + state->update_recommendation(state, rec, eval); + imcv_db->finalize_workitem(imcv_db, workitem); + workitem->destroy(workitem); + break; + } + } + enumerator->destroy(enumerator); + break; + case NEED_MORE: + if (received & IMV_SWID_ATTR_TAG_INV) + { + error_str = "not all requested SWID tags were received"; + status = FAILED; + json_object_put(jresponse); + break; + } + if (json_object_get_type(jresponse) != json_type_array) + { + error_str = "response was not a json_array"; + status = FAILED; + json_object_put(jresponse); + break; + } + attr = tcg_swid_attr_req_create(TCG_SWID_ATTR_REQ_FLAG_NONE, + swid_state->get_request_id(swid_state), 0); + cast_attr = (tcg_swid_attr_req_t*)attr; + + tag_id_count = json_object_array_length(jresponse); + DBG1(DBG_IMV, "%d SWID tag targets", tag_id_count); + + for (i = 0; i < tag_id_count; i++) + { + jvalue = json_object_array_get_idx(jresponse, i); + if (json_object_get_type(jvalue) != json_type_string) + { + error_str = "json_string element expected in json_array"; + status = FAILED; + json_object_put(jresponse); + break; + } + target = json_object_get_string(jvalue); + DBG1(DBG_IMV, " %s", target); + + /* Separate target into tag_creator and unique_sw_id */ + separator = strchr(target, '_'); + if (!separator) + { + error_str = "separation of regid from " + "unique software ID failed"; + break; + } + tag_creator = chunk_create(target, separator - target); + separator++; + unique_sw_id = chunk_create(separator, strlen(target) - + tag_creator.len - 1); + tag_id = swid_tag_id_create(tag_creator, unique_sw_id, + chunk_empty); + cast_attr->add_target(cast_attr, tag_id); + } + json_object_put(jresponse); + + out_msg->add_attribute(out_msg, attr); + break; + case FAILED: + default: break; + } + + if (status == FAILED) + { + enumerator = session->create_workitem_enumerator(session); + while (enumerator->enumerate(enumerator, &workitem)) + { + if (workitem->get_type(workitem) == IMV_WORKITEM_SWID_TAGS) + { + session->remove_workitem(session, enumerator); + eval = TNC_IMV_EVALUATION_RESULT_ERROR; + rec = workitem->set_result(workitem, error_str, eval); + state->update_recommendation(state, rec, eval); + imcv_db->finalize_workitem(imcv_db, workitem); + workitem->destroy(workitem); + break; + } } + enumerator->destroy(enumerator); } - enumerator->destroy(enumerator); } /* finalized all workitems ? */ @@ -528,6 +640,7 @@ METHOD(imv_agent_if_t, solicit_recommendation, TNC_Result, METHOD(imv_agent_if_t, destroy, void, private_imv_swid_agent_t *this) { + DESTROY_IF(this->rest_api); this->agent->destroy(this->agent); free(this); libpts_deinit(); @@ -541,6 +654,7 @@ imv_agent_if_t *imv_swid_agent_create(const char *name, TNC_IMVID id, { private_imv_swid_agent_t *this; imv_agent_t *agent; + char *rest_api_uri; agent = imv_agent_create(name, msg_types, countof(msg_types), id, actual_version); @@ -562,6 +676,12 @@ imv_agent_if_t *imv_swid_agent_create(const char *name, TNC_IMVID id, .agent = agent, ); + rest_api_uri = lib->settings->get_str(lib->settings, + "%s.plugins.imv-swid.rest_api_uri", NULL, lib->ns); + if (rest_api_uri) + { + this->rest_api = imv_swid_rest_create(rest_api_uri); + } libpts_init(); return &this->public; diff --git a/src/libpts/plugins/imv_swid/imv_swid_rest.c b/src/libpts/plugins/imv_swid/imv_swid_rest.c new file mode 100644 index 0000000000..3ad93a3768 --- /dev/null +++ b/src/libpts/plugins/imv_swid/imv_swid_rest.c @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2014 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#define _GNU_SOURCE +#include + +#include "imv_swid_rest.h" + +typedef struct private_imv_swid_rest_t private_imv_swid_rest_t; + +/** + * Private data of an imv_swid_rest_t object. + */ +struct private_imv_swid_rest_t { + + /** + * Public members of imv_swid_rest_t + */ + imv_swid_rest_t public; + + /** + * URI of REST API + */ + char *uri; + +}; + +#define HTTP_STATUS_CODE_PRECONDITION_FAILED 412 + +METHOD(imv_swid_rest_t, post, status_t, + private_imv_swid_rest_t *this, char *command, json_object *jrequest, + json_object **jresponse) +{ + struct json_tokener *tokener; + chunk_t data, response = chunk_empty; + u_int timeout = 30; + status_t status; + char *uri; + int code; + + if (asprintf(&uri, "%s%s",this->uri, command) < 0) + { + return FAILED; + } + data = chunk_from_str(json_object_to_json_string(jrequest)); + + status = lib->fetcher->fetch(lib->fetcher, uri, &response, + FETCH_TIMEOUT, timeout, + FETCH_REQUEST_DATA, data, + FETCH_REQUEST_TYPE, "application/json; charset=utf-8", + FETCH_REQUEST_HEADER, "Accept: application/json", + FETCH_REQUEST_HEADER, "Expect:", + FETCH_RESPONSE_CODE, &code, + FETCH_END); + free(uri); + + if (status == SUCCESS) + { + return SUCCESS; + } + if (code != HTTP_STATUS_CODE_PRECONDITION_FAILED || !response.ptr) + { + return FAILED; + } + + if (jresponse) + { + /* Parse HTTP response into a JSON object */ + tokener = json_tokener_new(); + *jresponse = json_tokener_parse_ex(tokener, response.ptr, response.len); + json_tokener_free(tokener); + } + free(response.ptr); + + return NEED_MORE; +} + +METHOD(imv_swid_rest_t, destroy, void, + private_imv_swid_rest_t *this) +{ + free(this->uri); + free(this); +} + +/** + * Described in header. + */ +imv_swid_rest_t *imv_swid_rest_create(char *uri) +{ + private_imv_swid_rest_t *this; + + INIT(this, + .public = { + .post = _post, + .destroy = _destroy, + }, + .uri = strdup(uri), + ); + + return &this->public; +} + + diff --git a/src/libpts/plugins/imv_swid/imv_swid_rest.h b/src/libpts/plugins/imv_swid/imv_swid_rest.h new file mode 100644 index 0000000000..b68f72ffe7 --- /dev/null +++ b/src/libpts/plugins/imv_swid/imv_swid_rest.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2013-2014 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +/** + * @defgroup imv_swid imv_swid + * @ingroup libimcv_plugins + * + * @defgroup imv_swid_rest_t imv_swid_rest + * @{ @ingroup imv_swid + */ + +#ifndef IMV_SWID_REST_H_ +#define IMV_SWID_REST_H_ + +#include + +#include + +typedef struct imv_swid_rest_t imv_swid_rest_t; + +/** + * Public REST interface + */ +struct imv_swid_rest_t { + + /** + * Post a HTTP request including a JSON object + * + * @param jreq JSON object in HTTP request + * @param jresp JSON object in HTTP response if NEED_MORE + * @return Status (SUCCESS, NEED_MORE or FAILED) + */ + status_t (*post)(imv_swid_rest_t *this, char *command, json_object *jreq, + json_object **jresp); + + /** + * Destroy imv_swid_rest_t object + */ + void (*destroy)(imv_swid_rest_t *this); + +}; + +/** + * Create an imv_swid_rest_t instance + * + * @param uri REST URI (http://username:password@hostname[:port]/api/) + */ +imv_swid_rest_t* imv_swid_rest_create(char *uri); + +#endif /** IMV_SWID_REST_H_ @}*/ diff --git a/src/libpts/plugins/imv_swid/imv_swid_state.c b/src/libpts/plugins/imv_swid/imv_swid_state.c index 3afeaed53f..fa8a79c977 100644 --- a/src/libpts/plugins/imv_swid/imv_swid_state.c +++ b/src/libpts/plugins/imv_swid/imv_swid_state.c @@ -14,9 +14,11 @@ */ #include "imv_swid_state.h" -#include "imv/imv_lang_string.h" -#include "imv/imv_reason_string.h" -#include "imv/imv_remediation_string.h" + +#include +#include +#include +#include #include @@ -96,9 +98,24 @@ struct private_imv_swid_state_t { imv_remediation_string_t *remediation_string; /** - * Number of processed SWID Tags or SWID Tag IDs + * SWID Tag Request ID + */ + uint32_t request_id; + + /** + * Number of processed SWID Tag IDs + */ + int tag_id_count; + + /** + * Number of processed SWID Tags */ - int count; + int tag_count; + + /** + * JSON array containing an inventory of SWID Tag IDs + */ + json_object *jarray; /** * Angel count @@ -215,6 +232,7 @@ METHOD(imv_state_t, get_remediation_instructions, bool, METHOD(imv_state_t, destroy, void, private_imv_swid_state_t *this) { + json_object_put(this->jarray); DESTROY_IF(this->session); DESTROY_IF(this->reason_string); DESTROY_IF(this->remediation_string); @@ -233,18 +251,68 @@ METHOD(imv_swid_state_t, get_handshake_state, imv_swid_handshake_state_t, return this->handshake_state; } +METHOD(imv_swid_state_t, set_request_id, void, + private_imv_swid_state_t *this, uint32_t request_id) +{ + this->request_id = request_id; +} + +METHOD(imv_swid_state_t, get_request_id, uint32_t, + private_imv_swid_state_t *this) +{ + return this->request_id; +} + +METHOD(imv_swid_state_t, set_swid_inventory, void, + private_imv_swid_state_t *this, swid_inventory_t *inventory) +{ + chunk_t tag_creator, unique_sw_id; + char software_id[256]; + json_object *jstring; + swid_tag_id_t *tag_id; + enumerator_t *enumerator; + + enumerator = inventory->create_enumerator(inventory); + while (enumerator->enumerate(enumerator, &tag_id)) + { + /* Construct software ID from tag creator and unique software ID */ + tag_creator = tag_id->get_tag_creator(tag_id); + unique_sw_id = tag_id->get_unique_sw_id(tag_id, NULL); + snprintf(software_id, 256, "%.*s_%.*s", + tag_creator.len, tag_creator.ptr, + unique_sw_id.len, unique_sw_id.ptr); + DBG3(DBG_IMV, " %s", software_id); + + /* Add software ID to JSON array */ + jstring = json_object_new_string(software_id); + json_object_array_add(this->jarray, jstring); + } + enumerator->destroy(enumerator); +} + +METHOD(imv_swid_state_t, get_swid_inventory, json_object*, + private_imv_swid_state_t *this) +{ + return this->jarray; +} + METHOD(imv_swid_state_t, set_count, void, - private_imv_swid_state_t *this, int count) + private_imv_swid_state_t *this, int tag_id_count, int tag_count) { - this->count += count; + this->tag_id_count += tag_id_count; + this->tag_count += tag_count; } METHOD(imv_swid_state_t, get_count, void, - private_imv_swid_state_t *this, int *count) + private_imv_swid_state_t *this, int *tag_id_count, int *tag_count) { - if (count) + if (tag_id_count) + { + *tag_id_count = this->tag_id_count; + } + if (tag_count) { - *count = this->count; + *tag_count = this->tag_count; } } @@ -290,6 +358,10 @@ imv_state_t *imv_swid_state_create(TNC_ConnectionID connection_id) }, .set_handshake_state = _set_handshake_state, .get_handshake_state = _get_handshake_state, + .set_request_id = _set_request_id, + .get_request_id = _get_request_id, + .set_swid_inventory = _set_swid_inventory, + .get_swid_inventory = _get_swid_inventory, .set_count = _set_count, .get_count = _get_count, .set_angel_count = _set_angel_count, @@ -299,6 +371,7 @@ imv_state_t *imv_swid_state_create(TNC_ConnectionID connection_id) .rec = TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION, .eval = TNC_IMV_EVALUATION_RESULT_DONT_KNOW, .connection_id = connection_id, + .jarray = json_object_new_array(), ); return &this->public.interface; diff --git a/src/libpts/plugins/imv_swid/imv_swid_state.h b/src/libpts/plugins/imv_swid/imv_swid_state.h index 8e7cd613d6..7ffabfd26a 100644 --- a/src/libpts/plugins/imv_swid/imv_swid_state.h +++ b/src/libpts/plugins/imv_swid/imv_swid_state.h @@ -25,8 +25,11 @@ #define IMV_SWID_STATE_H_ #include +#include #include +#include + typedef struct imv_swid_state_t imv_swid_state_t; typedef enum imv_swid_handshake_state_t imv_swid_handshake_state_t; @@ -64,31 +67,61 @@ struct imv_swid_state_t { */ imv_swid_handshake_state_t (*get_handshake_state)(imv_swid_state_t *this); + /** + * Set the SWID request ID + * + * @param request_id SWID request ID to be set + */ + void (*set_request_id)(imv_swid_state_t *this, uint32_t request_id); + + /** + * Get the SWID request ID + * + * @return SWID request ID + */ + uint32_t (*get_request_id)(imv_swid_state_t *this); + + /** + * Set or extend the SWID Tag ID inventory in the state + * + * @param inventory SWID Tags ID inventory to be added + */ + void (*set_swid_inventory)(imv_swid_state_t *this, swid_inventory_t *inventory); + + /** + * Get the encoding of the complete SWID Tag ID inventory + * + * @return SWID Tags ID inventory as a JSON array + */ + json_object* (*get_swid_inventory)(imv_swid_state_t *this); + /** * Set [or with multiple attributes increment] SWID Tag [ID] counters * - * @param count Number of received SWID Tags or SWID Tag IDs + * @param tag_id_count Number of received SWID Tag IDs + * @param tag_count Number of received SWID Tags */ - void (*set_count)(imv_swid_state_t *this, int count); + void (*set_count)(imv_swid_state_t *this, int tag_id_count, int tag_count); /** * Set [or with multiple attributes increment] SWID Tag [ID] counters * - * @param count Number of received SWID Tags or SWID Tag IDs + * @param tag_id_count Number of received SWID Tag IDs + * @param tag_count Number of received SWID Tags */ - void (*get_count)(imv_swid_state_t *this, int *count); + void (*get_count)(imv_swid_state_t *this, int *tag_id_count, int *tag_count); /** * Increase/Decrease the ITA Angel count * - * @param start TRUE increases and FALSE decreases count by one + * @param start TRUE increases and FALSE decreases count by one */ void (*set_angel_count)(imv_swid_state_t *this, bool start); /** * Get the ITA Angel count * - * @return ITA Angel count + * @return ITA Angel count */ int (*get_angel_count)(imv_swid_state_t *this);