aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndreas Steffen <andreas.steffen@strongswan.org>2011-10-30 22:20:20 +0100
committerAndreas Steffen <andreas.steffen@strongswan.org>2011-11-28 14:39:53 +0100
commite881ee23eec13d1a8c35c04d614376ea856fe7da (patch)
treebc8b2d6ada37886b49738a3452766dbea9e0d172 /src
parente4ac6698bd0bc5899f36ce5814f17b2b88d0710b (diff)
downloadstrongswan-e881ee23eec13d1a8c35c04d614376ea856fe7da.tar.bz2
strongswan-e881ee23eec13d1a8c35c04d614376ea856fe7da.tar.xz
refactored attest database tool
Diffstat (limited to 'src')
-rw-r--r--src/libimcv/plugins/imv_attestation/Makefile.am5
-rw-r--r--src/libimcv/plugins/imv_attestation/attest.c442
-rw-r--r--src/libimcv/plugins/imv_attestation/attest_db.c544
-rw-r--r--src/libimcv/plugins/imv_attestation/attest_db.h120
-rw-r--r--src/libimcv/plugins/imv_attestation/attest_usage.c2
5 files changed, 708 insertions, 405 deletions
diff --git a/src/libimcv/plugins/imv_attestation/Makefile.am b/src/libimcv/plugins/imv_attestation/Makefile.am
index d485aa473..ee045dd0e 100644
--- a/src/libimcv/plugins/imv_attestation/Makefile.am
+++ b/src/libimcv/plugins/imv_attestation/Makefile.am
@@ -22,7 +22,10 @@ imv_attestation_la_SOURCES = imv_attestation.c \
imv_attestation_la_LDFLAGS = -module -avoid-version
ipsec_PROGRAMS = attest
-attest_SOURCES = attest.c attest_usage.h attest_usage.c
+attest_SOURCES = attest.c \
+ attest_usage.h attest_usage.c \
+ attest_db.h attest_db.c \
+ tables.sql data.sql
attest_LDADD = \
$(top_builddir)/src/libpts/libpts.la \
$(top_builddir)/src/libimcv/libimcv.la \
diff --git a/src/libimcv/plugins/imv_attestation/attest.c b/src/libimcv/plugins/imv_attestation/attest.c
index 8fbfb200b..6b45dafe5 100644
--- a/src/libimcv/plugins/imv_attestation/attest.c
+++ b/src/libimcv/plugins/imv_attestation/attest.c
@@ -20,390 +20,28 @@
#include <string.h>
#include <errno.h>
-#include <debug.h>
#include <library.h>
#include <pts/pts_meas_algo.h>
+#include "attest_db.h"
#include "attest_usage.h"
/**
- * global database handle
+ * global attestation database object
*/
-database_t *db;
-
-/**
- * forward declarations
- */
-static void do_args(int argc, char *argv[]);
-
-/**
- * ipsec attest --files - show files
- */
-static void list_files(char *product, int pid)
-{
- enumerator_t *e;
- char *file;
- bool select = TRUE;
- int fid, is_dir, count = 0;
-
- if (pid)
- {
- e = db->query(db,
- "SELECT f.id, f.type, f.path FROM files AS f "
- "JOIN product_file AS pf ON f.id = pf.file "
- "JOIN products AS p ON p.id = pf.product "
- "WHERE p.id = ? ORDER BY f.path",
- DB_INT, pid, DB_INT, DB_INT, DB_TEXT);
- }
- else if (!product || *product == '\0')
- {
- select = FALSE;
- e = db->query(db,
- "SELECT id, type, path FROM files "
- "ORDER BY path",
- DB_INT, DB_INT, DB_TEXT);
- }
- else
- {
- e = db->query(db,
- "SELECT f.id, f.type, f.path FROM files AS f "
- "JOIN product_file AS pf ON f.id = pf.file "
- "JOIN products AS p ON p.id = pf.product "
- "WHERE p.name = ? ORDER BY f.path",
- DB_TEXT, product, DB_INT, DB_INT, DB_TEXT);
- }
- if (e)
- {
- while (e->enumerate(e, &fid, &is_dir, &file))
- {
- printf("%3d: %s %s\n", fid, is_dir ? "d":" ", file);
- count++;
- }
- e->destroy(e);
-
- printf("%d file%s found", count, (count == 1) ? "" : "s");
- if (select)
- {
- printf(" for product '%s'", product);
- }
- printf("\n");
- }
-}
-
-/**
- * ipsec attest --products - show products
- */
-static void list_products(char *file, int fid)
-{
- enumerator_t *e;
- char *product;
- bool select = TRUE;
- int pid, count = 0;
-
- if (fid)
- {
- e = db->query(db,
- "SELECT p.id, p.name FROM products AS p "
- "JOIN product_file AS pf ON p.id = pf.product "
- "JOIN files AS f ON f.id = pf.file "
- "WHERE f.id = ? ORDER BY p.name",
- DB_INT, fid, DB_INT, DB_TEXT);
- }
- else if (!file || *file == '\0')
- {
- select = FALSE;
- e = db->query(db, "SELECT id, name FROM products "
- "ORDER BY name",
- DB_INT, DB_TEXT);
- }
- else
- {
- e = db->query(db,
- "SELECT p.id, p.name FROM products AS p "
- "JOIN product_file AS pf ON p.id = pf.product "
- "JOIN files AS f ON f.id = pf.file "
- "WHERE f.path = ? ORDER BY p.name",
- DB_TEXT, file, DB_INT, DB_TEXT);
- }
- if (e)
- {
- while (e->enumerate(e, &pid, &product))
- {
- printf("%3d: %s\n", pid, product);
- count++;
- }
- e->destroy(e);
-
- printf("%d product%s found", count, (count == 1) ? "" : "s");
- if (select)
- {
- printf(" for file '%s'", file);
- }
- printf("\n");
- }
-}
-
-/**
- * get the directory if there is one from the files tables
- */
-static void get_directory(int did, char **directory)
-{
- enumerator_t *e;
- char *dir;
-
- free(*directory);
- *directory = strdup("");
-
- if (did)
- {
- e = db->query(db, "SELECT path from files WHERE id = ?",
- DB_INT, did, DB_TEXT);
- if (e)
- {
- if (e->enumerate(e, &dir))
- {
- free(*directory);
- *directory = strdup(dir);
- }
- e->destroy(e);
- }
- }
-}
-
-static bool slash(char *directory, char *file)
-{
- return *file != '/' && directory[max(0, strlen(directory)-1)] != '/';
-}
-
-/**
- * ipsec attest --hashes - show all file measurement hashes
- */
-static void list_hashes(pts_meas_algorithms_t algo)
-{
- enumerator_t *e;
- chunk_t hash;
- char *file, *dir, *product;
- int fid, fid_old = 0, did, did_old = 0, count = 0;
-
- dir = strdup("");
-
- e = db->query(db,
- "SELECT f.id, f.path, p.name, fh.hash, fh.directory "
- "FROM file_hashes AS fh "
- "JOIN files AS f ON f.id = fh.file "
- "JOIN products AS p ON p.id = fh.product "
- "WHERE fh.algo = ? "
- "ORDER BY fh.directory, f.path, p.name",
- DB_INT, algo, DB_INT, DB_TEXT, DB_TEXT, DB_BLOB, DB_INT);
- if (e)
- {
- while (e->enumerate(e, &fid, &file, &product, &hash, &did))
- {
- if (fid != fid_old || did != did_old)
- {
- if (did != did_old)
- {
- get_directory(did, &dir);
- did_old = did;
- }
- printf("%3d: %s%s%s\n", fid,
- dir, slash(dir, file) ? "/" : "", file);
- fid_old = fid;
- }
- printf(" %#B '%s'\n", &hash, product);
- count++;
- }
- e->destroy(e);
-
- printf("%d %N value%s found\n", count, hash_algorithm_names,
- pts_meas_algo_to_hash(algo), (count == 1) ? "" : "s");
- free(dir);
- }
-}
-
-/**
- * ipsec attest --hashes - show file measurement hashes for a given file
- */
-static void list_hashes_for_file(pts_meas_algorithms_t algo, char *file, int fid)
-{
- enumerator_t *e;
- chunk_t hash;
- char *product, *dir;
- int did, count = 0;
-
- dir = strdup("");
-
- if (fid)
- {
- e = db->query(db,
- "SELECT p.name, fh.hash, fh.directory "
- "FROM file_hashes AS fh "
- "JOIN files AS f ON f.id = fh.file "
- "JOIN products AS p ON p.id = fh.product "
- "WHERE fh.algo = ? AND f.id = ? "
- "ORDER BY p.name",
- DB_INT, algo, DB_INT, fid, DB_TEXT, DB_BLOB, DB_INT);
- }
- else
- {
- e = db->query(db,
- "SELECT p.name, fh.hash, fh.directory "
- "FROM file_hashes AS fh "
- "JOIN files AS f ON f.id = fh.file "
- "JOIN products AS p ON p.id = fh.product "
- "WHERE fh.algo = ? AND f.path = ? "
- "ORDER BY p.name",
- DB_INT, algo, DB_TEXT, file, DB_TEXT, DB_BLOB, DB_INT);
- }
- if (e)
- {
- while (e->enumerate(e, &product, &hash, &did))
- {
- printf("%#B '%s'\n", &hash, product);
- count++;
- }
- e->destroy(e);
-
- get_directory(did, &dir);
- printf("%d %N value%s found for file '%s%s%s'\n",
- count, hash_algorithm_names, pts_meas_algo_to_hash(algo),
- (count == 1) ? "" : "s",
- dir, slash(dir, file) ? "/" : "", file);
- free(dir);
- }
-}
-
-/**
- * ipsec attest --hashes - show file measurement hashes for a given product
- */
-static void list_hashes_for_product(pts_meas_algorithms_t algo,
- char *product, int pid)
-{
- enumerator_t *e;
- chunk_t hash;
- char *file, *dir;
- int fid, fid_old = 0, did, did_old = 0, count = 0;
-
- dir = strdup("");
-
- if (pid)
- {
- e = db->query(db,
- "SELECT f.id, f. f.path, fh.hash, fh.directory "
- "FROM file_hashes AS fh "
- "JOIN files AS f ON f.id = fh.file "
- "JOIN products AS p ON p.id = fh.product "
- "WHERE fh.algo = ? AND p.id = ? "
- "ORDER BY fh.directory, f.path",
- DB_INT, algo, DB_INT, pid, DB_INT, DB_TEXT, DB_BLOB, DB_INT);
- }
- else
- {
- e = db->query(db,
- "SELECT f.id, f.path, fh.hash, fh.directory "
- "FROM file_hashes AS fh "
- "JOIN files AS f ON f.id = fh.file "
- "JOIN products AS p ON p.id = fh.product "
- "WHERE fh.algo = ? AND p.name = ? "
- "ORDER BY fh.directory, f.path",
- DB_INT, algo, DB_TEXT, product, DB_INT, DB_TEXT, DB_BLOB, DB_INT);
- }
- if (e)
- {
- while (e->enumerate(e, &fid, &file, &hash, &did))
- {
- if (fid != fid_old || did != did_old)
- {
- if (did != did_old)
- {
- get_directory(did, &dir);
- }
- printf("%3d: %s%s%s\n", fid,
- dir, slash(dir, file) ? "/" : "", file);
- fid_old = fid;
- did_old = did;
- }
- printf(" %#B\n", &hash);
- count++;
- }
- e->destroy(e);
-
- printf("%d %N value%s found for product '%s'\n",
- count, hash_algorithm_names, pts_meas_algo_to_hash(algo),
- (count == 1) ? "" : "s", product);
- free(dir);
- }
-}
-
-/**
- * find file corresponding to primary key fid
- */
-static bool fid_to_file(int fid, char **file)
-{
- enumerator_t *e;
- bool found = FALSE;
- char *f;
-
- e = db->query(db, "SELECT path FROM files WHERE id = ?",
- DB_INT, fid, DB_TEXT);
- if (e)
- {
- if (e->enumerate(e, &f))
- {
- found = TRUE;
- *file = strdup(f);
- }
- else
- {
- printf("no file found with fid %d\n", fid);
- }
- e->destroy(e);
- }
- return found;
-}
-
-/**
- * find product corresponding to primary key pid
- */
-static bool pid_to_product(int pid, char **product)
-{
- enumerator_t *e;
- bool found = FALSE;
- char *p;
-
- e = db->query(db, "SELECT name FROM products WHERE id = ?",
- DB_INT, pid, DB_TEXT);
- if (e)
- {
- if (e->enumerate(e, &p))
- {
- found = TRUE;
- *product = strdup(p);
- }
- else
- {
- printf("no product found with pid %d\n", pid);
- }
- e->destroy(e);
- }
- return found;
-}
+attest_db_t *attest;
/**
* atexit handler to close db on shutdown
*/
static void cleanup(void)
{
- db->destroy(db);
+ attest->destroy(attest);
}
static void do_args(int argc, char *argv[])
{
- char *product = NULL, *file = NULL;
- int fid = 0, pid = 0;
- pts_meas_algorithms_t algo = PTS_MEAS_ALGO_SHA256;
-
enum {
OP_UNDEF,
OP_USAGE,
@@ -424,13 +62,15 @@ static void do_args(int argc, char *argv[])
{ "files", no_argument, NULL, 'f' },
{ "products", no_argument, NULL, 'p' },
{ "hashes", no_argument, NULL, 'H' },
+ { "directory", required_argument, NULL, 'D' },
{ "file", required_argument, NULL, 'F' },
{ "product", required_argument, NULL, 'P' },
{ "sha1", no_argument, NULL, '1' },
{ "sha256", no_argument, NULL, '2' },
{ "sha384", no_argument, NULL, '3' },
- { "fid", required_argument, NULL, '4' },
- { "pid", required_argument, NULL, '5' },
+ { "did", required_argument, NULL, '4' },
+ { "fid", required_argument, NULL, '5' },
+ { "pid", required_argument, NULL, '6' },
{ 0,0,0,0 }
};
@@ -451,31 +91,47 @@ static void do_args(int argc, char *argv[])
case 'H':
operation = OP_HASHES;
continue;
+ case 'D':
+ if (!attest->set_directory(attest, optarg))
+ {
+ exit(EXIT_FAILURE);
+ }
+ continue;
case 'F':
- file = optarg;
+ if (!attest->set_file(attest, optarg))
+ {
+ exit(EXIT_FAILURE);
+ }
continue;
case 'P':
- product = optarg;
+ if (!attest->set_product(attest, optarg))
+ {
+ exit(EXIT_FAILURE);
+ }
continue;
case '1':
- algo = PTS_MEAS_ALGO_SHA1;
+ attest->set_algo(attest, PTS_MEAS_ALGO_SHA1);
continue;
case '2':
- algo = PTS_MEAS_ALGO_SHA256;
+ attest->set_algo(attest, PTS_MEAS_ALGO_SHA256);
continue;
case '3':
- algo = PTS_MEAS_ALGO_SHA384;
+ attest->set_algo(attest, PTS_MEAS_ALGO_SHA384);
continue;
case '4':
- fid = atoi(optarg);
- if (!fid_to_file(fid, &file))
+ if (!attest->set_did(attest, atoi(optarg)))
{
exit(EXIT_FAILURE);
}
continue;
case '5':
- pid = atoi(optarg);
- if (!pid_to_product(pid, &product))
+ if (!attest->set_fid(attest, atoi(optarg)))
+ {
+ exit(EXIT_FAILURE);
+ }
+ continue;
+ case '6':
+ if (!attest->set_pid(attest, atoi(optarg)))
{
exit(EXIT_FAILURE);
}
@@ -490,39 +146,18 @@ static void do_args(int argc, char *argv[])
usage();
break;
case OP_PRODUCTS:
- list_products(file, fid);
+ attest->list_products(attest);
break;
case OP_FILES:
- list_files(product, pid);
+ attest->list_files(attest);
break;
case OP_HASHES:
- if ((!product || *product == '\0') && (!file || *file == '\0'))
- {
- list_hashes(algo);
- }
- else if (product)
- {
- list_hashes_for_product(algo, product, pid);
- }
- else
- {
- list_hashes_for_file(algo, file, fid);
- }
+ attest->list_hashes(attest);
break;
default:
usage();
exit(EXIT_FAILURE);
}
-
- if (fid)
- {
- free(file);
- }
- if (pid)
- {
- free(product);
- }
-
}
int main(int argc, char *argv[])
@@ -548,10 +183,9 @@ int main(int argc, char *argv[])
fprintf(stderr, "database URI attest.database not set.\n");
exit(SS_RC_INITIALIZATION_FAILED);
}
- db = lib->db->create(lib->db, uri);
- if (!db)
+ attest = attest_db_create(uri);
+ if (!attest)
{
- fprintf(stderr, "opening database failed.\n");
exit(SS_RC_INITIALIZATION_FAILED);
}
atexit(cleanup);
diff --git a/src/libimcv/plugins/imv_attestation/attest_db.c b/src/libimcv/plugins/imv_attestation/attest_db.c
new file mode 100644
index 000000000..107f6e029
--- /dev/null
+++ b/src/libimcv/plugins/imv_attestation/attest_db.c
@@ -0,0 +1,544 @@
+/*
+ * Copyright (C) 2011 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "attest_db.h"
+
+typedef struct private_attest_db_t private_attest_db_t;
+
+/**
+ * Private data of an attest_db_t object.
+ */
+struct private_attest_db_t {
+
+ /**
+ * Public members of attest_db_state_t
+ */
+ attest_db_t public;
+
+ /**
+ * Software product to be queried
+ */
+ char *product;
+
+ /**
+ * Primary key of software product to be queried
+ */
+ int pid;
+
+ /**
+ * TRUE if product has been set
+ */
+ bool product_set;
+
+ /**
+ * Measurement file to be queried
+ */
+ char *file;
+
+ /**
+ * Primary key of measurement file to be queried
+ */
+ int fid;
+
+ /**
+ * TRUE if file has been set
+ */
+ bool file_set;
+
+ /**
+ * Directory containing the Measurement file to be queried
+ */
+ char *dir;
+
+ /**
+ * Primary key of the directory to be queried
+ */
+ int did;
+
+ /**
+ * TRUE if directory has been set
+ */
+ bool dir_set;
+
+ /**
+ * File measurement hash algorithm
+ */
+ pts_meas_algorithms_t algo;
+
+ /**
+ * Attestation database
+ */
+ database_t *db;
+
+};
+
+METHOD(attest_db_t, set_product, bool,
+ private_attest_db_t *this, char *product)
+{
+ enumerator_t *e;
+
+ if (this->product_set)
+ {
+ printf("product has already been set\n");
+ return FALSE;
+ }
+ this->product = strdup(product);
+
+ e = this->db->query(this->db, "SELECT id FROM products WHERE name = ?",
+ DB_TEXT, product, DB_INT);
+ if (e)
+ {
+ if (e->enumerate(e, &this->pid))
+ {
+ this->product_set = TRUE;
+ }
+ else
+ {
+ printf("product '%s' not found in database\n", product);
+ }
+ e->destroy(e);
+ }
+ return this->product_set;
+}
+
+METHOD(attest_db_t, set_pid, bool,
+ private_attest_db_t *this, int pid)
+{
+ enumerator_t *e;
+ char *product;
+
+ if (this->product_set)
+ {
+ printf("product has already been set\n");
+ return FALSE;
+ }
+ this->pid = pid;
+
+ e = this->db->query(this->db, "SELECT name FROM products WHERE id = ?",
+ DB_INT, pid, DB_TEXT);
+ if (e)
+ {
+ if (e->enumerate(e, &product))
+ {
+ this->product = strdup(product);
+ this->product_set = TRUE;
+ }
+ else
+ {
+ printf("no product found with pid %d in database\n", pid);
+ }
+ e->destroy(e);
+ }
+ return this->product_set;
+}
+
+METHOD(attest_db_t, set_file, bool,
+ private_attest_db_t *this, char *file)
+{
+ enumerator_t *e;
+
+ if (this->file_set)
+ {
+ printf("file has already been set\n");
+ return FALSE;
+ }
+ this->file = strdup(file);
+
+ e = this->db->query(this->db, "SELECT id FROM file WHERE path = ?",
+ DB_TEXT, file, DB_INT);
+ if (e)
+ {
+ if (e->enumerate(e, &this->fid))
+ {
+ this->file_set = TRUE;
+ }
+ else
+ {
+ printf("file '%s' not found in database\n", file);
+ }
+ e->destroy(e);
+ }
+ return this->file_set;
+}
+
+METHOD(attest_db_t, set_fid, bool,
+ private_attest_db_t *this, int fid)
+{
+ enumerator_t *e;
+ char *file;
+
+ if (this->product_set)
+ {
+ printf("file has already been set\n");
+ return FALSE;
+ }
+ this->fid = fid;
+
+ e = this->db->query(this->db, "SELECT path FROM files WHERE id = ?",
+ DB_INT, fid, DB_TEXT);
+ if (e)
+ {
+ if (e->enumerate(e, &file))
+ {
+ this->file = strdup(file);
+ this->file_set = TRUE;
+ }
+ else
+ {
+ printf("no file found with fid %d\n", fid);
+ }
+ e->destroy(e);
+ }
+ return this->file_set;
+}
+
+METHOD(attest_db_t, set_directory, bool,
+ private_attest_db_t *this, char *dir)
+{
+ enumerator_t *e;
+
+ if (this->dir_set)
+ {
+ printf("directory has already been set\n");
+ return FALSE;
+ }
+ free(this->dir);
+ this->dir = strdup(dir);
+
+ e = this->db->query(this->db, "SELECT id FROM file WHERE path = ?",
+ DB_TEXT, dir, DB_INT);
+ if (e)
+ {
+ if (e->enumerate(e, &this->did))
+ {
+ this->dir_set = TRUE;
+ }
+ else
+ {
+ printf("directory '%s' not found in database\n", dir);
+ }
+ e->destroy(e);
+ }
+ return this->dir_set;
+}
+
+METHOD(attest_db_t, set_did, bool,
+ private_attest_db_t *this, int did)
+{
+ enumerator_t *e;
+ char *dir;
+
+ if (this->dir_set)
+ {
+ printf("directory has already been set\n");
+ return FALSE;
+ }
+ this->did = did;
+
+ e = this->db->query(this->db, "SELECT path FROM file WHERE id = ?",
+ DB_INT, did, DB_TEXT);
+ if (e)
+ {
+ if (e->enumerate(e, &dir))
+ {
+ free(this->dir);
+ this->dir = strdup(dir);
+ this->dir_set = TRUE;
+ }
+ else
+ {
+ printf("no directory found with did %d\n", did);
+ }
+ e->destroy(e);
+ }
+ return this->dir_set;
+}
+
+METHOD(attest_db_t, set_algo, void,
+ private_attest_db_t *this, pts_meas_algorithms_t algo)
+{
+ this->algo = algo;
+}
+
+METHOD(attest_db_t, list_files, void,
+ private_attest_db_t *this)
+{
+ enumerator_t *e;
+ char *file;
+ int fid, is_dir, count = 0;
+
+ if (this->pid)
+ {
+ e = this->db->query(this->db,
+ "SELECT f.id, f.type, f.path FROM files AS f "
+ "JOIN product_file AS pf ON f.id = pf.file "
+ "JOIN products AS p ON p.id = pf.product "
+ "WHERE p.id = ? ORDER BY f.path",
+ DB_INT, this->pid, DB_INT, DB_INT, DB_TEXT);
+ }
+ else
+ {
+ e = this->db->query(this->db,
+ "SELECT id, type, path FROM files "
+ "ORDER BY path",
+ DB_INT, DB_INT, DB_TEXT);
+ }
+ if (e)
+ {
+ while (e->enumerate(e, &fid, &is_dir, &file))
+ {
+ printf("%3d: %s %s\n", fid, is_dir ? "d":" ", file);
+ count++;
+ }
+ e->destroy(e);
+
+ printf("%d file%s found", count, (count == 1) ? "" : "s");
+ if (this->product)
+ {
+ printf(" for product '%s'", this->product);
+ }
+ printf("\n");
+ }
+}
+
+METHOD(attest_db_t, list_products, void,
+ private_attest_db_t *this)
+{
+ enumerator_t *e;
+ char *product;
+ int pid, count = 0;
+
+ if (this->fid)
+ {
+ e = this->db->query(this->db,
+ "SELECT p.id, p.name FROM products AS p "
+ "JOIN product_file AS pf ON p.id = pf.product "
+ "JOIN files AS f ON f.id = pf.file "
+ "WHERE f.id = ? ORDER BY p.name",
+ DB_INT, this->fid, DB_INT, DB_TEXT);
+ }
+ else
+ {
+ e = this->db->query(this->db, "SELECT id, name FROM products "
+ "ORDER BY name",
+ DB_INT, DB_TEXT);
+ }
+ if (e)
+ {
+ while (e->enumerate(e, &pid, &product))
+ {
+ printf("%3d: %s\n", pid, product);
+ count++;
+ }
+ e->destroy(e);
+
+ printf("%d product%s found", count, (count == 1) ? "" : "s");
+ if (this->file)
+ {
+ printf(" for file '%s'", this->file);
+ }
+ printf("\n");
+ }
+}
+
+/**
+ * get the directory if there is one from the files tables
+ */
+static void get_directory(private_attest_db_t *this, int did, char **directory)
+{
+ enumerator_t *e;
+ char *dir;
+
+ free(*directory);
+ *directory = strdup("");
+
+ if (did)
+ {
+ e = this->db->query(this->db,
+ "SELECT path from files WHERE id = ?",
+ DB_INT, did, DB_TEXT);
+ if (e)
+ {
+ if (e->enumerate(e, &dir))
+ {
+ free(*directory);
+ *directory = strdup(dir);
+ }
+ e->destroy(e);
+ }
+ }
+}
+
+static bool slash(char *directory, char *file)
+{
+ return *file != '/' && directory[max(0, strlen(directory)-1)] != '/';
+}
+
+METHOD(attest_db_t, list_hashes, void,
+ private_attest_db_t *this)
+{
+ enumerator_t *e;
+ chunk_t hash;
+ char *file, *dir, *product;
+ int fid, fid_old = 0, did, did_old = 0, count = 0;
+
+ dir = strdup("");
+
+ if (this->pid)
+ {
+ e = this->db->query(this->db,
+ "SELECT f.id, f. f.path, fh.hash, fh.directory "
+ "FROM file_hashes AS fh "
+ "JOIN files AS f ON f.id = fh.file "
+ "JOIN products AS p ON p.id = fh.product "
+ "WHERE fh.algo = ? AND p.id = ? "
+ "ORDER BY fh.directory, f.path",
+ DB_INT, this->algo, DB_INT, this->pid,
+ DB_INT, DB_TEXT, DB_BLOB, DB_INT);
+ if (e)
+ {
+ while (e->enumerate(e, &fid, &file, &hash, &did))
+ {
+ if (fid != fid_old || did != did_old)
+ {
+ if (did != did_old)
+ {
+ get_directory(this, did, &dir);
+ }
+ printf("%3d: %s%s%s\n", fid,
+ dir, slash(dir, file) ? "/" : "", file);
+ fid_old = fid;
+ did_old = did;
+ }
+ printf(" %#B\n", &hash);
+ count++;
+ }
+ e->destroy(e);
+
+ printf("%d %N value%s found for product '%s'\n", count,
+ hash_algorithm_names, pts_meas_algo_to_hash(this->algo),
+ (count == 1) ? "" : "s", this->product);
+ }
+ }
+ else if (this->fid)
+ {
+ e = this->db->query(this->db,
+ "SELECT p.name, fh.hash, fh.directory "
+ "FROM file_hashes AS fh "
+ "JOIN files AS f ON f.id = fh.file "
+ "JOIN products AS p ON p.id = fh.product "
+ "WHERE fh.algo = ? AND f.id = ? "
+ "ORDER BY p.name",
+ DB_INT, this->algo, DB_INT, this->fid,
+ DB_TEXT, DB_BLOB, DB_INT);
+ if (e)
+ {
+ while (e->enumerate(e, &product, &hash, &did))
+ {
+ printf("%#B '%s'\n", &hash, product);
+ count++;
+ }
+ e->destroy(e);
+
+ get_directory(this, did, &dir);
+ printf("%d %N value%s found for file '%s%s%s'\n",
+ count, hash_algorithm_names, pts_meas_algo_to_hash(this->algo),
+ (count == 1) ? "" : "s",
+ dir, slash(dir, this->file) ? "/" : "", this->file);
+ }
+ }
+ else
+ {
+ e = this->db->query(this->db,
+ "SELECT f.id, f.path, p.name, fh.hash, fh.directory "
+ "FROM file_hashes AS fh "
+ "JOIN files AS f ON f.id = fh.file "
+ "JOIN products AS p ON p.id = fh.product "
+ "WHERE fh.algo = ? "
+ "ORDER BY fh.directory, f.path, p.name",
+ DB_INT, this->algo,
+ DB_INT, DB_TEXT, DB_TEXT, DB_BLOB, DB_INT);
+ if (e)
+ {
+ while (e->enumerate(e, &fid, &file, &product, &hash, &did))
+ {
+ if (fid != fid_old || did != did_old)
+ {
+ if (did != did_old)
+ {
+ get_directory(this, did, &dir);
+ did_old = did;
+ }
+ printf("%3d: %s%s%s\n", fid,
+ dir, slash(dir, file) ? "/" : "", file);
+ fid_old = fid;
+ }
+ printf(" %#B '%s'\n", &hash, product);
+ count++;
+ }
+ e->destroy(e);
+
+ printf("%d %N value%s found\n", count, hash_algorithm_names,
+ pts_meas_algo_to_hash(this->algo), (count == 1) ? "" : "s");
+ }
+ }
+ free(dir);
+}
+
+METHOD(attest_db_t, destroy, void,
+ private_attest_db_t *this)
+{
+ DESTROY_IF(this->db);
+ free(this->product);
+ free(this->file);
+ free(this->dir);
+ free(this);
+}
+
+/**
+ * Described in header.
+ */
+attest_db_t *attest_db_create(char *uri)
+{
+ private_attest_db_t *this;
+
+ INIT(this,
+ .public = {
+ .set_product = _set_product,
+ .set_pid = _set_pid,
+ .set_file = _set_file,
+ .set_fid = _set_fid,
+ .set_directory = _set_directory,
+ .set_did = _set_did,
+ .set_algo = _set_algo,
+ .list_products = _list_products,
+ .list_files = _list_files,
+ .list_hashes = _list_hashes,
+ .destroy = _destroy,
+ },
+ .dir = strdup(""),
+ .algo = PTS_MEAS_ALGO_SHA256,
+ .db = lib->db->create(lib->db, uri),
+ );
+
+ if (!this->db)
+ {
+ fprintf(stderr, "opening database failed.\n");
+ destroy(this);
+ return NULL;
+ }
+
+ return &this->public;
+}
diff --git a/src/libimcv/plugins/imv_attestation/attest_db.h b/src/libimcv/plugins/imv_attestation/attest_db.h
new file mode 100644
index 000000000..9c6ba1ab2
--- /dev/null
+++ b/src/libimcv/plugins/imv_attestation/attest_db.h
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2011 Andreas Steffen
+ * HSR Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+/**
+ *
+ * @defgroup attest_db_t attest_db
+ * @{ @ingroup attest_db
+ */
+
+#ifndef ATTEST_DB_H_
+#define ATTEST_DB_H_
+
+#include <pts/pts_meas_algo.h>
+
+#include <library.h>
+
+typedef struct attest_db_t attest_db_t;
+
+/**
+ * Attestation database object
+ */
+struct attest_db_t {
+
+ /**
+ * Set software product to be queried
+ *
+ * @param product software product
+ * @return TRUE if successful
+ */
+ bool (*set_product)(attest_db_t *this, char *product);
+
+ /**
+ * Set primary key of the software product to be queried
+ *
+ * @param pid primary key of software product
+ * @return TRUE if successful
+ */
+ bool (*set_pid)(attest_db_t *this, int pid);
+
+ /**
+ * Set measurement file to be queried
+ *
+ * @param file measurement file
+ * @return TRUE if successful
+ */
+ bool (*set_file)(attest_db_t *this, char *file);
+
+ /**
+ * Set primary key of the measurement file to be queried
+ *
+ * @param fid primary key of measurement file
+ * @return TRUE if successful
+ */
+ bool (*set_fid)(attest_db_t *this, int fid);
+
+ /**
+ * Set directory of the measurement file to be queried
+ *
+ * @param directory directory containing the measurement file
+ * @return TRUE if successful
+ */
+ bool (*set_directory)(attest_db_t *this, char *dir);
+
+ /**
+ * Set primary key of the directory to be queried
+ *
+ * @param did primary key of directory
+ * @return TRUE if successful
+ */
+ bool (*set_did)(attest_db_t *this, int did);
+
+ /**
+ * Set measurement hash algorithm
+ *
+ * @param algo hash algorithm
+ */
+ void (*set_algo)(attest_db_t *this, pts_meas_algorithms_t algo);
+
+ /**
+ * List all products stored in the database
+ */
+ void (*list_products)(attest_db_t *this);
+
+ /**
+ * List selected files stored in the database
+ */
+ void (*list_files)(attest_db_t *this);
+
+ /**
+ * List selected measurement hashes stored in the database
+ */
+ void (*list_hashes)(attest_db_t *this);
+
+ /**
+ * Destroy attest_db_t object
+ */
+ void (*destroy)(attest_db_t *this);
+
+};
+
+/**
+ * Create an attest_db_t instance
+ *
+ * @param uri database URI
+ */
+attest_db_t* attest_db_create(char *uri);
+
+#endif /** ATTEST_DB_H_ @}*/
diff --git a/src/libimcv/plugins/imv_attestation/attest_usage.c b/src/libimcv/plugins/imv_attestation/attest_usage.c
index 61cffb988..32d175483 100644
--- a/src/libimcv/plugins/imv_attestation/attest_usage.c
+++ b/src/libimcv/plugins/imv_attestation/attest_usage.c
@@ -15,6 +15,8 @@
#include <stdio.h>
+#include "attest_usage.h"
+
/**
* print attest usage info
*/