mirror of
https://github.com/strongswan/strongswan.git
synced 2025-10-05 00:00:45 -04:00
implemented os_info_t class
This commit is contained in:
parent
7f3bf2b12f
commit
6ab1502519
@ -764,10 +764,13 @@ Debug level for a stand-alone libimcv library
|
||||
.TP
|
||||
.BR libimcv.stderr_quiet " [no]"
|
||||
Disable output to stderr with a stand-alone libimcv library
|
||||
.SS libimcv plugins section
|
||||
.TP
|
||||
.BR libimcv.plugins.imc-attestation.platform_info
|
||||
Information on operating system and hardware platform
|
||||
.BR libimcv.os_info.name
|
||||
Manually set the name of the client OS (e.g. Ubuntu)
|
||||
.TP
|
||||
.BR libimcv.os_info.version
|
||||
Manually set the version of the client OS (e.g. 12.04 i686)
|
||||
.SS libimcv plugins section
|
||||
.TP
|
||||
.BR libimcv.plugins.imc-attestation.aik_blob
|
||||
AIK encrypted private key blob file
|
||||
@ -799,9 +802,6 @@ Preferred measurement hash algorithm
|
||||
.BR libimcv.plugins.imv-attestation.min_nonce_len " [0]"
|
||||
DH minimum nonce length
|
||||
.TP
|
||||
.BR libimcv.plugins.imv-attestation.platform_info
|
||||
Information on operating system and hardware platform
|
||||
.TP
|
||||
.BR libimcv.plugins.imv-scanner.closed_port_policy " [yes]"
|
||||
By default all ports must be closed (yes) or can be open (no)
|
||||
.TP
|
||||
|
@ -20,6 +20,7 @@ libimcv_la_SOURCES = \
|
||||
ita/ita_attr.h ita/ita_attr.c \
|
||||
ita/ita_attr_command.h ita/ita_attr_command.c \
|
||||
ita/ita_attr_dummy.h ita/ita_attr_dummy.c \
|
||||
os_info/os_info.h os_info/os_info.c \
|
||||
pa_tnc/pa_tnc_attr.h \
|
||||
pa_tnc/pa_tnc_msg.h pa_tnc/pa_tnc_msg.c \
|
||||
pa_tnc/pa_tnc_attr_manager.h pa_tnc/pa_tnc_attr_manager.c
|
||||
|
@ -73,7 +73,7 @@ struct private_ietf_attr_product_info_t {
|
||||
/**
|
||||
* Product Name
|
||||
*/
|
||||
char *product_name;
|
||||
chunk_t product_name;
|
||||
|
||||
/**
|
||||
* Reference count
|
||||
@ -109,18 +109,15 @@ METHOD(pa_tnc_attr_t, build, void,
|
||||
private_ietf_attr_product_info_t *this)
|
||||
{
|
||||
bio_writer_t *writer;
|
||||
chunk_t product_name;
|
||||
|
||||
if (this->value.ptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
product_name = chunk_create(this->product_name, strlen(this->product_name));
|
||||
|
||||
writer = bio_writer_create(PRODUCT_INFO_MIN_SIZE);
|
||||
writer->write_uint24(writer, this->product_vendor_id);
|
||||
writer->write_uint16(writer, this->product_id);
|
||||
writer->write_data (writer, product_name);
|
||||
writer->write_data (writer, this->product_name);
|
||||
|
||||
this->value = chunk_clone(writer->get_buf(writer));
|
||||
writer->destroy(writer);
|
||||
@ -151,10 +148,7 @@ METHOD(pa_tnc_attr_t, process, status_t,
|
||||
*offset = 3;
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
this->product_name = malloc(product_name.len + 1);
|
||||
memcpy(this->product_name, product_name.ptr, product_name.len);
|
||||
this->product_name[product_name.len] = '\0';
|
||||
this->product_name = chunk_clone(product_name);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
@ -171,13 +165,13 @@ METHOD(pa_tnc_attr_t, destroy, void,
|
||||
{
|
||||
if (ref_put(&this->ref))
|
||||
{
|
||||
free(this->product_name);
|
||||
free(this->product_name.ptr);
|
||||
free(this->value.ptr);
|
||||
free(this);
|
||||
}
|
||||
}
|
||||
|
||||
METHOD(ietf_attr_product_info_t, get_info, char*,
|
||||
METHOD(ietf_attr_product_info_t, get_info, chunk_t,
|
||||
private_ietf_attr_product_info_t *this, pen_t *vendor_id, u_int16_t *id)
|
||||
{
|
||||
if (vendor_id)
|
||||
@ -195,7 +189,7 @@ METHOD(ietf_attr_product_info_t, get_info, char*,
|
||||
* Described in header.
|
||||
*/
|
||||
pa_tnc_attr_t *ietf_attr_product_info_create(pen_t vendor_id, u_int16_t id,
|
||||
char *name)
|
||||
chunk_t name)
|
||||
{
|
||||
private_ietf_attr_product_info_t *this;
|
||||
|
||||
@ -216,7 +210,7 @@ pa_tnc_attr_t *ietf_attr_product_info_create(pen_t vendor_id, u_int16_t id,
|
||||
.type = { PEN_IETF, IETF_ATTR_PRODUCT_INFORMATION },
|
||||
.product_vendor_id = vendor_id,
|
||||
.product_id = id,
|
||||
.product_name = strdup(name),
|
||||
.product_name = chunk_clone(name),
|
||||
.ref = 1,
|
||||
);
|
||||
|
||||
|
@ -45,8 +45,8 @@ struct ietf_attr_product_info_t {
|
||||
* @param id Product ID
|
||||
* @return Product Name
|
||||
*/
|
||||
char* (*get_info)(ietf_attr_product_info_t *this,
|
||||
pen_t *vendor_id, u_int16_t *id);
|
||||
chunk_t (*get_info)(ietf_attr_product_info_t *this,
|
||||
pen_t *vendor_id, u_int16_t *id);
|
||||
|
||||
};
|
||||
|
||||
@ -55,7 +55,7 @@ struct ietf_attr_product_info_t {
|
||||
*
|
||||
*/
|
||||
pa_tnc_attr_t* ietf_attr_product_info_create(pen_t vendor_id, u_int16_t id,
|
||||
char *name);
|
||||
chunk_t name);
|
||||
|
||||
/**
|
||||
* Creates an ietf_attr_product_info_t object from received data
|
||||
|
309
src/libimcv/os_info/os_info.c
Normal file
309
src/libimcv/os_info/os_info.c
Normal file
@ -0,0 +1,309 @@
|
||||
/*
|
||||
* Copyright (C) 2012 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <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 "os_info.h"
|
||||
|
||||
#include <sys/utsname.h>
|
||||
|
||||
#include <utils/linked_list.h>
|
||||
#include <debug.h>
|
||||
|
||||
|
||||
typedef struct private_os_info_t private_os_info_t;
|
||||
|
||||
|
||||
/**
|
||||
* Private data of an os_info_t object.
|
||||
*
|
||||
*/
|
||||
struct private_os_info_t {
|
||||
|
||||
/**
|
||||
* Public os_info_t interface.
|
||||
*/
|
||||
os_info_t public;
|
||||
|
||||
/**
|
||||
* OS name
|
||||
*/
|
||||
chunk_t name;
|
||||
|
||||
/**
|
||||
* OS version
|
||||
*/
|
||||
chunk_t version;
|
||||
|
||||
};
|
||||
|
||||
METHOD(os_info_t, get_name, chunk_t,
|
||||
private_os_info_t *this)
|
||||
{
|
||||
return this->name;
|
||||
}
|
||||
|
||||
METHOD(os_info_t, get_version, chunk_t,
|
||||
private_os_info_t *this)
|
||||
{
|
||||
return this->version;
|
||||
}
|
||||
|
||||
METHOD(os_info_t, create_package_enumerator, enumerator_t*,
|
||||
private_os_info_t *this)
|
||||
{
|
||||
/* TODO */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
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(chunk_t *name, chunk_t *version)
|
||||
{
|
||||
FILE *file;
|
||||
u_char buf[BUF_LEN], *pos = buf;
|
||||
int len = BUF_LEN - 1;
|
||||
chunk_t os_name = chunk_empty;
|
||||
chunk_t os_version = chunk_empty;
|
||||
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:
|
||||
{
|
||||
char str_debian[] = "Debian";
|
||||
|
||||
os_name = chunk_create(str_debian, strlen(str_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_name.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;
|
||||
}
|
||||
|
||||
/* copy OS name */
|
||||
*name = chunk_clone(os_name);
|
||||
|
||||
/* copy OS version and machine architecture */
|
||||
*version = chunk_alloc(os_version.len + 1 + strlen(uninfo.machine));
|
||||
pos = version->ptr;
|
||||
memcpy(pos, os_version.ptr, os_version.len);
|
||||
pos += os_version.len;
|
||||
*pos++ = ' ';
|
||||
memcpy(pos, uninfo.machine, strlen(uninfo.machine));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* See header
|
||||
*/
|
||||
os_info_t *os_info_create(void)
|
||||
{
|
||||
private_os_info_t *this;
|
||||
chunk_t name, version;
|
||||
|
||||
/* As an opton OS name and OS version can be configured manually */
|
||||
name.ptr = lib->settings->get_str(lib->settings,
|
||||
"libimcv.os_info.name", NULL);
|
||||
version.ptr = lib->settings->get_str(lib->settings,
|
||||
"libimcv.os_info.version", NULL);
|
||||
if (name.ptr && version.ptr)
|
||||
{
|
||||
name.len = strlen(name.ptr);
|
||||
name = chunk_clone(name);
|
||||
|
||||
version.len = strlen(version.ptr);
|
||||
version = chunk_clone(version);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!extract_platform_info(&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_name = _get_name,
|
||||
.get_version = _get_version,
|
||||
.create_package_enumerator = _create_package_enumerator,
|
||||
.destroy = _destroy,
|
||||
},
|
||||
.name = name,
|
||||
.version = version,
|
||||
);
|
||||
|
||||
return &this->public;
|
||||
}
|
65
src/libimcv/os_info/os_info.h
Normal file
65
src/libimcv/os_info/os_info.h
Normal file
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (C) 2012 Andreas Steffen
|
||||
* HSR Hochschule fuer Technik Rapperswil
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version. See <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 os_info os_info
|
||||
* @{ @ingroup libimcv
|
||||
*/
|
||||
|
||||
#ifndef OS_INFO_H_
|
||||
#define OS_INFO_H_
|
||||
|
||||
typedef struct os_info_t os_info_t;
|
||||
|
||||
#include <library.h>
|
||||
|
||||
/**
|
||||
* Interface for the Operating System (OS) information module
|
||||
*/
|
||||
struct os_info_t {
|
||||
|
||||
/**
|
||||
* Get the OS product name or distribution
|
||||
*
|
||||
* @return OS name
|
||||
*/
|
||||
chunk_t (*get_name)(os_info_t *this);
|
||||
|
||||
/**
|
||||
* Get the OS version or release
|
||||
*
|
||||
* @return OS version
|
||||
*/
|
||||
chunk_t (*get_version)(os_info_t *this);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create an os_info_t object
|
||||
*/
|
||||
os_info_t* os_info_create(void);
|
||||
|
||||
#endif /** OS_INFO_H_ @}*/
|
@ -24,6 +24,7 @@
|
||||
#include <ietf/ietf_attr_pa_tnc_error.h>
|
||||
#include <ietf/ietf_attr_product_info.h>
|
||||
#include <ietf/ietf_attr_string_version.h>
|
||||
#include <os_info/os_info.h>
|
||||
|
||||
#include <tncif_pa_subtypes.h>
|
||||
|
||||
@ -40,6 +41,7 @@ static const char imc_name[] = "OS";
|
||||
#define IMC_SUBTYPE PA_SUBTYPE_IETF_OPERATING_SYSTEM
|
||||
|
||||
static imc_agent_t *imc_os;
|
||||
static os_info_t *os;
|
||||
|
||||
/**
|
||||
* see section 3.8.1 of TCG TNC IF-IMC Specification 1.3
|
||||
@ -60,6 +62,16 @@ TNC_Result TNC_IMC_Initialize(TNC_IMCID imc_id,
|
||||
{
|
||||
return TNC_RESULT_FATAL;
|
||||
}
|
||||
|
||||
os = os_info_create();
|
||||
if (!os)
|
||||
{
|
||||
imc_os->destroy(imc_os);
|
||||
imc_os = NULL;
|
||||
|
||||
return TNC_RESULT_FATAL;
|
||||
}
|
||||
|
||||
if (min_version > TNC_IFIMC_VERSION_1 || max_version < TNC_IFIMC_VERSION_1)
|
||||
{
|
||||
DBG1(DBG_IMC, "no common IF-IMC version");
|
||||
@ -110,9 +122,8 @@ TNC_Result TNC_IMC_NotifyConnectionChange(TNC_IMCID imc_id,
|
||||
static void add_product_info(linked_list_t *attr_list)
|
||||
{
|
||||
pa_tnc_attr_t *attr;
|
||||
char *os_name = "Ubuntu";
|
||||
|
||||
attr = ietf_attr_product_info_create(PEN_IETF, 0, os_name);
|
||||
attr = ietf_attr_product_info_create(PEN_IETF, 0, os->get_name(os));
|
||||
attr_list->insert_last(attr_list, attr);
|
||||
}
|
||||
|
||||
@ -122,9 +133,9 @@ static void add_product_info(linked_list_t *attr_list)
|
||||
static void add_string_version(linked_list_t *attr_list)
|
||||
{
|
||||
pa_tnc_attr_t *attr;
|
||||
chunk_t os_version = { "12.04", 5};
|
||||
|
||||
attr = ietf_attr_string_version_create(os_version, chunk_empty, chunk_empty);
|
||||
attr = ietf_attr_string_version_create(os->get_version(os),
|
||||
chunk_empty, chunk_empty);
|
||||
attr_list->insert_last(attr_list, attr);
|
||||
}
|
||||
|
||||
@ -362,6 +373,9 @@ TNC_Result TNC_IMC_Terminate(TNC_IMCID imc_id)
|
||||
imc_os->destroy(imc_os);
|
||||
imc_os = NULL;
|
||||
|
||||
os->destroy(os);
|
||||
os = NULL;
|
||||
|
||||
return TNC_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -112,7 +112,7 @@ static TNC_Result receive_message(TNC_IMVID imv_id,
|
||||
imv_os_state_t *os_state;
|
||||
enumerator_t *enumerator;
|
||||
TNC_Result result;
|
||||
char *os_name = NULL;
|
||||
chunk_t os_name = chunk_empty;
|
||||
chunk_t os_version = chunk_empty;
|
||||
bool fatal_error, assessment = FALSE;
|
||||
|
||||
@ -161,7 +161,8 @@ static TNC_Result receive_message(TNC_IMVID imv_id,
|
||||
|
||||
attr_cast = (ietf_attr_product_info_t*)attr;
|
||||
os_name = attr_cast->get_info(attr_cast, NULL, NULL);
|
||||
DBG1(DBG_IMV, "operating system name is '%s'", os_name);
|
||||
DBG1(DBG_IMV, "operating system name is '%.*s'",
|
||||
os_name.len, os_name.ptr);
|
||||
break;
|
||||
}
|
||||
case IETF_ATTR_STRING_VERSION:
|
||||
@ -204,15 +205,30 @@ static TNC_Result receive_message(TNC_IMVID imv_id,
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
if (os_name && os_version.len)
|
||||
if (os_name.len && os_version.len)
|
||||
{
|
||||
os_state->set_info(os_state, os_name, os_version);
|
||||
char *product_info;
|
||||
|
||||
DBG1(DBG_IMV, "requesting installed packages for '%s'",
|
||||
os_state->get_info(os_state));
|
||||
attr = ietf_attr_attr_request_create(PEN_IETF,
|
||||
IETF_ATTR_INSTALLED_PACKAGES);
|
||||
attr_list->insert_last(attr_list, attr);
|
||||
os_state->set_info(os_state, os_name, os_version);
|
||||
product_info = os_state->get_info(os_state);
|
||||
|
||||
if (streq(product_info, "Windows 1.2.3"))
|
||||
{
|
||||
DBG1(DBG_IMV, "OS '%s' is not supported", product_info);
|
||||
|
||||
state->set_recommendation(state,
|
||||
TNC_IMV_ACTION_RECOMMENDATION_ISOLATE,
|
||||
TNC_IMV_EVALUATION_RESULT_NONCOMPLIANT_MINOR);
|
||||
assessment = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG1(DBG_IMV, "requesting installed packages for '%s'",
|
||||
product_info);
|
||||
attr = ietf_attr_attr_request_create(PEN_IETF,
|
||||
IETF_ATTR_INSTALLED_PACKAGES);
|
||||
attr_list->insert_last(attr_list, attr);
|
||||
}
|
||||
}
|
||||
pa_tnc_msg->destroy(pa_tnc_msg);
|
||||
|
||||
|
@ -164,14 +164,15 @@ METHOD(imv_state_t, destroy, void,
|
||||
}
|
||||
|
||||
METHOD(imv_os_state_t, set_info, void,
|
||||
private_imv_os_state_t *this, char *name, chunk_t version)
|
||||
private_imv_os_state_t *this, chunk_t name, chunk_t version)
|
||||
{
|
||||
int len = strlen(name) + 1 + version.len + 1;
|
||||
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", name, version.len, version.ptr);
|
||||
snprintf(this->info, len, "%.*s %.*s", name.len, name.ptr,
|
||||
version.len, version.ptr);
|
||||
}
|
||||
|
||||
METHOD(imv_os_state_t, get_info, char*,
|
||||
|
@ -43,7 +43,7 @@ struct imv_os_state_t {
|
||||
* @param name OS name
|
||||
* @param version OS version
|
||||
*/
|
||||
void (*set_info)(imv_os_state_t *this, char *name, chunk_t version);
|
||||
void (*set_info)(imv_os_state_t *this, chunk_t name, chunk_t version);
|
||||
|
||||
/**
|
||||
* Get OS Product Information
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include <ietf/ietf_attr_pa_tnc_error.h>
|
||||
#include <ietf/ietf_attr_product_info.h>
|
||||
#include <ietf/ietf_attr_assess_result.h>
|
||||
#include <os_info/os_info.h>
|
||||
|
||||
#include <libpts.h>
|
||||
|
||||
@ -44,6 +45,7 @@ static const char imc_name[] = "Attestation";
|
||||
#define IMC_SUBTYPE PA_SUBTYPE_TCG_PTS
|
||||
|
||||
static imc_agent_t *imc_attestation;
|
||||
static os_info_t *os;
|
||||
|
||||
/**
|
||||
* Supported PTS measurement algorithms
|
||||
@ -80,6 +82,15 @@ TNC_Result TNC_IMC_Initialize(TNC_IMCID imc_id,
|
||||
return TNC_RESULT_FATAL;
|
||||
}
|
||||
|
||||
os = os_info_create();
|
||||
if (!os)
|
||||
{
|
||||
imc_attestation->destroy(imc_attestation);
|
||||
imc_attestation = NULL;
|
||||
|
||||
return TNC_RESULT_FATAL;
|
||||
}
|
||||
|
||||
libpts_init();
|
||||
|
||||
if (min_version > TNC_IFIMC_VERSION_1 || max_version < TNC_IFIMC_VERSION_1)
|
||||
@ -135,10 +146,9 @@ TNC_Result TNC_IMC_NotifyConnectionChange(TNC_IMCID imc_id,
|
||||
TNC_Result TNC_IMC_BeginHandshake(TNC_IMCID imc_id,
|
||||
TNC_ConnectionID connection_id)
|
||||
{
|
||||
imc_state_t *state;
|
||||
imc_attestation_state_t *attestation_state;
|
||||
pts_t *pts;
|
||||
char *platform_info;
|
||||
linked_list_t *attr_list;
|
||||
pa_tnc_attr_t *attr;
|
||||
chunk_t os_name, os_version;
|
||||
TNC_Result result = TNC_RESULT_SUCCESS;
|
||||
|
||||
if (!imc_attestation)
|
||||
@ -147,27 +157,15 @@ TNC_Result TNC_IMC_BeginHandshake(TNC_IMCID imc_id,
|
||||
return TNC_RESULT_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
/* get current IMC state */
|
||||
if (!imc_attestation->get_state(imc_attestation, connection_id, &state))
|
||||
{
|
||||
return TNC_RESULT_FATAL;
|
||||
}
|
||||
attestation_state = (imc_attestation_state_t*)state;
|
||||
pts = attestation_state->get_pts(attestation_state);
|
||||
|
||||
platform_info = pts->get_platform_info(pts);
|
||||
if (platform_info)
|
||||
{
|
||||
linked_list_t *attr_list;
|
||||
pa_tnc_attr_t *attr;
|
||||
|
||||
attr_list = linked_list_create();
|
||||
attr = ietf_attr_product_info_create(0, 0, platform_info);
|
||||
attr_list->insert_last(attr_list, attr);
|
||||
result = imc_attestation->send_message(imc_attestation, connection_id,
|
||||
FALSE, 0, TNC_IMVID_ANY, attr_list);
|
||||
attr_list->destroy(attr_list);
|
||||
}
|
||||
attr_list = linked_list_create();
|
||||
attr = ietf_attr_product_info_create(0, 0, os->get_name(os));
|
||||
attr_list->insert_last(attr_list, attr);
|
||||
attr = ietf_attr_string_version_create(os->get_version(os),
|
||||
chunk_empty, chunk_empty);
|
||||
attr_list->insert_last(attr_list, attr);
|
||||
result = imc_attestation->send_message(imc_attestation, connection_id,
|
||||
FALSE, 0, TNC_IMVID_ANY, attr_list);
|
||||
attr_list->destroy(attr_list);
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -348,6 +346,9 @@ TNC_Result TNC_IMC_Terminate(TNC_IMCID imc_id)
|
||||
imc_attestation->destroy(imc_attestation);
|
||||
imc_attestation = NULL;
|
||||
|
||||
os->destroy(os);
|
||||
os = NULL;
|
||||
|
||||
return TNC_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -212,7 +212,6 @@ METHOD(imc_attestation_state_t, next_evidence, bool,
|
||||
imc_state_t *imc_attestation_state_create(TNC_ConnectionID connection_id)
|
||||
{
|
||||
private_imc_attestation_state_t *this;
|
||||
char *platform_info;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
@ -240,13 +239,6 @@ imc_state_t *imc_attestation_state_create(TNC_ConnectionID connection_id)
|
||||
.components = linked_list_create(),
|
||||
.list = linked_list_create(),
|
||||
);
|
||||
|
||||
platform_info = lib->settings->get_str(lib->settings,
|
||||
"libimcv.plugins.imc-attestation.platform_info", NULL);
|
||||
if (platform_info)
|
||||
{
|
||||
this->pts->set_platform_info(this->pts, platform_info);
|
||||
}
|
||||
|
||||
return &this->public.interface;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
p="Ubuntu 12.04.1 LTS i686"
|
||||
p="Ubuntu 12.04 i686"
|
||||
|
||||
ipsec attest --add --product "$p" --sha1-ima --dir /sbin
|
||||
ipsec attest --add --product "$p" --sha1-ima --dir /usr/sbin
|
||||
|
@ -51,7 +51,7 @@ INSERT INTO products (
|
||||
INSERT INTO products (
|
||||
name
|
||||
) VALUES (
|
||||
'Ubuntu 12.04.1 LTS i686'
|
||||
'Ubuntu 12.04 i686'
|
||||
);
|
||||
|
||||
/* Files */
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include <ietf/ietf_attr.h>
|
||||
#include <ietf/ietf_attr_pa_tnc_error.h>
|
||||
#include <ietf/ietf_attr_product_info.h>
|
||||
#include <ietf/ietf_attr_string_version.h>
|
||||
|
||||
#include <libpts.h>
|
||||
|
||||
@ -219,6 +220,8 @@ static TNC_Result receive_message(TNC_IMVID imv_id,
|
||||
imv_state_t *state;
|
||||
imv_attestation_state_t *attestation_state;
|
||||
pts_t *pts;
|
||||
chunk_t os_name = chunk_empty;
|
||||
chunk_t os_version = chunk_empty;
|
||||
enumerator_t *enumerator;
|
||||
TNC_Result result;
|
||||
|
||||
@ -228,7 +231,7 @@ static TNC_Result receive_message(TNC_IMVID imv_id,
|
||||
return TNC_RESULT_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
/* get current IMV state */
|
||||
/* get current IMV state */
|
||||
if (!imv_attestation->get_state(imv_attestation, connection_id, &state))
|
||||
{
|
||||
return TNC_RESULT_FATAL;
|
||||
@ -260,34 +263,47 @@ static TNC_Result receive_message(TNC_IMVID imv_id,
|
||||
|
||||
if (type.vendor_id == PEN_IETF)
|
||||
{
|
||||
if (type.type == IETF_ATTR_PA_TNC_ERROR)
|
||||
switch (type.type)
|
||||
{
|
||||
ietf_attr_pa_tnc_error_t *error_attr;
|
||||
pen_type_t error_code;
|
||||
chunk_t msg_info;
|
||||
|
||||
error_attr = (ietf_attr_pa_tnc_error_t*)attr;
|
||||
error_code = error_attr->get_error_code(error_attr);
|
||||
|
||||
if (error_code.vendor_id == PEN_TCG)
|
||||
case IETF_ATTR_PA_TNC_ERROR:
|
||||
{
|
||||
msg_info = error_attr->get_msg_info(error_attr);
|
||||
ietf_attr_pa_tnc_error_t *error_attr;
|
||||
pen_type_t error_code;
|
||||
chunk_t msg_info;
|
||||
|
||||
DBG1(DBG_IMV, "received TCG-PTS error '%N'",
|
||||
pts_error_code_names, error_code.type);
|
||||
DBG1(DBG_IMV, "error information: %B", &msg_info);
|
||||
error_attr = (ietf_attr_pa_tnc_error_t*)attr;
|
||||
error_code = error_attr->get_error_code(error_attr);
|
||||
|
||||
result = TNC_RESULT_FATAL;
|
||||
if (error_code.vendor_id == PEN_TCG)
|
||||
{
|
||||
msg_info = error_attr->get_msg_info(error_attr);
|
||||
|
||||
DBG1(DBG_IMV, "received TCG-PTS error '%N'",
|
||||
pts_error_code_names, error_code.type);
|
||||
DBG1(DBG_IMV, "error information: %B", &msg_info);
|
||||
|
||||
result = TNC_RESULT_FATAL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (type.type == IETF_ATTR_PRODUCT_INFORMATION)
|
||||
{
|
||||
ietf_attr_product_info_t *attr_cast;
|
||||
char *platform_info;
|
||||
case IETF_ATTR_PRODUCT_INFORMATION:
|
||||
{
|
||||
ietf_attr_product_info_t *attr_cast;
|
||||
|
||||
attr_cast = (ietf_attr_product_info_t*)attr;
|
||||
platform_info = attr_cast->get_info(attr_cast, NULL, NULL);
|
||||
pts->set_platform_info(pts, platform_info);
|
||||
attr_cast = (ietf_attr_product_info_t*)attr;
|
||||
os_name = attr_cast->get_info(attr_cast, NULL, NULL);
|
||||
break;
|
||||
}
|
||||
case IETF_ATTR_STRING_VERSION:
|
||||
{
|
||||
ietf_attr_string_version_t *attr_cast;
|
||||
|
||||
attr_cast = (ietf_attr_string_version_t*)attr;
|
||||
os_version = attr_cast->get_version(attr_cast, NULL, NULL);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (type.vendor_id == PEN_TCG)
|
||||
@ -301,6 +317,11 @@ static TNC_Result receive_message(TNC_IMVID imv_id,
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
if (os_name.len && os_version.len)
|
||||
{
|
||||
pts->set_platform_info(pts, os_name, os_version);
|
||||
}
|
||||
pa_tnc_msg->destroy(pa_tnc_msg);
|
||||
|
||||
if (result != TNC_RESULT_SUCCESS)
|
||||
|
@ -436,7 +436,6 @@ METHOD(imv_attestation_state_t, components_finalized, bool,
|
||||
imv_state_t *imv_attestation_state_create(TNC_ConnectionID connection_id)
|
||||
{
|
||||
private_imv_attestation_state_t *this;
|
||||
char *platform_info;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
@ -476,12 +475,5 @@ imv_state_t *imv_attestation_state_create(TNC_ConnectionID connection_id)
|
||||
.pts = pts_create(FALSE),
|
||||
);
|
||||
|
||||
platform_info = lib->settings->get_str(lib->settings,
|
||||
"libimcv.plugins.imv-attestation.platform_info", NULL);
|
||||
if (platform_info)
|
||||
{
|
||||
this->pts->set_platform_info(this->pts, platform_info);
|
||||
}
|
||||
|
||||
return &this->public.interface;
|
||||
}
|
||||
|
@ -314,10 +314,15 @@ METHOD(pts_t, get_platform_info, char*,
|
||||
}
|
||||
|
||||
METHOD(pts_t, set_platform_info, void,
|
||||
private_pts_t *this, char *info)
|
||||
private_pts_t *this, chunk_t name, chunk_t version)
|
||||
{
|
||||
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 = strdup(info);
|
||||
this->platform_info = malloc(len);
|
||||
snprintf(this->platform_info, len, "%.*s %.*s", name.len, name.ptr,
|
||||
version.len, version.ptr);
|
||||
}
|
||||
|
||||
METHOD(pts_t, get_tpm_version_info, bool,
|
||||
@ -1047,122 +1052,6 @@ METHOD(pts_t, destroy, void,
|
||||
free(this);
|
||||
}
|
||||
|
||||
#define RELEASE_LSB 0
|
||||
#define RELEASE_DEBIAN 1
|
||||
|
||||
/**
|
||||
* Determine Linux distribution and hardware platform
|
||||
*/
|
||||
static char* extract_platform_info(void)
|
||||
{
|
||||
FILE *file;
|
||||
char buf[BUF_LEN], *pos = buf, *value = NULL;
|
||||
int i, len = BUF_LEN - 1;
|
||||
struct utsname uninfo;
|
||||
|
||||
/* 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 description[] = "DISTRIB_DESCRIPTION=\"";
|
||||
const char str_debian[] = "Debian ";
|
||||
|
||||
for (i = 0; i < countof(releases); i++)
|
||||
{
|
||||
file = fopen(releases[i], "r");
|
||||
if (!file)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (i == RELEASE_DEBIAN)
|
||||
{
|
||||
strcpy(buf, str_debian);
|
||||
pos += strlen(str_debian);
|
||||
len -= strlen(str_debian);
|
||||
}
|
||||
|
||||
fseek(file, 0, SEEK_END);
|
||||
len = min(ftell(file), len);
|
||||
rewind(file);
|
||||
pos[len] = '\0';
|
||||
if (fread(pos, 1, len, file) != len)
|
||||
{
|
||||
DBG1(DBG_PTS, "failed to read file '%s'", releases[i]);
|
||||
fclose(file);
|
||||
return NULL;
|
||||
}
|
||||
fclose(file);
|
||||
|
||||
if (i == RELEASE_LSB)
|
||||
{
|
||||
pos = strstr(buf, description);
|
||||
if (!pos)
|
||||
{
|
||||
DBG1(DBG_PTS, "failed to find begin of lsb-release "
|
||||
"DESCRIPTION field");
|
||||
return NULL;
|
||||
}
|
||||
value = pos + strlen(description);
|
||||
pos = strchr(value, '"');
|
||||
if (!pos)
|
||||
{
|
||||
DBG1(DBG_PTS, "failed to find end of lsb-release "
|
||||
"DESCRIPTION field");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
value = buf;
|
||||
pos = strchr(pos, '\n');
|
||||
if (!pos)
|
||||
{
|
||||
DBG1(DBG_PTS, "failed to find end of release string");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!value)
|
||||
{
|
||||
DBG1(DBG_PTS, "no distribution release file found");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (uname(&uninfo) < 0)
|
||||
{
|
||||
DBG1(DBG_PTS, "could not retrieve machine architecture");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*pos++ = ' ';
|
||||
len = sizeof(buf)-1 + (pos - buf);
|
||||
strncpy(pos, uninfo.machine, len);
|
||||
|
||||
DBG1(DBG_PTS, "platform is '%s'", value);
|
||||
return strdup(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for a TPM by querying for TPM Version Info
|
||||
*/
|
||||
@ -1264,8 +1153,6 @@ pts_t *pts_create(bool is_imc)
|
||||
|
||||
if (is_imc)
|
||||
{
|
||||
this->platform_info = extract_platform_info();
|
||||
|
||||
if (has_tpm(this))
|
||||
{
|
||||
this->has_tpm = TRUE;
|
||||
|
@ -171,9 +171,10 @@ struct pts_t {
|
||||
/**
|
||||
* Set Platform and OS Info
|
||||
*
|
||||
* @param info Platform and OS info
|
||||
* @param name OS name
|
||||
* @param version OS version
|
||||
*/
|
||||
void (*set_platform_info)(pts_t *this, char *info);
|
||||
void (*set_platform_info)(pts_t *this, chunk_t name, chunk_t version);
|
||||
|
||||
/**
|
||||
* Get TPM 1.2 Version Info
|
||||
|
Loading…
x
Reference in New Issue
Block a user