Separated IMV session management from IMV policy database
authorAndreas Steffen <andreas.steffen@strongswan.org>
Fri, 4 Apr 2014 21:00:40 +0000 (23:00 +0200)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Tue, 15 Apr 2014 07:21:05 +0000 (09:21 +0200)
38 files changed:
src/libimcv/Makefile.am
src/libimcv/imc/imc_os_info.c [new file with mode: 0644]
src/libimcv/imc/imc_os_info.h [new file with mode: 0644]
src/libimcv/imcv.c
src/libimcv/imcv.h
src/libimcv/imv/imv_agent.c
src/libimcv/imv/imv_agent.h
src/libimcv/imv/imv_database.c
src/libimcv/imv/imv_database.h
src/libimcv/imv/imv_os_info.c [new file with mode: 0644]
src/libimcv/imv/imv_os_info.h [new file with mode: 0644]
src/libimcv/imv/imv_session.c
src/libimcv/imv/imv_session.h
src/libimcv/imv/imv_session_manager.c [new file with mode: 0644]
src/libimcv/imv/imv_session_manager.h [new file with mode: 0644]
src/libimcv/imv/imv_state.h
src/libimcv/imv/tables.sql
src/libimcv/os_info/os_info.c
src/libimcv/os_info/os_info.h
src/libimcv/plugins/imc_os/imc_os.c
src/libimcv/plugins/imv_os/imv_os_agent.c
src/libimcv/plugins/imv_os/imv_os_database.c
src/libimcv/plugins/imv_os/imv_os_state.c
src/libimcv/plugins/imv_os/imv_os_state.h
src/libimcv/plugins/imv_scanner/imv_scanner_agent.c
src/libimcv/plugins/imv_scanner/imv_scanner_state.c
src/libimcv/plugins/imv_test/imv_test_state.c
src/libpts/plugins/imv_attestation/imv_attestation_agent.c
src/libpts/plugins/imv_attestation/imv_attestation_build.c
src/libpts/plugins/imv_attestation/imv_attestation_process.c
src/libpts/plugins/imv_attestation/imv_attestation_state.c
src/libpts/plugins/imv_attestation/imv_attestation_state.h
src/libpts/plugins/imv_swid/imv_swid_agent.c
src/libpts/plugins/imv_swid/imv_swid_state.c
src/libpts/pts/pts.c
src/libpts/pts/pts.h
src/libpts/pts/pts_database.c
src/libpts/pts/pts_database.h

index 96e7597..3732267 100644 (file)
@@ -15,14 +15,17 @@ libimcv_la_SOURCES = \
        imcv.h imcv.c \
        imc/imc_agent.h imc/imc_agent.c imc/imc_state.h \
        imc/imc_msg.h imc/imc_msg.c \
+       imc/imc_os_info.h imc/imc_os_info.c \
        imv/imv_agent.h imv/imv_agent.c imv/imv_state.h \
        imv/imv_agent_if.h imv/imv_if.h \
        imv/imv_database.h imv/imv_database.c \
        imv/imv_msg.h imv/imv_msg.c \
        imv/imv_lang_string.h imv/imv_lang_string.c \
+       imv/imv_os_info.h imv/imv_os_info.c \
        imv/imv_reason_string.h imv/imv_reason_string.c \
        imv/imv_remediation_string.h imv/imv_remediation_string.c \
        imv/imv_session.h imv/imv_session.c \
+       imv/imv_session_manager.h imv/imv_session_manager.c \
        imv/imv_workitem.h imv/imv_workitem.c \
        ietf/ietf_attr.h ietf/ietf_attr.c \
        ietf/ietf_attr_assess_result.h ietf/ietf_attr_assess_result.c \
