Verification of directory contents measurements implemented
This commit is contained in:
committed by
Andreas Steffen
parent
35cd6ec43c
commit
6ef5c05829
@@ -68,6 +68,11 @@ static pts_meas_algorithms_t supported_algorithms = 0;
|
|||||||
*/
|
*/
|
||||||
static pts_database_t *pts_db;
|
static pts_database_t *pts_db;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
*/
|
*/
|
||||||
@@ -248,6 +253,8 @@ 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);
|
||||||
@@ -257,6 +264,7 @@ 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);
|
||||||
}
|
}
|
||||||
enumerator->destroy(enumerator);
|
enumerator->destroy(enumerator);
|
||||||
break;
|
break;
|
||||||
@@ -445,7 +453,10 @@ 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;
|
||||||
|
linked_list_t *files_in_dir_with_meas;
|
||||||
|
|
||||||
|
files_in_dir_with_meas = linked_list_create();
|
||||||
platform_info = pts->get_platform_info(pts);
|
platform_info = pts->get_platform_info(pts);
|
||||||
if (!pts_db || !platform_info)
|
if (!pts_db || !platform_info)
|
||||||
{
|
{
|
||||||
@@ -461,13 +472,38 @@ 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))
|
||||||
|
{
|
||||||
|
DBG1(DBG_IMV, "file entry with request id:%d not found", request_id);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_directory)
|
||||||
|
{
|
||||||
|
requested_files->remove(requested_files, (void*)request_id, NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
enumerator_t *e;
|
||||||
|
char *file;
|
||||||
|
|
||||||
|
e = pts_db->create_files_in_dir_enumerator(pts_db, request_id);
|
||||||
|
while (e->enumerate(e, &file))
|
||||||
|
{
|
||||||
|
files_in_dir_with_meas->insert_last(files_in_dir_with_meas, file);
|
||||||
|
DBG3(DBG_IMV, "expecting measurement for: %s with request_id: %d", file, request_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))
|
||||||
{
|
{
|
||||||
enumerator_t *e;
|
enumerator_t *e;
|
||||||
chunk_t db_measurement;
|
chunk_t db_measurement;
|
||||||
|
|
||||||
e = pts_db->create_meas_enumerator(pts_db,
|
e = (is_directory) ? pts_db->create_dir_meas_enumerator(pts_db,
|
||||||
|
platform_info, request_id, filename, algo) :
|
||||||
|
pts_db->create_file_meas_enumerator(pts_db,
|
||||||
platform_info, request_id, algo);
|
platform_info, request_id, algo);
|
||||||
if (!e)
|
if (!e)
|
||||||
{
|
{
|
||||||
@@ -492,8 +528,20 @@ TNC_Result TNC_IMV_ReceiveMessage(TNC_IMVID imv_id,
|
|||||||
&measurement, filename, &db_measurement);
|
&measurement, filename, &db_measurement);
|
||||||
measurement_error = TRUE;
|
measurement_error = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (is_directory)
|
||||||
|
{
|
||||||
|
files_in_dir_with_meas->remove(files_in_dir_with_meas,
|
||||||
|
filename, (bool (*)(void*,void*))strcmp);
|
||||||
|
}
|
||||||
e->destroy(e);
|
e->destroy(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(is_directory && !files_in_dir_with_meas->get_count(files_in_dir_with_meas))
|
||||||
|
{
|
||||||
|
requested_files->remove(requested_files, (void*)request_id, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
e_meas->destroy(e_meas);
|
e_meas->destroy(e_meas);
|
||||||
attestation_state->set_handshake_state(attestation_state,
|
attestation_state->set_handshake_state(attestation_state,
|
||||||
IMV_ATTESTATION_STATE_END);
|
IMV_ATTESTATION_STATE_END);
|
||||||
@@ -549,8 +597,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)
|
if (measurement_error || requested_files->get_count(requested_files))
|
||||||
{
|
{
|
||||||
|
enumerator_t *e;
|
||||||
|
int request;
|
||||||
|
|
||||||
|
e = requested_files->create_enumerator(requested_files);
|
||||||
|
while (e->enumerate(e, &request))
|
||||||
|
{
|
||||||
|
DBG1(DBG_IMV, "measurement/s not received for requests: %d", request);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|||||||
@@ -54,7 +54,50 @@ METHOD(pts_database_t, create_file_enumerator, enumerator_t*,
|
|||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(pts_database_t, create_meas_enumerator, enumerator_t*,
|
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*,
|
||||||
|
private_pts_database_t *this, int id)
|
||||||
|
{
|
||||||
|
enumerator_t *e;
|
||||||
|
|
||||||
|
/* look for all entries in file_hashes belonging to a same directory*/
|
||||||
|
e = this->db->query(this->db,
|
||||||
|
"SELECT DISTINCT f.path FROM files AS f "
|
||||||
|
"JOIN file_hashes AS fh ON f.id = fh.file "
|
||||||
|
"WHERE fh.directory = ?",
|
||||||
|
DB_INT, id, DB_TEXT);
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(pts_database_t, create_file_meas_enumerator, enumerator_t*,
|
||||||
private_pts_database_t *this, char *product, int id, pts_meas_algorithms_t algorithm)
|
private_pts_database_t *this, char *product, int id, pts_meas_algorithms_t algorithm)
|
||||||
{
|
{
|
||||||
enumerator_t *e;
|
enumerator_t *e;
|
||||||
@@ -69,6 +112,21 @@ METHOD(pts_database_t, create_meas_enumerator, enumerator_t*,
|
|||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
{
|
{
|
||||||
@@ -86,7 +144,10 @@ 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,
|
||||||
.create_meas_enumerator = _create_meas_enumerator,
|
.is_directory = _is_directory,
|
||||||
|
.create_files_in_dir_enumerator = _create_files_in_dir_enumerator,
|
||||||
|
.create_file_meas_enumerator = _create_file_meas_enumerator,
|
||||||
|
.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),
|
||||||
|
|||||||
@@ -32,27 +32,57 @@ typedef struct pts_database_t pts_database_t;
|
|||||||
*/
|
*/
|
||||||
struct pts_database_t {
|
struct pts_database_t {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get files to be measured by PTS
|
* Get files to be measured by PTS
|
||||||
*
|
*
|
||||||
* @product software product (os, vpn client, etc.)
|
* @product software product (os, vpn client, etc.)
|
||||||
* @return enumerator over all files matching a given release
|
* @return enumerator over all files matching a given release
|
||||||
*/
|
*/
|
||||||
enumerator_t* (*create_file_enumerator)(pts_database_t *this, char *product);
|
enumerator_t* (*create_file_enumerator)(pts_database_t *this, char *product);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get Hash measurement of a file with given id and hashing algorithm type
|
* Get if file with given id is directory
|
||||||
*
|
*
|
||||||
* @product software product (os, vpn client, etc.)
|
* @id primary key in files table
|
||||||
* @id primary key in files table
|
* @is_directory TRUE if entry with given ID has type of directory
|
||||||
* @algorithm measurement algorithm type
|
* @return TRUE if query is not failed
|
||||||
* @return enumerator over all measurements matching a given release
|
*/
|
||||||
*/
|
bool (*is_directory)(pts_database_t *this, int id, bool *is_directory);
|
||||||
enumerator_t* (*create_meas_enumerator)(pts_database_t *this, char *product, int id, pts_meas_algorithms_t algorithm);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destroys a pts_database_t object.
|
* Get Enumerator over files in a given directory with measurements
|
||||||
*/
|
*
|
||||||
|
* @id primary key in files table, directory column in file_hashes table
|
||||||
|
* @return enumerator over all measurements matching a given release
|
||||||
|
*/
|
||||||
|
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
|
||||||
|
*
|
||||||
|
* @product software product (os, vpn client, etc.)
|
||||||
|
* @id primary key in files table
|
||||||
|
* @file_name path in files table
|
||||||
|
* @algorithm measurement algorithm type
|
||||||
|
* @return enumerator over all measurements matching a given release
|
||||||
|
*/
|
||||||
|
enumerator_t* (*create_dir_meas_enumerator)(pts_database_t *this, char *product,
|
||||||
|
int id, char *file_name, pts_meas_algorithms_t algorithm);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroys a pts_database_t object.
|
||||||
|
*/
|
||||||
void (*destroy)(pts_database_t *this);
|
void (*destroy)(pts_database_t *this);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user