From: Andreas Steffen Date: Sun, 4 Nov 2012 08:25:31 +0000 (+0100) Subject: created pacman - an Ubuntu/Debian package manager X-Git-Tag: 5.0.2dr4~243 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=d79ec8e9116cc3f425f2b72a0f2165f7ce80b538;p=thirdparty%2Fstrongswan.git created pacman - an Ubuntu/Debian package manager --- diff --git a/src/libimcv/plugins/imv_os/Makefile.am b/src/libimcv/plugins/imv_os/Makefile.am index a01ec1ba2c..195c458bc0 100644 --- a/src/libimcv/plugins/imv_os/Makefile.am +++ b/src/libimcv/plugins/imv_os/Makefile.am @@ -13,3 +13,8 @@ imv_os_la_SOURCES = imv_os.c imv_os_state.h imv_os_state.c imv_os_la_LDFLAGS = -module -avoid-version +ipsec_PROGRAMS = pacman +pacman_SOURCES = pacman.c +pacman_LDADD = $(top_builddir)/src/libstrongswan/libstrongswan.la +pacman.o : $(top_builddir)/config.status + diff --git a/src/libimcv/plugins/imv_os/pacman b/src/libimcv/plugins/imv_os/pacman new file mode 100755 index 0000000000..c9b89f2311 --- /dev/null +++ b/src/libimcv/plugins/imv_os/pacman @@ -0,0 +1,228 @@ +#! /bin/bash + +# pacman - temporary wrapper script for .libs/pacman +# Generated by libtool (GNU libtool) 2.4.2 Debian-2.4.2-1ubuntu1 +# +# The pacman 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/strongswan/src/libimcv/plugins/imv_os; { 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 -include /home/andi/strongswan/config.h -o \$progdir/\$file pacman.o ../../../../src/libstrongswan/.libs/libstrongswan.so -Wl,-rpath -Wl,/home/andi/strongswan/src/libstrongswan/.libs)" + +# 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.2' + 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 "pacman:pacman:${LINENO}: libtool wrapper (GNU libtool) 2.4.2 Debian-2.4.2-1ubuntu1" 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 "pacman:pacman:${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 "pacman:pacman:${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 () +{ + case " $* " in + *\ --lt-*) + for lt_wr_arg + do + case $lt_wr_arg in + --lt-*) ;; + *) set x "$@" "$lt_wr_arg"; shift;; + esac + shift + done ;; + esac + 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-'pacman' + 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_os/pacman.c b/src/libimcv/plugins/imv_os/pacman.c new file mode 100644 index 0000000000..7a3a53c682 --- /dev/null +++ b/src/libimcv/plugins/imv_os/pacman.c @@ -0,0 +1,356 @@ +/* + * Copyright (C) 2012 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 . + * + * 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 +#include +#include +#include +#include +#include + +#include +#include + +/** + * global debug output variables + */ +static int debug_level = 1; +static bool stderr_quiet = TRUE; + +/** + * pacman dbg function + */ +static void pacman_dbg(debug_t group, level_t level, char *fmt, ...) +{ + int priority = LOG_INFO; + char buffer[8192]; + char *current = buffer, *next; + va_list args; + + if (level <= debug_level) + { + if (!stderr_quiet) + { + va_start(args, fmt); + vfprintf(stderr, fmt, args); + fprintf(stderr, "\n"); + va_end(args); + } + + /* write in memory buffer first */ + va_start(args, fmt); + vsnprintf(buffer, sizeof(buffer), fmt, args); + va_end(args); + + /* do a syslog with every line */ + while (current) + { + next = strchr(current, '\n'); + if (next) + { + *(next++) = '\0'; + } + syslog(priority, "%s\n", current); + current = next; + } + } +} + +/** + * atexit handler to close everything on shutdown + */ +static void cleanup(void) +{ + closelog(); + library_deinit(); +} + +static void usage(void) +{ + printf("Usage:\n" + "ipsec pacman --file --package \n"); +} + +/** + * Process a package file and store updates in the database + */ +static void process_packages(char *filename, char *product) +{ + char *uri, line[1024], *pos; + int count = 0, errored = 0, vulnerable = 0; + int new_packages = 0, new_versions = 0, updates = 0, reverted = 0; + u_int32_t pid = 0; + enumerator_t *e; + database_t *db; + FILE *file; + + /* opening package file */ + printf("loading\"%s\"\n", filename); + file = fopen(filename, "r"); + if (!file) + { + fprintf(stderr, "could not open \"%s\"", filename); + exit(EXIT_FAILURE); + } + + /* connect package database */ + uri = lib->settings->get_str(lib->settings, "pacman.database", NULL); + if (!uri) + { + fprintf(stderr, "database URI pacman.database not set\n"); + fclose(file); + exit(EXIT_FAILURE); + } + db = lib->db->create(lib->db, uri); + if (!db) + { + fprintf(stderr, "could not connect to database '%s'\n", uri); + fclose(file); + exit(EXIT_FAILURE); + } + + /* check if product is already in database */ + e = db->query(db, "SELECT id FROM products WHERE name = ?", + DB_TEXT, product, DB_INT); + if (e) + { + if (!e->enumerate(e, &pid)) + { + pid = 0; + } + e->destroy(e); + } + if (!pid) + { + if (db->execute(db, &pid, "INSERT INTO products (name) VALUES (?)", + DB_TEXT, product) != 1) + { + fprintf(stderr, "could not store product '%s' to database\n", + product); + fclose(file); + db->destroy(db); + exit(EXIT_FAILURE); + } + } + + while (fgets(line, sizeof(line), file)) + { + char *package, *version; + bool security; + int current_security; + u_int32_t gid = 0, vid = 0; + + count++; + if (count == 1 || count == 3) + { + printf("%s", line); + } + if (count < 7) + { + continue; + } + + /* look for the package name */ + pos = strchr(line, ' '); + if (!pos) + { + fprintf(stderr, "could not extract package name from '%.*s'", + strlen(line)-1, line); + errored++; + continue; + } + *pos++ = '\0'; + package = line; + version = ""; + + /* check if package is already in database */ + e = db->query(db, "SELECT id FROM packages WHERE name = ?", + DB_TEXT, package, DB_INT); + if (e) + { + if (!e->enumerate(e, &gid)) + { + gid = 0; + } + e->destroy(e); + } + if (!gid) + { + if (db->execute(db, &gid, "INSERT INTO packages (name) VALUES (?)", + DB_TEXT, package) != 1) + { + fprintf(stderr, "could not store package '%s' to database\n", + package); + fclose(file); + db->destroy(db); + exit(EXIT_FAILURE); + } + new_packages++; + } + + /* look for version string in parentheses */ + if (*pos == '(') + { + version = ++pos; + pos = strchr(pos, ')'); + if (pos) + { + *pos++ = '\0'; + } + else + { + fprintf(stderr, "could not extract package version from '%.*s'", + strlen(line)-1, line); + errored++; + continue; + } + } + security = (strstr(pos, "[security]") != NULL); + if (security) + { + vulnerable++; + } + + /* check if version is already in database */ + e = db->query(db, "SELECT id, security FROM versions " + "WHERE release = ? AND package = ? AND product = ?", + DB_TEXT, version, DB_INT, pid, DB_INT, gid, + DB_INT, DB_INT); + if (e) + { + if (!e->enumerate(e, &vid, ¤t_security)) + { + vid = 0; + } + e->destroy(e); + } + if (!vid) + { + if (db->execute(db, &gid, + "INSERT INTO versions (package, product, release, security) " + "VALUES (?, ?, ?, ?)", DB_INT, gid, DB_INT, pid, + DB_TEXT, version, DB_INT, security) != 1) + { + fprintf(stderr, "could not store version '%s' to database\n", + version); + fclose(file); + db->destroy(db); + exit(EXIT_FAILURE); + } + new_versions++; + } + else if (current_security != security) + { + printf("'%s' (%s) %s\n", package, version, security ? "[s]" : ""); + + if (security) + { + if (db->execute(db, NULL, + "UPDATE versions SET security = ? WHERE vid = ?", + DB_INT, security, DB_INT, vid) < 0) + { + fprintf(stderr, "could not store update security field\n"); + fclose(file); + db->destroy(db); + exit(EXIT_FAILURE); + } + updates++; + } + else + { + reverted++; + } + } + } + + fclose(file); + db->destroy(db); + printf("processed %d packages, %d vulnerable, %d errored, " + "%d new packages, %d new versions, %d updates, %d reverted\n", + count - 6, vulnerable, errored, new_packages, new_versions, + updates, reverted); +} + +static void do_args(int argc, char *argv[]) +{ + char *filename = NULL, *product = NULL; + + /* reinit getopt state */ + optind = 0; + + while (TRUE) + { + int c; + + struct option long_opts[] = { + { "help", no_argument, NULL, 'h' }, + { "file", required_argument, NULL, 'f' }, + { "product", required_argument, NULL, 'p' }, + { 0,0,0,0 } + }; + + c = getopt_long(argc, argv, "", long_opts, NULL); + switch (c) + { + case EOF: + break; + case 'h': + usage(); + exit(EXIT_SUCCESS); + case 'f': + filename = optarg; + continue; + case 'p': + product = optarg; + continue; + } + break; + } + + if (filename && product) + { + process_packages(filename, product); + } + else + { + usage(); + exit(EXIT_FAILURE); + } +} + +int main(int argc, char *argv[]) +{ + /* enable attest debugging hook */ + dbg = pacman_dbg; + openlog("pacman", 0, LOG_DEBUG); + + atexit(cleanup); + + /* 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); + } + do_args(argc, argv); + + exit(EXIT_SUCCESS); +} +