diff --git a/src/libimcv/imc/imc_os_info.c b/src/libimcv/imc/imc_os_info.c
new file mode 100644 (file)
index 0000000..86a7f82
--- /dev/null
@@ -0,0 +1,562 @@
+/*
+ * Copyright (C) 2012-2014 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 "imc_os_info.h"
+
+#include <sys/utsname.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#include <collections/linked_list.h>
+#include <utils/debug.h>
+
+typedef struct private_imc_os_info_t private_imc_os_info_t;
+
+/**
+ * Private data of an imc_os_info_t object.
+ *
+ */
+struct private_imc_os_info_t {
+
+       /**
+        * Public imc_os_info_t interface.
+        */
+       imc_os_info_t public;
+
+       /**
+        * OS type
+        */
+       os_type_t type;
+
+       /**
+        * OS name
+        */
+       chunk_t name;
+
+       /**
+        * OS version
+        */
+       chunk_t version;
+
+};
+
+METHOD(imc_os_info_t, get_type, os_type_t,
+       private_imc_os_info_t *this)
+{
+       return this->type;
+}
+
+METHOD(imc_os_info_t, get_name, chunk_t,
+       private_imc_os_info_t *this)
+{
+       return this->name;
+}
+
+METHOD(imc_os_info_t, get_numeric_version, void,
+       private_imc_os_info_t *this, u_int32_t *major, u_int32_t *minor)
+{
+       u_char *pos;
+
+       if (major)
+       {
+               *major = atol(this->version.ptr);
+       }
+       pos = memchr(this->version.ptr, '.', this->version.len);
+       if (minor)
+       {
+               *minor = pos ? atol(pos + 1) : 0;
+       }
+}
+
+METHOD(imc_os_info_t, get_version, chunk_t,
+       private_imc_os_info_t *this)
+{
+       return this->version;
+}
+
+METHOD(imc_os_info_t, get_fwd_status, os_fwd_status_t,
+       private_imc_os_info_t *this)
+{
+       const char ip_forward[] = "/proc/sys/net/ipv4/ip_forward";
+       char buf[2];
+       FILE *file;
+
+       os_fwd_status_t fwd_status = OS_FWD_UNKNOWN;
+
+       file = fopen(ip_forward, "r");
+       if (file)
+       {
+               if (fread(buf, 1, 1, file) == 1)
+               {
+                       switch (buf[0])
+                       {
+                               case '0':
+                                       fwd_status = OS_FWD_DISABLED;
+                                       break;
+                               case '1':
+                                       fwd_status = OS_FWD_ENABLED;
+                                       break;
+                               default:
+                                       DBG1(DBG_IMC, "\"%s\" returns invalid value ", ip_forward);
+                                       break;
+                       }
+               }
+               else
+               {
+                       DBG1(DBG_IMC, "could not read from \"%s\"", ip_forward);
+               }
+               fclose(file);
+       }
+       else
+       {
+               DBG1(DBG_IMC, "failed to open \"%s\"", ip_forward);
+       }
+
+       return fwd_status;
+}
+
+METHOD(imc_os_info_t, get_uptime, time_t,
+       private_imc_os_info_t *this)
+{
+       const char proc_uptime[] = "/proc/uptime";
+       FILE *file;
+       u_int uptime;
+
+       file = fopen(proc_uptime, "r");
+       if (!file)
+       {
+               DBG1(DBG_IMC, "failed to open \"%s\"", proc_uptime);
+               return 0;
+       }
+       if (fscanf(file, "%u", &uptime) != 1)
+       {
+               DBG1(DBG_IMC, "failed to read file \"%s\"", proc_uptime);
+               uptime = 0;
+       }
+       fclose(file);
+
+       return uptime;
+}
+
+METHOD(imc_os_info_t, get_setting, chunk_t,
+       private_imc_os_info_t *this, char *name)
+{
+       FILE *file;
+       u_char buf[2048];
+       size_t i = 0;
+       chunk_t value;
+
+       if (!strpfx(name, "/etc/") && !strpfx(name, "/proc/") &&
+               !strpfx(name, "/sys/") && !strpfx(name, "/var/"))
+       {
+               /**
+                * In order to guarantee privacy, only settings from the
+                * /etc/, /proc/ and /sys/ directories can be retrieved
+                */
+               DBG1(DBG_IMC, "not allowed to access '%s'", name);
+
+               return chunk_empty;
+       }
+
+       file = fopen(name, "r");
+       if (!file)
+       {
+               DBG1(DBG_IMC, "failed to open '%s'", name);
+
+               return chunk_empty;
+       }
+       while (i < sizeof(buf) && fread(buf + i, 1, 1, file) == 1)
+       {
+               i++;
+       }
+       fclose(file);
+
+       value = chunk_create(buf, i);
+
+       return chunk_clone(value);
+}
+
+typedef struct {
+       /**
+        * implements enumerator_t
+        */
+       enumerator_t public;
+
+       /**
+        * package info pipe stream
+        */
+       FILE* file;
+
+       /**
+        * line buffer
+        */
+       u_char line[512];
+
+} package_enumerator_t;
+
+/**
+ * Implementation of package_enumerator.destroy.
+ */
+static void package_enumerator_destroy(package_enumerator_t *this)
+{
+       pclose(this->file);
+       free(this);
+}
+
+/**
+ * Implementation of package_enumerator.enumerate
+ */
+static bool package_enumerator_enumerate(package_enumerator_t *this, ...)
+{
+       chunk_t *name, *version;
+       u_char *pos;
+       va_list args;
+
+       while (TRUE)
+       {
+               if (!fgets(this->line, sizeof(this->line), this->file))
+               {
+                       return FALSE;
+               }
+
+               pos = strchr(this->line, '\t');
+               if (!pos)
+               {
+                       return FALSE;
+               }
+               *pos++ = '\0';
+
+               if (!streq(this->line, "install ok installed"))
+               {
+                       continue;
+               }
+               va_start(args, this);
+
+               name = va_arg(args, chunk_t*);
+               name->ptr = pos;
+               pos = strchr(pos, '\t');
+               if (!pos)
+               {
+                       va_end(args);
+                       return FALSE;
+               }
+               name->len = pos++ - name->ptr;
+
+               version = va_arg(args, chunk_t*);
+               version->ptr = pos;
+               version->len = strlen(pos) - 1;
+
+               va_end(args);
+               return TRUE;
+       }
+}
+
+METHOD(imc_os_info_t, create_package_enumerator, enumerator_t*,
+       private_imc_os_info_t *this)
+{
+       FILE *file;
+       const char command[] = "dpkg-query --show --showformat="
+                                                               "'${Status}\t${Package}\t${Version}\n'";
+       package_enumerator_t *enumerator;
+
+       /* Only Debian and Ubuntu package enumeration is currently supported */
+       if (this->type != OS_TYPE_DEBIAN && this->type != OS_TYPE_UBUNTU)
+       {
+               return NULL;
+       }
+
+       /* Open a pipe stream for reading the output of the dpkg-query commmand */
+       file = popen(command, "r");
+       if (!file)
+       {
+               DBG1(DBG_IMC, "failed to run dpkg command");
+               return NULL;
+       }
+
+       /* Create a package enumerator instance */
+       enumerator = malloc_thing(package_enumerator_t);
+       enumerator->public.enumerate = (void*)package_enumerator_enumerate;
+       enumerator->public.destroy = (void*)package_enumerator_destroy;
+       enumerator->file = file;
+
+       return (enumerator_t*)enumerator;
+}
+
+
+METHOD(imc_os_info_t, destroy, void,
+       private_imc_os_info_t *this)
+{
+       free(this->name.ptr);
+       free(this->version.ptr);
+       free(this);
+}
+
+#define RELEASE_LSB            0
+#define RELEASE_DEBIAN 1
+
+/**
+ * Determine Linux distribution version and hardware platform
+ */
+static bool extract_platform_info(os_type_t *type, chunk_t *name,
+                                                                 chunk_t *version)
+{
+       FILE *file;
+       u_char buf[BUF_LEN], *pos = buf;
+       int len = BUF_LEN - 1;
+       os_type_t os_type = OS_TYPE_UNKNOWN;
+       chunk_t os_name = chunk_empty;
+       chunk_t os_version = chunk_empty;
+       char *os_str;
+       struct utsname uninfo;
+       int i;
+
+       /* Linux/Unix distribution release info (from http://linuxmafia.com) */
+       const char* releases[] = {
+               "/etc/lsb-release",           "/etc/debian_version",
+               "/etc/SuSE-release",          "/etc/novell-release",
+               "/etc/sles-release",          "/etc/redhat-release",
+               "/etc/fedora-release",        "/etc/gentoo-release",
+               "/etc/slackware-version",     "/etc/annvix-release",
+               "/etc/arch-release",          "/etc/arklinux-release",
+               "/etc/aurox-release",         "/etc/blackcat-release",
+               "/etc/cobalt-release",        "/etc/conectiva-release",
+               "/etc/debian_release",        "/etc/immunix-release",
+               "/etc/lfs-release",           "/etc/linuxppc-release",
+               "/etc/mandrake-release",      "/etc/mandriva-release",
+               "/etc/mandrakelinux-release", "/etc/mklinux-release",
+               "/etc/pld-release",           "/etc/redhat_version",
+               "/etc/slackware-release",     "/etc/e-smith-release",
+               "/etc/release",               "/etc/sun-release",
+               "/etc/tinysofa-release",      "/etc/turbolinux-release",
+               "/etc/ultrapenguin-release",  "/etc/UnitedLinux-release",
+               "/etc/va-release",            "/etc/yellowdog-release"
+       };
+
+       const char lsb_distrib_id[]      = "DISTRIB_ID=";
+       const char lsb_distrib_release[] = "DISTRIB_RELEASE=";
+
+       for (i = 0; i < countof(releases); i++)
+       {
+               file = fopen(releases[i], "r");
+               if (!file)
+               {
+                       continue;
+               }
+
+               /* read release file into buffer */
+               fseek(file, 0, SEEK_END);
+               len = min(ftell(file), len);
+               rewind(file);
+               buf[len] = '\0';
+               if (fread(buf, 1, len, file) != len)
+               {
+                       DBG1(DBG_IMC, "failed to read file \"%s\"", releases[i]);
+                       fclose(file);
+                       return FALSE;
+               }
+               fclose(file);
+
+               DBG1(DBG_IMC, "processing \"%s\" file", releases[i]);
+
+               switch (i)
+               {
+                       case RELEASE_LSB:
+                       {
+                               /* Determine Distribution ID */
+                               pos = strstr(buf, lsb_distrib_id);
+                               if (!pos)
+                               {
+                                       DBG1(DBG_IMC, "failed to find begin of DISTRIB_ID field");
+                                       return FALSE;
+                               }
+                               pos += strlen(lsb_distrib_id);
+
+                               os_name.ptr = pos;
+
+                               pos = strchr(pos, '\n');
+                               if (!pos)
+                               {
+                                       DBG1(DBG_IMC, "failed to find end of DISTRIB_ID field");
+                                       return FALSE;
+                               }
+                               os_name.len = pos - os_name.ptr;
+
+                               /* Determine Distribution Release */
+                               pos = strstr(buf, lsb_distrib_release);
+                               if (!pos)
+                               {
+                                       DBG1(DBG_IMC, "failed to find begin of DISTRIB_RELEASE field");
+                                       return FALSE;
+                               }
+                               pos += strlen(lsb_distrib_release);
+
+                               os_version.ptr = pos;
+
+                               pos = strchr(pos, '\n');
+                               if (!pos)
+                               {
+                                       DBG1(DBG_IMC, "failed to find end of DISTRIB_RELEASE field");
+                                       return FALSE;
+                               }
+                               os_version.len = pos - os_version.ptr;
+
+                               break;
+                       }
+                       case RELEASE_DEBIAN:
+                       {
+                               os_type = OS_TYPE_DEBIAN;
+
+                               os_version.ptr = buf;
+                               pos = strchr(buf, '\n');
+                               if (!pos)
+                               {
+                                       DBG1(DBG_PTS, "failed to find end of release string");
+                                       return FALSE;
+                               }
+
+                               os_version.len = pos - os_version.ptr;
+
+                               break;
+                       }
+                       default:
+                       {
+                               const char str_release[] = " release ";
+
+                               os_name.ptr = buf;
+
+                               pos = strstr(buf, str_release);
+                               if (!pos)
+                               {
+                                       DBG1(DBG_IMC, "failed to find release keyword");
+                                       return FALSE;
+                               }
+
+                               os_name.len = pos - os_name.ptr;
+
+                               pos += strlen(str_release);
+                               os_version.ptr = pos;
+
+                               pos = strchr(pos, '\n');
+                               if (!pos)
+                               {
+                                       DBG1(DBG_IMC, "failed to find end of release string");
+                                       return FALSE;
+                               }
+
+                               os_version.len = pos - os_version.ptr;
+
+                               break;
+                       }
+               }
+               break;
+       }
+
+       if (!os_version.ptr)
+       {
+               DBG1(DBG_IMC, "no distribution release file found");
+               return FALSE;
+       }
+
+       if (uname(&uninfo) < 0)
+       {
+               DBG1(DBG_IMC, "could not retrieve machine architecture");
+               return FALSE;
+       }
+
+       /* Try to find a matching OS type based on the OS name */
+       if (os_type == OS_TYPE_UNKNOWN)
+       {
+               os_type = os_type_from_name(os_name);
+       }
+
+       /* If known use the official OS name */
+       if (os_type != OS_TYPE_UNKNOWN)
+       {
+               os_str = enum_to_name(os_type_names, os_type);
+               os_name = chunk_create(os_str, strlen(os_str));
+       }
+
+       /* copy OS type */
+       *type = os_type;
+
+       /* copy OS name */
+       *name = chunk_clone(os_name);
+
+       /* copy OS version and machine architecture */
+       *version = chunk_alloc(os_version.len + 1 + strlen(uninfo.machine));
+       pos = version->ptr;
+       memcpy(pos, os_version.ptr, os_version.len);
+       pos += os_version.len;
+       *pos++ = ' ';
+       memcpy(pos, uninfo.machine, strlen(uninfo.machine));
+
+       return TRUE;
+}
+
+/**
+ * See header
+ */
+imc_os_info_t *imc_os_info_create(void)
+{
+       private_imc_os_info_t *this;
+       chunk_t name, version;
+       os_type_t type;
+
+       /* As an option OS name and OS version can be configured manually */
+       name.ptr = lib->settings->get_str(lib->settings,
+                                                                         "%s.imcv.imc_os_info.name", NULL, lib->ns);
+       version.ptr = lib->settings->get_str(lib->settings,
+                                                                         "%s.imcv.imc_os_info.version", NULL, lib->ns);
+       if (name.ptr && version.ptr)
+       {
+               name.len = strlen(name.ptr);
+               name = chunk_clone(name);
+
+               version.len = strlen(version.ptr);
+               version = chunk_clone(version);
+
+               type = os_type_from_name(name);
+       }
+       else
+       {
+               if (!extract_platform_info(&type, &name, &version))
+               {
+                       return NULL;
+               }
+       }
+       DBG1(DBG_IMC, "operating system name is '%.*s'",
+                                  name.len, name.ptr);
+       DBG1(DBG_IMC, "operating system version is '%.*s'",
+                                  version.len, version.ptr);
+
+       INIT(this,
+               .public = {
+                       .get_type = _get_type,
+                       .get_name = _get_name,
+                       .get_numeric_version = _get_numeric_version,
+                       .get_version = _get_version,
+                       .get_fwd_status = _get_fwd_status,
+                       .get_uptime = _get_uptime,
+                       .get_setting = _get_setting,
+                       .create_package_enumerator = _create_package_enumerator,
+                       .destroy = _destroy,
+               },
+               .type = type,
+               .name = name,
+               .version = version,
+       );
+
+       return &this->public;
+}
diff --git a/src/libimcv/imc/imc_os_info.h b/src/libimcv/imc/imc_os_info.h
new file mode 100644 (file)
index 0000000..a6db443
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2012-2014 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 imc_os_info imc_os_info
+ * @{ @ingroup libimcv
+ */
+
+#ifndef IMC_OS_INFO_H_
+#define IMC_OS_INFO_H_
+
+typedef struct imc_os_info_t imc_os_info_t;
+
+#include "os_info/os_info.h"
+
+#include <library.h>
+
+#include <time.h>
+
+/**
+ * Interface for the IMC Operating System (OS) information module
+ */
+struct imc_os_info_t {
+
+       /**
+        * Get the OS type if it can be determined
+        *
+        * @return                                      OS type
+        */
+       os_type_t (*get_type)(imc_os_info_t *this);
+
+       /**
+        * Get the OS product name or distribution
+        *
+        * @return                                      OS name
+        */
+       chunk_t (*get_name)(imc_os_info_t *this);
+
+       /**
+        * Get the numeric OS version or release
+        *
+        * @param major                         OS major version number
+        * @param minor                         OS minor version number
+        */
+       void (*get_numeric_version)(imc_os_info_t *this, u_int32_t *major,
+                                                                                                u_int32_t *minor);
+
+       /**
+        * Get the OS version or release
+        *
+        * @return                                      OS version
+        */
+       chunk_t (*get_version)(imc_os_info_t *this);
+
+       /**
+        * Get the OS IPv4 forwarding status
+        *
+        * @return                                      IP forwarding status
+        */
+       os_fwd_status_t (*get_fwd_status)(imc_os_info_t *this);
+
+       /**
+        * Get the OS uptime in seconds
+        *
+        * @return                                      OS uptime
+        */
+       time_t (*get_uptime)(imc_os_info_t *this);
+
+       /**
+        * Get an OS setting (restricted to /proc, /sys, and /etc)
+        *
+        * @param name                          name of OS setting
+        * @return                                      value of OS setting
+        */
+       chunk_t (*get_setting)(imc_os_info_t *this, char *name);
+
+       /**
+        * Enumerates over all installed packages
+        *
+        * @return                              return package enumerator
+        */
+       enumerator_t* (*create_package_enumerator)(imc_os_info_t *this);
+
+       /**
+        * Destroys an imc_os_info_t object.
+        */
+       void (*destroy)(imc_os_info_t *this);
+};
+
+/**
+ * Create an imc_os_info_t object
+ */
+imc_os_info_t* imc_os_info_create(void);
+
+#endif /** IMC_OS_INFO_H_ @}*/
index 2a4fd33..8616448 100644 (file)
 pa_tnc_attr_manager_t *imcv_pa_tnc_attributes;
 
 /**
+ * Global list of IMV sessions
+ */
+imv_session_manager_t *imcv_sessions;
+
+/**
  * Global IMV database
  */
 imv_database_t *imcv_db;
@@ -149,9 +154,12 @@ bool libimcv_init(bool is_imv)
                imcv_pa_tnc_attributes->add_vendor(imcv_pa_tnc_attributes, PEN_ITA,
                                                        ita_attr_create_from_data, ita_attr_names);
 
-               /* attach global IMV database */
                if (is_imv)
                {
+                       /* instantiate global IMV session manager */
+                       imcv_sessions = imv_session_manager_create();
+
+                       /* instantiate and attach global IMV database if URI is valid */
                        uri = lib->settings->get_str(lib->settings,
                                                "%s.imcv.database", NULL, lib->ns);
                        script = lib->settings->get_str(lib->settings,
@@ -181,6 +189,7 @@ void libimcv_deinit(void)
                DESTROY_IF(imcv_pa_tnc_attributes);
                imcv_pa_tnc_attributes = NULL;
                DESTROY_IF(imcv_db);
+               DESTROY_IF(imcv_sessions);
                DBG1(DBG_LIB, "libimcv terminated");
        }
        if (ref_put(&libstrongswan_ref))
index 10c66e6..7710388 100644 (file)
@@ -36,6 +36,7 @@
 
 #include "pa_tnc/pa_tnc_attr_manager.h"
 #include "imv/imv_database.h"
+#include "imv/imv_session_manager.h"
 
 #include <library.h>
 
@@ -62,4 +63,9 @@ extern pa_tnc_attr_manager_t* imcv_pa_tnc_attributes;
  */
 extern imv_database_t* imcv_db;
 
+/**
+ * Global IMV session manager
+ */
+extern imv_session_manager_t* imcv_sessions;
+
 #endif /** IMCV_H_ @}*/
index 435c25a..5fc3f79 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2013 Andreas Steffen
+ * Copyright (C) 2011-2014 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -52,7 +52,7 @@ struct private_imv_agent_t {
        /**
         * number of message types registered by IMV
         */
-       u_int32_t type_count;
+       uint32_t type_count;
 
        /**
         * ID of IMV as assigned by TNCS
@@ -296,10 +296,7 @@ static bool delete_connection(private_imv_agent_t *this, TNC_ConnectionID id)
                {
                        found = TRUE;
                        session = state->get_session(state);
-                       if (session)
-                       {
-                               imcv_db->remove_session(imcv_db, session);
-                       }
+                       imcv_sessions->remove_session(imcv_sessions, session);
                        state->destroy(state);
                        this->connections->remove_at(this->connections, enumerator);
                        break;
@@ -346,7 +343,7 @@ static char* get_str_attribute(private_imv_agent_t *this, TNC_ConnectionID id,
 /**
  * Read an UInt32 attribute
  */
-static u_int32_t get_uint_attribute(private_imv_agent_t *this, TNC_ConnectionID id,
+static uint32_t get_uint_attribute(private_imv_agent_t *this, TNC_ConnectionID id,
                                                                        TNC_AttributeID attribute_id)
 {
        TNC_UInt32 len;
@@ -370,7 +367,7 @@ static linked_list_t* get_identity_attribute(private_imv_agent_t *this,
 {
        TNC_UInt32 len;
        char buf[2048];
-       u_int32_t count;
+       uint32_t count;
        tncif_identity_t *tnc_id;
        bio_reader_t *reader;
        linked_list_t *list;
@@ -415,8 +412,8 @@ METHOD(imv_agent_t, create_state, TNC_Result,
        enumerator_t *enumerator;
        tncif_identity_t *tnc_id;
        imv_session_t *session;
-       u_int32_t max_msg_len;
-       u_int32_t ar_id_type = TNC_ID_UNKNOWN;
+       uint32_t max_msg_len;
+       uint32_t ar_id_type = TNC_ID_UNKNOWN;
        chunk_t ar_id_value = chunk_empty;
 
        conn_id = state->get_connection_id(state);
@@ -453,7 +450,7 @@ METHOD(imv_agent_t, create_state, TNC_Result,
        while (enumerator->enumerate(enumerator, &tnc_id))
        {
                pen_type_t id_type, subject_type, auth_type;
-               u_int32_t tcg_id_type, tcg_subject_type, tcg_auth_type;
+               uint32_t tcg_id_type, tcg_subject_type, tcg_auth_type;
                chunk_t id_value;
 
                id_type = tnc_id->get_identity_type(tnc_id);
@@ -474,30 +471,21 @@ METHOD(imv_agent_t, create_state, TNC_Result,
                         id_value.len, id_value.ptr,
                         TNC_Authentication_names, tcg_auth_type);
 
+               /* keep the first access requestor ID */
                if (first)
                {
                        ar_id_type = tcg_id_type;
                        ar_id_value = id_value;
-                       state->set_ar_id(state, ar_id_type, ar_id_value);
                        first = FALSE;
                }
        }
        enumerator->destroy(enumerator);
 
-       if (imcv_db)
-       {
-               session = imcv_db->add_session(imcv_db, conn_id, ar_id_type, ar_id_value);
-               if (session)
-               {
-                       DBG2(DBG_IMV, "  assigned session ID %d",
-                                session->get_session_id(session));
-                       state->set_session(state, session);
-               }
-               else
-               {
-                       DBG1(DBG_IMV, "  no session ID assigned");
-               }
-       }
+       session = imcv_sessions->add_session(imcv_sessions, conn_id,
+                                                                                ar_id_type, ar_id_value);
+       state->set_session(state, session);
+
+       /* clean up temporary variables */
        ar_identities->destroy_offset(ar_identities,
                                                   offsetof(tncif_identity_t, destroy));
        free(tnccs_p);
@@ -505,9 +493,11 @@ METHOD(imv_agent_t, create_state, TNC_Result,
        free(t_p);
        free(t_v);
 
+       /* insert state in connection list */
        this->connection_lock->write_lock(this->connection_lock);
        this->connections->insert_last(this->connections, state);
        this->connection_lock->unlock(this->connection_lock);
+
        return TNC_RESULT_SUCCESS;
 }
 
@@ -800,7 +790,7 @@ METHOD(imv_agent_t, destroy, void,
  * Described in header.
  */
 imv_agent_t *imv_agent_create(const char *name,
-                                                         pen_type_t *supported_types, u_int32_t type_count,
+                                                         pen_type_t *supported_types, uint32_t type_count,
                                                          TNC_IMVID id, TNC_Version *actual_version)
 {
        private_imv_agent_t *this;
index d58af26..47ce770 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2013 Andreas Steffen
+ * Copyright (C) 2011-2014 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -205,7 +205,7 @@ struct imv_agent_t {
  *
  */
 imv_agent_t *imv_agent_create(const char *name,
-                                                         pen_type_t *supported_types, u_int32_t type_count,
+                                                         pen_type_t *supported_types, uint32_t type_count,
                                                          TNC_IMVID id, TNC_Version *actual_version);
 
 #endif /** IMV_AGENT_H_ @}*/
index dc7edd7..2edb4df 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Andreas Steffen
+ * Copyright (C) 2013-2014 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -47,48 +47,28 @@ struct private_imv_database_t {
         */
        char *script;
 
-       /**
-        * Session list
-        */
-       linked_list_t *sessions;
-
-       /**
-        * mutex used to lock session list
-        */
-       mutex_t *mutex;
-
 };
 
-METHOD(imv_database_t, add_session, imv_session_t*,
-       private_imv_database_t *this, TNC_ConnectionID conn_id,
-       u_int32_t ar_id_type, chunk_t ar_id_value)
+METHOD(imv_database_t, get_database, database_t*,
+       private_imv_database_t *this)
 {
-       enumerator_t *enumerator, *e;
-       imv_session_t *current, *session = NULL;
-       int ar_id = 0, session_id;
-       u_int created;
-
-       this->mutex->lock(this->mutex);
-
-       /* check if a session has already been assigned */
-       enumerator = this->sessions->create_enumerator(this->sessions);
-       while (enumerator->enumerate(enumerator, &current))
-       {
-               if (conn_id == current->get_connection_id(current))
-               {
-                       session = current;
-                       break;
-               }
-       }
-       enumerator->destroy(enumerator);
-
-       /* session already exists */
-       if (session)
-       {
-               this->mutex->unlock(this->mutex);
-               return session->get_ref(session);
-       }
+       return this->db;
+}
 
+/**
+ * Create a session entry in the IMV database
+ */
+static bool create_session(private_imv_database_t *this, imv_session_t *session)
+{
+       enumerator_t *e;
+       imv_os_info_t *os_info;
+       chunk_t device_id, ar_id_value;
+       TNC_ConnectionID conn_id;
+       uint32_t ar_id_type;
+       char *product, *device;
+       int session_id = 0, ar_id = 0, pid = 0, did = 0, trusted = 0, created;
+
+       ar_id_value = session->get_ar_id(session, &ar_id_type);
        if (ar_id_value.len)
        {
                /* get primary key of AR identity if it exists */
@@ -108,46 +88,22 @@ METHOD(imv_database_t, add_session, imv_session_t*,
                                "INSERT INTO identities (type, value) VALUES (?, ?)",
                                 DB_INT, ar_id_type, DB_BLOB, ar_id_value);
                }
-       }
-       /* create a new session entry */
-       created = time(NULL);
-       this->db->execute(this->db, &session_id,
-                               "INSERT INTO sessions (time, connection, identity) "
-                               "VALUES (?, ?, ?)",
-                               DB_UINT, created, DB_INT, conn_id, DB_INT, ar_id);
-       session = imv_session_create(session_id, conn_id);
-       this->sessions->insert_last(this->sessions, session);
-
-       this->mutex->unlock(this->mutex);
-
-       return session;
-}
 
-METHOD(imv_database_t, remove_session, void,
-       private_imv_database_t *this, imv_session_t *session)
-{
-       enumerator_t *enumerator;
-       imv_session_t *current;
-
-       this->mutex->lock(this->mutex);
-       enumerator = this->sessions->create_enumerator(this->sessions);
-       while (enumerator->enumerate(enumerator, &current))
-       {
-               if (current == session)
+               if (!ar_id)
                {
-                       this->sessions->remove_at(this->sessions, enumerator);
-                       break;
+                       DBG1(DBG_IMV, "imv_db: registering access requestor failed");
+                       return FALSE;
                }
        }
-       enumerator->destroy(enumerator);
-       this->mutex->unlock(this->mutex);
-}
 
-METHOD(imv_database_t, add_product, int,
-       private_imv_database_t *this, imv_session_t *session, char *product)
-{
-       enumerator_t *e;
-       int pid = 0;
+       /* get product info string */
+       os_info = session->get_os_info(session);
+       product = os_info->get_info(os_info);
+       if (!product)
+       {
+               DBG1(DBG_IMV, "imv_db: product info is not available");
+               return FALSE;
+       }
 
        /* get primary key of product info string if it exists */
        e = this->db->query(this->db,
@@ -164,92 +120,150 @@ METHOD(imv_database_t, add_product, int,
                this->db->execute(this->db, &pid,
                        "INSERT INTO products (name) VALUES (?)", DB_TEXT, product);
        }
+
+       if (!pid)
+       {
+               DBG1(DBG_IMV, "imv_db: registering product info failed");
+               return FALSE;
+       }
        
-       /* add product reference to session */
-       if (pid)
+       /* get device ID string */
+       if (!session->get_device_id(session, &device_id))
        {
-               this->db->execute(this->db, NULL,
-                       "UPDATE sessions SET product = ? WHERE id = ?",
-                        DB_INT, pid, DB_INT, session->get_session_id(session));
+               DBG1(DBG_IMV, "imv_db: device ID is not available");
+               return FALSE;
        }
+       device = strndup(device_id.ptr, device_id.len);
 
-       return pid;
-}
-
-METHOD(imv_database_t, add_device, int,
-       private_imv_database_t *this, imv_session_t *session, chunk_t device)
-{
-       enumerator_t *e;
-       char *device_str;
-       int pid = 0, did = 0;
-
-       /* get primary key of product from session */
+       /* get primary key of device ID if it exists */
        e = this->db->query(this->db,
-                       "SELECT product FROM sessions WHERE id = ?",
-                        DB_INT, session->get_session_id(session), DB_INT);
+                       "SELECT id, trusted FROM devices WHERE value = ? AND product = ?",
+                        DB_TEXT, device, DB_INT, pid, DB_INT, DB_INT);
        if (e)
        {
-               e->enumerate(e, &pid);
+               e->enumerate(e, &did, &trusted);
                e->destroy(e);
        }
 
-       /* some IMV policy manager expect a text string */
-       device_str = strndup(device.ptr, device.len);
-
-       /* get primary key of device identification if it exists */
-       e = this->db->query(this->db,
-                       "SELECT id FROM devices WHERE value = ? AND product = ?",
-                        DB_TEXT, device_str, DB_INT, pid, DB_INT);
-       if (e)
+       /* if device ID is trusted, set trust in session */
+       if (trusted)
        {
-               e->enumerate(e, &did);
-               e->destroy(e);
+               session->set_device_trust(session, TRUE);
        }
 
-       /* if device identification has not been found - register it */
+       /* if device ID has not been found - register it */
        if (!did)
        {
                this->db->execute(this->db, &did,
                        "INSERT INTO devices (value, product) VALUES (?, ?)",
-                        DB_TEXT, device_str, DB_INT, pid);
+                        DB_TEXT, device, DB_INT, pid);
        }
-       free(device_str);
-       
-       /* add device reference to session */
-       if (did)
+       free(device);
+
+       if (!did)
+       {
+               DBG1(DBG_IMV, "imv_db: registering device ID failed");
+               return FALSE;
+       }
+
+       /* create a new session entry */
+       created = session->get_creation_time(session);
+       conn_id = session->get_connection_id(session);
+       this->db->execute(this->db, &session_id,
+                       "INSERT INTO sessions (time, connection, identity, product, device) "
+                       "VALUES (?, ?, ?, ?, ?)",
+                       DB_INT, created, DB_INT, conn_id, DB_INT, ar_id,
+                       DB_INT, pid, DB_INT, did);
+
+       if (session_id)
+       {
+               DBG2(DBG_IMV, "assigned session ID %d to Connection ID %d",
+                                          session_id, conn_id);
+       }
+       else
+       {
+               DBG1(DBG_IMV, "imv_db: registering session failed");
+               return FALSE;
+       }
+       session->set_session_id(session, session_id, pid, did);
+
+       return TRUE;
+}
+
+static bool add_workitems(private_imv_database_t *this, imv_session_t *session)
+{
+       char *arg_str;
+       int id, arg_int, rec_fail, rec_noresult;
+       imv_workitem_t *workitem;
+       imv_workitem_type_t type;
+       enumerator_t *e;
+
+       e = this->db->query(this->db,
+                       "SELECT id, type, arg_str, arg_int, rec_fail, rec_noresult "
+                       "FROM workitems WHERE session = ?",
+                        DB_INT, session->get_session_id(session, NULL, NULL),
+                        DB_INT, DB_INT, DB_TEXT, DB_INT,DB_INT, DB_INT);
+       if (!e)
        {
-               this->db->execute(this->db, NULL,
-                       "UPDATE sessions SET device = ? WHERE id = ?",
-                        DB_INT, did, DB_INT, session->get_session_id(session));
+               DBG1(DBG_IMV, "imv_db: no workitem enumerator returned");
+               return FALSE;
+       }
+       while (e->enumerate(e, &id, &type, &arg_str, &arg_int, &rec_fail,
+                                                  &rec_noresult))
+       {
+               DBG2(DBG_IMV, "%N workitem %d", imv_workitem_type_names, type, id);
+               workitem = imv_workitem_create(id, type, arg_str, arg_int, rec_fail,
+                                                                          rec_noresult);
+               session->insert_workitem(session, workitem);
        }
+       e->destroy(e);
 
-       return did;
+       return TRUE;
 }
 
 METHOD(imv_database_t, add_recommendation, void,
        private_imv_database_t *this, imv_session_t *session,
        TNC_IMV_Action_Recommendation rec)
 {
-       /* add final recommendation to session */
+       /* add final recommendation to session DB entry */
        this->db->execute(this->db, NULL,
                        "UPDATE sessions SET rec = ? WHERE id = ?",
-                        DB_INT, rec, DB_INT, session->get_session_id(session));
+                        DB_INT, rec, DB_INT, session->get_session_id(session, NULL, NULL));
 }
 
 METHOD(imv_database_t, policy_script, bool,
        private_imv_database_t *this, imv_session_t *session, bool start)
 {
-       imv_workitem_t *workitem;
-       imv_workitem_type_t type;
-       int id, session_id, arg_int, rec_fail, rec_noresult;
-       enumerator_t *e;
-       char command[512], resp[128], *last, *arg_str;
+       char command[512], resp[128], *last;
        FILE *shell;
 
-       session_id = session->get_session_id(session);
+       if (start)
+       {
+               if (session->get_policy_started(session))
+               {
+                       DBG1(DBG_IMV, "policy script as already been started");
+                       return FALSE;
+               }
 
+               /* add product info and device ID to session DB entry */
+               if (!create_session(this, session))
+               {
+                       return FALSE;
+               }
+       }
+       else
+       {
+               if (!session->get_policy_started(session))
+               {
+                       DBG1(DBG_IMV, "policy script as already been stopped");
+                       return FALSE;
+               }
+       }
+
+       /* call the policy script */
        snprintf(command, sizeof(command), "2>&1 TNC_SESSION_ID='%d' %s %s",
-                        session_id, this->script, start ? "start" : "stop");
+                        session->get_session_id(session, NULL, NULL), this->script,
+                        start ? "start" : "stop");
        DBG3(DBG_IMV, "running policy script: %s", command);
 
        shell = popen(command, "r");
@@ -282,30 +296,16 @@ METHOD(imv_database_t, policy_script, bool,
        }
        pclose(shell);
 
-       if (start && !session->get_policy_started(session))
+       if (start)
        {
-               /* get workitem list generated by policy manager */
-               e = this->db->query(this->db,
-                               "SELECT id, type, arg_str, arg_int, rec_fail, rec_noresult "
-                               "FROM workitems WHERE session = ?",     DB_INT, session_id,
-                                DB_INT, DB_INT, DB_TEXT, DB_INT,DB_INT, DB_INT);
-               if (!e)
+               /* add workitem list generated by policy manager to session object */
+               if (!add_workitems(this, session))
                {
-                       DBG1(DBG_IMV, "no workitem enumerator returned");
                        return FALSE;
                }
-               while (e->enumerate(e, &id, &type, &arg_str, &arg_int, &rec_fail,
-                                                          &rec_noresult))
-               {
-                       workitem = imv_workitem_create(id, type, arg_str, arg_int, rec_fail,
-                                                                                  rec_noresult);
-                       session->insert_workitem(session, workitem);
-               }
-               e->destroy(e);
-
                session->set_policy_started(session, TRUE);
        }
-       else if (!start && session->get_policy_started(session))
+       else
        {
                session->set_policy_started(session, FALSE);
        }
@@ -327,19 +327,10 @@ METHOD(imv_database_t, finalize_workitem, bool,
                                DB_INT, workitem->get_id(workitem)) == 1;
 }
 
-METHOD(imv_database_t, get_database, database_t*,
-       private_imv_database_t *this)
-{
-       return this->db;
-}
-
 METHOD(imv_database_t, destroy, void,
        private_imv_database_t *this)
 {
        DESTROY_IF(this->db);
-       this->sessions->destroy_offset(this->sessions,
-                                                       offsetof(imv_session_t, destroy));
-       this->mutex->destroy(this->mutex);
        free(this);
 }
 
@@ -352,20 +343,14 @@ imv_database_t *imv_database_create(char *uri, char *script)
 
        INIT(this,
                .public = {
-                       .add_session = _add_session,
-                       .remove_session = _remove_session,
-                       .add_product = _add_product,
-                       .add_device = _add_device,
-                       .add_recommendation = _add_recommendation,
+                       .get_database = _get_database,
                        .policy_script = _policy_script,
                        .finalize_workitem = _finalize_workitem,
-                       .get_database = _get_database,
+                       .add_recommendation = _add_recommendation,
                        .destroy = _destroy,
                },
                .db = lib->db->create(lib->db, uri),
                .script = script,
-               .sessions = linked_list_create(),
-               .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
        );
 
        if (!this->db)
index 48a3ded..79551cc 100644 (file)
@@ -56,26 +56,6 @@ struct imv_database_t {
         void (*remove_session)(imv_database_t *this, imv_session_t *session);
 
        /**
-        * Add product information string to a session database entry
-        *
-        * @param session               Session
-        * @param product               Product information string
-        * @return                              Product ID
-        */
-        int (*add_product)(imv_database_t *this, imv_session_t *session,
-                                               char *product);
-
-       /**
-        * Add device identification to a session database entry
-        *
-        * @param session               Session
-        * @param device                Device identification
-        * @return                              Device ID
-        */
-        int (*add_device)(imv_database_t *this, imv_session_t *session,
-                                          chunk_t device);
-
-       /**
         * Add final recommendation to a session database entry
         *
         * @param session               Session
diff --git a/src/libimcv/imv/imv_os_info.c b/src/libimcv/imv/imv_os_info.c
new file mode 100644 (file)
index 0000000..dfab194
--- /dev/null
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2014 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 "imv_os_info.h"
+
+typedef struct private_imv_os_info_t private_imv_os_info_t;
+
+/**
+ * Private data of an imv_os_info_t object.
+ *
+ */
+struct private_imv_os_info_t {
+
+       /**
+        * Public imv_os_info_t interface.
+        */
+       imv_os_info_t public;
+
+       /**
+        * OS type
+        */
+       os_type_t type;
+
+       /**
+        * OS name
+        */
+       chunk_t name;
+
+       /**
+        * OS version
+        */
+       chunk_t version;
+
+       /**
+        * This flag allows the OS version to be empty
+        */
+       bool version_is_set;
+
+       /**
+        * OS Product Information (OS Name | OS Version)
+        */
+       char *info;
+
+};
+
+METHOD(imv_os_info_t, get_type, os_type_t,
+       private_imv_os_info_t *this)
+{
+       return this->type;
+}
+
+METHOD(imv_os_info_t, set_name, void,
+       private_imv_os_info_t *this, chunk_t name)
+{
+       /* Has the OS name already been set? */
+       if (this->name.len)
+       {
+               if (chunk_equals(name, this->name))
+               {
+                       return;
+               }
+               free(this->name.ptr);
+
+               /* Also clear the OS info string */
+               free(this->info);
+               this->info = NULL;
+       }
+       this->name = chunk_clone(name);
+       this->type = os_type_from_name(name); 
+}
+
+METHOD(imv_os_info_t, get_name, chunk_t,
+       private_imv_os_info_t *this)
+{
+       return this->name;
+}
+
+METHOD(imv_os_info_t, set_version, void,
+       private_imv_os_info_t *this, chunk_t version)
+{
+       /* Has the OS version already been set? */
+       if (this->version_is_set)
+       {
+               if (chunk_equals(version, this->version))
+               {
+                       return;
+               }
+               free(this->version.ptr);
+
+               /* Also clear the OS info string */
+               free(this->info);
+               this->info = NULL;
+       }
+       this->version = chunk_clone(version);
+       this->version_is_set = TRUE;
+}
+
+METHOD(imv_os_info_t, get_version, chunk_t,
+       private_imv_os_info_t *this)
+{
+       return this->version;
+}
+
+METHOD(imv_os_info_t, get_info, char*,
+       private_imv_os_info_t *this)
+{
+       int len;
+
+       if (!this->info)
+       {
+               /* Have both OS name and OS version been set? */
+               if (this->name.len == 0 || !this->version_is_set)
+               {
+                       return NULL;
+               }
+
+               /* OS info is a concatenation of OS name and OS version */
+               len = this->name.len + 1 + this->version.len + 1;
+               this->info = malloc(len);
+               snprintf(this->info, len, "%.*s %.*s",
+                               (int)this->name.len, this->name.ptr,
+                               (int)this->version.len, this->version.ptr);
+       }
+       return this->info;
+}
+
+METHOD(imv_os_info_t, destroy, void,
+       private_imv_os_info_t *this)
+{
+       free(this->name.ptr);
+       free(this->version.ptr);
+       free(this->info);
+       free(this);
+}
+
+/**
+ * See header
+ */
+imv_os_info_t *imv_os_info_create(void)
+{
+       private_imv_os_info_t *this;
+
+       INIT(this,
+               .public = {
+                       .get_type = _get_type,
+                       .set_name = _set_name,
+                       .get_name = _get_name,
+                       .set_version = _set_version,
+                       .get_version = _get_version,
+                       .get_info = _get_info,
+                       .destroy = _destroy,
+               },
+       );
+
+       return &this->public;
+}
diff --git a/src/libimcv/imv/imv_os_info.h b/src/libimcv/imv/imv_os_info.h
new file mode 100644 (file)
index 0000000..b68a17e
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2014 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 imv_os_info imv_os_info
+ * @{ @ingroup libimcv
+ */
+
+#ifndef IMV_OS_INFO_H_
+#define IMV_OS_INFO_H_
+
+typedef struct imv_os_info_t imv_os_info_t;
+
+#include "os_info/os_info.h"
+
+#include <library.h>
+
+/**
+ * Interface for the IMV Operating System (OS) information module
+ */
+struct imv_os_info_t {
+
+       /**
+        * Get the OS type
+        *
+        * @return                                      OS type
+        */
+       os_type_t (*get_type)(imv_os_info_t *this);
+
+       /**
+        * Set the OS product name or distribution
+        *
+        * @param name                          OS name
+        */
+       void (*set_name)(imv_os_info_t *this, chunk_t name);
+
+       /**
+        * Get the OS product name or distribution
+        *
+        * @return                                      OS name
+        */
+       chunk_t (*get_name)(imv_os_info_t *this);
+
+       /**
+        * Set the OS version or release
+        *
+        * @param version                       OS version
+        */
+       void (*set_version)(imv_os_info_t *this, chunk_t version);
+
+       /**
+        * Get the OS version or release
+        *
+        * @return                                      OS version
+        */
+       chunk_t (*get_version)(imv_os_info_t *this);
+
+       /**
+        * Get the OS version or release
+        *
+        * @return                                      OS name | OS version
+        */
+       char* (*get_info)(imv_os_info_t *this);
+
+       /**
+        * Destroys an imv_os_info_t object.
+        */
+       void (*destroy)(imv_os_info_t *this);
+};
+
+/**
+ * Create an imv_os_info_t object
+ */
+imv_os_info_t* imv_os_info_create(void);
+
+#endif /** IMV_OS_INFO_H_ @}*/
index 754f1f7..14fea2b 100644 (file)
@@ -35,11 +35,51 @@ struct private_imv_session_t {
        int session_id;
 
        /**
+        * Unique Product ID
+        */
+       int pid;
+
+       /**
+        * Unique Device ID
+        */
+       int did;
+
+       /**
         * TNCCS connection ID
         */
        TNC_ConnectionID conn_id;
 
        /**
+        * Session creation time
+        */
+       time_t created;
+
+       /**
+        * Access Requestor ID type
+        */
+       uint32_t ar_id_type;
+
+       /**
+        * Access Requestor ID value
+        */
+       chunk_t ar_id_value;
+
+       /**
+        * OS information
+        */
+       imv_os_info_t *os_info;
+
+       /**
+        * Device ID
+        */
+       chunk_t device_id;
+
+       /**
+        * Is Device ID trusted?
+        */
+       bool trusted;
+
+       /**
         * Have the workitems been generated?
         */
        bool policy_started;
@@ -56,9 +96,25 @@ struct private_imv_session_t {
 
 };
 
+METHOD(imv_session_t, set_session_id, void,
+       private_imv_session_t *this, int session_id, int pid, int did)
+{
+       this->session_id = session_id;
+       this->pid = pid;
+       this->did = did;
+}
+
 METHOD(imv_session_t, get_session_id, int,
-       private_imv_session_t *this)
+       private_imv_session_t *this, int *pid, int *did)
 {
+       if (pid)
+       {
+               *pid = this->pid;
+       }
+       if (did)
+       {
+               *did = this->did;
+       }
        return this->session_id;
 }
 
@@ -68,6 +124,72 @@ METHOD(imv_session_t, get_connection_id, TNC_ConnectionID,
        return this->conn_id;
 }
 
+METHOD(imv_session_t, get_creation_time, time_t,
+       private_imv_session_t *this)
+{
+       return this->created;
+}
+
+METHOD(imv_session_t, get_ar_id, chunk_t,
+       private_imv_session_t *this, uint32_t *ar_id_type)
+{
+       if (ar_id_type)
+       {
+               *ar_id_type = this->ar_id_type;
+       }
+       return this->ar_id_value;
+}
+
+METHOD(imv_session_t, get_os_info, imv_os_info_t*,
+       private_imv_session_t *this)
+{
+       return this->os_info;
+}
+
+METHOD(imv_session_t, set_device_id, void,
+       private_imv_session_t *this, chunk_t device_id)
+{
+       if (device_id.len == 0)
+       {
+               device_id = chunk_from_str("unknown");
+       }
+       if (this->device_id.len)
+       {
+               if (chunk_equals(device_id, this->device_id))
+               {
+                       return;
+               }
+               free(this->device_id.ptr);
+       }
+       this->device_id = chunk_clone(device_id);
+}
+
+METHOD(imv_session_t, get_device_id, bool,
+       private_imv_session_t *this, chunk_t *device_id)
+{
+       if (this->device_id.len == 0)
+       {
+               return FALSE;
+       }
+       if (device_id)
+       {
+               *device_id = this->device_id;
+       }
+       return TRUE;
+}
+
+METHOD(imv_session_t, set_device_trust, void,
+       private_imv_session_t *this, bool trusted)
+{
+       this->trusted = trusted;
+}
+
+METHOD(imv_session_t, get_device_trust, bool,
+       private_imv_session_t *this)
+{
+       return this->trusted;
+}
+
 METHOD(imv_session_t, set_policy_started, void,
        private_imv_session_t *this, bool start)
 {
@@ -137,6 +259,9 @@ METHOD(imv_session_t, destroy, void,
        {
                this->workitems->destroy_offset(this->workitems,
                                                                 offsetof(imv_workitem_t, destroy));
+               this->os_info->destroy(this->os_info);
+               free(this->ar_id_value.ptr);
+               free(this->device_id.ptr);
                free(this);
        }
 }
@@ -144,14 +269,23 @@ METHOD(imv_session_t, destroy, void,
 /**
  * See header
  */
-imv_session_t *imv_session_create(int session_id, TNC_ConnectionID conn_id)
+imv_session_t *imv_session_create(TNC_ConnectionID conn_id, time_t created,
+                                                                 uint32_t ar_id_type, chunk_t ar_id_value)
 {
        private_imv_session_t *this;
 
        INIT(this,
                .public = {
+                       .set_session_id = _set_session_id,
                        .get_session_id = _get_session_id,
                        .get_connection_id = _get_connection_id,
+                       .get_creation_time = _get_creation_time,
+                       .get_ar_id = _get_ar_id,
+                       .get_os_info = _get_os_info,
+                       .set_device_id = _set_device_id,
+                       .get_device_id = _get_device_id,
+                       .set_device_trust = _set_device_trust,
+                       .get_device_trust = _get_device_trust,
                        .set_policy_started = _set_policy_started,
                        .get_policy_started = _get_policy_started,
                        .insert_workitem = _insert_workitem,
@@ -161,8 +295,11 @@ imv_session_t *imv_session_create(int session_id, TNC_ConnectionID conn_id)
                        .get_ref = _get_ref,
                        .destroy = _destroy,
                },
-               .session_id = session_id,
                .conn_id = conn_id,
+               .created = created,
+               .ar_id_type = ar_id_type,
+               .ar_id_value = chunk_clone(ar_id_value),
+               .os_info = imv_os_info_create(),
                .workitems = linked_list_create(),
                .ref = 1,
        );
index 6b94523..42b9118 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Andreas Steffen
+ * Copyright (C) 2013-2014 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
 #define  IMV_SESSION_H_
 
 #include "imv_workitem.h"
+#include "imv_os_info.h"
 
 #include <tncifimv.h>
-
 #include <library.h>
 
+#include <time.h>
+
 typedef struct imv_session_t imv_session_t;
 
 /**
@@ -36,11 +38,22 @@ typedef struct imv_session_t imv_session_t;
 struct imv_session_t {
 
        /**
+        * Set unique session ID
+        *
+        * @param session_id    primary key into sessions table
+        * @param pid                   primary key into products table
+        * @param did                   Primary key into devices table
+        */
+       void (*set_session_id)(imv_session_t *this, int session_id, int pid, int did);
+
+       /**
         * Get unique session ID
         *
-        * @return                              Session ID
+        * @param pid                   primary key into products table
+        * @param did                   Primary key into devices table
+        * @return                              primary key into sessions table
         */
-       int (*get_session_id)(imv_session_t *this);
+       int (*get_session_id)(imv_session_t *this, int *pid, int *did);
 
        /**
         * Get TNCCS Connection ID
@@ -50,6 +63,58 @@ struct imv_session_t {
        TNC_ConnectionID (*get_connection_id)(imv_session_t *this);
 
        /**
+        * Get session creation time
+        *
+        * @return                              Session creation time
+        */
+       time_t (*get_creation_time)(imv_session_t *this);
+
+       /**
+        * Get Access Requestor ID
+        *
+        * @param id_type               Access Requestor TCG Standard ID Type
+        * @return                              Access Requestor TCG Standard ID Value
+        */
+       chunk_t (*get_ar_id)(imv_session_t *this, uint32_t *id_type);
+
+       /**
+        * Get OS Information
+        *
+        * @return                              OS info object
+        */
+       imv_os_info_t* (*get_os_info)(imv_session_t *this);
+
+       /**
+        * Set Device ID
+        *
+        * @param device_id             Device ID
+        */
+       void (*set_device_id)(imv_session_t *this, chunk_t device_id);
+
+       /**
+        * Get Device ID
+        *
+        * @param device_id             Device ID
+        * @return                              TRUE if Device ID has already been set
+        */
+       bool (*get_device_id)(imv_session_t *this, chunk_t *device_id);
+
+       /**
+        * Set trust into Device ID
+        *
+        * @param trusted               TRUE if Device ID is trusted
+        */
+       void (*set_device_trust)(imv_session_t *this, bool trusted);
+
+
+       /**
+        * Get device ID trust (needed for TPM-based attestation)
+        *
+        * @return                              TRUE if Device ID is trusted
+        */
+       bool (*get_device_trust)(imv_session_t *this);
+
+       /**
         * Set policy_started status
         *
         * @param start                 TRUE if policy started, FALSE if policy stopped
@@ -105,9 +170,12 @@ struct imv_session_t {
 /**
  * Create an imv_session_t instance
  *
- * @param session_id           Unique Session ID
  * @param id                           Associated Connection ID
+ * @param created                      Session creation time
+ * @param ar_id_type           Access Requestor ID type
+ * @param ar_id_value          Access Requestor ID value
  */
-imv_session_t* imv_session_create(int session_id, TNC_ConnectionID id);
+imv_session_t* imv_session_create(TNC_ConnectionID id, time_t created,
+                                                                 uint32_t ar_id_type, chunk_t ar_id_value);
 
 #endif /**  IMV_SESSION_H_ @}*/
diff --git a/src/libimcv/imv/imv_session_manager.c b/src/libimcv/imv/imv_session_manager.c
new file mode 100644 (file)
index 0000000..0fb8de4
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2014 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 "imv_session_manager.h"
+
+#include <threading/mutex.h>
+
+typedef struct private_imv_session_manager_t private_imv_session_manager_t;
+
+/**
+ * Private data of a imv_session_manager_t object.
+ */
+struct private_imv_session_manager_t {
+
+       /**
+        * Public imv_session_manager_t interface.
+        */
+       imv_session_manager_t public;
+
+       /**
+        * Session list
+        */
+       linked_list_t *sessions;
+
+       /**
+        * mutex used to lock session list
+        */
+       mutex_t *mutex;
+
+};
+
+METHOD(imv_session_manager_t, add_session, imv_session_t*,
+       private_imv_session_manager_t *this, TNC_ConnectionID conn_id,
+       uint32_t ar_id_type, chunk_t ar_id_value)
+{
+       enumerator_t *enumerator;
+       imv_session_t *current, *session = NULL;
+       time_t created;
+
+       this->mutex->lock(this->mutex);
+
+       /* check if a session has already been assigned */
+       enumerator = this->sessions->create_enumerator(this->sessions);
+       while (enumerator->enumerate(enumerator, &current))
+       {
+               if (conn_id == current->get_connection_id(current))
+               {
+                       session = current;
+                       break;
+               }
+       }
+       enumerator->destroy(enumerator);
+
+       /* session already exists */
+       if (session)
+       {
+               this->mutex->unlock(this->mutex);
+               return session->get_ref(session);
+       }
+
+       /* create a new session entry */
+       created = time(NULL);
+       session = imv_session_create(conn_id, created, ar_id_type, ar_id_value);
+       this->sessions->insert_last(this->sessions, session);
+
+       this->mutex->unlock(this->mutex);
+
+       return session;
+}
+
+METHOD(imv_session_manager_t, remove_session, void,
+       private_imv_session_manager_t *this, imv_session_t *session)
+{
+       enumerator_t *enumerator;
+       imv_session_t *current;
+
+       this->mutex->lock(this->mutex);
+       enumerator = this->sessions->create_enumerator(this->sessions);
+       while (enumerator->enumerate(enumerator, &current))
+       {
+               if (current == session)
+               {
+                       this->sessions->remove_at(this->sessions, enumerator);
+                       break;
+               }
+       }
+       enumerator->destroy(enumerator);
+       this->mutex->unlock(this->mutex);
+}
+
+METHOD(imv_session_manager_t, destroy, void,
+       private_imv_session_manager_t *this)
+{
+       this->sessions->destroy_offset(this->sessions,
+                                                       offsetof(imv_session_t, destroy));
+       this->mutex->destroy(this->mutex);
+       free(this);
+}
+
+/**
+ * See header
+ */
+imv_session_manager_t *imv_session_manager_create(void)
+{
+       private_imv_session_manager_t *this;
+
+       INIT(this,
+               .public = {
+                       .add_session = _add_session,
+                       .remove_session = _remove_session,
+                       .destroy = _destroy,
+               },
+               .sessions = linked_list_create(),
+               .mutex = mutex_create(MUTEX_TYPE_DEFAULT),
+       );
+
+       return &this->public;
+}
+
diff --git a/src/libimcv/imv/imv_session_manager.h b/src/libimcv/imv/imv_session_manager.h
new file mode 100644 (file)
index 0000000..8a733ac
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2014 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 imv_session_manager_t imv_session_manager
+ * @{ @ingroup libimcv_imv
+ */
+
+#ifndef IMV_SESSION_MANAGER_H_
+#define IMV_SESSION_MANAGER_H_
+
+#include "imv_session.h"
+
+#include <tncifimv.h>
+
+#include <library.h>
+
+typedef struct imv_session_manager_t imv_session_manager_t;
+
+/**
+ * IMV session manager interface 
+ */
+struct imv_session_manager_t {
+
+       /**
+        * Create or get a session associated with a TNCCS connection
+        *
+        * @param conn_id               TNCCS Connection ID
+        * @param ar_id_type    Access Requestor identity type
+        * @param ar_id_value   Access Requestor identity value
+        * @return                              Session associated with TNCCS Connection
+        */
+        imv_session_t* (*add_session)(imv_session_manager_t *this,
+                                                                  TNC_ConnectionID conn_id,
+                                                                  uint32_t ar_id_type, chunk_t ar_id_value);
+
+       /**
+        * Remove a session
+        *
+        * @param session               Session
+        */
+        void (*remove_session)(imv_session_manager_t *this, imv_session_t *session);
+
+
+       /**
+        * Destroys an imv_session_manager_t object
+        */
+       void (*destroy)(imv_session_manager_t *this);
+};
+
+/**
+ * Create an imv_session_manager_t instance
+ */
+imv_session_manager_t* imv_session_manager_create();
+
+#endif /** IMV_SESSION_MANAGER_H_ @}*/
index 791846b..d11d15e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2013 Andreas Steffen
+ * Copyright (C) 2011-2014 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -70,45 +70,28 @@ struct imv_state_t {
         *
         * @param max_msg_len   maximum size of a PA-TNC message
         */
-       void (*set_max_msg_len)(imv_state_t *this, u_int32_t max_msg_len);
+       void (*set_max_msg_len)(imv_state_t *this, uint32_t max_msg_len);
 
        /**
         * Get the maximum size of a PA-TNC message for this TNCCS connection
         *
         * @return                              maximum size of a PA-TNC message
         */
-       u_int32_t (*get_max_msg_len)(imv_state_t *this);
+       uint32_t (*get_max_msg_len)(imv_state_t *this);
 
        /**
         * Set flags for completed actions
         *
         * @param flags                 Flags to be set
         */
-       void (*set_action_flags)(imv_state_t *this, u_int32_t flags);
+       void (*set_action_flags)(imv_state_t *this, uint32_t flags);
 
        /**
         * Get flags set for completed actions
         *
         * @return                              Flags set for completed actions
         */
-       u_int32_t (*get_action_flags)(imv_state_t *this);
-
-       /**
-        * Set Access Requestor ID
-        *
-        * @param id_type               Access Requestor TCG Standard ID Type
-        * @param id_value              Access Requestor TCG Standard ID Value
-        *
-        */
-       void (*set_ar_id)(imv_state_t *this, u_int32_t id_type, chunk_t id_value);
-
-       /**
-        * Get Access Requestor ID
-        *
-        * @param id_type               Access Requestor TCG Standard ID Type
-        * @return                              Access Requestor TCG Standard ID Value
-        */
-       chunk_t (*get_ar_id)(imv_state_t *this, u_int32_t *id_type);
+       uint32_t (*get_action_flags)(imv_state_t *this);
 
        /**
         * Set session associated with TNCCS Connection
index a0f3a4e..45ae78c 100644 (file)
@@ -42,27 +42,11 @@ CREATE TABLE file_hashes (
   id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
   file INTEGER NOT NULL REFERENCES files(id),
   product INTEGER NOT NULL REFERENCES products(id),
-  device INTEGER DEFAULT 0,
-  key INTEGER DEFAULT 0 REFERENCES keys(id),
+  device INTEGER DEFAULT 0 REFERENCES devices(id),
   algo INTEGER NOT NULL REFERENCES algorithms(id),
   hash BLOB NOT NULL
 );
 
-DROP TABLE IF EXISTS keys;
-CREATE TABLE keys (
-  id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
-  keyid BLOB NOT NULL,
-  owner TEXT NOT NULL
-);
-DROP INDEX IF EXISTS keys_keyid;
-CREATE INDEX keys_keyid ON keys (
-  keyid
-);
-DROP INDEX IF EXISTS keys_owner;
-CREATE INDEX keys_owner ON keys (
-  owner
-);
-
 DROP TABLE IF EXISTS groups;
 CREATE TABLE groups (
   id INTEGER NOT NULL PRIMARY KEY,
@@ -159,17 +143,6 @@ CREATE TABLE components (
   qualifier INTEGER DEFAULT 0
 );
 
-
-DROP TABLE IF EXISTS key_component;
-CREATE TABLE key_component (
-  key INTEGER NOT NULL,
-  component INTEGER NOT NULL,
-  depth INTEGER DEFAULT 0,
-  seq_no INTEGER DEFAULT 0,
-  PRIMARY KEY (key, component)
-);
-
-
 DROP TABLE IF EXISTS component_hashes;
 CREATE TABLE component_hashes (
   component INTEGER NOT NULL,
@@ -217,6 +190,7 @@ CREATE TABLE devices (
   description TEXT DEFAULT '',
   value TEXT NOT NULL,
   product INTEGER REFERENCES products(id),
+  trusted INTEGER DEFAULT 0,
   created INTEGER
 );
 DROP INDEX IF EXISTS devices_id;
index 0642757..67b09cd 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 Andreas Steffen
+ * Copyright (C) 2012-2014 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
 
 #include "os_info.h"
 
-#include <sys/utsname.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#include <collections/linked_list.h>
-#include <utils/debug.h>
-
-typedef struct private_os_info_t private_os_info_t;
-
 ENUM(os_type_names, OS_TYPE_UNKNOWN, OS_TYPE_ANDROID,
        "Unknown",
        "Debian",
@@ -49,487 +40,6 @@ ENUM(os_package_state_names, OS_PACKAGE_STATE_UPDATE, OS_PACKAGE_STATE_BLACKLIST
 );
 
 /**
- * Private data of an os_info_t object.
- *
- */
-struct private_os_info_t {
-
-       /**
-        * Public os_info_t interface.
-        */
-       os_info_t public;
-
-       /**
-        * OS type
-        */
-       os_type_t type;
-
-       /**
-        * OS name
-        */
-       chunk_t name;
-
-       /**
-        * OS version
-        */
-       chunk_t version;
-
-};
-
-METHOD(os_info_t, get_type, os_type_t,
-       private_os_info_t *this)
-{
-       return this->type;
-}
-
-METHOD(os_info_t, get_name, chunk_t,
-       private_os_info_t *this)
-{
-       return this->name;
-}
-
-METHOD(os_info_t, get_numeric_version, void,
-       private_os_info_t *this, u_int32_t *major, u_int32_t *minor)
-{
-       u_char *pos;
-
-       if (major)
-       {
-               *major = atol(this->version.ptr);
-       }
-       pos = memchr(this->version.ptr, '.', this->version.len);
-       if (minor)
-       {
-               *minor = pos ? atol(pos + 1) : 0;
-       }
-}
-
-METHOD(os_info_t, get_version, chunk_t,
-       private_os_info_t *this)
-{
-       return this->version;
-}
-
-METHOD(os_info_t, get_fwd_status, os_fwd_status_t,
-       private_os_info_t *this)
-{
-       const char ip_forward[] = "/proc/sys/net/ipv4/ip_forward";
-       char buf[2];
-       FILE *file;
-
-       os_fwd_status_t fwd_status = OS_FWD_UNKNOWN;
-
-       file = fopen(ip_forward, "r");
-       if (file)
-       {
-               if (fread(buf, 1, 1, file) == 1)
-               {
-                       switch (buf[0])
-                       {
-                               case '0':
-                                       fwd_status = OS_FWD_DISABLED;
-                                       break;
-                               case '1':
-                                       fwd_status = OS_FWD_ENABLED;
-                                       break;
-                               default:
-                                       DBG1(DBG_IMC, "\"%s\" returns invalid value ", ip_forward);
-                                       break;
-                       }
-               }
-               else
-               {
-                       DBG1(DBG_IMC, "could not read from \"%s\"", ip_forward);
-               }
-               fclose(file);
-       }
-       else
-       {
-               DBG1(DBG_IMC, "failed to open \"%s\"", ip_forward);
-       }
-
-       return fwd_status;
-}
-
-METHOD(os_info_t, get_uptime, time_t,
-       private_os_info_t *this)
-{
-       const char proc_uptime[] = "/proc/uptime";
-       FILE *file;
-       u_int uptime;
-
-       file = fopen(proc_uptime, "r");
-       if (!file)
-       {
-               DBG1(DBG_IMC, "failed to open \"%s\"", proc_uptime);
-               return 0;
-       }
-       if (fscanf(file, "%u", &uptime) != 1)
-       {
-               DBG1(DBG_IMC, "failed to read file \"%s\"", proc_uptime);
-               uptime = 0;
-       }
-       fclose(file);
-
-       return uptime;
-}
-
-METHOD(os_info_t, get_setting, chunk_t,
-       private_os_info_t *this, char *name)
-{
-       FILE *file;
-       u_char buf[2048];
-       size_t i = 0;
-       chunk_t value;
-
-       if (!strpfx(name, "/etc/") && !strpfx(name, "/proc/") &&
-               !strpfx(name, "/sys/") && !strpfx(name, "/var/"))
-       {
-               /**
-                * In order to guarantee privacy, only settings from the
-                * /etc/, /proc/ and /sys/ directories can be retrieved
-                */
-               DBG1(DBG_IMC, "not allowed to access '%s'", name);
-
-               return chunk_empty;
-       }
-
-       file = fopen(name, "r");
-       if (!file)
-       {
-               DBG1(DBG_IMC, "failed to open '%s'", name);
-
-               return chunk_empty;
-       }
-       while (i < sizeof(buf) && fread(buf + i, 1, 1, file) == 1)
-       {
-               i++;
-       }
-       fclose(file);
-
-       value = chunk_create(buf, i);
-
-       return chunk_clone(value);
-}
-
-typedef struct {
-       /**
-        * implements enumerator_t
-        */
-       enumerator_t public;
-
-       /**
-        * package info pipe stream
-        */
-       FILE* file;
-
-       /**
-        * line buffer
-        */
-       u_char line[512];
-
-} package_enumerator_t;
-
-/**
- * Implementation of package_enumerator.destroy.
- */
-static void package_enumerator_destroy(package_enumerator_t *this)
-{
-       pclose(this->file);
-       free(this);
-}
-
-/**
- * Implementation of package_enumerator.enumerate
- */
-static bool package_enumerator_enumerate(package_enumerator_t *this, ...)
-{
-       chunk_t *name, *version;
-       u_char *pos;
-       va_list args;
-
-       while (TRUE)
-       {
-               if (!fgets(this->line, sizeof(this->line), this->file))
-               {
-                       return FALSE;
-               }
-
-               pos = strchr(this->line, '\t');
-               if (!pos)
-               {
-                       return FALSE;
-               }
-               *pos++ = '\0';
-
-               if (!streq(this->line, "install ok installed"))
-               {
-                       continue;
-               }
-               va_start(args, this);
-
-               name = va_arg(args, chunk_t*);
-               name->ptr = pos;
-               pos = strchr(pos, '\t');
-               if (!pos)
-               {
-                       va_end(args);
-                       return FALSE;
-               }
-               name->len = pos++ - name->ptr;
-
-               version = va_arg(args, chunk_t*);
-               version->ptr = pos;
-               version->len = strlen(pos) - 1;
-
-               va_end(args);
-               return TRUE;
-       }
-}
-
-METHOD(os_info_t, create_package_enumerator, enumerator_t*,
-       private_os_info_t *this)
-{
-       FILE *file;
-       const char command[] = "dpkg-query --show --showformat="
-                                                               "'${Status}\t${Package}\t${Version}\n'";
-       package_enumerator_t *enumerator;
-
-       /* Only Debian and Ubuntu package enumeration is currently supported */
-       if (this->type != OS_TYPE_DEBIAN && this->type != OS_TYPE_UBUNTU)
-       {
-               return NULL;
-       }
-
-       /* Open a pipe stream for reading the output of the dpkg-query commmand */
-       file = popen(command, "r");
-       if (!file)
-       {
-               DBG1(DBG_IMC, "failed to run dpkg command");
-               return NULL;
-       }
-
-       /* Create a package enumerator instance */
-       enumerator = malloc_thing(package_enumerator_t);
-       enumerator->public.enumerate = (void*)package_enumerator_enumerate;
-       enumerator->public.destroy = (void*)package_enumerator_destroy;
-       enumerator->file = file;
-
-       return (enumerator_t*)enumerator;
-}
-
-
-METHOD(os_info_t, destroy, void,
-       private_os_info_t *this)
-{
-       free(this->name.ptr);
-       free(this->version.ptr);
-       free(this);
-}
-
-#define RELEASE_LSB            0
-#define RELEASE_DEBIAN 1
-
-/**
- * Determine Linux distribution version and hardware platform
- */
-static bool extract_platform_info(os_type_t *type, chunk_t *name,
-                                                                 chunk_t *version)
-{
-       FILE *file;
-       u_char buf[BUF_LEN], *pos = buf;
-       int len = BUF_LEN - 1;
-       os_type_t os_type = OS_TYPE_UNKNOWN;
-       chunk_t os_name = chunk_empty;
-       chunk_t os_version = chunk_empty;
-       char *os_str;
-       struct utsname uninfo;
-       int i;
-
-       /* Linux/Unix distribution release info (from http://linuxmafia.com) */
-       const char* releases[] = {
-               "/etc/lsb-release",           "/etc/debian_version",
-               "/etc/SuSE-release",          "/etc/novell-release",
-               "/etc/sles-release",          "/etc/redhat-release",
-               "/etc/fedora-release",        "/etc/gentoo-release",
-               "/etc/slackware-version",     "/etc/annvix-release",
-               "/etc/arch-release",          "/etc/arklinux-release",
-               "/etc/aurox-release",         "/etc/blackcat-release",
-               "/etc/cobalt-release",        "/etc/conectiva-release",
-               "/etc/debian_release",        "/etc/immunix-release",
-               "/etc/lfs-release",           "/etc/linuxppc-release",
-               "/etc/mandrake-release",      "/etc/mandriva-release",
-               "/etc/mandrakelinux-release", "/etc/mklinux-release",
-               "/etc/pld-release",           "/etc/redhat_version",
-               "/etc/slackware-release",     "/etc/e-smith-release",
-               "/etc/release",               "/etc/sun-release",
-               "/etc/tinysofa-release",      "/etc/turbolinux-release",
-               "/etc/ultrapenguin-release",  "/etc/UnitedLinux-release",
-               "/etc/va-release",            "/etc/yellowdog-release"
-       };
-
-       const char lsb_distrib_id[]      = "DISTRIB_ID=";
-       const char lsb_distrib_release[] = "DISTRIB_RELEASE=";
-
-       for (i = 0; i < countof(releases); i++)
-       {
-               file = fopen(releases[i], "r");
-               if (!file)
-               {
-                       continue;
-               }
-
-               /* read release file into buffer */
-               fseek(file, 0, SEEK_END);
-               len = min(ftell(file), len);
-               rewind(file);
-               buf[len] = '\0';
-               if (fread(buf, 1, len, file) != len)
-               {
-                       DBG1(DBG_IMC, "failed to read file \"%s\"", releases[i]);
-                       fclose(file);
-                       return FALSE;
-               }
-               fclose(file);
-
-               DBG1(DBG_IMC, "processing \"%s\" file", releases[i]);
-
-               switch (i)
-               {
-                       case RELEASE_LSB:
-                       {
-                               /* Determine Distribution ID */
-                               pos = strstr(buf, lsb_distrib_id);
-                               if (!pos)
-                               {
-                                       DBG1(DBG_IMC, "failed to find begin of DISTRIB_ID field");
-                                       return FALSE;
-                               }
-                               pos += strlen(lsb_distrib_id);
-
-                               os_name.ptr = pos;
-
-                               pos = strchr(pos, '\n');
-                               if (!pos)
-                               {
-                                       DBG1(DBG_IMC, "failed to find end of DISTRIB_ID field");
-                                       return FALSE;
-                               }
-                               os_name.len = pos - os_name.ptr;
-
-                               /* Determine Distribution Release */
-                               pos = strstr(buf, lsb_distrib_release);
-                               if (!pos)
-                               {
-                                       DBG1(DBG_IMC, "failed to find begin of DISTRIB_RELEASE field");
-                                       return FALSE;
-                               }
-                               pos += strlen(lsb_distrib_release);
-
-                               os_version.ptr = pos;
-
-                               pos = strchr(pos, '\n');
-                               if (!pos)
-                               {
-                                       DBG1(DBG_IMC, "failed to find end of DISTRIB_RELEASE field");
-                                       return FALSE;
-                               }
-                               os_version.len = pos - os_version.ptr;
-
-                               break;
-                       }
-                       case RELEASE_DEBIAN:
-                       {
-                               os_type = OS_TYPE_DEBIAN;
-
-                               os_version.ptr = buf;
-                               pos = strchr(buf, '\n');
-                               if (!pos)
-                               {
-                                       DBG1(DBG_PTS, "failed to find end of release string");
-                                       return FALSE;
-                               }
-
-                               os_version.len = pos - os_version.ptr;
-
-                               break;
-                       }
-                       default:
-                       {
-                               const char str_release[] = " release ";
-
-                               os_name.ptr = buf;
-
-                               pos = strstr(buf, str_release);
-                               if (!pos)
-                               {
-                                       DBG1(DBG_IMC, "failed to find release keyword");
-                                       return FALSE;
-                               }
-
-                               os_name.len = pos - os_name.ptr;
-
-                               pos += strlen(str_release);
-                               os_version.ptr = pos;
-
-                               pos = strchr(pos, '\n');
-                               if (!pos)
-                               {
-                                       DBG1(DBG_IMC, "failed to find end of release string");
-                                       return FALSE;
-                               }
-
-                               os_version.len = pos - os_version.ptr;
-
-                               break;
-                       }
-               }
-               break;
-       }
-
-       if (!os_version.ptr)
-       {
-               DBG1(DBG_IMC, "no distribution release file found");
-               return FALSE;
-       }
-
-       if (uname(&uninfo) < 0)
-       {
-               DBG1(DBG_IMC, "could not retrieve machine architecture");
-               return FALSE;
-       }
-
-       /* Try to find a matching OS type based on the OS name */
-       if (os_type == OS_TYPE_UNKNOWN)
-       {
-               os_type = os_type_from_name(os_name);
-       }
-
-       /* If known use the official OS name */
-       if (os_type != OS_TYPE_UNKNOWN)
-       {
-               os_str = enum_to_name(os_type_names, os_type);
-               os_name = chunk_create(os_str, strlen(os_str));
-       }
-
-       /* copy OS type */
-       *type = os_type;
-
-       /* copy OS name */
-       *name = chunk_clone(os_name);
-
-       /* copy OS version and machine architecture */
-       *version = chunk_alloc(os_version.len + 1 + strlen(uninfo.machine));
-       pos = version->ptr;
-       memcpy(pos, os_version.ptr, os_version.len);
-       pos += os_version.len;
-       *pos++ = ' ';
-       memcpy(pos, uninfo.machine, strlen(uninfo.machine));
-
-       return TRUE;
-}
-
-/**
  * See header
  */
 os_type_t os_type_from_name(chunk_t name)
@@ -548,59 +58,3 @@ os_type_t os_type_from_name(chunk_t name)
        }
        return OS_TYPE_UNKNOWN;
 }
-
-/**
- * See header
- */
-os_info_t *os_info_create(void)
-{
-       private_os_info_t *this;
-       chunk_t name, version;
-       os_type_t type;
-
-       /* As an option OS name and OS version can be configured manually */
-       name.ptr = lib->settings->get_str(lib->settings,
-                                                                         "%s.imcv.os_info.name", NULL, lib->ns);
-       version.ptr = lib->settings->get_str(lib->settings,
-                                                                         "%s.imcv.os_info.version", NULL, lib->ns);
-       if (name.ptr && version.ptr)
-       {
-               name.len = strlen(name.ptr);
-               name = chunk_clone(name);
-
-               version.len = strlen(version.ptr);
-               version = chunk_clone(version);
-
-               type = os_type_from_name(name);
-       }
-       else
-       {
-               if (!extract_platform_info(&type, &name, &version))
-               {
-                       return NULL;
-               }
-       }
-       DBG1(DBG_IMC, "operating system name is '%.*s'",
-                                  name.len, name.ptr);
-       DBG1(DBG_IMC, "operating system version is '%.*s'",
-                                  version.len, version.ptr);
-
-       INIT(this,
-               .public = {
-                       .get_type = _get_type,
-                       .get_name = _get_name,
-                       .get_numeric_version = _get_numeric_version,
-                       .get_version = _get_version,
-                       .get_fwd_status = _get_fwd_status,
-                       .get_uptime = _get_uptime,
-                       .get_setting = _get_setting,
-                       .create_package_enumerator = _create_package_enumerator,
-                       .destroy = _destroy,
-               },
-               .type = type,
-               .name = name,
-               .version = version,
-       );
-
-       return &this->public;
-}
index f474607..e77d888 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 Andreas Steffen
+ * Copyright (C) 2012-2014 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -68,86 +68,11 @@ enum os_fwd_status_t {
 extern enum_name_t *os_fwd_status_names;
 
 /**
- * Interface for the Operating System (OS) information module
- */
-struct os_info_t {
-
-       /**
-        * Get the OS type if it can be determined
-        *
-        * @return                                      OS type
-        */
-       os_type_t (*get_type)(os_info_t *this);
-
-       /**
-        * Get the OS product name or distribution
-        *
-        * @return                                      OS name
-        */
-       chunk_t (*get_name)(os_info_t *this);
-
-       /**
-        * Get the numeric OS version or release
-        *
-        * @param major                         OS major version number
-        * @param minor                         OS minor version number
-        */
-       void (*get_numeric_version)(os_info_t *this, u_int32_t *major,
-                                                                                                u_int32_t *minor);
-
-       /**
-        * Get the OS version or release
-        *
-        * @return                                      OS version
-        */
-       chunk_t (*get_version)(os_info_t *this);
-
-       /**
-        * Get the OS IPv4 forwarding status
-        *
-        * @return                                      IP forwarding status
-        */
-       os_fwd_status_t (*get_fwd_status)(os_info_t *this);
-
-       /**
-        * Get the OS uptime in seconds
-        *
-        * @return                                      OS uptime
-        */
-       time_t (*get_uptime)(os_info_t *this);
-
-       /**
-        * Get an OS setting (restricted to /proc, /sys, and /etc)
-        *
-        * @param name                          name of OS setting
-        * @return                                      value of OS setting
-        */
-       chunk_t (*get_setting)(os_info_t *this, char *name);
-
-       /**
-        * Enumerates over all installed packages
-        *
-        * @return                              return package enumerator
-        */
-       enumerator_t* (*create_package_enumerator)(os_info_t *this);
-
-       /**
-        * Destroys an os_info_t object.
-        */
-       void (*destroy)(os_info_t *this);
-};
-
-/**
  * Convert an OS name into an OS enumeration type
  *
- * @param name                         OS name
- * @return                                     OS enumeration type
+ * @param name                                                 OS name
+ * @return                                                             OS enumeration type
  */
 os_type_t os_type_from_name(chunk_t name);
 
-/**
- * Create an os_info_t object
- */
-os_info_t* os_info_create(void);
-
 #endif /** OS_INFO_H_ @}*/
index 1c7d589..7d84249 100644 (file)
@@ -17,6 +17,7 @@
 
 #include <imc/imc_agent.h>
 #include <imc/imc_msg.h>
+#include <imc/imc_os_info.h>
 #include <ietf/ietf_attr.h>
 #include <ietf/ietf_attr_attr_request.h>
 #include <ietf/ietf_attr_default_pwd_enabled.h>
@@ -31,7 +32,6 @@
 #include <ita/ita_attr_settings.h>
 #include <ita/ita_attr_angel.h>
 #include <ita/ita_attr_device_id.h>
-#include <os_info/os_info.h>
 
 #include <tncif_pa_subtypes.h>
 
@@ -47,7 +47,7 @@ static pen_type_t msg_types[] = {
 };
 
 static imc_agent_t *imc_os;
-static os_info_t *os;
+static imc_os_info_t *os;
 
 /**
  * see section 3.8.1 of TCG TNC IF-IMC Specification 1.3
@@ -69,7 +69,7 @@ TNC_Result TNC_IMC_Initialize(TNC_IMCID imc_id,
                return TNC_RESULT_FATAL;
        }
 
-       os = os_info_create();
+       os = imc_os_info_create();
        if (!os)
        {
                imc_os->destroy(imc_os);
index 84a24b4..874f0a5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Andreas Steffen
+ * Copyright (C) 2013-2014 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -134,7 +134,13 @@ METHOD(imv_agent_if_t, notify_connection_change, TNC_Result,
                                }
                                session = state->get_session(state);
                                imcv_db->add_recommendation(imcv_db, session, rec);
-                               imcv_db->policy_script(imcv_db, session, FALSE);
+                               if (session->get_policy_started(session))
+                               {
+                                       if (!imcv_db->policy_script(imcv_db, session, FALSE))
+                                       {
+                                               DBG1(DBG_IMV, "error in policy script stop");
+                                       }
+                               }
                        }
                        /* fall through to default state */
                default:
@@ -150,6 +156,8 @@ static TNC_Result receive_msg(private_imv_os_agent_t *this, imv_state_t *state,
 {
        imv_msg_t *out_msg;
        imv_os_state_t *os_state;
+       imv_session_t *session;
+       imv_os_info_t *os_info = NULL;
        enumerator_t *enumerator;
        pa_tnc_attr_t *attr;
        pen_type_t type;
@@ -159,6 +167,8 @@ static TNC_Result receive_msg(private_imv_os_agent_t *this, imv_state_t *state,
        bool fatal_error = FALSE, assessment = FALSE;
 
        os_state = (imv_os_state_t*)state;
+       session = state->get_session(state);
+       os_info = session->get_os_info(session);
 
        /* parse received PA-TNC message and handle local and remote errors */
        result = in_msg->receive(in_msg, &fatal_error);
@@ -188,6 +198,8 @@ static TNC_Result receive_msg(private_imv_os_agent_t *this, imv_state_t *state,
                                                                                        IMV_OS_ATTR_PRODUCT_INFORMATION);
                                        attr_cast = (ietf_attr_product_info_t*)attr;
                                        os_name = attr_cast->get_info(attr_cast, &vendor_id, NULL);
+                                       os_info->set_name(os_info, os_name);
+
                                        if (vendor_id != PEN_IETF)
                                        {
                                                DBG1(DBG_IMV, "operating system name is '%.*s' "
@@ -209,6 +221,8 @@ static TNC_Result receive_msg(private_imv_os_agent_t *this, imv_state_t *state,
                                                                                        IMV_OS_ATTR_STRING_VERSION);
                                        attr_cast = (ietf_attr_string_version_t*)attr;
                                        os_version = attr_cast->get_version(attr_cast, NULL, NULL);
+                                       os_info->set_version(os_info, os_version);
+
                                        if (os_version.len)
                                        {
                                                DBG1(DBG_IMV, "operating system version is '%.*s'",
@@ -350,8 +364,8 @@ static TNC_Result receive_msg(private_imv_os_agent_t *this, imv_state_t *state,
                                        state->set_action_flags(state, IMV_OS_ATTR_DEVICE_ID);
 
                                        value = attr->get_value(attr);
-                                       os_state->set_device_id(os_state, value);
                                        DBG1(DBG_IMV, "device ID is %.*s", value.len, value.ptr);
+                                       session->set_device_id(session, value);
                                        break;
                                }
                                case ITA_ATTR_START_ANGEL:
@@ -367,25 +381,6 @@ static TNC_Result receive_msg(private_imv_os_agent_t *this, imv_state_t *state,
        }
        enumerator->destroy(enumerator);
 
-       /**
-        * The IETF Product Information and String Version attributes
-        * are supposed to arrive in the same PA-TNC message
-        */
-       if (os_name.len && os_version.len)
-       {
-               os_type_t os_type;
-
-               /* set the OS type, name and version */
-               os_type = os_type_from_name(os_name);
-               os_state->set_info(os_state,os_type, os_name, os_version);
-
-               if (imcv_db)
-               {
-                       imcv_db->add_product(imcv_db, state->get_session(state),
-                                       os_state->get_info(os_state, NULL, NULL, NULL));
-               }
-       }
-
        if (fatal_error)
        {
                state->set_recommendation(state,
@@ -542,56 +537,69 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result,
 
        if (handshake_state < IMV_OS_STATE_POLICY_START)
        {
-               if (((received & IMV_OS_ATTR_PRODUCT_INFORMATION) &&
-                        (received & IMV_OS_ATTR_STRING_VERSION)) &&
-                       ((received & IMV_OS_ATTR_DEVICE_ID) ||
-                        (handshake_state == IMV_OS_STATE_ATTR_REQ)))
+               if (session->get_policy_started(session))
+               {
+                       /* the policy script has already been started by another IMV */
+                       handshake_state = IMV_OS_STATE_POLICY_START;
+               }
+               else
                {
-                       if (imcv_db)
+                       if (((received & IMV_OS_ATTR_PRODUCT_INFORMATION) &&
+                                (received & IMV_OS_ATTR_STRING_VERSION)) &&
+                               ((received & IMV_OS_ATTR_DEVICE_ID) ||
+                                (handshake_state == IMV_OS_STATE_ATTR_REQ)))
                        {
-                               imcv_db->add_device(imcv_db, session,
-                                                               os_state->get_device_id(os_state));
-
-                               /* trigger the policy manager */
-                               imcv_db->policy_script(imcv_db, session, TRUE);
+                               if (!session->get_device_id(session, NULL))
+                               {
+                                       session->set_device_id(session, chunk_empty);
+                               }
+                               if (imcv_db)
+                               {
+                                       /* start the policy script */
+                                       if (!imcv_db->policy_script(imcv_db, session, TRUE))
+                                       {
+                                               DBG1(DBG_IMV, "error in policy script start");
+                                       }
+                               }
+                               else
+                               {
+                                       DBG2(DBG_IMV, "no workitems available - "
+                                                                 "no evaluation possible");
+                                       state->set_recommendation(state,
+                                                                       TNC_IMV_ACTION_RECOMMENDATION_ALLOW,
+                                                                       TNC_IMV_EVALUATION_RESULT_DONT_KNOW);
+                               }
+                               handshake_state = IMV_OS_STATE_POLICY_START;
                        }
-                       else
+                       else if (handshake_state == IMV_OS_STATE_ATTR_REQ)
                        {
-                               DBG2(DBG_IMV, "no workitems available - no evaluation possible");
+                               /**
+                                * both the IETF Product Information and IETF String Version
+                                * attribute should have been present
+                                */
                                state->set_recommendation(state,
-                                                               TNC_IMV_ACTION_RECOMMENDATION_ALLOW,
-                                                               TNC_IMV_EVALUATION_RESULT_DONT_KNOW);
-                       }
-                       handshake_state = IMV_OS_STATE_POLICY_START;
-               }
-               else if (handshake_state == IMV_OS_STATE_ATTR_REQ)
-               {
-                       /**
-                        * both the IETF Product Information and IETF String Version
-                        * attribute should have been present
-                        */
-                       state->set_recommendation(state,
                                                                TNC_IMV_ACTION_RECOMMENDATION_NO_RECOMMENDATION,
                                                                TNC_IMV_EVALUATION_RESULT_ERROR);
 
-                       /* send assessment */
-                       result = out_msg->send_assessment(out_msg);
-                       out_msg->destroy(out_msg);
+                               /* send assessment */
+                               result = out_msg->send_assessment(out_msg);
+                               out_msg->destroy(out_msg);
 
-                       if (result != TNC_RESULT_SUCCESS)
+                               if (result != TNC_RESULT_SUCCESS)
+                               {
+                                       return result;
+                               }  
+                               return this->agent->provide_recommendation(this->agent, state);
+                       }
+                       else
                        {
-                               return result;
-                       }  
-                       return this->agent->provide_recommendation(this->agent, state);
-               }
-               else
-               {
-                       handshake_state = IMV_OS_STATE_ATTR_REQ;
+                               handshake_state = IMV_OS_STATE_ATTR_REQ;
+                       }
                }
                os_state->set_handshake_state(os_state, handshake_state);
        }
 
-       if (handshake_state == IMV_OS_STATE_POLICY_START && session)
+       if (handshake_state == IMV_OS_STATE_POLICY_START)
        {
                enumerator = session->create_workitem_enumerator(session);
                if (enumerator)
@@ -638,7 +646,7 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result,
                }
        }
 
-       if (handshake_state == IMV_OS_STATE_WORKITEMS && session)
+       if (handshake_state == IMV_OS_STATE_WORKITEMS)
        {
                TNC_IMV_Evaluation_Result eval;
                TNC_IMV_Action_Recommendation rec;
index 12cf207..106d56a 100644 (file)
@@ -41,19 +41,26 @@ struct private_imv_os_database_t {
 };
 
 METHOD(imv_os_database_t, check_packages, status_t,
-       private_imv_os_database_t *this, imv_os_state_t *state,
+       private_imv_os_database_t *this, imv_os_state_t *os_state,
        enumerator_t *package_enumerator)
 {
+       imv_state_t *state;
+       imv_session_t *session;
+       imv_os_info_t *os_info;
+       os_type_t os_type;
        char *product, *package, *release, *cur_release;
        chunk_t name, version;
-       os_type_t os_type;
        int pid, gid, security, blacklist;
        int count = 0, count_ok = 0, count_no_match = 0, count_blacklist = 0;
        enumerator_t *e;
        status_t status = SUCCESS;
        bool found, match;
 
-       product = state->get_info(state, &os_type, NULL, NULL);
+       state = &os_state->interface;
+       session = state->get_session(state);
+       os_info = session->get_os_info(session);
+       os_type = os_info->get_type(os_info);
+       product = os_info->get_info(os_info);
 
        if (os_type == OS_TYPE_ANDROID)
        {
@@ -143,8 +150,8 @@ METHOD(imv_os_database_t, check_packages, status_t,
                                        DBG2(DBG_IMV, "package '%s' (%s) is blacklisted",
                                                                   package, release);
                                        count_blacklist++;
-                                       state->add_bad_package(state, package,
-                                                                                  OS_PACKAGE_STATE_BLACKLIST);
+                                       os_state->add_bad_package(os_state, package,
+                                                                                         OS_PACKAGE_STATE_BLACKLIST);
                                }
                                else
                                {
@@ -157,8 +164,8 @@ METHOD(imv_os_database_t, check_packages, status_t,
                        {
                                DBG1(DBG_IMV, "package '%s' (%s) no match", package, release);
                                count_no_match++;
-                               state->add_bad_package(state, package,
-                                                                          OS_PACKAGE_STATE_SECURITY);
+                               os_state->add_bad_package(os_state, package,
+                                                                                 OS_PACKAGE_STATE_SECURITY);
                        }
                }
                else
@@ -168,7 +175,8 @@ METHOD(imv_os_database_t, check_packages, status_t,
                free(package);
                free(release);
        }
-       state->set_count(state, count, count_no_match, count_blacklist, count_ok);
+       os_state->set_count(os_state, count, count_no_match,
+                                                                 count_blacklist, count_ok);
 
        return status;
 }
index 4f5a4b0..dc8474a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012-2013 Andreas Steffen
+ * Copyright (C) 2012-2014 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -18,6 +18,7 @@
 #include "imv/imv_lang_string.h"
 #include "imv/imv_reason_string.h"
 #include "imv/imv_remediation_string.h"
+#include "imv/imv_os_info.h"
 
 #include <tncif_policy.h>
 
@@ -62,22 +63,12 @@ struct private_imv_os_state_t {
        /**
         * Maximum PA-TNC message size for this TNCCS connection
         */
-       u_int32_t max_msg_len;
+       uint32_t max_msg_len;
 
        /**
         * Flags set for completed actions
         */
-       u_int32_t action_flags;
-
-       /**
-        * Access Requestor ID Type
-        */
-       u_int32_t ar_id_type;
-
-       /**
-        * Access Requestor ID Value
-        */
-       chunk_t ar_id_value;
+       uint32_t action_flags;
 
        /**
         * IMV database session associated with TNCCS connection
@@ -100,32 +91,12 @@ struct private_imv_os_state_t {
        imv_os_handshake_state_t handshake_state;
 
        /**
-        * OS Product Information (concatenation of OS Name and Version)
-        */
-       char *info;
-
-       /**
-        * OS Type
-        */
-       os_type_t type;
-
-       /**
-        * OS Name
-        */
-       chunk_t name;
-
-       /**
-        * OS Version
-        */
-       chunk_t version;
-
-       /**
         * List of blacklisted packages to be removed
         */
        linked_list_t *remove_packages;
 
        /**
-        * List of vulnerable packages to be updated
+        h* List of vulnerable packages to be updated
         */
        linked_list_t *update_packages;
 
@@ -140,11 +111,6 @@ struct private_imv_os_state_t {
        imv_remediation_string_t *remediation_string;
 
        /**
-        * Dgevice ID
-        */
-       chunk_t device_id;
-
-       /**
         * Number of processed packages
         */
        int count;
@@ -326,46 +292,29 @@ METHOD(imv_state_t, set_flags, void,
 }
 
 METHOD(imv_state_t, set_max_msg_len, void,
-       private_imv_os_state_t *this, u_int32_t max_msg_len)
+       private_imv_os_state_t *this, uint32_t max_msg_len)
 {
        this->max_msg_len = max_msg_len;
 }
 
-METHOD(imv_state_t, get_max_msg_len, u_int32_t,
+METHOD(imv_state_t, get_max_msg_len, uint32_t,
        private_imv_os_state_t *this)
 {
        return this->max_msg_len;
 }
 
 METHOD(imv_state_t, set_action_flags, void,
-       private_imv_os_state_t *this, u_int32_t flags)
+       private_imv_os_state_t *this, uint32_t flags)
 {
        this->action_flags |= flags;
 }
 
-METHOD(imv_state_t, get_action_flags, u_int32_t,
+METHOD(imv_state_t, get_action_flags, uint32_t,
        private_imv_os_state_t *this)
 {
        return this->action_flags;
 }
 
-METHOD(imv_state_t, set_ar_id, void,
-       private_imv_os_state_t *this, u_int32_t id_type, chunk_t id_value)
-{
-       this->ar_id_type = id_type;
-       this->ar_id_value = chunk_clone(id_value);
-}
-
-METHOD(imv_state_t, get_ar_id, chunk_t,
-       private_imv_os_state_t *this, u_int32_t *id_type)
-{
-       if (id_type)
-       {
-               *id_type = this->ar_id_type;
-       }
-       return this->ar_id_value;
-}
-
 METHOD(imv_state_t, set_session, void,
        private_imv_os_state_t *this, imv_session_t *session)
 {
@@ -440,6 +389,9 @@ METHOD(imv_state_t, get_remediation_instructions, bool,
        private_imv_os_state_t *this, enumerator_t *language_enumerator,
        chunk_t *string, char **lang_code, char **uri)
 {
+       imv_os_info_t *os_info;
+       bool as_xml = FALSE;
+
        if (!this->count_update && !this->count_blacklist & !this->os_settings)
        {
                return FALSE;
@@ -449,8 +401,12 @@ METHOD(imv_state_t, get_remediation_instructions, bool,
 
        /* Instantiate an IETF Remediation Instructions String object */
        DESTROY_IF(this->remediation_string);
-       this->remediation_string = imv_remediation_string_create(
-                                                                       this->type == OS_TYPE_ANDROID, *lang_code);
+       if (this->session)
+       {
+               os_info = this->session->get_os_info(this->session);
+               as_xml = os_info->get_type(os_info) == OS_TYPE_ANDROID;
+       }
+       this->remediation_string = imv_remediation_string_create(as_xml, *lang_code);
 
        /* List of blacklisted packages to be removed, if any */
        if (this->count_blacklist)
@@ -507,11 +463,6 @@ METHOD(imv_state_t, destroy, void,
        DESTROY_IF(this->remediation_string);
        this->update_packages->destroy_function(this->update_packages, free);
        this->remove_packages->destroy_function(this->remove_packages, free);
-       free(this->info);
-       free(this->name.ptr);
-       free(this->version.ptr);
-       free(this->ar_id_value.ptr);
-       free(this->device_id.ptr);
        free(this);
 }
 
@@ -527,39 +478,6 @@ METHOD(imv_os_state_t, get_handshake_state, imv_os_handshake_state_t,
        return this->handshake_state;
 }
 
-METHOD(imv_os_state_t, set_info, void,
-       private_imv_os_state_t *this, os_type_t type, chunk_t name, chunk_t version)
-{
-       int len = name.len + 1 + version.len + 1;
-
-       /* OS info is a concatenation of OS name and OS version */
-       free(this->info);
-       this->info = malloc(len);
-       snprintf(this->info, len, "%.*s %.*s", (int)name.len, name.ptr,
-                                                                                  (int)version.len, version.ptr);
-       this->type = type;
-       this->name = chunk_clone(name);
-       this->version = chunk_clone(version);
-}
-
-METHOD(imv_os_state_t, get_info, char*,
-       private_imv_os_state_t *this, os_type_t *type, chunk_t *name,
-       chunk_t *version)
-{
-       if (type)
-       {
-               *type = this->type;
-       }
-       if (name)
-       {
-               *name = this->name;
-       }
-       if (version)
-       {
-               *version = this->version;
-       }
-       return this->info;
-}
 
 METHOD(imv_os_state_t, set_count, void,
        private_imv_os_state_t *this, int count, int count_update,
@@ -593,18 +511,6 @@ METHOD(imv_os_state_t, get_count, void,
        }
 }
 
-METHOD(imv_os_state_t, set_device_id, void,
-       private_imv_os_state_t *this, chunk_t id)
-{
-       this->device_id = chunk_clone(id);
-}
-
-METHOD(imv_os_state_t, get_device_id, chunk_t,
-       private_imv_os_state_t *this)
-{
-       return this->device_id;
-}
-
 METHOD(imv_os_state_t, set_os_settings, void,
        private_imv_os_state_t *this, u_int settings)
 {
@@ -663,8 +569,6 @@ imv_state_t *imv_os_state_create(TNC_ConnectionID connection_id)
                                .get_max_msg_len = _get_max_msg_len,
                                .set_action_flags = _set_action_flags,
                                .get_action_flags = _get_action_flags,
-                               .set_ar_id = _set_ar_id,
-                               .get_ar_id = _get_ar_id,
                                .set_session = _set_session,
                                .get_session = _get_session,
                                .change_state = _change_state,
@@ -677,12 +581,8 @@ imv_state_t *imv_os_state_create(TNC_ConnectionID connection_id)
                        },
                        .set_handshake_state = _set_handshake_state,
                        .get_handshake_state = _get_handshake_state,
-                       .set_info = _set_info,
-                       .get_info = _get_info,
                        .set_count = _set_count,
                        .get_count = _get_count,
-                       .set_device_id = _set_device_id,
-                       .get_device_id = _get_device_id,
                        .set_os_settings = _set_os_settings,
                        .get_os_settings = _get_os_settings,
                        .set_angel_count = _set_angel_count,
index 97f6953..82ebb6c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012 Andreas Steffen
+ * Copyright (C) 2012-2014 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -78,27 +78,6 @@ struct imv_os_state_t {
        imv_os_handshake_state_t (*get_handshake_state)(imv_os_state_t *this);
 
        /**
-        * Set OS Product Information
-        *
-        * @param type                  OS type (enumerated)
-        * @param name                  OS name (string)
-        * @param version               OS version
-        */
-       void (*set_info)(imv_os_state_t *this, os_type_t os_type,
-                                        chunk_t name, chunk_t version);
-
-       /**
-        * Get OS Product Information
-        *
-        * @param type                  OS type (enumerated)
-        * @param name                  OS name (string)
-        * @param version               OS version
-        * @return                              OS name & version as a concatenated string
-        */
-       char* (*get_info)(imv_os_state_t *this, os_type_t *os_type,
-                                         chunk_t *name, chunk_t *version);
-
-       /**
         * Set [or with multiple attributes increment] package counters
         *
         * @param count                         Number of processed packages
@@ -121,20 +100,6 @@ struct imv_os_state_t {
                                          int *count_blacklist, int *count_ok);
 
        /**
-        * Set device ID
-        *
-        * @param device_id             Device ID
-        */
-       void (*set_device_id)(imv_os_state_t *this, chunk_t id);
-
-       /**
-        * Get device ID
-        *
-        * @return                              Device ID
-        */
-       chunk_t (*get_device_id)(imv_os_state_t *this);
-
-       /**
         * Set OS settings
         *
         * @param settings              OS settings
index d1e0931..85ef23b 100644 (file)
@@ -259,7 +259,7 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result,
        out_msg = imv_msg_create(this->agent, state, id, imv_id, TNC_IMCID_ANY,
                                                         msg_types[0]);
 
-       if (!session)
+       if (!imcv_db)
        {
                DBG2(DBG_IMV, "no workitems available - no evaluation possible");
                state->set_recommendation(state,
@@ -276,7 +276,8 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result,
                return this->agent->provide_recommendation(this->agent, state);
        }
 
-       if (handshake_state == IMV_SCANNER_STATE_INIT)
+       if (handshake_state == IMV_SCANNER_STATE_INIT &&
+               session->get_policy_started(session))
        {
                enumerator = session->create_workitem_enumerator(session);
                if (enumerator)
index 90475d3..24a49a7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011-2013 Andreas Steffen
+ * Copyright (C) 2011-2014 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -58,22 +58,12 @@ struct private_imv_scanner_state_t {
        /**
         * Maximum PA-TNC message size for this TNCCS connection
         */
-       u_int32_t max_msg_len;
+       uint32_t max_msg_len;
 
        /**
         * Flags set for completed actions
         */
-       u_int32_t action_flags;
-
-       /**
-        * Access Requestor ID Type
-        */
-       u_int32_t ar_id_type;
-
-       /**
-        * Access Requestor ID Value
-        */
-       chunk_t ar_id_value;
+       uint32_t action_flags;
 
        /**
         * IMV database session associatied with TNCCS connection
@@ -186,46 +176,29 @@ METHOD(imv_state_t, set_flags, void,
 }
 
 METHOD(imv_state_t, set_max_msg_len, void,
-       private_imv_scanner_state_t *this, u_int32_t max_msg_len)
+       private_imv_scanner_state_t *this, uint32_t max_msg_len)
 {
        this->max_msg_len = max_msg_len;
 }
 
-METHOD(imv_state_t, get_max_msg_len, u_int32_t,
+METHOD(imv_state_t, get_max_msg_len, uint32_t,
        private_imv_scanner_state_t *this)
 {
        return this->max_msg_len;
 }
 
 METHOD(imv_state_t, set_action_flags, void,
-       private_imv_scanner_state_t *this, u_int32_t flags)
+       private_imv_scanner_state_t *this, uint32_t flags)
 {
        this->action_flags |= flags;
 }
 
-METHOD(imv_state_t, get_action_flags, u_int32_t,
+METHOD(imv_state_t, get_action_flags, uint32_t,
        private_imv_scanner_state_t *this)
 {
        return this->action_flags;
 }
 
-METHOD(imv_state_t, set_ar_id, void,
-       private_imv_scanner_state_t *this, u_int32_t id_type, chunk_t id_value)
-{
-       this->ar_id_type = id_type;
-       this->ar_id_value = chunk_clone(id_value);
-}
-
-METHOD(imv_state_t, get_ar_id, chunk_t,
-       private_imv_scanner_state_t *this, u_int32_t *id_type)
-{
-       if (id_type)
-       {
-               *id_type = this->ar_id_type;
-       }
-       return this->ar_id_value;
-}
-
 METHOD(imv_state_t, set_session, void,
        private_imv_scanner_state_t *this, imv_session_t *session)
 {
@@ -327,7 +300,6 @@ METHOD(imv_state_t, destroy, void,
        DESTROY_IF(this->remediation_string);
        DESTROY_IF(&this->port_filter_attr->pa_tnc_attribute);
        this->violating_ports->destroy_function(this->violating_ports, free);
-       free(this->ar_id_value.ptr);
        free(this);
 }
 
@@ -380,8 +352,6 @@ imv_state_t *imv_scanner_state_create(TNC_ConnectionID connection_id)
                                .get_max_msg_len = _get_max_msg_len,
                                .set_action_flags = _set_action_flags,
                                .get_action_flags = _get_action_flags,
-                               .set_ar_id = _set_ar_id,
-                               .get_ar_id = _get_ar_id,
                                .set_session = _set_session,
                                .get_session= _get_session,
                                .change_state = _change_state,
index f05db80..3564456 100644 (file)
@@ -58,17 +58,7 @@ struct private_imv_test_state_t {
        /**
         * Maximum PA-TNC message size for this TNCCS connection
         */
-       u_int32_t max_msg_len;
-
-       /**
-        * Access Requestor ID Type
-        */
-       u_int32_t ar_id_type;
-
-       /**
-        * Access Requestor ID Value
-        */
-       chunk_t ar_id_value;
+       uint32_t max_msg_len;
 
        /**
         * IMV database session associated with TNCCS connection
@@ -149,34 +139,17 @@ METHOD(imv_state_t, set_flags, void,
 }
 
 METHOD(imv_state_t, set_max_msg_len, void,
-       private_imv_test_state_t *this, u_int32_t max_msg_len)
+       private_imv_test_state_t *this, uint32_t max_msg_len)
 {
        this->max_msg_len = max_msg_len;
 }
 
-METHOD(imv_state_t, get_max_msg_len, u_int32_t,
+METHOD(imv_state_t, get_max_msg_len, uint32_t,
        private_imv_test_state_t *this)
 {
        return this->max_msg_len;
 }
 
-METHOD(imv_state_t, set_ar_id, void,
-       private_imv_test_state_t *this, u_int32_t id_type, chunk_t id_value)
-{
-       this->ar_id_type = id_type;
-       this->ar_id_value = chunk_clone(id_value);
-}
-
-METHOD(imv_state_t, get_ar_id, chunk_t,
-       private_imv_test_state_t *this, u_int32_t *id_type)
-{
-       if (id_type)
-       {
-               *id_type = this->ar_id_type;
-       }
-       return this->ar_id_value;
-}
-
 METHOD(imv_state_t, set_session, void,
        private_imv_test_state_t *this, imv_session_t *session)
 {
@@ -248,7 +221,6 @@ METHOD(imv_state_t, destroy, void,
        DESTROY_IF(this->session);
        DESTROY_IF(this->reason_string);
        this->imcs->destroy_function(this->imcs, free);
-       free(this->ar_id_value.ptr);
        free(this);
 }
 
@@ -333,8 +305,6 @@ imv_state_t *imv_test_state_create(TNC_ConnectionID connection_id)
                                .set_flags = _set_flags,
                                .set_max_msg_len = _set_max_msg_len,
                                .get_max_msg_len = _get_max_msg_len,
-                               .set_ar_id = _set_ar_id,
-                               .get_ar_id = _get_ar_id,
                                .set_session = _set_session,
                                .get_session = _get_session,
                                .change_state = _change_state,
index ae2660b..1201319 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2011-2012 Sansar Choinyambuu
- * Copyright (C) 2011-2013 Andreas Steffen
+ * Copyright (C) 2011-2014 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -25,6 +25,8 @@
 #include <imcv.h>
 #include <imv/imv_agent.h>
 #include <imv/imv_msg.h>
+#include <imv/imv_session.h>
+#include <imv/imv_os_info.h>
 #include <ietf/ietf_attr.h>
 #include <ietf/ietf_attr_attr_request.h>
 #include <ietf/ietf_attr_pa_tnc_error.h>
@@ -131,15 +133,14 @@ METHOD(imv_agent_if_t, notify_connection_change, TNC_Result,
 static TNC_Result receive_msg(private_imv_attestation_agent_t *this,
                                                          imv_state_t *state, imv_msg_t *in_msg)
 {
-       imv_attestation_state_t *attestation_state;
        imv_msg_t *out_msg;
+       imv_session_t *session;
+       imv_os_info_t *os_info = NULL;
        enumerator_t *enumerator;
        pa_tnc_attr_t *attr;
        pen_type_t type;
        TNC_Result result;
-       pts_t *pts;
-       chunk_t os_name = chunk_empty;
-       chunk_t os_version = chunk_empty;
+       chunk_t os_name, os_version;
        bool fatal_error = FALSE;
 
        /* parse received PA-TNC message and handle local and remote errors */
@@ -149,8 +150,8 @@ static TNC_Result receive_msg(private_imv_attestation_agent_t *this,
                return result;
        }
 
-       attestation_state = (imv_attestation_state_t*)state;
-       pts = attestation_state->get_pts(attestation_state);
+       session = state->get_session(state);
+       os_info = session->get_os_info(session);
 
        out_msg = imv_msg_create_as_reply(in_msg);
        out_msg->set_msg_type(out_msg, msg_types[0]);
@@ -189,16 +190,22 @@ static TNC_Result receive_msg(private_imv_attestation_agent_t *this,
                                {
                                        ietf_attr_product_info_t *attr_cast;
 
+                                       state->set_action_flags(state,
+                                                                               IMV_ATTESTATION_ATTR_PRODUCT_INFO);
                                        attr_cast = (ietf_attr_product_info_t*)attr;
                                        os_name = attr_cast->get_info(attr_cast, NULL, NULL);
+                                       os_info->set_name(os_info, os_name);
                                        break;
                                }
                                case IETF_ATTR_STRING_VERSION:
                                {
                                        ietf_attr_string_version_t *attr_cast;
 
+                                       state->set_action_flags(state,
+                                                                               IMV_ATTESTATION_ATTR_STRING_VERSION);
                                        attr_cast = (ietf_attr_string_version_t*)attr;
                                        os_version = attr_cast->get_version(attr_cast, NULL, NULL);
+                                       os_info->set_version(os_info, os_version);
                                        break;
                                }
                                default:
@@ -218,15 +225,6 @@ static TNC_Result receive_msg(private_imv_attestation_agent_t *this,
        }
        enumerator->destroy(enumerator);
 
-       /**
-        * The IETF Product Information and String Version attributes
-        * are supposed to arrive in the same PA-TNC message
-        */
-       if (os_name.len && os_version.len)
-       {
-               pts->set_platform_info(pts, os_name, os_version);
-       }
-
        if (fatal_error || result != TNC_RESULT_SUCCESS)
        {
                state->set_recommendation(state,
@@ -288,12 +286,39 @@ METHOD(imv_agent_if_t, receive_message_long, TNC_Result,
        return result;
 }
 
+/**
+ * Build an IETF Attribute Request attribute for missing attributes
+ */
+static pa_tnc_attr_t* build_attr_request(u_int32_t received)
+{
+       pa_tnc_attr_t *attr;
+       ietf_attr_attr_request_t *attr_cast;
+
+       attr = ietf_attr_attr_request_create(PEN_RESERVED, 0);
+       attr_cast = (ietf_attr_attr_request_t*)attr;
+
+       if (!(received & IMV_ATTESTATION_ATTR_PRODUCT_INFO) ||
+               !(received & IMV_ATTESTATION_ATTR_STRING_VERSION))
+       {
+               attr_cast->add(attr_cast, PEN_IETF, IETF_ATTR_PRODUCT_INFORMATION);
+               attr_cast->add(attr_cast, PEN_IETF, IETF_ATTR_STRING_VERSION);
+       }
+/*
+       if (!(received & IMV_ATTESTATION_ATTR_DEVICE_ID))
+       {
+               attr_cast->add(attr_cast, PEN_ITA,  ITA_ATTR_DEVICE_ID);
+       }
+*/
+       return attr;
+}
+
 METHOD(imv_agent_if_t, batch_ending, TNC_Result,
        private_imv_attestation_agent_t *this, TNC_ConnectionID id)
 {
        imv_msg_t *out_msg;
        imv_state_t *state;
        imv_session_t *session;
+       imv_os_info_t *os_info;
        imv_attestation_state_t *attestation_state;
        imv_attestation_handshake_state_t handshake_state;
        imv_workitem_t *workitem;
@@ -302,7 +327,7 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result,
        TNC_IMVID imv_id;
        TNC_Result result = TNC_RESULT_SUCCESS;
        pts_t *pts;
-       char *platform_info;
+       u_int32_t actions;
        enumerator_t *enumerator;
 
        if (!this->agent->get_state(this->agent, id, &state))
@@ -312,40 +337,36 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result,
        attestation_state = (imv_attestation_state_t*)state;
        pts = attestation_state->get_pts(attestation_state);
        handshake_state = attestation_state->get_handshake_state(attestation_state);
-       platform_info = pts->get_platform_info(pts);
+       actions = state->get_action_flags(state);
        session = state->get_session(state);
        imv_id = this->agent->get_id(this->agent);
 
        /* exit if a recommendation has already been provided */
-       if (state->get_action_flags(state) & IMV_ATTESTATION_FLAG_REC)
+       if (actions & IMV_ATTESTATION_REC)
        {
                return TNC_RESULT_SUCCESS;
        }
 
        /* send an IETF attribute request if no platform info was received */
-       if (!platform_info &&
-               !(state->get_action_flags(state) & IMV_ATTESTATION_FLAG_ATTR_REQ))
+       if (!(actions & IMV_ATTESTATION_ATTR_REQ))
        {
-               pa_tnc_attr_t *attr;
-               ietf_attr_attr_request_t *attr_cast;
-               imv_msg_t *os_msg;
-
-               attr = ietf_attr_attr_request_create(PEN_IETF,
-                                                                                        IETF_ATTR_PRODUCT_INFORMATION);
-               attr_cast = (ietf_attr_attr_request_t*)attr;
-               attr_cast->add(attr_cast, PEN_IETF, IETF_ATTR_STRING_VERSION);
+               if ((actions & IMV_ATTESTATION_ATTR_MUST) != IMV_ATTESTATION_ATTR_MUST)
+               {
+                       imv_msg_t *os_msg;
 
-               os_msg = imv_msg_create(this->agent, state, id, imv_id, TNC_IMCID_ANY,
-                                                                msg_types[1]);
-               os_msg->add_attribute(os_msg, attr);
-               result = os_msg->send(os_msg, FALSE);
-               os_msg->destroy(os_msg);
+                       /* create attribute request for missing mandatory attributes */
+                       os_msg = imv_msg_create(this->agent, state, id, imv_id,
+                                                                       TNC_IMCID_ANY, msg_types[1]);
+                       os_msg->add_attribute(os_msg, build_attr_request(actions));
+                       result = os_msg->send(os_msg, FALSE);
+                       os_msg->destroy(os_msg);
 
-               if (result != TNC_RESULT_SUCCESS)
-               {
-                       return result;
-               }
-               state->set_action_flags(state, IMV_ATTESTATION_FLAG_ATTR_REQ);
+                       if (result != TNC_RESULT_SUCCESS)
+                       {
+                               return result;
+                       }
+                }
+               state->set_action_flags(state, IMV_ATTESTATION_ATTR_REQ);
        }
 
        if (handshake_state == IMV_ATTESTATION_STATE_INIT)
@@ -378,18 +399,19 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result,
        }
 
        /* exit if we are not ready yet for PTS measurements */
-       if (!platform_info || !session ||
-           !(state->get_action_flags(state) & IMV_ATTESTATION_FLAG_ALGO))
+       if (!session->get_policy_started(session) || !(actions & IMV_ATTESTATION_ALGO))
        {
                return TNC_RESULT_SUCCESS;
        }
+       os_info = session->get_os_info(session);
+       pts->set_platform_info(pts, os_info->get_info(os_info));
 
        /* create an empty out message - we might need it */
        out_msg = imv_msg_create(this->agent, state, id, imv_id, TNC_IMCID_ANY,
                                                         msg_types[0]);
 
        /* establish the PTS measurements to be taken */
-       if (!(state->get_action_flags(state) & IMV_ATTESTATION_FLAG_FILE_MEAS))
+       if (!(actions & IMV_ATTESTATION_FILE_MEAS))
        {
                bool is_dir, no_workitems = TRUE;
                u_int32_t delimiter = SOLIDUS_UTF;
@@ -555,7 +577,7 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result,
                        enumerator->destroy(enumerator);
 
                        /* sent all file and directory measurement and metadata requests */
-                       state->set_action_flags(state, IMV_ATTESTATION_FLAG_FILE_MEAS);
+                       state->set_action_flags(state, IMV_ATTESTATION_FILE_MEAS);
 
                        if (no_workitems)
                        {
@@ -600,14 +622,14 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result,
        enumerator->destroy(enumerator);
 
        /* finalized all workitems? */
-       if (session && session->get_policy_started(session) &&
+       if (session->get_policy_started(session) &&
                session->get_workitem_count(session, imv_id) == 0 &&
                attestation_state->get_handshake_state(attestation_state) ==
                        IMV_ATTESTATION_STATE_END)
        {
                result = out_msg->send_assessment(out_msg);
                out_msg->destroy(out_msg);
-               state->set_action_flags(state, IMV_ATTESTATION_FLAG_REC);
+               state->set_action_flags(state, IMV_ATTESTATION_REC);
 
                if (result != TNC_RESULT_SUCCESS)
                {
@@ -642,7 +664,7 @@ METHOD(imv_agent_if_t, solicit_recommendation, TNC_Result,
        session = state->get_session(state);
        imv_id = this->agent->get_id(this->agent);
 
-       if (session)
+       if (imcv_db)
        {
                TNC_IMV_Evaluation_Result eval;
                TNC_IMV_Action_Recommendation rec;
index 84023c6..5688a7d 100644 (file)
@@ -90,7 +90,6 @@ bool imv_attestation_build(imv_msg_t *out_msg, imv_state_t *state,
                        enumerator_t *enumerator;
                        pts_comp_func_name_t *name;
                        chunk_t keyid;
-                       int kid;
                        u_int8_t flags;
                        u_int32_t depth;
                        bool first_component = TRUE;
@@ -98,8 +97,7 @@ bool imv_attestation_build(imv_msg_t *out_msg, imv_state_t *state,
                        attestation_state->set_handshake_state(attestation_state,
                                                                                IMV_ATTESTATION_STATE_END);
 
-                       if (!pts->get_aik_keyid(pts, &keyid) ||
-                                pts_db->check_aik_keyid(pts_db, keyid, &kid) != SUCCESS)
+                       if (!pts->get_aik_keyid(pts, &keyid))
                        {
                                attestation_state->set_measurement_error(attestation_state,
                                                                        IMV_ATTESTATION_ERROR_NO_TRUSTED_AIK);
index e40c92a..9249058 100644 (file)
@@ -46,10 +46,12 @@ bool imv_attestation_process(pa_tnc_attr_t *attr, imv_msg_t *out_msg,
                                                         pts_database_t *pts_db,
                                                         credential_manager_t *pts_credmgr)
 {
+       imv_session_t *session;
        imv_attestation_state_t *attestation_state;
        pen_type_t attr_type;
        pts_t *pts;
 
+       session = state->get_session(state);
        attestation_state = (imv_attestation_state_t*)state;
        pts = attestation_state->get_pts(attestation_state);
        attr_type = attr->get_type(attr);
@@ -80,7 +82,7 @@ bool imv_attestation_process(pa_tnc_attr_t *attr, imv_msg_t *out_msg,
                                return FALSE;
                        }
                        pts->set_meas_algorithm(pts, selected_algorithm);
-                       state->set_action_flags(state, IMV_ATTESTATION_FLAG_ALGO);
+                       state->set_action_flags(state, IMV_ATTESTATION_ALGO);
                        break;
                }
                case TCG_PTS_DH_NONCE_PARAMS_RESP:
@@ -157,9 +159,9 @@ bool imv_attestation_process(pa_tnc_attr_t *attr, imv_msg_t *out_msg,
                        tcg_pts_attr_aik_t *attr_cast;
                        certificate_t *aik, *issuer;
                        public_key_t *public;
-                       chunk_t keyid;
+                       chunk_t keyid, keyid_hex, device_id;
                        enumerator_t *e;
-                       bool trusted = FALSE;
+                       bool trusted = FALSE, trusted_chain = FALSE;
 
                        attr_cast = (tcg_pts_attr_aik_t*)attr;
                        aik = attr_cast->get_aik(attr_cast);
@@ -170,12 +172,27 @@ bool imv_attestation_process(pa_tnc_attr_t *attr, imv_msg_t *out_msg,
                                                                        IMV_ATTESTATION_ERROR_NO_TRUSTED_AIK);
                                break;
                        }
+
+                       /* check trust into public key as stored in the database */
+                       public = aik->get_public_key(aik);
+                       public->get_fingerprint(public, KEYID_PUBKEY_INFO_SHA1, &keyid);
+                       DBG1(DBG_IMV, "verifying AIK with keyid %#B", &keyid);
+                       keyid_hex = chunk_to_hex(keyid, NULL, FALSE);
+                       if (session->get_device_id(session, &device_id) &&
+                               chunk_equals(keyid_hex, device_id))
+                       {
+                               trusted = session->get_device_trust(session);
+                       }
+                       else
+                       {
+                               DBG1(DBG_IMV, "device ID unknown or different from AIK keyid");
+                       }
+                       DBG1(DBG_IMV, "AIK public key is %strusted", trusted ? "" : "not ");
+                       public->destroy(public);
+                       chunk_free(&keyid_hex);
+
                        if (aik->get_type(aik) == CERT_X509)
                        {
-                               public = aik->get_public_key(aik);
-                               public->get_fingerprint(public, KEYID_PUBKEY_INFO_SHA1, &keyid);
-                               DBG1(DBG_IMV, "verifying AIK certificate with keyid %#B", &keyid);
-                               public->destroy(public);
 
                                e = pts_credmgr->create_trusted_enumerator(pts_credmgr,
                                                        KEY_ANY, aik->get_issuer(aik), FALSE);
@@ -183,14 +200,14 @@ bool imv_attestation_process(pa_tnc_attr_t *attr, imv_msg_t *out_msg,
                                {
                                        if (aik->issued_by(aik, issuer, NULL))
                                        {
-                                               trusted = TRUE;
+                                               trusted_chain = TRUE;
                                                break;
                                        }
                                }
                                e->destroy(e);
                                DBG1(DBG_IMV, "AIK certificate is %strusted",
-                                                          trusted ? "" : "not ");
-                               if (!trusted)
+                                                          trusted_chain ? "" : "not ");
+                               if (!trusted || !trusted_chain)
                                {
                                        attestation_state->set_measurement_error(attestation_state,
                                                                                IMV_ATTESTATION_ERROR_NO_TRUSTED_AIK);
index 9304b9a..28ad849 100644 (file)
@@ -63,22 +63,12 @@ struct private_imv_attestation_state_t {
        /**
         * Maximum PA-TNC message size for this TNCCS connection
         */
-       u_int32_t max_msg_len;
+       uint32_t max_msg_len;
 
        /**
         * Flags set for completed actions
         */
-       u_int32_t action_flags;
-
-       /**
-        * Access Requestor ID Type
-        */
-       u_int32_t ar_id_type;
-
-       /**
-        * Access Requestor ID Value
-        */
-       chunk_t ar_id_value;
+       uint32_t action_flags;
 
        /**
         * IMV database session associated with TNCCS connection
@@ -113,7 +103,7 @@ struct private_imv_attestation_state_t {
        /**
         * Measurement error flags
         */
-       u_int32_t measurement_error;
+       uint32_t measurement_error;
 
        /**
         * TNC Reason String
@@ -215,46 +205,29 @@ METHOD(imv_state_t, set_flags, void,
 }
 
 METHOD(imv_state_t, set_max_msg_len, void,
-       private_imv_attestation_state_t *this, u_int32_t max_msg_len)
+       private_imv_attestation_state_t *this, uint32_t max_msg_len)
 {
        this->max_msg_len = max_msg_len;
 }
 
-METHOD(imv_state_t, get_max_msg_len, u_int32_t,
+METHOD(imv_state_t, get_max_msg_len, uint32_t,
        private_imv_attestation_state_t *this)
 {
        return this->max_msg_len;
 }
 
 METHOD(imv_state_t, set_action_flags, void,
-       private_imv_attestation_state_t *this, u_int32_t flags)
+       private_imv_attestation_state_t *this, uint32_t flags)
 {
        this->action_flags |= flags;
 }
 
-METHOD(imv_state_t, get_action_flags, u_int32_t,
+METHOD(imv_state_t, get_action_flags, uint32_t,
        private_imv_attestation_state_t *this)
 {
        return this->action_flags;
 }
 
-METHOD(imv_state_t, set_ar_id, void,
-       private_imv_attestation_state_t *this, u_int32_t id_type, chunk_t id_value)
-{
-       this->ar_id_type = id_type;
-       this->ar_id_value = chunk_clone(id_value);
-}
-
-METHOD(imv_state_t, get_ar_id, chunk_t,
-       private_imv_attestation_state_t *this, u_int32_t *id_type)
-{
-       if (id_type)
-       {
-               *id_type = this->ar_id_type;
-       }
-       return this->ar_id_value;
-}
-
 METHOD(imv_state_t, set_session, void,
        private_imv_attestation_state_t *this, imv_session_t *session)
 {
@@ -362,7 +335,6 @@ METHOD(imv_state_t, destroy, void,
        DESTROY_IF(this->reason_string);
        this->components->destroy_function(this->components, (void *)free_func_comp);
        this->pts->destroy(this->pts);
-       free(this->ar_id_value.ptr);
        free(this);
 }
 
@@ -387,7 +359,7 @@ METHOD(imv_attestation_state_t, get_pts, pts_t*,
 
 METHOD(imv_attestation_state_t, create_component, pts_component_t*,
        private_imv_attestation_state_t *this, pts_comp_func_name_t *name,
-       u_int32_t depth, pts_database_t *pts_db)
+       uint32_t depth, pts_database_t *pts_db)
 {
        enumerator_t *enumerator;
        func_comp_t *entry, *new_entry;
@@ -438,7 +410,7 @@ METHOD(imv_attestation_state_t, create_component, pts_component_t*,
  * Enumerate file measurement entries
  */
 static bool entry_filter(void *null, func_comp_t **entry, u_int8_t *flags,
-                                                void *i2, u_int32_t *depth,
+                                                void *i2, uint32_t *depth,
                                                 void *i3, pts_comp_func_name_t **comp_name)
 {
        pts_component_t *comp;
@@ -482,14 +454,14 @@ METHOD(imv_attestation_state_t, get_component, pts_component_t*,
        return found;
 }
 
-METHOD(imv_attestation_state_t, get_measurement_error, u_int32_t,
+METHOD(imv_attestation_state_t, get_measurement_error, uint32_t,
        private_imv_attestation_state_t *this)
 {
        return this->measurement_error;
 }
 
 METHOD(imv_attestation_state_t, set_measurement_error, void,
-       private_imv_attestation_state_t *this, u_int32_t error)
+       private_imv_attestation_state_t *this, uint32_t error)
 {
        this->measurement_error |= error;
 }
@@ -529,8 +501,6 @@ imv_state_t *imv_attestation_state_create(TNC_ConnectionID connection_id)
                                .get_max_msg_len = _get_max_msg_len,
                                .set_action_flags = _set_action_flags,
                                .get_action_flags = _get_action_flags,
-                               .set_ar_id = _set_ar_id,
-                               .get_ar_id = _get_ar_id,
                                .set_session = _set_session,
                                .get_session = _get_session,
                                .change_state = _change_state,
index 9369d30..2019a56 100644 (file)
@@ -40,10 +40,14 @@ typedef enum imv_meas_error_t imv_meas_error_t;
  * IMV Attestation Flags set for completed actions
  */
 enum imv_attestation_flag_t {
-       IMV_ATTESTATION_FLAG_ATTR_REQ =  (1<<0),
-       IMV_ATTESTATION_FLAG_ALGO =      (1<<1),
-       IMV_ATTESTATION_FLAG_FILE_MEAS = (1<<2),
-       IMV_ATTESTATION_FLAG_REC =       (1<<3)
+       IMV_ATTESTATION_ATTR_PRODUCT_INFO =   (1<<0),
+       IMV_ATTESTATION_ATTR_STRING_VERSION = (1<<1),
+       IMV_ATTESTATION_ATTR_MUST =           (1<<2)-1,
+       IMV_ATTESTATION_ATTR_DEVICE_ID =      (1<<2),
+       IMV_ATTESTATION_ATTR_REQ =            (1<<3),
+       IMV_ATTESTATION_ALGO =                (1<<4),
+       IMV_ATTESTATION_FILE_MEAS =           (1<<5),
+       IMV_ATTESTATION_REC =                 (1<<6)
 };
 
 /**
index a0326f8..743037b 100644 (file)
@@ -364,7 +364,7 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result,
        out_msg = imv_msg_create(this->agent, state, id, imv_id, TNC_IMCID_ANY,
                                                         msg_types[0]);
 
-       if (!session)
+       if (!imcv_db)
        {
                DBG2(DBG_IMV, "no workitems available - no evaluation possible");
                state->set_recommendation(state,
@@ -381,7 +381,8 @@ METHOD(imv_agent_if_t, batch_ending, TNC_Result,
                return this->agent->provide_recommendation(this->agent, state);
        }
 
-       if (handshake_state == IMV_SWID_STATE_INIT)
+       if (handshake_state == IMV_SWID_STATE_INIT &&
+               session->get_policy_started(session))
        {
                enumerator = session->create_workitem_enumerator(session);
                if (enumerator)
index 5be8c02..156a6bb 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Andreas Steffen
+ * Copyright (C) 2013-2014 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -58,22 +58,12 @@ struct private_imv_swid_state_t {
        /**
         * Maximum PA-TNC message size for this TNCCS connection
         */
-       u_int32_t max_msg_len;
+       uint32_t max_msg_len;
 
        /**
         * Flags set for completed actions
         */
-       u_int32_t action_flags;
-
-       /**
-        * Access Requestor ID Type
-        */
-       u_int32_t ar_id_type;
-
-       /**
-        * Access Requestor ID Value
-        */
-       chunk_t ar_id_value;
+       uint32_t action_flags;
 
        /**
         * IMV database session associatied with TNCCS connection
@@ -133,46 +123,29 @@ METHOD(imv_state_t, set_flags, void,
 }
 
 METHOD(imv_state_t, set_max_msg_len, void,
-       private_imv_swid_state_t *this, u_int32_t max_msg_len)
+       private_imv_swid_state_t *this, uint32_t max_msg_len)
 {
        this->max_msg_len = max_msg_len;
 }
 
-METHOD(imv_state_t, get_max_msg_len, u_int32_t,
+METHOD(imv_state_t, get_max_msg_len, uint32_t,
        private_imv_swid_state_t *this)
 {
        return this->max_msg_len;
 }
 
 METHOD(imv_state_t, set_action_flags, void,
-       private_imv_swid_state_t *this, u_int32_t flags)
+       private_imv_swid_state_t *this, uint32_t flags)
 {
        this->action_flags |= flags;
 }
 
-METHOD(imv_state_t, get_action_flags, u_int32_t,
+METHOD(imv_state_t, get_action_flags, uint32_t,
        private_imv_swid_state_t *this)
 {
        return this->action_flags;
 }
 
-METHOD(imv_state_t, set_ar_id, void,
-       private_imv_swid_state_t *this, u_int32_t id_type, chunk_t id_value)
-{
-       this->ar_id_type = id_type;
-       this->ar_id_value = chunk_clone(id_value);
-}
-
-METHOD(imv_state_t, get_ar_id, chunk_t,
-       private_imv_swid_state_t *this, u_int32_t *id_type)
-{
-       if (id_type)
-       {
-               *id_type = this->ar_id_type;
-       }
-       return this->ar_id_value;
-}
-
 METHOD(imv_state_t, set_session, void,
        private_imv_swid_state_t *this, imv_session_t *session)
 {
@@ -235,7 +208,6 @@ METHOD(imv_state_t, destroy, void,
        DESTROY_IF(this->session);
        DESTROY_IF(this->reason_string);
        DESTROY_IF(this->remediation_string);
-       free(this->ar_id_value.ptr);
        free(this);
 }
 
@@ -269,8 +241,6 @@ imv_state_t *imv_swid_state_create(TNC_ConnectionID connection_id)
                                .get_max_msg_len = _get_max_msg_len,
                                .set_action_flags = _set_action_flags,
                                .get_action_flags = _get_action_flags,
-                               .set_ar_id = _set_ar_id,
-                               .get_ar_id = _get_ar_id,
                                .set_session = _set_session,
                                .get_session= _get_session,
                                .change_state = _change_state,
index 178a642..d155f2d 100644 (file)
@@ -337,15 +337,10 @@ METHOD(pts_t, get_platform_info, char*,
 }
 
 METHOD(pts_t, set_platform_info, void,
-       private_pts_t *this, chunk_t name, chunk_t version)
+       private_pts_t *this, char *info)
 {
-       int len = name.len + 1 + version.len + 1;
-
-       /* platform info is a concatenation of OS name and OS version */
        free(this->platform_info);
-       this->platform_info = malloc(len);
-       snprintf(this->platform_info, len, "%.*s %.*s", (int)name.len, name.ptr,
-                       (int)version.len, version.ptr);
+       this->platform_info = strdup(info);
 }
 
 METHOD(pts_t, get_tpm_version_info, bool,
index 11154aa..bff1dba 100644 (file)
@@ -174,7 +174,7 @@ struct pts_t {
         * @param name                          OS name
         * @param version                       OS version
         */
-       void (*set_platform_info)(pts_t *this, chunk_t name, chunk_t version);
+       void (*set_platform_info)(pts_t *this, char *info);
 
        /**
         * Get TPM 1.2 Version Info
index fda644a..30002d7 100644 (file)
@@ -1,5 +1,6 @@
 /*
- * Copyright (C) 2011-2012 Sansar Choinyambuu, Andreas Steffen
+ * Copyright (C) 2011-2012 Sansar Choinyambuu
+ * Copyright (C) 2012-2014 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -114,10 +115,15 @@ METHOD(pts_database_t, check_aik_keyid, status_t,
        private_pts_database_t *this, chunk_t keyid, int *kid)
 {
        enumerator_t *e;
+       chunk_t keyid_hex;
+
+       /* Convert keyid into a hex-encoded string */
+       keyid_hex = chunk_to_hex(keyid, NULL, FALSE);
 
        /* If the AIK is registered get the primary key */
        e = this->db->query(this->db,
-                               "SELECT id FROM keys WHERE keyid = ?", DB_BLOB, keyid, DB_INT);
+                               "SELECT id FROM devices WHERE name = ?",
+                                DB_TEXT, keyid_hex.ptr, DB_INT);
        if (!e)
        {
                DBG1(DBG_PTS, "no database query enumerator returned");
@@ -497,7 +503,6 @@ pts_database_t *pts_database_create(imv_database_t *imv_db)
                        .get_pathname = _get_pathname,
                        .create_comp_evid_enumerator = _create_comp_evid_enumerator,
                        .create_file_hash_enumerator = _create_file_hash_enumerator,
-                       .check_aik_keyid = _check_aik_keyid,
                        .add_file_measurement = _add_file_measurement,
                        .check_file_measurement = _check_file_measurement,
                        .check_comp_measurement = _check_comp_measurement,
index eb8aca3..323d1b8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011 Andreas Steffen
+ * Copyright (C) 2011-2014 Andreas Steffen
  * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
@@ -61,7 +61,7 @@ struct pts_database_t {
        * Check if an AIK given by its keyid is registered in the database
        *
        * @param keyid                  AIK keyid (SHA-1 hash of the AIK public key info)
-       * @param kid                    Primary key of AIK entry in keys table
+       * @param kid                    Primary key of AIK entry in devices table
        * @return                               SUCCESS if AIK is present, FAILED otherwise
        */
        status_t (*check_aik_keyid)(pts_database_t *this, chunk_t keyid, int *kid);