aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/libimcv/plugins/imv_attestation/imv_attestation.c64
-rw-r--r--src/libimcv/tcg/pts/pts_database.c65
-rw-r--r--src/libimcv/tcg/pts/pts_database.h64
3 files changed, 171 insertions, 22 deletions
diff --git a/src/libimcv/plugins/imv_attestation/imv_attestation.c b/src/libimcv/plugins/imv_attestation/imv_attestation.c
index 4f25d51e8..0bf705d54 100644
--- a/src/libimcv/plugins/imv_attestation/imv_attestation.c
+++ b/src/libimcv/plugins/imv_attestation/imv_attestation.c
@@ -69,6 +69,11 @@ static pts_meas_algorithms_t supported_algorithms = 0;
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
*/
TNC_Result TNC_IMV_Initialize(TNC_IMVID imv_id,
@@ -248,6 +253,8 @@ static TNC_Result send_message(TNC_ConnectionID connection_id)
{
break;
}
+
+ requested_files = linked_list_create();
while (enumerator->enumerate(enumerator, &id, &type, &pathname))
{
is_directory = (type != 0);
@@ -257,6 +264,7 @@ static TNC_Result send_message(TNC_ConnectionID connection_id)
delimiter, pathname);
attr->set_noskip_flag(attr, TRUE);
msg->add_attribute(msg, attr);
+ requested_files->insert_last(requested_files, (void*)id);
}
enumerator->destroy(enumerator);
break;
@@ -445,7 +453,10 @@ TNC_Result TNC_IMV_ReceiveMessage(TNC_IMVID imv_id,
chunk_t measurement;
char *platform_info, *filename;
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);
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:",
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);
while (e_meas->enumerate(e_meas, &filename, &measurement))
{
enumerator_t *e;
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);
if (!e)
{
@@ -492,8 +528,20 @@ TNC_Result TNC_IMV_ReceiveMessage(TNC_IMVID imv_id,
&measurement, filename, &db_measurement);
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);
}
+
+ 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);
attestation_state->set_handshake_state(attestation_state,
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) &
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,
TNC_IMV_ACTION_RECOMMENDATION_ISOLATE,
TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MAJOR);
diff --git a/src/libimcv/tcg/pts/pts_database.c b/src/libimcv/tcg/pts/pts_database.c
index ea2fa1192..e256dc99e 100644
--- a/src/libimcv/tcg/pts/pts_database.c
+++ b/src/libimcv/tcg/pts/pts_database.c
@@ -54,7 +54,50 @@ METHOD(pts_database_t, create_file_enumerator, enumerator_t*,
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)
{
enumerator_t *e;
@@ -69,6 +112,21 @@ METHOD(pts_database_t, create_meas_enumerator, enumerator_t*,
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,
private_pts_database_t *this)
{
@@ -86,7 +144,10 @@ pts_database_t *pts_database_create(char *uri)
INIT(this,
.public = {
.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,
},
.db = lib->db->create(lib->db, uri),
diff --git a/src/libimcv/tcg/pts/pts_database.h b/src/libimcv/tcg/pts/pts_database.h
index af334d0e5..d4d595c15 100644
--- a/src/libimcv/tcg/pts/pts_database.h
+++ b/src/libimcv/tcg/pts/pts_database.h
@@ -32,27 +32,57 @@ typedef struct pts_database_t pts_database_t;
*/
struct pts_database_t {
-/**
- * Get files to be measured by PTS
- *
- * @product software product (os, vpn client, etc.)
- * @return enumerator over all files matching a given release
- */
+ /**
+ * Get files to be measured by PTS
+ *
+ * @product software product (os, vpn client, etc.)
+ * @return enumerator over all files matching a given release
+ */
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 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_meas_enumerator)(pts_database_t *this, char *product, int id, pts_meas_algorithms_t algorithm);
+ * 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.
- */
+ * Destroys a pts_database_t object.
+ */
void (*destroy)(pts_database_t *this);
};