list file measurement hashes
[strongswan.git] / src / libimcv / plugins / imv_attestation / attest.c
index f2b2eb5..81807b2 100644 (file)
 #include <string.h>
 #include <errno.h>
 
-#include <debug.h>
 #include <library.h>
 
-#include "attest_usage.h"
-
-/**
- * global database handle
- */
-database_t *db;
+#include <pts/pts_meas_algo.h>
 
-/**
- * forward declarations
- */
-static void do_args(int argc, char *argv[]);
+#include "attest_db.h"
+#include "attest_usage.h"
 
 /**
- * ipsec attest --files - show files
+ * global attestation database object
  */
-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 name FROM products WHERE id = ?",
-                               DB_INT, pid, DB_TEXT);
-               if (e)
-               {
-                       if (e->enumerate(e, &product))
-                       {
-                               product = strdup(product);
-                               e->destroy(e);
-                       }
-                       else
-                       {
-                               printf("no product found with pid %d\n", pid);
-                               e->destroy(e);
-                               return;
-                       }
-               }
-               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":"f", file);
-                       count++;
-               }
-               e->destroy(e);
-
-               printf("%d file%s found", count, (count == 1) ? "" : "s");
-               if (select)
-               {
-                       printf(" for product '%s'", product);
-               }
-               printf("\n");
-               if (pid)
-               {
-                       free(product);
-               }
-       }
-}
-
-/**
- * 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 path FROM files WHERE id = ?",
-                               DB_INT, fid, DB_TEXT);
-               if (e)
-               {
-                       if (e->enumerate(e, &file))
-                       {
-                               file = strdup(file);
-                               e->destroy(e);
-                       }
-                       else
-                       {
-                               printf("no file found with fid %d\n", fid);
-                               e->destroy(e);
-                               return;
-                       }
-               }
-               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");
-               if (fid)
-               {
-                       free(file);
-               }
-       }
-}
+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;
-
        enum {
                OP_UNDEF,
                OP_USAGE,
-               OP_PRODUCTS,
                OP_FILES,
-       } operation = OP_UNDEF;
+               OP_PRODUCTS,
+               OP_HASHES,
+               OP_ADD,
+               OP_DEL,
+       } op = OP_UNDEF;
 
        /* reinit getopt state */
        optind = 0;
@@ -215,10 +63,20 @@ static void do_args(int argc, char *argv[])
                        { "help", no_argument, NULL, 'h' },
                        { "files", no_argument, NULL, 'f' },
                        { "products", no_argument, NULL, 'p' },
+                       { "hashes", no_argument, NULL, 'H' },
+                       { "add", no_argument, NULL, 'a' },
+                       { "delete", no_argument, NULL, 'd' },
+                       { "del", no_argument, NULL, 'd' },
+                       { "directory", required_argument, NULL, 'D' },
+                       { "dir", required_argument, NULL, 'D' },
                        { "file", required_argument, NULL, 'F' },
                        { "product", required_argument, NULL, 'P' },
-                       { "fid", required_argument, NULL, '1' },
-                       { "pid", required_argument, NULL, '2' },
+                       { "sha1", no_argument, NULL, '1' },
+                       { "sha256", no_argument, NULL, '2' },
+                       { "sha384", no_argument, NULL, '3' },
+                       { "did", required_argument, NULL, '4' },
+                       { "fid", required_argument, NULL, '5' },
+                       { "pid", required_argument, NULL, '6' },
                        { 0,0,0,0 }
                };
 
@@ -228,45 +86,119 @@ static void do_args(int argc, char *argv[])
                        case EOF:
                                break;
                        case 'h':
-                               operation = OP_USAGE;
+                               op = OP_USAGE;
                                break;
                        case 'f':
-                               operation = OP_FILES;
+                               op = OP_FILES;
                                continue;
                        case 'p':
-                               operation = OP_PRODUCTS;
+                               op = OP_PRODUCTS;
+                               continue;
+                       case 'H':
+                               op = OP_HASHES;
+                               continue;
+                       case 'a':
+                               op = OP_ADD;
+                               continue;
+                       case 'd':
+                               op = OP_DEL;
+                               continue;
+                       case 'D':
+                               if (!attest->set_directory(attest, optarg, op == OP_ADD))
+                               {
+                                       exit(EXIT_FAILURE);
+                               }
+                               continue;
+                       case 'H':
+                               operation = OP_HASHES;
                                continue;
                        case 'F':
-                               file = optarg;
+                               if (!attest->set_file(attest, optarg, op == OP_ADD))
+                               {
+                                       exit(EXIT_FAILURE);
+                               }
                                continue;
                        case 'P':
-                               product = optarg;
+                               if (!attest->set_product(attest, optarg, op == OP_ADD))
+                               {
+                                       exit(EXIT_FAILURE);
+                               }
                                continue;
                        case '1':
-                               fid = atoi(optarg);
+                               attest->set_algo(attest, PTS_MEAS_ALGO_SHA1);
                                continue;
                        case '2':
-                               pid = atoi(optarg);
+                               attest->set_algo(attest, PTS_MEAS_ALGO_SHA256);
+                               continue;
+                       case '3':
+                               attest->set_algo(attest, PTS_MEAS_ALGO_SHA384);
+                               continue;
+                       case '4':
+                               if (!attest->set_did(attest, atoi(optarg)))
+                               {
+                                       exit(EXIT_FAILURE);
+                               }
+                               continue;
+                       case '5':
+                               if (!attest->set_fid(attest, atoi(optarg)))
+                               {
+                                       exit(EXIT_FAILURE);
+                               }
+                               continue;
+                       case '6':
+                               if (!attest->set_pid(attest, atoi(optarg)))
+                               {
+                                       exit(EXIT_FAILURE);
+                               }
                                continue;
                }
                break;
        }
 
-       switch (operation)
+       switch (op)
        {
                case OP_USAGE:
                        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:
+                       attest->list_hashes(attest);
+                       break;
+               case OP_ADD:
+                       attest->add(attest);
+                       break;
+               case OP_DEL:
+                       attest->delete(attest);
+                       break;
+               case OP_HASHES:
+                       if ((!product || *product == '\0') && (!file || *file == '\0'))
+                       {
+                               list_hashes(algo);
+                       }
+                       else
+                       {
+                               list_hashes_for_product(algo, product, pid);
+                       }
                        break;
                default:
                        usage();
                        exit(EXIT_FAILURE);
        }
+
+       if (fid)
+       {
+               free(file);
+       }
+       if (pid)
+       {
+               free(product);
+       }
+
 }
 
 int main(int argc, char *argv[])
@@ -292,10 +224,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);