implemented os_info_t class

This commit is contained in:
Andreas Steffen
2012-10-10 21:54:21 +02:00
parent 7f3bf2b12f
commit 6ab1502519
18 changed files with 521 additions and 227 deletions
+6 -6
View File
@@ -764,10 +764,13 @@ Debug level for a stand-alone libimcv library
.TP .TP
.BR libimcv.stderr_quiet " [no]" .BR libimcv.stderr_quiet " [no]"
Disable output to stderr with a stand-alone libimcv library Disable output to stderr with a stand-alone libimcv library
.SS libimcv plugins section
.TP .TP
.BR libimcv.plugins.imc-attestation.platform_info .BR libimcv.os_info.name
Information on operating system and hardware platform 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 .TP
.BR libimcv.plugins.imc-attestation.aik_blob .BR libimcv.plugins.imc-attestation.aik_blob
AIK encrypted private key blob file AIK encrypted private key blob file
@@ -799,9 +802,6 @@ Preferred measurement hash algorithm
.BR libimcv.plugins.imv-attestation.min_nonce_len " [0]" .BR libimcv.plugins.imv-attestation.min_nonce_len " [0]"
DH minimum nonce length DH minimum nonce length
.TP .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]" .BR libimcv.plugins.imv-scanner.closed_port_policy " [yes]"
By default all ports must be closed (yes) or can be open (no) By default all ports must be closed (yes) or can be open (no)
.TP .TP
+1
View File
@@ -20,6 +20,7 @@ libimcv_la_SOURCES = \
ita/ita_attr.h ita/ita_attr.c \ ita/ita_attr.h ita/ita_attr.c \
ita/ita_attr_command.h ita/ita_attr_command.c \ ita/ita_attr_command.h ita/ita_attr_command.c \
ita/ita_attr_dummy.h ita/ita_attr_dummy.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_attr.h \
pa_tnc/pa_tnc_msg.h pa_tnc/pa_tnc_msg.c \ 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 pa_tnc/pa_tnc_attr_manager.h pa_tnc/pa_tnc_attr_manager.c
+7 -13
View File
@@ -73,7 +73,7 @@ struct private_ietf_attr_product_info_t {
/** /**
* Product Name * Product Name
*/ */
char *product_name; chunk_t product_name;
/** /**
* Reference count * Reference count
@@ -109,18 +109,15 @@ METHOD(pa_tnc_attr_t, build, void,
private_ietf_attr_product_info_t *this) private_ietf_attr_product_info_t *this)
{ {
bio_writer_t *writer; bio_writer_t *writer;
chunk_t product_name;
if (this->value.ptr) if (this->value.ptr)
{ {
return; return;
} }
product_name = chunk_create(this->product_name, strlen(this->product_name));
writer = bio_writer_create(PRODUCT_INFO_MIN_SIZE); writer = bio_writer_create(PRODUCT_INFO_MIN_SIZE);
writer->write_uint24(writer, this->product_vendor_id); writer->write_uint24(writer, this->product_vendor_id);
writer->write_uint16(writer, this->product_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)); this->value = chunk_clone(writer->get_buf(writer));
writer->destroy(writer); writer->destroy(writer);
@@ -151,10 +148,7 @@ METHOD(pa_tnc_attr_t, process, status_t,
*offset = 3; *offset = 3;
return FAILED; return FAILED;
} }
this->product_name = chunk_clone(product_name);
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';
return SUCCESS; return SUCCESS;
} }
@@ -171,13 +165,13 @@ METHOD(pa_tnc_attr_t, destroy, void,
{ {
if (ref_put(&this->ref)) if (ref_put(&this->ref))
{ {
free(this->product_name); free(this->product_name.ptr);
free(this->value.ptr); free(this->value.ptr);
free(this); 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) private_ietf_attr_product_info_t *this, pen_t *vendor_id, u_int16_t *id)
{ {
if (vendor_id) if (vendor_id)
@@ -195,7 +189,7 @@ METHOD(ietf_attr_product_info_t, get_info, char*,
* Described in header. * Described in header.
*/ */
pa_tnc_attr_t *ietf_attr_product_info_create(pen_t vendor_id, u_int16_t id, 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; 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 }, .type = { PEN_IETF, IETF_ATTR_PRODUCT_INFORMATION },
.product_vendor_id = vendor_id, .product_vendor_id = vendor_id,
.product_id = id, .product_id = id,
.product_name = strdup(name), .product_name = chunk_clone(name),
.ref = 1, .ref = 1,
); );
+3 -3
View File
@@ -45,8 +45,8 @@ struct ietf_attr_product_info_t {
* @param id Product ID * @param id Product ID
* @return Product Name * @return Product Name
*/ */
char* (*get_info)(ietf_attr_product_info_t *this, chunk_t (*get_info)(ietf_attr_product_info_t *this,
pen_t *vendor_id, u_int16_t *id); 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, 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 * Creates an ietf_attr_product_info_t object from received data
+309
View 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
View 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_ @}*/
+18 -4
View File
@@ -24,6 +24,7 @@
#include <ietf/ietf_attr_pa_tnc_error.h> #include <ietf/ietf_attr_pa_tnc_error.h>
#include <ietf/ietf_attr_product_info.h> #include <ietf/ietf_attr_product_info.h>
#include <ietf/ietf_attr_string_version.h> #include <ietf/ietf_attr_string_version.h>
#include <os_info/os_info.h>
#include <tncif_pa_subtypes.h> #include <tncif_pa_subtypes.h>
@@ -40,6 +41,7 @@ static const char imc_name[] = "OS";
#define IMC_SUBTYPE PA_SUBTYPE_IETF_OPERATING_SYSTEM #define IMC_SUBTYPE PA_SUBTYPE_IETF_OPERATING_SYSTEM
static imc_agent_t *imc_os; static imc_agent_t *imc_os;
static os_info_t *os;
/** /**
* see section 3.8.1 of TCG TNC IF-IMC Specification 1.3 * 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; 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) if (min_version > TNC_IFIMC_VERSION_1 || max_version < TNC_IFIMC_VERSION_1)
{ {
DBG1(DBG_IMC, "no common IF-IMC version"); 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) static void add_product_info(linked_list_t *attr_list)
{ {
pa_tnc_attr_t *attr; 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); 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) static void add_string_version(linked_list_t *attr_list)
{ {
pa_tnc_attr_t *attr; 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); 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->destroy(imc_os);
imc_os = NULL; imc_os = NULL;
os->destroy(os);
os = NULL;
return TNC_RESULT_SUCCESS; return TNC_RESULT_SUCCESS;
} }
+25 -9
View File
@@ -112,7 +112,7 @@ static TNC_Result receive_message(TNC_IMVID imv_id,
imv_os_state_t *os_state; imv_os_state_t *os_state;
enumerator_t *enumerator; enumerator_t *enumerator;
TNC_Result result; TNC_Result result;
char *os_name = NULL; chunk_t os_name = chunk_empty;
chunk_t os_version = chunk_empty; chunk_t os_version = chunk_empty;
bool fatal_error, assessment = FALSE; 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; attr_cast = (ietf_attr_product_info_t*)attr;
os_name = attr_cast->get_info(attr_cast, NULL, NULL); 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; break;
} }
case IETF_ATTR_STRING_VERSION: case IETF_ATTR_STRING_VERSION:
@@ -204,15 +205,30 @@ static TNC_Result receive_message(TNC_IMVID imv_id,
} }
enumerator->destroy(enumerator); 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->set_info(os_state, os_name, os_version);
os_state->get_info(os_state)); product_info = os_state->get_info(os_state);
attr = ietf_attr_attr_request_create(PEN_IETF,
IETF_ATTR_INSTALLED_PACKAGES); if (streq(product_info, "Windows 1.2.3"))
attr_list->insert_last(attr_list, attr); {
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); pa_tnc_msg->destroy(pa_tnc_msg);
+4 -3
View File
@@ -164,14 +164,15 @@ METHOD(imv_state_t, destroy, void,
} }
METHOD(imv_os_state_t, set_info, 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 */ /* OS info is a concatenation of OS name and OS version */
free(this->info); free(this->info);
this->info = malloc(len); 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*, METHOD(imv_os_state_t, get_info, char*,
+1 -1
View File
@@ -43,7 +43,7 @@ struct imv_os_state_t {
* @param name OS name * @param name OS name
* @param version OS version * @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 * Get OS Product Information
@@ -22,6 +22,7 @@
#include <ietf/ietf_attr_pa_tnc_error.h> #include <ietf/ietf_attr_pa_tnc_error.h>
#include <ietf/ietf_attr_product_info.h> #include <ietf/ietf_attr_product_info.h>
#include <ietf/ietf_attr_assess_result.h> #include <ietf/ietf_attr_assess_result.h>
#include <os_info/os_info.h>
#include <libpts.h> #include <libpts.h>
@@ -44,6 +45,7 @@ static const char imc_name[] = "Attestation";
#define IMC_SUBTYPE PA_SUBTYPE_TCG_PTS #define IMC_SUBTYPE PA_SUBTYPE_TCG_PTS
static imc_agent_t *imc_attestation; static imc_agent_t *imc_attestation;
static os_info_t *os;
/** /**
* Supported PTS measurement algorithms * Supported PTS measurement algorithms
@@ -80,6 +82,15 @@ TNC_Result TNC_IMC_Initialize(TNC_IMCID imc_id,
return TNC_RESULT_FATAL; return TNC_RESULT_FATAL;
} }
os = os_info_create();
if (!os)
{
imc_attestation->destroy(imc_attestation);
imc_attestation = NULL;
return TNC_RESULT_FATAL;
}
libpts_init(); libpts_init();
if (min_version > TNC_IFIMC_VERSION_1 || max_version < TNC_IFIMC_VERSION_1) 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_Result TNC_IMC_BeginHandshake(TNC_IMCID imc_id,
TNC_ConnectionID connection_id) TNC_ConnectionID connection_id)
{ {
imc_state_t *state; linked_list_t *attr_list;
imc_attestation_state_t *attestation_state; pa_tnc_attr_t *attr;
pts_t *pts; chunk_t os_name, os_version;
char *platform_info;
TNC_Result result = TNC_RESULT_SUCCESS; TNC_Result result = TNC_RESULT_SUCCESS;
if (!imc_attestation) if (!imc_attestation)
@@ -147,27 +157,15 @@ TNC_Result TNC_IMC_BeginHandshake(TNC_IMCID imc_id,
return TNC_RESULT_NOT_INITIALIZED; return TNC_RESULT_NOT_INITIALIZED;
} }
/* get current IMC state */ attr_list = linked_list_create();
if (!imc_attestation->get_state(imc_attestation, connection_id, &state)) attr = ietf_attr_product_info_create(0, 0, os->get_name(os));
{ attr_list->insert_last(attr_list, attr);
return TNC_RESULT_FATAL; attr = ietf_attr_string_version_create(os->get_version(os),
} chunk_empty, chunk_empty);
attestation_state = (imc_attestation_state_t*)state; attr_list->insert_last(attr_list, attr);
pts = attestation_state->get_pts(attestation_state); result = imc_attestation->send_message(imc_attestation, connection_id,
FALSE, 0, TNC_IMVID_ANY, attr_list);
platform_info = pts->get_platform_info(pts); attr_list->destroy(attr_list);
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);
}
return result; return result;
} }
@@ -348,6 +346,9 @@ TNC_Result TNC_IMC_Terminate(TNC_IMCID imc_id)
imc_attestation->destroy(imc_attestation); imc_attestation->destroy(imc_attestation);
imc_attestation = NULL; imc_attestation = NULL;
os->destroy(os);
os = NULL;
return TNC_RESULT_SUCCESS; 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) imc_state_t *imc_attestation_state_create(TNC_ConnectionID connection_id)
{ {
private_imc_attestation_state_t *this; private_imc_attestation_state_t *this;
char *platform_info;
INIT(this, INIT(this,
.public = { .public = {
@@ -241,13 +240,6 @@ imc_state_t *imc_attestation_state_create(TNC_ConnectionID connection_id)
.list = 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; return &this->public.interface;
} }
@@ -1,6 +1,6 @@
#!/bin/sh #!/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 /sbin
ipsec attest --add --product "$p" --sha1-ima --dir /usr/sbin ipsec attest --add --product "$p" --sha1-ima --dir /usr/sbin
+1 -1
View File
@@ -51,7 +51,7 @@ INSERT INTO products (
INSERT INTO products ( INSERT INTO products (
name name
) VALUES ( ) VALUES (
'Ubuntu 12.04.1 LTS i686' 'Ubuntu 12.04 i686'
); );
/* Files */ /* Files */
@@ -22,6 +22,7 @@
#include <ietf/ietf_attr.h> #include <ietf/ietf_attr.h>
#include <ietf/ietf_attr_pa_tnc_error.h> #include <ietf/ietf_attr_pa_tnc_error.h>
#include <ietf/ietf_attr_product_info.h> #include <ietf/ietf_attr_product_info.h>
#include <ietf/ietf_attr_string_version.h>
#include <libpts.h> #include <libpts.h>
@@ -219,6 +220,8 @@ static TNC_Result receive_message(TNC_IMVID imv_id,
imv_state_t *state; imv_state_t *state;
imv_attestation_state_t *attestation_state; imv_attestation_state_t *attestation_state;
pts_t *pts; pts_t *pts;
chunk_t os_name = chunk_empty;
chunk_t os_version = chunk_empty;
enumerator_t *enumerator; enumerator_t *enumerator;
TNC_Result result; TNC_Result result;
@@ -228,7 +231,7 @@ static TNC_Result receive_message(TNC_IMVID imv_id,
return TNC_RESULT_NOT_INITIALIZED; return TNC_RESULT_NOT_INITIALIZED;
} }
/* get current IMV state */ /* get current IMV state */
if (!imv_attestation->get_state(imv_attestation, connection_id, &state)) if (!imv_attestation->get_state(imv_attestation, connection_id, &state))
{ {
return TNC_RESULT_FATAL; 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.vendor_id == PEN_IETF)
{ {
if (type.type == IETF_ATTR_PA_TNC_ERROR) switch (type.type)
{ {
ietf_attr_pa_tnc_error_t *error_attr; case IETF_ATTR_PA_TNC_ERROR:
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)
{ {
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'", error_attr = (ietf_attr_pa_tnc_error_t*)attr;
pts_error_code_names, error_code.type); error_code = error_attr->get_error_code(error_attr);
DBG1(DBG_IMV, "error information: %B", &msg_info);
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;
} }
} case IETF_ATTR_PRODUCT_INFORMATION:
else if (type.type == IETF_ATTR_PRODUCT_INFORMATION) {
{ ietf_attr_product_info_t *attr_cast;
ietf_attr_product_info_t *attr_cast;
char *platform_info;
attr_cast = (ietf_attr_product_info_t*)attr; attr_cast = (ietf_attr_product_info_t*)attr;
platform_info = attr_cast->get_info(attr_cast, NULL, NULL); os_name = attr_cast->get_info(attr_cast, NULL, NULL);
pts->set_platform_info(pts, platform_info); 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) else if (type.vendor_id == PEN_TCG)
@@ -301,6 +317,11 @@ static TNC_Result receive_message(TNC_IMVID imv_id,
} }
} }
enumerator->destroy(enumerator); 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); pa_tnc_msg->destroy(pa_tnc_msg);
if (result != TNC_RESULT_SUCCESS) 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) imv_state_t *imv_attestation_state_create(TNC_ConnectionID connection_id)
{ {
private_imv_attestation_state_t *this; private_imv_attestation_state_t *this;
char *platform_info;
INIT(this, INIT(this,
.public = { .public = {
@@ -476,12 +475,5 @@ imv_state_t *imv_attestation_state_create(TNC_ConnectionID connection_id)
.pts = pts_create(FALSE), .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; return &this->public.interface;
} }
+7 -120
View File
@@ -314,10 +314,15 @@ METHOD(pts_t, get_platform_info, char*,
} }
METHOD(pts_t, set_platform_info, void, 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); 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, METHOD(pts_t, get_tpm_version_info, bool,
@@ -1047,122 +1052,6 @@ METHOD(pts_t, destroy, void,
free(this); 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 * Check for a TPM by querying for TPM Version Info
*/ */
@@ -1264,8 +1153,6 @@ pts_t *pts_create(bool is_imc)
if (is_imc) if (is_imc)
{ {
this->platform_info = extract_platform_info();
if (has_tpm(this)) if (has_tpm(this))
{ {
this->has_tpm = TRUE; this->has_tpm = TRUE;
+3 -2
View File
@@ -171,9 +171,10 @@ struct pts_t {
/** /**
* Set Platform and OS Info * 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 * Get TPM 1.2 Version Info