Added Check_Measurement function to pts_database instead of returning enumerator over hashes
List of requested files/directories are kept within imv state now Allocated memory for entries in files_in_dir_with_meas list
This commit is contained in:
committed by
Andreas Steffen
parent
85a276e985
commit
e9fd8b4b7b
@@ -43,7 +43,6 @@
|
|||||||
|
|
||||||
#include <pen/pen.h>
|
#include <pen/pen.h>
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
#include <utils/linked_list.h>
|
|
||||||
#include <credentials/credential_manager.h>
|
#include <credentials/credential_manager.h>
|
||||||
|
|
||||||
/* IMV definitions */
|
/* IMV definitions */
|
||||||
@@ -81,11 +80,6 @@ static pts_creds_t *pts_creds;
|
|||||||
*/
|
*/
|
||||||
static credential_manager_t *pts_credmgr;
|
static credential_manager_t *pts_credmgr;
|
||||||
|
|
||||||
/**
|
|
||||||
* List of id's for the files that are requested for measurement
|
|
||||||
*/
|
|
||||||
static linked_list_t *requested_files;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* see section 3.7.1 of TCG TNC IF-IMV Specification 1.2
|
* see section 3.7.1 of TCG TNC IF-IMV Specification 1.2
|
||||||
*/
|
*/
|
||||||
@@ -282,7 +276,6 @@ static TNC_Result send_message(TNC_ConnectionID connection_id)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
requested_files = linked_list_create();
|
|
||||||
while (enumerator->enumerate(enumerator, &id, &type, &pathname))
|
while (enumerator->enumerate(enumerator, &id, &type, &pathname))
|
||||||
{
|
{
|
||||||
is_directory = (type != 0);
|
is_directory = (type != 0);
|
||||||
@@ -292,7 +285,8 @@ static TNC_Result send_message(TNC_ConnectionID connection_id)
|
|||||||
delimiter, pathname);
|
delimiter, pathname);
|
||||||
attr->set_noskip_flag(attr, TRUE);
|
attr->set_noskip_flag(attr, TRUE);
|
||||||
msg->add_attribute(msg, attr);
|
msg->add_attribute(msg, attr);
|
||||||
requested_files->insert_last(requested_files, (void*)id);
|
|
||||||
|
attestation_state->add_requested_file(attestation_state, id, type);
|
||||||
}
|
}
|
||||||
enumerator->destroy(enumerator);
|
enumerator->destroy(enumerator);
|
||||||
|
|
||||||
@@ -319,6 +313,15 @@ static TNC_Result send_message(TNC_ConnectionID connection_id)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* String matching function with boolean return value
|
||||||
|
* Used to remove an item from linked list of strings
|
||||||
|
*/
|
||||||
|
static bool string_cmp(char *a, char *b)
|
||||||
|
{
|
||||||
|
return (strcmp(a,b) == 0) ? TRUE : FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* see section 3.7.3 of TCG TNC IF-IMV Specification 1.2
|
* see section 3.7.3 of TCG TNC IF-IMV Specification 1.2
|
||||||
*/
|
*/
|
||||||
@@ -518,15 +521,15 @@ 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 (!pts_db->is_directory(pts_db, request_id, &is_directory))
|
if (!attestation_state->is_request_dir(attestation_state, request_id, &is_directory))
|
||||||
{
|
{
|
||||||
DBG1(DBG_IMV, "file entry with request id:%d not found", request_id);
|
DBG1(DBG_IMV, "received measurement with id: %d was not requested", request_id);
|
||||||
|
fatal_error = TRUE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_directory)
|
if (!is_directory)
|
||||||
{
|
{
|
||||||
requested_files->remove(requested_files, (void*)request_id, NULL);
|
attestation_state->remove_requested_file(attestation_state, request_id);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -536,61 +539,46 @@ TNC_Result TNC_IMV_ReceiveMessage(TNC_IMVID imv_id,
|
|||||||
e = pts_db->create_files_in_dir_enumerator(pts_db, request_id);
|
e = pts_db->create_files_in_dir_enumerator(pts_db, request_id);
|
||||||
while (e->enumerate(e, &file))
|
while (e->enumerate(e, &file))
|
||||||
{
|
{
|
||||||
files_in_dir_with_meas->insert_last(files_in_dir_with_meas, file);
|
char *file_copy = (char *)malloc(strlen(file) * sizeof(char));
|
||||||
DBG3(DBG_IMV, "expecting measurement for: %s with request_id: %d", file, request_id);
|
strcpy(file_copy, file);
|
||||||
|
|
||||||
|
files_in_dir_with_meas->insert_last(files_in_dir_with_meas, file_copy);
|
||||||
|
DBG3(DBG_IMV, "expecting measurement for: %s with request_id: %d", file_copy, request_id);
|
||||||
}
|
}
|
||||||
|
e->destroy(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
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))
|
||||||
{
|
{
|
||||||
enumerator_t *e;
|
bool hash_matched;
|
||||||
chunk_t db_measurement;
|
|
||||||
|
|
||||||
e = (is_directory) ? pts_db->create_dir_meas_enumerator(pts_db,
|
hash_matched = pts_db->check_measurement(pts_db,
|
||||||
platform_info, request_id, filename, algo) :
|
measurement, platform_info,
|
||||||
pts_db->create_file_meas_enumerator(pts_db,
|
request_id, filename, algo, is_directory);
|
||||||
platform_info, request_id, algo);
|
if (!hash_matched)
|
||||||
if (!e)
|
|
||||||
{
|
{
|
||||||
DBG1(DBG_IMV, " database enumerator failed");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!e->enumerate(e, &db_measurement))
|
|
||||||
{
|
|
||||||
DBG2(DBG_IMV, " measurement for '%s' not found"
|
|
||||||
" in database", filename);
|
|
||||||
e->destroy(e);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (chunk_equals(db_measurement, measurement))
|
|
||||||
{
|
|
||||||
DBG2(DBG_IMV, " %#B for '%s' is ok",
|
|
||||||
&measurement, filename);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DBG1(DBG_IMV, " %#B for '%s' does not match %#B",
|
|
||||||
&measurement, filename, &db_measurement);
|
|
||||||
measurement_error = TRUE;
|
measurement_error = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_directory)
|
if (is_directory &&
|
||||||
{
|
|
||||||
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*))strcmp);
|
filename, (bool (*)(void*,void*))string_cmp))
|
||||||
|
{
|
||||||
|
DBG3(DBG_IMV, "Removed %s from expected files list", filename);
|
||||||
}
|
}
|
||||||
e->destroy(e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_directory &&
|
if (is_directory &&
|
||||||
!files_in_dir_with_meas->get_count(files_in_dir_with_meas))
|
!files_in_dir_with_meas->get_count(files_in_dir_with_meas))
|
||||||
{
|
{
|
||||||
requested_files->remove(requested_files, (void*)request_id, NULL);
|
attestation_state->remove_requested_file(attestation_state, request_id);
|
||||||
|
DBG3(DBG_IMV, "Received all expected files measured for request: %d", request_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
files_in_dir_with_meas->destroy(files_in_dir_with_meas);
|
files_in_dir_with_meas->destroy_function(files_in_dir_with_meas, free);
|
||||||
e_meas->destroy(e_meas);
|
e_meas->destroy(e_meas);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -630,7 +618,6 @@ TNC_Result TNC_IMV_ReceiveMessage(TNC_IMVID imv_id,
|
|||||||
pa_tnc_msg->destroy(pa_tnc_msg);
|
pa_tnc_msg->destroy(pa_tnc_msg);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (fatal_error)
|
if (fatal_error)
|
||||||
{
|
{
|
||||||
state->set_recommendation(state,
|
state->set_recommendation(state,
|
||||||
@@ -643,18 +630,18 @@ 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 || requested_files->get_count(requested_files))
|
if (measurement_error || attestation_state->get_requests_count(attestation_state))
|
||||||
{
|
{
|
||||||
enumerator_t *e;
|
enumerator_t *e;
|
||||||
int request;
|
int request;
|
||||||
|
|
||||||
e = requested_files->create_enumerator(requested_files);
|
e = attestation_state->create_requests_enumerator(attestation_state);
|
||||||
while (e->enumerate(e, &request))
|
while (e->enumerate(e, &request))
|
||||||
{
|
{
|
||||||
DBG1(DBG_IMV, "measurement/s not received for requests: %d", request);
|
DBG1(DBG_IMV, "measurement/s not received for requests: %d", request);
|
||||||
}
|
}
|
||||||
|
|
||||||
e->destroy(e);
|
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);
|
||||||
@@ -733,7 +720,6 @@ TNC_Result TNC_IMV_Terminate(TNC_IMVID imv_id)
|
|||||||
}
|
}
|
||||||
DESTROY_IF(pts_db);
|
DESTROY_IF(pts_db);
|
||||||
pts_credmgr->destroy(pts_credmgr);
|
pts_credmgr->destroy(pts_credmgr);
|
||||||
requested_files->destroy(requested_files);
|
|
||||||
imv_attestation->destroy(imv_attestation);
|
imv_attestation->destroy(imv_attestation);
|
||||||
imv_attestation = NULL;
|
imv_attestation = NULL;
|
||||||
|
|
||||||
|
|||||||
@@ -60,6 +60,11 @@ struct private_imv_attestation_state_t {
|
|||||||
*/
|
*/
|
||||||
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;
|
||||||
@@ -157,6 +162,7 @@ METHOD(imv_state_t, destroy, void,
|
|||||||
private_imv_attestation_state_t *this)
|
private_imv_attestation_state_t *this)
|
||||||
{
|
{
|
||||||
this->pts->destroy(this->pts);
|
this->pts->destroy(this->pts);
|
||||||
|
this->requested_files->destroy_function(this->requested_files, free);
|
||||||
free(this);
|
free(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -178,6 +184,73 @@ 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*,
|
||||||
|
private_imv_attestation_state_t *this)
|
||||||
|
{
|
||||||
|
enumerator_t *e;
|
||||||
|
e = this->requested_files->create_enumerator(this->requested_files);
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(imv_attestation_state_t, get_requests_count, int,
|
||||||
|
private_imv_attestation_state_t *this)
|
||||||
|
{
|
||||||
|
return this->requested_files->get_count(this->requested_files);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Described in header.
|
* Described in header.
|
||||||
*/
|
*/
|
||||||
@@ -199,6 +272,11 @@ 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,
|
||||||
|
.get_requests_count = _get_requests_count,
|
||||||
|
.add_requested_file = _add_requested_file,
|
||||||
|
.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,
|
||||||
@@ -206,6 +284,7 @@ imv_state_t *imv_attestation_state_create(TNC_ConnectionID connection_id)
|
|||||||
.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,
|
||||||
.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,9 +25,11 @@
|
|||||||
#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)
|
||||||
@@ -40,6 +42,14 @@ 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
|
||||||
*/
|
*/
|
||||||
@@ -72,6 +82,43 @@ 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
|
||||||
|
*
|
||||||
|
* @param request_id unique request id
|
||||||
|
* @param is_dir 0 for file and 1 for directory
|
||||||
|
*/
|
||||||
|
void (*add_requested_file)(imv_attestation_state_t *this, int request_id, int is_dir);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates enumerator over the list of requested file/directories
|
||||||
|
*
|
||||||
|
* @return enumerator over requested files/directories list
|
||||||
|
*/
|
||||||
|
enumerator_t* (*create_requests_enumerator)(imv_attestation_state_t *this);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns number of entries in the list of requested file/directories
|
||||||
|
*
|
||||||
|
* @return number of entries in the list of requested file/directories
|
||||||
|
*/
|
||||||
|
int (*get_requests_count)(imv_attestation_state_t *this);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -54,35 +54,6 @@ METHOD(pts_database_t, create_file_enumerator, enumerator_t*,
|
|||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(pts_database_t, is_directory, bool,
|
|
||||||
private_pts_database_t *this, int id, bool *is_directory)
|
|
||||||
{
|
|
||||||
enumerator_t *e;
|
|
||||||
int is_dir;
|
|
||||||
|
|
||||||
/* look for a entry in files table with matching id */
|
|
||||||
e = this->db->query(this->db,
|
|
||||||
"SELECT f.type FROM files AS f "
|
|
||||||
"WHERE f.id = ?",
|
|
||||||
DB_INT, id, DB_INT);
|
|
||||||
|
|
||||||
if (!e)
|
|
||||||
{
|
|
||||||
DBG1(DBG_TNC, "database enumerator failed", id);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
if (!e->enumerate(e, &is_dir))
|
|
||||||
{
|
|
||||||
e->destroy(e);
|
|
||||||
DBG1(DBG_TNC, "file entry with given id:%d not found", id);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
*is_directory = (is_dir == 1) ? TRUE : FALSE;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
METHOD(pts_database_t, create_files_in_dir_enumerator, enumerator_t*,
|
METHOD(pts_database_t, create_files_in_dir_enumerator, enumerator_t*,
|
||||||
private_pts_database_t *this, int id)
|
private_pts_database_t *this, int id)
|
||||||
{
|
{
|
||||||
@@ -97,35 +68,53 @@ METHOD(pts_database_t, create_files_in_dir_enumerator, enumerator_t*,
|
|||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(pts_database_t, create_file_meas_enumerator, enumerator_t*,
|
METHOD(pts_database_t, check_measurement, bool,
|
||||||
private_pts_database_t *this, char *product, int id, pts_meas_algorithms_t algorithm)
|
private_pts_database_t *this, chunk_t received_hash, char *product, int id, char *file_name, pts_meas_algorithms_t algorithm, bool is_dir)
|
||||||
{
|
{
|
||||||
enumerator_t *e;
|
enumerator_t *e;
|
||||||
|
chunk_t db_measurement;
|
||||||
|
|
||||||
/* look for all entries belonging to a product and file in file_hashes table */
|
/* look for all entries belonging to a product, file and directory in file_hashes table */
|
||||||
e = this->db->query(this->db,
|
|
||||||
|
e = (is_dir) ? this->db->query(this->db,
|
||||||
|
"SELECT fh.hash FROM file_hashes AS fh "
|
||||||
|
"JOIN files AS f ON fh.file = f.id "
|
||||||
|
"JOIN products AS p ON fh.product = p.id "
|
||||||
|
"WHERE f.path = ? AND p.name = ? AND fh.directory = ? AND fh.algo = ?",
|
||||||
|
DB_TEXT, file_name, DB_TEXT, product, DB_INT, id, DB_INT, algorithm, DB_BLOB) :
|
||||||
|
|
||||||
|
this->db->query(this->db,
|
||||||
"SELECT fh.hash FROM file_hashes AS fh "
|
"SELECT fh.hash FROM file_hashes AS fh "
|
||||||
"JOIN files AS f ON fh.file = f.id "
|
"JOIN files AS f ON fh.file = f.id "
|
||||||
"JOIN products AS p ON fh.product = p.id "
|
"JOIN products AS p ON fh.product = p.id "
|
||||||
"WHERE p.name = ? AND f.id = ? AND fh.algo = ?",
|
"WHERE p.name = ? AND f.id = ? AND fh.algo = ?",
|
||||||
DB_TEXT, product, DB_INT, id, DB_INT, algorithm, DB_BLOB);
|
DB_TEXT, product, DB_INT, id, DB_INT, algorithm, DB_BLOB);
|
||||||
return e;
|
|
||||||
|
if (!e)
|
||||||
|
{
|
||||||
|
DBG1(DBG_TNC, " database enumerator failed");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (!e->enumerate(e, &db_measurement))
|
||||||
|
{
|
||||||
|
DBG2(DBG_TNC, " measurement for '%s' not found"
|
||||||
|
" in database", file_name);
|
||||||
|
e->destroy(e);
|
||||||
|
/* Ignore the measurements for which we do not have the hash saved in database */
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
if (chunk_equals(db_measurement, received_hash))
|
||||||
|
{
|
||||||
|
DBG2(DBG_TNC, " %#B for '%s' is ok",
|
||||||
|
&received_hash, file_name);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
DBG1(DBG_IMV, " %#B for '%s' does not match %#B",
|
||||||
|
&received_hash, file_name, &db_measurement);
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(pts_database_t, create_dir_meas_enumerator, enumerator_t*,
|
|
||||||
private_pts_database_t *this, char *product, int id, char *file_name, pts_meas_algorithms_t algorithm)
|
|
||||||
{
|
|
||||||
enumerator_t *e;
|
|
||||||
|
|
||||||
/* look for all entries belonging to a product, file and directory in file_hashes table */
|
|
||||||
e = this->db->query(this->db,
|
|
||||||
"SELECT fh.hash FROM file_hashes AS fh "
|
|
||||||
"JOIN files AS f ON fh.file = f.id "
|
|
||||||
"JOIN products AS p ON fh.product = p.id "
|
|
||||||
"WHERE f.path = ? AND p.name = ? AND fh.directory = ? AND fh.algo = ?",
|
|
||||||
DB_TEXT, file_name, DB_TEXT, product, DB_INT, id, DB_INT, algorithm, DB_BLOB);
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
|
|
||||||
METHOD(pts_database_t, destroy, void,
|
METHOD(pts_database_t, destroy, void,
|
||||||
private_pts_database_t *this)
|
private_pts_database_t *this)
|
||||||
@@ -144,10 +133,8 @@ pts_database_t *pts_database_create(char *uri)
|
|||||||
INIT(this,
|
INIT(this,
|
||||||
.public = {
|
.public = {
|
||||||
.create_file_enumerator = _create_file_enumerator,
|
.create_file_enumerator = _create_file_enumerator,
|
||||||
.is_directory = _is_directory,
|
|
||||||
.create_files_in_dir_enumerator = _create_files_in_dir_enumerator,
|
.create_files_in_dir_enumerator = _create_files_in_dir_enumerator,
|
||||||
.create_file_meas_enumerator = _create_file_meas_enumerator,
|
.check_measurement = _check_measurement,
|
||||||
.create_dir_meas_enumerator = _create_dir_meas_enumerator,
|
|
||||||
.destroy = _destroy,
|
.destroy = _destroy,
|
||||||
},
|
},
|
||||||
.db = lib->db->create(lib->db, uri),
|
.db = lib->db->create(lib->db, uri),
|
||||||
|
|||||||
@@ -40,15 +40,6 @@ struct pts_database_t {
|
|||||||
*/
|
*/
|
||||||
enumerator_t* (*create_file_enumerator)(pts_database_t *this, char *product);
|
enumerator_t* (*create_file_enumerator)(pts_database_t *this, char *product);
|
||||||
|
|
||||||
/**
|
|
||||||
* Get if file with given id is directory
|
|
||||||
*
|
|
||||||
* @id primary key in files table
|
|
||||||
* @is_directory TRUE if entry with given ID has type of directory
|
|
||||||
* @return TRUE if query is not failed
|
|
||||||
*/
|
|
||||||
bool (*is_directory)(pts_database_t *this, int id, bool *is_directory);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get Enumerator over files in a given directory with measurements
|
* Get Enumerator over files in a given directory with measurements
|
||||||
*
|
*
|
||||||
@@ -57,27 +48,19 @@ struct pts_database_t {
|
|||||||
*/
|
*/
|
||||||
enumerator_t* (*create_files_in_dir_enumerator)(pts_database_t *this, int id);
|
enumerator_t* (*create_files_in_dir_enumerator)(pts_database_t *this, int id);
|
||||||
|
|
||||||
/**
|
|
||||||
* Get Hash measurement of a file with given id and hashing algorithm type
|
|
||||||
*
|
|
||||||
* @product software product (os, vpn client, etc.)
|
|
||||||
* @id primary key in files table
|
|
||||||
* @algorithm measurement algorithm type
|
|
||||||
* @return enumerator over all measurements matching a given release
|
|
||||||
*/
|
|
||||||
enumerator_t* (*create_file_meas_enumerator)(pts_database_t *this, char *product,
|
|
||||||
int id, pts_meas_algorithms_t algorithm);
|
|
||||||
/**
|
/**
|
||||||
* Get Hash measurement of a file in a folder with given id and hashing algorithm type
|
* Get Hash measurement of a file in a folder with given id and hashing algorithm type
|
||||||
*
|
*
|
||||||
|
* @received_hash measurement of a file to match with database entry
|
||||||
* @product software product (os, vpn client, etc.)
|
* @product software product (os, vpn client, etc.)
|
||||||
* @id primary key in files table
|
* @id primary key in files table
|
||||||
* @file_name path in files table
|
* @file_name path in files table, obligatory for the files in directory
|
||||||
* @algorithm measurement algorithm type
|
* @algorithm measurement algorithm type
|
||||||
|
* @is_dir TRUE if file is requested as content in a directory
|
||||||
* @return enumerator over all measurements matching a given release
|
* @return enumerator over all measurements matching a given release
|
||||||
*/
|
*/
|
||||||
enumerator_t* (*create_dir_meas_enumerator)(pts_database_t *this, char *product,
|
bool (*check_measurement)(pts_database_t *this, chunk_t received_hash,
|
||||||
int id, char *file_name, pts_meas_algorithms_t algorithm);
|
char *product, int id, char *file_name, pts_meas_algorithms_t algorithm, bool is_dir);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -90,7 +73,7 @@ struct pts_database_t {
|
|||||||
/**
|
/**
|
||||||
* Creates an pts_database_t object
|
* Creates an pts_database_t object
|
||||||
*
|
*
|
||||||
* @param ur database uri
|
* @param uri database uri
|
||||||
*/
|
*/
|
||||||
pts_database_t* pts_database_create(char *uri);
|
pts_database_t* pts_database_create(char *uri);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user