refactored file measurement request list
This commit is contained in:
@@ -240,7 +240,7 @@ static TNC_Result send_message(TNC_ConnectionID connection_id)
|
|||||||
u_int32_t delimiter = SOLIDUS_UTF;
|
u_int32_t delimiter = SOLIDUS_UTF;
|
||||||
char *platform_info, *pathname;
|
char *platform_info, *pathname;
|
||||||
int id, type;
|
int id, type;
|
||||||
bool is_directory;
|
bool is_dir;
|
||||||
|
|
||||||
/* Does the PTS-IMC have TPM support? */
|
/* Does the PTS-IMC have TPM support? */
|
||||||
if (pts->get_proto_caps(pts) & PTS_PROTO_CAPS_T)
|
if (pts->get_proto_caps(pts) & PTS_PROTO_CAPS_T)
|
||||||
@@ -277,14 +277,14 @@ static TNC_Result send_message(TNC_ConnectionID connection_id)
|
|||||||
}
|
}
|
||||||
while (enumerator->enumerate(enumerator, &id, &type, &pathname))
|
while (enumerator->enumerate(enumerator, &id, &type, &pathname))
|
||||||
{
|
{
|
||||||
is_directory = (type != 0);
|
is_dir = (type != 0);
|
||||||
DBG2(DBG_IMV, "measurement request %d for %s '%s'",
|
DBG2(DBG_IMV, "measurement request %d for %s '%s'",
|
||||||
id, is_directory ? "directory" : "file", pathname);
|
id, is_dir ? "directory" : "file", pathname);
|
||||||
attr = tcg_pts_attr_req_file_meas_create(is_directory, id,
|
attr = tcg_pts_attr_req_file_meas_create(is_dir, id, delimiter,
|
||||||
delimiter, pathname);
|
pathname);
|
||||||
attr->set_noskip_flag(attr, TRUE);
|
attr->set_noskip_flag(attr, TRUE);
|
||||||
msg->add_attribute(msg, attr);
|
msg->add_attribute(msg, attr);
|
||||||
attestation_state->add_requested_file(attestation_state, id , type);
|
attestation_state->add_request(attestation_state, id , is_dir);
|
||||||
}
|
}
|
||||||
enumerator->destroy(enumerator);
|
enumerator->destroy(enumerator);
|
||||||
|
|
||||||
@@ -491,7 +491,7 @@ TNC_Result TNC_IMV_ReceiveMessage(TNC_IMVID imv_id,
|
|||||||
chunk_t measurement;
|
chunk_t measurement;
|
||||||
char *platform_info, *filename;
|
char *platform_info, *filename;
|
||||||
enumerator_t *e_meas;
|
enumerator_t *e_meas;
|
||||||
bool is_directory;
|
bool is_dir;
|
||||||
linked_list_t *files_in_dir_with_meas;
|
linked_list_t *files_in_dir_with_meas;
|
||||||
|
|
||||||
files_in_dir_with_meas = linked_list_create();
|
files_in_dir_with_meas = linked_list_create();
|
||||||
@@ -510,17 +510,13 @@ TNC_Result TNC_IMV_ReceiveMessage(TNC_IMVID imv_id,
|
|||||||
DBG1(DBG_IMV, "measurement request %d returned %d file%s:",
|
DBG1(DBG_IMV, "measurement request %d returned %d file%s:",
|
||||||
request_id, file_count, (file_count == 1) ? "":"s");
|
request_id, file_count, (file_count == 1) ? "":"s");
|
||||||
|
|
||||||
if (!attestation_state->is_request_dir(attestation_state, request_id, &is_directory))
|
if (!attestation_state->check_off_request(attestation_state,
|
||||||
|
request_id, &is_dir))
|
||||||
{
|
{
|
||||||
DBG1(DBG_IMV, "received measurement with id: %d was not requested", request_id);
|
DBG1(DBG_IMV, " no entry found for this request");
|
||||||
fatal_error = TRUE;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!is_directory)
|
if (is_dir)
|
||||||
{
|
|
||||||
attestation_state->remove_requested_file(attestation_state, request_id);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
enumerator_t *e;
|
enumerator_t *e;
|
||||||
char *file;
|
char *file;
|
||||||
@@ -540,29 +536,27 @@ TNC_Result TNC_IMV_ReceiveMessage(TNC_IMVID imv_id,
|
|||||||
e_meas = measurements->create_enumerator(measurements);
|
e_meas = measurements->create_enumerator(measurements);
|
||||||
while (e_meas->enumerate(e_meas, &filename, &measurement))
|
while (e_meas->enumerate(e_meas, &filename, &measurement))
|
||||||
{
|
{
|
||||||
bool hash_matched;
|
bool hash_match;
|
||||||
|
|
||||||
hash_matched = pts_db->check_measurement(pts_db,
|
hash_match = pts_db->check_measurement(pts_db, measurement,
|
||||||
measurement, platform_info,
|
platform_info, request_id, filename, algo, is_dir);
|
||||||
request_id, filename, algo, is_directory);
|
|
||||||
if (!hash_matched)
|
if (!hash_match)
|
||||||
{
|
{
|
||||||
measurement_error = TRUE;
|
measurement_error = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_directory &&
|
if (is_dir && files_in_dir_with_meas->remove(files_in_dir_with_meas,
|
||||||
files_in_dir_with_meas->remove(files_in_dir_with_meas,
|
filename, (bool (*)(void*,void*))string_equals))
|
||||||
filename, (bool (*)(void*,void*))string_cmp))
|
|
||||||
{
|
{
|
||||||
DBG3(DBG_IMV, "Removed %s from expected files list", filename);
|
DBG3(DBG_IMV, "Removed %s from expected files list", filename);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_directory &&
|
if (is_dir &&
|
||||||
!files_in_dir_with_meas->get_count(files_in_dir_with_meas))
|
!files_in_dir_with_meas->get_count(files_in_dir_with_meas))
|
||||||
{
|
{
|
||||||
attestation_state->remove_requested_file(attestation_state, request_id);
|
DBG3(DBG_IMV, "recevied all expected file measurements for request: %d", request_id);
|
||||||
DBG3(DBG_IMV, "Received all expected files measured for request: %d", request_id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
files_in_dir_with_meas->destroy_function(files_in_dir_with_meas, free);
|
files_in_dir_with_meas->destroy_function(files_in_dir_with_meas, free);
|
||||||
@@ -617,21 +611,15 @@ TNC_Result TNC_IMV_ReceiveMessage(TNC_IMVID imv_id,
|
|||||||
|
|
||||||
if (attestation_state->get_handshake_state(attestation_state) &
|
if (attestation_state->get_handshake_state(attestation_state) &
|
||||||
IMV_ATTESTATION_STATE_END)
|
IMV_ATTESTATION_STATE_END)
|
||||||
{
|
{
|
||||||
if (measurement_error || attestation_state->get_requests_count(attestation_state))
|
if (attestation_state->get_request_count(attestation_state))
|
||||||
|
{
|
||||||
|
DBG1(DBG_IMV, "failure due to %d pending file measurements",
|
||||||
|
attestation_state->get_request_count(attestation_state));
|
||||||
|
measurement_error = TRUE;
|
||||||
|
}
|
||||||
|
if (measurement_error)
|
||||||
{
|
{
|
||||||
file_request_t *entry;
|
|
||||||
enumerator_t *e;
|
|
||||||
int request;
|
|
||||||
|
|
||||||
e = attestation_state->create_requests_enumerator(attestation_state);
|
|
||||||
while (e->enumerate(e, &request))
|
|
||||||
{
|
|
||||||
DBG1(DBG_IMV, "%s measurement not received for request: %d",
|
|
||||||
(entry->is_dir) ? "Directory" : "File", entry->request_id);
|
|
||||||
}
|
|
||||||
e->destroy(e);
|
|
||||||
|
|
||||||
state->set_recommendation(state,
|
state->set_recommendation(state,
|
||||||
TNC_IMV_ACTION_RECOMMENDATION_ISOLATE,
|
TNC_IMV_ACTION_RECOMMENDATION_ISOLATE,
|
||||||
TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MAJOR);
|
TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MAJOR);
|
||||||
|
|||||||
@@ -16,9 +16,19 @@
|
|||||||
#include "imv_attestation_state.h"
|
#include "imv_attestation_state.h"
|
||||||
|
|
||||||
#include <utils/lexparser.h>
|
#include <utils/lexparser.h>
|
||||||
|
#include <utils/linked_list.h>
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
typedef struct private_imv_attestation_state_t private_imv_attestation_state_t;
|
typedef struct private_imv_attestation_state_t private_imv_attestation_state_t;
|
||||||
|
typedef struct request_t request_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PTS File/Directory Measurement request entry
|
||||||
|
*/
|
||||||
|
struct request_t {
|
||||||
|
int id;
|
||||||
|
bool is_dir;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Private data of an imv_attestation_state_t object.
|
* Private data of an imv_attestation_state_t object.
|
||||||
@@ -55,16 +65,16 @@ struct private_imv_attestation_state_t {
|
|||||||
*/
|
*/
|
||||||
TNC_IMV_Evaluation_Result eval;
|
TNC_IMV_Evaluation_Result eval;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of PTS File/Directory Measurement requests
|
||||||
|
*/
|
||||||
|
linked_list_t *requests;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PTS object
|
* PTS object
|
||||||
*/
|
*/
|
||||||
pts_t *pts;
|
pts_t *pts;
|
||||||
|
|
||||||
/**
|
|
||||||
* Requested files and directories
|
|
||||||
*/
|
|
||||||
linked_list_t *requested_files;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct entry_t entry_t;
|
typedef struct entry_t entry_t;
|
||||||
@@ -161,8 +171,8 @@ METHOD(imv_state_t, get_reason_string, bool,
|
|||||||
METHOD(imv_state_t, destroy, void,
|
METHOD(imv_state_t, destroy, void,
|
||||||
private_imv_attestation_state_t *this)
|
private_imv_attestation_state_t *this)
|
||||||
{
|
{
|
||||||
|
this->requests->destroy_function(this->requests, free);
|
||||||
this->pts->destroy(this->pts);
|
this->pts->destroy(this->pts);
|
||||||
this->requested_files->destroy_function(this->requested_files, free);
|
|
||||||
free(this);
|
free(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -184,72 +194,45 @@ METHOD(imv_attestation_state_t, get_pts, pts_t*,
|
|||||||
return this->pts;
|
return this->pts;
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(imv_attestation_state_t, create_requests_enumerator, enumerator_t*,
|
METHOD(imv_attestation_state_t, add_request, void,
|
||||||
private_imv_attestation_state_t *this)
|
private_imv_attestation_state_t *this, int id, bool is_dir)
|
||||||
{
|
{
|
||||||
enumerator_t *e;
|
request_t *request;
|
||||||
e = this->requested_files->create_enumerator(this->requested_files);
|
|
||||||
return e;
|
request = malloc_thing(request_t);
|
||||||
|
request->id = id;
|
||||||
|
request->is_dir = is_dir;
|
||||||
|
this->requests->insert_last(this->requests, request);
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(imv_attestation_state_t, get_requests_count, int,
|
METHOD(imv_attestation_state_t, check_off_request, bool,
|
||||||
private_imv_attestation_state_t *this)
|
private_imv_attestation_state_t *this, int id, bool* is_dir)
|
||||||
{
|
{
|
||||||
return this->requested_files->get_count(this->requested_files);
|
enumerator_t *enumerator;
|
||||||
}
|
request_t *request;
|
||||||
|
bool found = FALSE;
|
||||||
|
|
||||||
METHOD(imv_attestation_state_t, add_requested_file, void,
|
|
||||||
private_imv_attestation_state_t *this, int request_id, int is_dir)
|
|
||||||
{
|
|
||||||
file_request_t *entry;
|
|
||||||
|
|
||||||
entry = malloc_thing(file_request_t);
|
|
||||||
entry->request_id = request_id;
|
|
||||||
entry->is_dir = is_dir;
|
|
||||||
this->requested_files->insert_last(this->requested_files, entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Comparison function to match an file request entry with its request_id
|
|
||||||
*/
|
|
||||||
static bool request_match(file_request_t *current_list_item, int request_id)
|
|
||||||
{
|
|
||||||
return (current_list_item->request_id == request_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
METHOD(imv_attestation_state_t, remove_requested_file, bool,
|
|
||||||
private_imv_attestation_state_t *this, int request_id)
|
|
||||||
{
|
|
||||||
file_request_t *entry;
|
|
||||||
|
|
||||||
if (this->requested_files->find_first(this->requested_files,
|
|
||||||
(linked_list_match_t)request_match, (void**)&entry, request_id) != SUCCESS)
|
|
||||||
{
|
|
||||||
DBG1(DBG_IMV, "request entry with id: %d not found", request_id);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
this->requested_files->remove(this->requested_files, entry, NULL);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
METHOD(imv_attestation_state_t, is_request_dir, bool,
|
|
||||||
private_imv_attestation_state_t *this, int request_id, bool *is_dir)
|
|
||||||
{
|
|
||||||
file_request_t *entry;
|
|
||||||
|
|
||||||
if (this->requested_files->find_first(this->requested_files,
|
|
||||||
(linked_list_match_t)request_match, (void**)&entry, request_id) != SUCCESS)
|
|
||||||
{
|
|
||||||
DBG1(DBG_IMV, "request entry with id: %d not found", request_id);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
*is_dir = (entry->is_dir);
|
enumerator = this->requests->create_enumerator(this->requests);
|
||||||
return TRUE;
|
while (enumerator->enumerate(enumerator, &request))
|
||||||
|
{
|
||||||
|
if (request->id == id)
|
||||||
|
{
|
||||||
|
found = TRUE;
|
||||||
|
*is_dir = request->is_dir;
|
||||||
|
this->requests->remove_at(this->requests, enumerator);
|
||||||
|
free(request);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
enumerator->destroy(enumerator);
|
||||||
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
METHOD(imv_attestation_state_t, get_request_count, int,
|
||||||
|
private_imv_attestation_state_t *this)
|
||||||
|
{
|
||||||
|
return this->requests->get_count(this->requests);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Described in header.
|
* Described in header.
|
||||||
@@ -272,19 +255,17 @@ imv_state_t *imv_attestation_state_create(TNC_ConnectionID connection_id)
|
|||||||
.get_handshake_state = _get_handshake_state,
|
.get_handshake_state = _get_handshake_state,
|
||||||
.set_handshake_state = _set_handshake_state,
|
.set_handshake_state = _set_handshake_state,
|
||||||
.get_pts = _get_pts,
|
.get_pts = _get_pts,
|
||||||
.create_requests_enumerator = _create_requests_enumerator,
|
.add_request = _add_request,
|
||||||
.get_requests_count = _get_requests_count,
|
.check_off_request = _check_off_request,
|
||||||
.add_requested_file = _add_requested_file,
|
.get_request_count = _get_request_count,
|
||||||
.remove_requested_file = _remove_requested_file,
|
|
||||||
.is_request_dir = _is_request_dir,
|
|
||||||
},
|
},
|
||||||
.connection_id = connection_id,
|
.connection_id = connection_id,
|
||||||
.state = TNC_CONNECTION_STATE_CREATE,
|
.state = TNC_CONNECTION_STATE_CREATE,
|
||||||
.handshake_state = IMV_ATTESTATION_STATE_INIT,
|
.handshake_state = IMV_ATTESTATION_STATE_INIT,
|
||||||
.rec = TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION,
|
.rec = TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION,
|
||||||
.eval = TNC_IMV_EVALUATION_RESULT_DONT_KNOW,
|
.eval = TNC_IMV_EVALUATION_RESULT_DONT_KNOW,
|
||||||
|
.requests = linked_list_create(),
|
||||||
.pts = pts_create(FALSE),
|
.pts = pts_create(FALSE),
|
||||||
.requested_files = linked_list_create(),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
platform_info = lib->settings->get_str(lib->settings,
|
platform_info = lib->settings->get_str(lib->settings,
|
||||||
|
|||||||
@@ -25,11 +25,9 @@
|
|||||||
#include <imv/imv_state.h>
|
#include <imv/imv_state.h>
|
||||||
#include <tcg/pts/pts.h>
|
#include <tcg/pts/pts.h>
|
||||||
#include <library.h>
|
#include <library.h>
|
||||||
#include <utils/linked_list.h>
|
|
||||||
|
|
||||||
typedef struct imv_attestation_state_t imv_attestation_state_t;
|
typedef struct imv_attestation_state_t imv_attestation_state_t;
|
||||||
typedef enum imv_attestation_handshake_state_t imv_attestation_handshake_state_t;
|
typedef enum imv_attestation_handshake_state_t imv_attestation_handshake_state_t;
|
||||||
typedef struct file_request_t file_request_t;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* IMV Attestation Handshake States (state machine)
|
* IMV Attestation Handshake States (state machine)
|
||||||
@@ -42,14 +40,6 @@ enum imv_attestation_handshake_state_t {
|
|||||||
IMV_ATTESTATION_STATE_END,
|
IMV_ATTESTATION_STATE_END,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Defines an structure to hold requested file/directory
|
|
||||||
*/
|
|
||||||
struct file_request_t {
|
|
||||||
int request_id;
|
|
||||||
int is_dir;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal state of an imv_attestation_t connection instance
|
* Internal state of an imv_attestation_t connection instance
|
||||||
*/
|
*/
|
||||||
@@ -83,42 +73,30 @@ struct imv_attestation_state_t {
|
|||||||
pts_t* (*get_pts)(imv_attestation_state_t *this);
|
pts_t* (*get_pts)(imv_attestation_state_t *this);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add an entry to list of requested files/directories
|
* Add an entry to the list of pending file/directory measurement requests
|
||||||
*
|
*
|
||||||
* @param request_id unique request id
|
* @param id unique request ID
|
||||||
* @param is_dir 0 for file and 1 for directory
|
* @param is_dir TRUE if directory
|
||||||
*/
|
*/
|
||||||
void (*add_requested_file)(imv_attestation_state_t *this, int request_id, int is_dir);
|
void (*add_request)(imv_attestation_state_t *this, int id, bool is_dir);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates enumerator over the list of requested file/directories
|
* Returns the number of pending file/directory measurement requests
|
||||||
*
|
*
|
||||||
* @return enumerator over requested files/directories list
|
* @return number of pending requests
|
||||||
*/
|
*/
|
||||||
enumerator_t* (*create_requests_enumerator)(imv_attestation_state_t *this);
|
int (*get_request_count)(imv_attestation_state_t *this);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns number of entries in the list of requested file/directories
|
* Check for presence of request_id and if found remove it from the list
|
||||||
*
|
*
|
||||||
* @return number of entries in the list of requested file/directories
|
* @param id unique request ID
|
||||||
|
* @param is_dir return TRUE if request was for a directory
|
||||||
|
* @return TRUE if request ID found, FALSE otherwise
|
||||||
*/
|
*/
|
||||||
int (*get_requests_count)(imv_attestation_state_t *this);
|
bool (*check_off_request)(imv_attestation_state_t *this, int id,
|
||||||
|
bool *is_dir);
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes an entry with matching request_id from list of requested files/directories
|
|
||||||
*
|
|
||||||
* @param request_id unique request id
|
|
||||||
* @return TRUE if request entry found, FALSE otherwise
|
|
||||||
*/
|
|
||||||
bool (*remove_requested_file)(imv_attestation_state_t *this, int request_id);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns TRUE if entry with given ID is directory and FALSE otherwise
|
|
||||||
*
|
|
||||||
* @param request_id unique request id
|
|
||||||
* @return TRUE if request entry found, FALSE otherwise
|
|
||||||
*/
|
|
||||||
bool (*is_request_dir)(imv_attestation_state_t *this, int request_id, bool *is_dir);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user