ipsec attest lists data stored in an attestation database
authorAndreas Steffen <andreas.steffen@strongswan.org>
Fri, 28 Oct 2011 20:46:28 +0000 (22:46 +0200)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Mon, 28 Nov 2011 13:39:52 +0000 (14:39 +0100)
src/libimcv/plugins/imv_attestation/Makefile.am
src/libimcv/plugins/imv_attestation/attest [new file with mode: 0755]
src/libimcv/plugins/imv_attestation/attest.c [new file with mode: 0644]
src/libimcv/plugins/imv_attestation/attest_usage.c [new file with mode: 0644]
src/libimcv/plugins/imv_attestation/attest_usage.h [new file with mode: 0644]

index c6eb46d..59ce5ff 100644 (file)
@@ -17,3 +17,7 @@ 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_LDADD = $(top_builddir)/src/libstrongswan/libstrongswan.la
+attest.o :     $(top_builddir)/config.status
diff --git a/src/libimcv/plugins/imv_attestation/attest b/src/libimcv/plugins/imv_attestation/attest
new file mode 100755 (executable)
index 0000000..5f5393e
--- /dev/null
@@ -0,0 +1,225 @@
+#! /bin/bash
+
+# attest - temporary wrapper script for .libs/attest
+# Generated by libtool (GNU libtool) 2.4 Debian-2.4-2ubuntu1
+#
+# The attest program cannot be directly executed until all the libtool
+# libraries that it depends on are installed.
+#
+# This wrapper script should never be moved out of the build directory.
+# If it is, it will not operate correctly.
+
+# Sed substitution that helps us do robust quoting.  It backslashifies
+# metacharacters that are still active within double-quoted strings.
+sed_quote_subst='s/\([`"$\\]\)/\\\1/g'
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+  setopt NO_GLOB_SUBST
+else
+  case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
+fi
+BIN_SH=xpg4; export BIN_SH # for Tru64
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+relink_command="(cd /home/andi/pts-binding/src/libimcv/plugins/imv_attestation; { test -z \"\${LIBRARY_PATH+set}\" || unset LIBRARY_PATH || { LIBRARY_PATH=; export LIBRARY_PATH; }; }; { test -z \"\${COMPILER_PATH+set}\" || unset COMPILER_PATH || { COMPILER_PATH=; export COMPILER_PATH; }; }; { test -z \"\${GCC_EXEC_PREFIX+set}\" || unset GCC_EXEC_PREFIX || { GCC_EXEC_PREFIX=; export GCC_EXEC_PREFIX; }; }; { test -z \"\${LD_RUN_PATH+set}\" || unset LD_RUN_PATH || { LD_RUN_PATH=; export LD_RUN_PATH; }; }; { test -z \"\${LD_LIBRARY_PATH+set}\" || unset LD_LIBRARY_PATH || { LD_LIBRARY_PATH=; export LD_LIBRARY_PATH; }; }; PATH=/home/andi/bin:/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games; export PATH; gcc -rdynamic -g -O2 -Wall -Wno-format -Wno-pointer-sign -o \$progdir/\$file attest.o attest_usage.o  ../../../../src/libstrongswan/.libs/libstrongswan.so -Wl,-rpath -Wl,/home/andi/pts-binding/src/libstrongswan/.libs -Wl,-rpath -Wl,/usr/lib/ipsec)"
+
+# This environment variable determines our operation mode.
+if test "$libtool_install_magic" = "%%%MAGIC variable%%%"; then
+  # install mode needs the following variables:
+  generated_by_libtool_version='2.4'
+  notinst_deplibs=' ../../../../src/libstrongswan/libstrongswan.la'
+else
+  # When we are sourced in execute mode, $file and $ECHO are already set.
+  if test "$libtool_execute_magic" != "%%%MAGIC variable%%%"; then
+    file="$0"
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+  eval 'cat <<_LTECHO_EOF
+$1
+_LTECHO_EOF'
+}
+    ECHO="printf %s\\n"
+  fi
+
+# Very basic option parsing. These options are (a) specific to
+# the libtool wrapper, (b) are identical between the wrapper
+# /script/ and the wrapper /executable/ which is used only on
+# windows platforms, and (c) all begin with the string --lt-
+# (application programs are unlikely to have options which match
+# this pattern).
+#
+# There are only two supported options: --lt-debug and
+# --lt-dump-script. There is, deliberately, no --lt-help.
+#
+# The first argument to this parsing function should be the
+# script's ../../../../libtool value, followed by no.
+lt_option_debug=
+func_parse_lt_options ()
+{
+  lt_script_arg0=$0
+  shift
+  for lt_opt
+  do
+    case "$lt_opt" in
+    --lt-debug) lt_option_debug=1 ;;
+    --lt-dump-script)
+        lt_dump_D=`$ECHO "X$lt_script_arg0" | /bin/sed -e 's/^X//' -e 's%/[^/]*$%%'`
+        test "X$lt_dump_D" = "X$lt_script_arg0" && lt_dump_D=.
+        lt_dump_F=`$ECHO "X$lt_script_arg0" | /bin/sed -e 's/^X//' -e 's%^.*/%%'`
+        cat "$lt_dump_D/$lt_dump_F"
+        exit 0
+      ;;
+    --lt-*)
+        $ECHO "Unrecognized --lt- option: '$lt_opt'" 1>&2
+        exit 1
+      ;;
+    esac
+  done
+
+  # Print the debug banner immediately:
+  if test -n "$lt_option_debug"; then
+    echo "attest:attest:${LINENO}: libtool wrapper (GNU libtool) 2.4 Debian-2.4-2ubuntu1" 1>&2
+  fi
+}
+
+# Used when --lt-debug. Prints its arguments to stdout
+# (redirection is the responsibility of the caller)
+func_lt_dump_args ()
+{
+  lt_dump_args_N=1;
+  for lt_arg
+  do
+    $ECHO "attest:attest:${LINENO}: newargv[$lt_dump_args_N]: $lt_arg"
+    lt_dump_args_N=`expr $lt_dump_args_N + 1`
+  done
+}
+
+# Core function for launching the target application
+func_exec_program_core ()
+{
+
+      if test -n "$lt_option_debug"; then
+        $ECHO "attest:attest:${LINENO}: newargv[0]: $progdir/$program" 1>&2
+        func_lt_dump_args ${1+"$@"} 1>&2
+      fi
+      exec "$progdir/$program" ${1+"$@"}
+
+      $ECHO "$0: cannot exec $program $*" 1>&2
+      exit 1
+}
+
+# A function to encapsulate launching the target application
+# Strips options in the --lt-* namespace from $@ and
+# launches target application with the remaining arguments.
+func_exec_program ()
+{
+  for lt_wr_arg
+  do
+    case $lt_wr_arg in
+    --lt-*) ;;
+    *) set x "$@" "$lt_wr_arg"; shift;;
+    esac
+    shift
+  done
+  func_exec_program_core ${1+"$@"}
+}
+
+  # Parse options
+  func_parse_lt_options "$0" ${1+"$@"}
+
+  # Find the directory that this script lives in.
+  thisdir=`$ECHO "$file" | /bin/sed 's%/[^/]*$%%'`
+  test "x$thisdir" = "x$file" && thisdir=.
+
+  # Follow symbolic links until we get to the real thisdir.
+  file=`ls -ld "$file" | /bin/sed -n 's/.*-> //p'`
+  while test -n "$file"; do
+    destdir=`$ECHO "$file" | /bin/sed 's%/[^/]*$%%'`
+
+    # If there was a directory component, then change thisdir.
+    if test "x$destdir" != "x$file"; then
+      case "$destdir" in
+      [\\/]* | [A-Za-z]:[\\/]*) thisdir="$destdir" ;;
+      *) thisdir="$thisdir/$destdir" ;;
+      esac
+    fi
+
+    file=`$ECHO "$file" | /bin/sed 's%^.*/%%'`
+    file=`ls -ld "$thisdir/$file" | /bin/sed -n 's/.*-> //p'`
+  done
+
+  # Usually 'no', except on cygwin/mingw when embedded into
+  # the cwrapper.
+  WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=no
+  if test "$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR" = "yes"; then
+    # special case for '.'
+    if test "$thisdir" = "."; then
+      thisdir=`pwd`
+    fi
+    # remove .libs from thisdir
+    case "$thisdir" in
+    *[\\/].libs ) thisdir=`$ECHO "$thisdir" | /bin/sed 's%[\\/][^\\/]*$%%'` ;;
+    .libs )   thisdir=. ;;
+    esac
+  fi
+
+  # Try to get the absolute directory name.
+  absdir=`cd "$thisdir" && pwd`
+  test -n "$absdir" && thisdir="$absdir"
+
+  program=lt-'attest'
+  progdir="$thisdir/.libs"
+
+  if test ! -f "$progdir/$program" ||
+     { file=`ls -1dt "$progdir/$program" "$progdir/../$program" 2>/dev/null | /bin/sed 1q`; \
+       test "X$file" != "X$progdir/$program"; }; then
+
+    file="$$-$program"
+
+    if test ! -d "$progdir"; then
+      mkdir "$progdir"
+    else
+      rm -f "$progdir/$file"
+    fi
+
+    # relink executable if necessary
+    if test -n "$relink_command"; then
+      if relink_command_output=`eval $relink_command 2>&1`; then :
+      else
+       printf %s\n "$relink_command_output" >&2
+       rm -f "$progdir/$file"
+       exit 1
+      fi
+    fi
+
+    mv -f "$progdir/$file" "$progdir/$program" 2>/dev/null ||
+    { rm -f "$progdir/$program";
+      mv -f "$progdir/$file" "$progdir/$program"; }
+    rm -f "$progdir/$file"
+  fi
+
+  if test -f "$progdir/$program"; then
+    if test "$libtool_execute_magic" != "%%%MAGIC variable%%%"; then
+      # Run the actual program with our arguments.
+      func_exec_program ${1+"$@"}
+    fi
+  else
+    # The program doesn't exist.
+    $ECHO "$0: error: \`$progdir/$program' does not exist" 1>&2
+    $ECHO "This script is just a wrapper for $program." 1>&2
+    $ECHO "See the libtool documentation for more information." 1>&2
+    exit 1
+  fi
+fi
diff --git a/src/libimcv/plugins/imv_attestation/attest.c b/src/libimcv/plugins/imv_attestation/attest.c
new file mode 100644 (file)
index 0000000..f2b2eb5
--- /dev/null
@@ -0,0 +1,307 @@
+/*
+ * 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.
+ */
+
+#define _GNU_SOURCE
+#include <getopt.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#include <debug.h>
+#include <library.h>
+
+#include "attest_usage.h"
+
+/**
+ * global database handle
+ */
+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 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);
+               }
+       }
+}
+
+/**
+ * atexit handler to close db on shutdown
+ */
+static void cleanup(void)
+{
+       db->destroy(db);
+}
+
+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;
+
+       /* reinit getopt state */
+       optind = 0;
+
+       while (TRUE)
+       {
+               int c;
+
+               struct option long_opts[] = {
+                       { "help", no_argument, NULL, 'h' },
+                       { "files", no_argument, NULL, 'f' },
+                       { "products", no_argument, NULL, 'p' },
+                       { "file", required_argument, NULL, 'F' },
+                       { "product", required_argument, NULL, 'P' },
+                       { "fid", required_argument, NULL, '1' },
+                       { "pid", required_argument, NULL, '2' },
+                       { 0,0,0,0 }
+               };
+
+               c = getopt_long(argc, argv, "", long_opts, NULL);
+               switch (c)
+               {
+                       case EOF:
+                               break;
+                       case 'h':
+                               operation = OP_USAGE;
+                               break;
+                       case 'f':
+                               operation = OP_FILES;
+                               continue;
+                       case 'p':
+                               operation = OP_PRODUCTS;
+                               continue;
+                       case 'F':
+                               file = optarg;
+                               continue;
+                       case 'P':
+                               product = optarg;
+                               continue;
+                       case '1':
+                               fid = atoi(optarg);
+                               continue;
+                       case '2':
+                               pid = atoi(optarg);
+                               continue;
+               }
+               break;
+       }
+
+       switch (operation)
+       {
+               case OP_USAGE:
+                       usage();
+                       break;
+               case OP_PRODUCTS:
+                       list_products(file, fid);
+                       break;
+               case OP_FILES:
+                       list_files(product, pid);
+                       break;
+               default:
+                       usage();
+                       exit(EXIT_FAILURE);
+       }
+}
+
+int main(int argc, char *argv[])
+{
+       char *uri;
+
+       atexit(library_deinit);
+
+       /* initialize library */
+       if (!library_init(NULL))
+       {
+               exit(SS_RC_LIBSTRONGSWAN_INTEGRITY);
+       }
+       if (!lib->plugins->load(lib->plugins, NULL,
+                       lib->settings->get_str(lib->settings, "attest.load", "sqlite")))
+       {
+               exit(SS_RC_INITIALIZATION_FAILED);
+       }
+
+       uri = lib->settings->get_str(lib->settings, "attest.database", NULL);
+       if (!uri)
+       {
+               fprintf(stderr, "database URI attest.database not set.\n");
+               exit(SS_RC_INITIALIZATION_FAILED);
+       }
+       db = lib->db->create(lib->db, uri);
+       if (!db)
+       {
+               fprintf(stderr, "opening database failed.\n");
+               exit(SS_RC_INITIALIZATION_FAILED);
+       }
+       atexit(cleanup);
+
+       do_args(argc, argv);
+
+       exit(EXIT_SUCCESS);
+}
+
diff --git a/src/libimcv/plugins/imv_attestation/attest_usage.c b/src/libimcv/plugins/imv_attestation/attest_usage.c
new file mode 100644 (file)
index 0000000..9775c95
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Copyright (C) 2009-2010 Andreas Steffen
+ * 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 <stdio.h>
+
+/**
+ * print attest usage info
+ */
+void usage(void)
+{
+       printf("\
+Usage:\n\
+  ipsec attest --files|--products [options]\n\
+  \n\
+  ipsec attest --files [--product <name>|--pid <id>]\n\
+    Show a list of supported files with a sofware product name or\n\
+    its primary key as a selector.\n\
+  \n\
+  ipsec attest --products [--file <path>|--fid <id>]\n\
+    Show a list of software products with a file path or\n\
+    its primary key as a selector.\n\
+   \n");
+}
+
diff --git a/src/libimcv/plugins/imv_attestation/attest_usage.h b/src/libimcv/plugins/imv_attestation/attest_usage.h
new file mode 100644 (file)
index 0000000..bce801e
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+
+#ifndef ATTEST_USAGE_H_
+#define ATTEST_USAGE_H_
+
+/**
+ * print attest usage info
+ */
+void usage(void);
+
+
+#endif /* ATTEST_USAGE_H_ */