Verification of directory contents measurements implemented
authorSansar Choinyambuu <schoinya@hsr.ch>
Mon, 5 Sep 2011 15:52:31 +0000 (17:52 +0200)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Thu, 8 Sep 2011 10:08:17 +0000 (12:08 +0200)
src/libimcv/plugins/imv_attestation/imv_attestation.c
src/libimcv/tcg/pts/pts_database.c
src/libimcv/tcg/pts/pts_database.h

index 4f25d51..0bf705d 100644 (file)
@@ -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);
index ea2fa11..e256dc9 100644 (file)
@@ -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),
index af334d0..d4d595c 100644 (file)
@@ -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);
 
 };