Separated IMV session management from IMV policy database
This commit is contained in:
parent
0bd64fa5bf
commit
4894bfa227
|
@ -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 \
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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_ @}*/
|
|
@ -31,6 +31,11 @@
|
|||
*/
|
||||
pa_tnc_attr_manager_t *imcv_pa_tnc_attributes;
|
||||
|
||||
/**
|
||||
* Global list of IMV sessions
|
||||
*/
|
||||
imv_session_manager_t *imcv_sessions;
|
||||
|
||||
/**
|
||||
* Global IMV database
|
||||
*/
|
||||
|
@ -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))
|
||||
|
|
|
@ -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_ @}*/
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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_ @}*/
|
||||
|
|
|
@ -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;
|
||||
return this->db;
|
||||
}
|
||||
|
||||
this->mutex->lock(this->mutex);
|
||||
|
||||
/* check if a session has already been assigned */
|
||||
enumerator = this->sessions->create_enumerator(this->sessions);
|
||||
while (enumerator->enumerate(enumerator, ¤t))
|
||||
{
|
||||
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 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, ¤t))
|
||||
{
|
||||
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)
|
||||
{
|
||||
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: registering device ID failed");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return did;
|
||||
/* 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)
|
||||
{
|
||||
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 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)
|
||||
|
|
|
@ -55,26 +55,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
|
||||
*
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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_ @}*/
|
|
@ -34,11 +34,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?
|
||||
*/
|
||||
|
@ -56,9 +96,25 @@ struct private_imv_session_t {
|
|||
|
||||
};
|
||||
|
||||
METHOD(imv_session_t, get_session_id, int,
|
||||
private_imv_session_t *this)
|
||||
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, 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,
|
||||
);
|
||||
|
|
|
@ -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
|
||||
|
@ -23,11 +23,13 @@
|
|||
#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;
|
||||
|
||||
/**
|
||||
|
@ -35,12 +37,23 @@ 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
|
||||
|
@ -49,6 +62,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
|
||||
*
|
||||
|
@ -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_ @}*/
|
||||
|
|
|
@ -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, ¤t))
|
||||
{
|
||||
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, ¤t))
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
|
@ -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_ @}*/
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
@ -15,15 +15,6 @@
|
|||
|
||||
#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",
|
||||
|
@ -48,487 +39,6 @@ ENUM(os_package_state_names, OS_PACKAGE_STATE_UPDATE, OS_PACKAGE_STATE_BLACKLIST
|
|||
" [b]"
|
||||
);
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
@ -67,87 +67,12 @@ 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_ @}*/
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
if (imcv_db)
|
||||
{
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
/* the policy script has already been started by another IMV */
|
||||
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);
|
||||
|
||||
if (result != TNC_RESULT_SUCCESS)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
return this->agent->provide_recommendation(this->agent, state);
|
||||
}
|
||||
else
|
||||
{
|
||||
handshake_state = IMV_OS_STATE_ATTR_REQ;
|
||||
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_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 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);
|
||||
|
||||
if (result != TNC_RESULT_SUCCESS)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
return this->agent->provide_recommendation(this->agent, state);
|
||||
}
|
||||
else
|
||||
{
|
||||
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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
@ -99,33 +90,13 @@ 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;
|
||||
|
||||
|
@ -139,11 +110,6 @@ struct private_imv_os_state_t {
|
|||
*/
|
||||
imv_remediation_string_t *remediation_string;
|
||||
|
||||
/**
|
||||
* Dgevice ID
|
||||
*/
|
||||
chunk_t device_id;
|
||||
|
||||
/**
|
||||
* Number of processed packages
|
||||
*/
|
||||
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
@ -77,27 +77,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
|
||||
*
|
||||
|
@ -120,20 +99,6 @@ struct imv_os_state_t {
|
|||
void (*get_count)(imv_os_state_t *this, int *count, int *count_update,
|
||||
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
|
||||
*
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
||||
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);
|
||||
|
||||
if (result != TNC_RESULT_SUCCESS)
|
||||
if ((actions & IMV_ATTESTATION_ATTR_MUST) != IMV_ATTESTATION_ATTR_MUST)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
state->set_action_flags(state, IMV_ATTESTATION_FLAG_ATTR_REQ);
|
||||
imv_msg_t *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_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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue