libimcv: Support symlinks introduced by usrmerge
Debian, Ubuntu, Fedora et. al. started to apply usrmerge to their latest Linux distributions, i.e. /bin, /sbin, and /lib are now symbolical links to /usr/bin, /usr/sbin, and /usr/lib, respectively. Since executables and libraries are contained only once in Linux packages (e.g. /bin/cp in coreutils but not /usr/bin/cp) this leads to missing file measurments due to the symlinks when doing remote attestation. The new ita_attr_symlinks PA-TNC attribute fixes this problem by collecting symbolic links pointing to directories on the client platform.
This commit is contained in:
@@ -42,6 +42,7 @@ libimcv_la_SOURCES := \
|
|||||||
ita/ita_attr_get_settings.h ita/ita_attr_get_settings.c \
|
ita/ita_attr_get_settings.h ita/ita_attr_get_settings.c \
|
||||||
ita/ita_attr_settings.h ita/ita_attr_settings.c \
|
ita/ita_attr_settings.h ita/ita_attr_settings.c \
|
||||||
ita/ita_attr_angel.h ita/ita_attr_angel.c \
|
ita/ita_attr_angel.h ita/ita_attr_angel.c \
|
||||||
|
ita/ita_attr_symlinks.h ita/ita_attr_symlinks.c \
|
||||||
os_info/os_info.h os_info/os_info.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 \
|
||||||
@@ -60,6 +61,7 @@ libimcv_la_SOURCES := \
|
|||||||
pts/pts_ima_bios_list.h pts/pts_ima_bios_list.c \
|
pts/pts_ima_bios_list.h pts/pts_ima_bios_list.c \
|
||||||
pts/pts_ima_event_list.h pts/pts_ima_event_list.c \
|
pts/pts_ima_event_list.h pts/pts_ima_event_list.c \
|
||||||
pts/pts_meas_algo.h pts/pts_meas_algo.c \
|
pts/pts_meas_algo.h pts/pts_meas_algo.c \
|
||||||
|
pts/pts_symlinks.h pts/pts_symlinks.c \
|
||||||
pts/components/pts_component.h \
|
pts/components/pts_component.h \
|
||||||
pts/components/pts_component_manager.h pts/components/pts_component_manager.c \
|
pts/components/pts_component_manager.h pts/components/pts_component_manager.c \
|
||||||
pts/components/pts_comp_evidence.h pts/components/pts_comp_evidence.c \
|
pts/components/pts_comp_evidence.h pts/components/pts_comp_evidence.c \
|
||||||
|
|||||||
@@ -63,6 +63,7 @@ libimcv_la_SOURCES = \
|
|||||||
ita/ita_attr_get_settings.h ita/ita_attr_get_settings.c \
|
ita/ita_attr_get_settings.h ita/ita_attr_get_settings.c \
|
||||||
ita/ita_attr_settings.h ita/ita_attr_settings.c \
|
ita/ita_attr_settings.h ita/ita_attr_settings.c \
|
||||||
ita/ita_attr_angel.h ita/ita_attr_angel.c \
|
ita/ita_attr_angel.h ita/ita_attr_angel.c \
|
||||||
|
ita/ita_attr_symlinks.h ita/ita_attr_symlinks.c \
|
||||||
os_info/os_info.h os_info/os_info.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 \
|
||||||
@@ -81,6 +82,7 @@ libimcv_la_SOURCES = \
|
|||||||
pts/pts_ima_bios_list.h pts/pts_ima_bios_list.c \
|
pts/pts_ima_bios_list.h pts/pts_ima_bios_list.c \
|
||||||
pts/pts_ima_event_list.h pts/pts_ima_event_list.c \
|
pts/pts_ima_event_list.h pts/pts_ima_event_list.c \
|
||||||
pts/pts_meas_algo.h pts/pts_meas_algo.c \
|
pts/pts_meas_algo.h pts/pts_meas_algo.c \
|
||||||
|
pts/pts_symlinks.h pts/pts_symlinks.c \
|
||||||
pts/components/pts_component.h \
|
pts/components/pts_component.h \
|
||||||
pts/components/pts_component_manager.h pts/components/pts_component_manager.c \
|
pts/components/pts_component_manager.h pts/components/pts_component_manager.c \
|
||||||
pts/components/pts_comp_evidence.h pts/components/pts_comp_evidence.c \
|
pts/components/pts_comp_evidence.h pts/components/pts_comp_evidence.c \
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2011-2014 Andreas Steffen
|
* Copyright (C) 2011-2020 Andreas Steffen
|
||||||
* HSR Hochschule fuer Technik Rapperswil
|
* HSR Hochschule fuer Technik Rapperswil
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
@@ -19,9 +19,10 @@
|
|||||||
#include "ita/ita_attr_get_settings.h"
|
#include "ita/ita_attr_get_settings.h"
|
||||||
#include "ita/ita_attr_settings.h"
|
#include "ita/ita_attr_settings.h"
|
||||||
#include "ita/ita_attr_angel.h"
|
#include "ita/ita_attr_angel.h"
|
||||||
|
#include "ita/ita_attr_symlinks.h"
|
||||||
#include "generic/generic_attr_string.h"
|
#include "generic/generic_attr_string.h"
|
||||||
|
|
||||||
ENUM(ita_attr_names, ITA_ATTR_COMMAND, ITA_ATTR_DEVICE_ID,
|
ENUM(ita_attr_names, ITA_ATTR_COMMAND, ITA_ATTR_SYMLINKS,
|
||||||
"Command",
|
"Command",
|
||||||
"Dummy",
|
"Dummy",
|
||||||
"Get Settings",
|
"Get Settings",
|
||||||
@@ -29,7 +30,9 @@ ENUM(ita_attr_names, ITA_ATTR_COMMAND, ITA_ATTR_DEVICE_ID,
|
|||||||
"Start Angel",
|
"Start Angel",
|
||||||
"Stop Angel",
|
"Stop Angel",
|
||||||
"Echo",
|
"Echo",
|
||||||
"Device ID"
|
"Device ID",
|
||||||
|
"Get Symlinks",
|
||||||
|
"Symlinks"
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -55,6 +58,11 @@ pa_tnc_attr_t* ita_attr_create_from_data(uint32_t type, size_t length,
|
|||||||
case ITA_ATTR_DEVICE_ID:
|
case ITA_ATTR_DEVICE_ID:
|
||||||
return generic_attr_string_create_from_data(length, value,
|
return generic_attr_string_create_from_data(length, value,
|
||||||
pen_type_create(PEN_ITA, type));
|
pen_type_create(PEN_ITA, type));
|
||||||
|
case ITA_ATTR_GET_SYMLINKS:
|
||||||
|
return generic_attr_string_create_from_data(length, value,
|
||||||
|
pen_type_create(PEN_ITA, type));
|
||||||
|
case ITA_ATTR_SYMLINKS:
|
||||||
|
return ita_attr_symlinks_create_from_data(length, value);
|
||||||
default:
|
default:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2011-2014 Andreas Steffen
|
* Copyright (C) 2011-2020 Andreas Steffen
|
||||||
* HSR Hochschule fuer Technik Rapperswil
|
* HSR Hochschule fuer Technik Rapperswil
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
@@ -38,7 +38,9 @@ enum ita_attr_t {
|
|||||||
ITA_ATTR_START_ANGEL = 5,
|
ITA_ATTR_START_ANGEL = 5,
|
||||||
ITA_ATTR_STOP_ANGEL = 6,
|
ITA_ATTR_STOP_ANGEL = 6,
|
||||||
ITA_ATTR_ECHO = 7,
|
ITA_ATTR_ECHO = 7,
|
||||||
ITA_ATTR_DEVICE_ID = 8
|
ITA_ATTR_DEVICE_ID = 8,
|
||||||
|
ITA_ATTR_GET_SYMLINKS = 9,
|
||||||
|
ITA_ATTR_SYMLINKS = 10
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -0,0 +1,318 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2020 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 "ita_attr_symlinks.h"
|
||||||
|
|
||||||
|
#include <pa_tnc/pa_tnc_msg.h>
|
||||||
|
#include <bio/bio_writer.h>
|
||||||
|
#include <bio/bio_reader.h>
|
||||||
|
#include <collections/linked_list.h>
|
||||||
|
#include <utils/debug.h>
|
||||||
|
|
||||||
|
typedef struct private_ita_attr_symlinks_t private_ita_attr_symlinks_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of Symbolic Links pointing to Directories
|
||||||
|
*
|
||||||
|
* 1 2 3
|
||||||
|
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||||
|
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
* | Number of Symlinks |
|
||||||
|
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
* | Symlink #1 Length | Symlink #1 Path (Var Len) ~
|
||||||
|
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
* | Symlink #1 Path (Variable Length) |
|
||||||
|
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
* | Directory #1 Length | Directory #1 Path (Var Len) ~
|
||||||
|
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
* | Directory #1 Path (Variable Length) |
|
||||||
|
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
* | Symlink #2 Length | Symlink #2 Path (Var Len) ~
|
||||||
|
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
* | Symlink #2 Path (Variable Length) |
|
||||||
|
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
* | Directory #2 Length | Directory #2 Path (Var Len) ~
|
||||||
|
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
* | Directory #2 Path (Variable Length) |
|
||||||
|
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
* ...........................
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define ITA_ATTR_SYMLINKS_SIZE 4
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Private data of an ita_attr_symlinks_t object.
|
||||||
|
*/
|
||||||
|
struct private_ita_attr_symlinks_t {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Public members of ita_attr_symlinks_t
|
||||||
|
*/
|
||||||
|
ita_attr_symlinks_t public;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vendor-specific attribute type
|
||||||
|
*/
|
||||||
|
pen_type_t type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Length of attribute value
|
||||||
|
*/
|
||||||
|
size_t length;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Offset up to which attribute value has been processed
|
||||||
|
*/
|
||||||
|
size_t offset;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Current position of attribute value pointer
|
||||||
|
*/
|
||||||
|
chunk_t value;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Contains complete attribute or current segment
|
||||||
|
*/
|
||||||
|
chunk_t segment;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Noskip flag
|
||||||
|
*/
|
||||||
|
bool noskip_flag;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Number of symbolic link entries
|
||||||
|
*/
|
||||||
|
uint32_t count;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of symbolic links
|
||||||
|
*/
|
||||||
|
pts_symlinks_t *symlinks;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reference count
|
||||||
|
*/
|
||||||
|
refcount_t ref;
|
||||||
|
};
|
||||||
|
|
||||||
|
METHOD(pa_tnc_attr_t, get_type, pen_type_t,
|
||||||
|
private_ita_attr_symlinks_t *this)
|
||||||
|
{
|
||||||
|
return this->type;
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(pa_tnc_attr_t, get_value, chunk_t,
|
||||||
|
private_ita_attr_symlinks_t *this)
|
||||||
|
{
|
||||||
|
return this->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
|
||||||
|
private_ita_attr_symlinks_t *this)
|
||||||
|
{
|
||||||
|
return this->noskip_flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(pa_tnc_attr_t, set_noskip_flag,void,
|
||||||
|
private_ita_attr_symlinks_t *this, bool noskip)
|
||||||
|
{
|
||||||
|
this->noskip_flag = noskip;
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(pa_tnc_attr_t, build, void,
|
||||||
|
private_ita_attr_symlinks_t *this)
|
||||||
|
{
|
||||||
|
bio_writer_t *writer;
|
||||||
|
enumerator_t *enumerator;
|
||||||
|
chunk_t symlink, dir;
|
||||||
|
|
||||||
|
if (this->value.ptr)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this->count = this->symlinks->get_count(this->symlinks);
|
||||||
|
|
||||||
|
writer = bio_writer_create(ITA_ATTR_SYMLINKS_SIZE);
|
||||||
|
writer->write_uint32(writer, this->count);
|
||||||
|
|
||||||
|
enumerator = this->symlinks->create_enumerator(this->symlinks);
|
||||||
|
while (enumerator->enumerate(enumerator, &symlink, &dir))
|
||||||
|
{
|
||||||
|
writer->write_data16(writer, symlink);
|
||||||
|
writer->write_data16(writer, dir);
|
||||||
|
}
|
||||||
|
enumerator->destroy(enumerator);
|
||||||
|
|
||||||
|
this->value = writer->extract_buf(writer);
|
||||||
|
this->segment = this->value;
|
||||||
|
this->length = this->value.len;
|
||||||
|
writer->destroy(writer);
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(pa_tnc_attr_t, process, status_t,
|
||||||
|
private_ita_attr_symlinks_t *this, uint32_t *offset)
|
||||||
|
{
|
||||||
|
bio_reader_t *reader;
|
||||||
|
chunk_t symlink, dir;
|
||||||
|
status_t status = NEED_MORE;
|
||||||
|
|
||||||
|
if (this->offset == 0)
|
||||||
|
{
|
||||||
|
if (this->length < ITA_ATTR_SYMLINKS_SIZE)
|
||||||
|
{
|
||||||
|
DBG1(DBG_TNC, "insufficient data for %N/%N", pen_names, PEN_ITA,
|
||||||
|
ita_attr_names, this->type.type);
|
||||||
|
*offset = this->offset;
|
||||||
|
return FAILED;
|
||||||
|
}
|
||||||
|
if (this->value.len < ITA_ATTR_SYMLINKS_SIZE)
|
||||||
|
{
|
||||||
|
return NEED_MORE;
|
||||||
|
}
|
||||||
|
reader = bio_reader_create(this->value);
|
||||||
|
reader->read_uint32(reader, &this->count);
|
||||||
|
this->offset = ITA_ATTR_SYMLINKS_SIZE;
|
||||||
|
this->value = reader->peek(reader);
|
||||||
|
reader->destroy(reader);
|
||||||
|
}
|
||||||
|
|
||||||
|
this->symlinks = pts_symlinks_create();
|
||||||
|
reader = bio_reader_create(this->value);
|
||||||
|
|
||||||
|
while (this->count)
|
||||||
|
{
|
||||||
|
if (!reader->read_data16(reader, &symlink) ||
|
||||||
|
!reader->read_data16(reader, &dir))
|
||||||
|
{
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
this->offset += this->value.len - reader->remaining(reader);
|
||||||
|
this->value = reader->peek(reader);
|
||||||
|
this->symlinks->add(this->symlinks, symlink, dir);
|
||||||
|
this->count--;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = SUCCESS;
|
||||||
|
|
||||||
|
if (this->length != this->offset)
|
||||||
|
{
|
||||||
|
DBG1(DBG_TNC, "inconsistent length for %N/%N", pen_names, PEN_ITA,
|
||||||
|
ita_attr_names, this->type.type);
|
||||||
|
*offset = this->offset;
|
||||||
|
status = FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
end:
|
||||||
|
reader->destroy(reader);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(pa_tnc_attr_t, add_segment, void,
|
||||||
|
private_ita_attr_symlinks_t *this, chunk_t segment)
|
||||||
|
{
|
||||||
|
this->value = chunk_cat("cc", this->value, segment);
|
||||||
|
chunk_free(&this->segment);
|
||||||
|
this->segment = this->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(pa_tnc_attr_t, get_ref, pa_tnc_attr_t*,
|
||||||
|
private_ita_attr_symlinks_t *this)
|
||||||
|
{
|
||||||
|
ref_get(&this->ref);
|
||||||
|
return &this->public.pa_tnc_attribute;
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(pa_tnc_attr_t, destroy, void,
|
||||||
|
private_ita_attr_symlinks_t *this)
|
||||||
|
{
|
||||||
|
if (ref_put(&this->ref))
|
||||||
|
{
|
||||||
|
DESTROY_IF(this->symlinks);
|
||||||
|
free(this->segment.ptr);
|
||||||
|
free(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(ita_attr_symlinks_t, get_symlinks, pts_symlinks_t*,
|
||||||
|
private_ita_attr_symlinks_t *this)
|
||||||
|
{
|
||||||
|
return this->symlinks;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Described in header.
|
||||||
|
*/
|
||||||
|
pa_tnc_attr_t *ita_attr_symlinks_create(pts_symlinks_t *symlinks)
|
||||||
|
{
|
||||||
|
private_ita_attr_symlinks_t *this;
|
||||||
|
|
||||||
|
INIT(this,
|
||||||
|
.public = {
|
||||||
|
.pa_tnc_attribute = {
|
||||||
|
.get_type = _get_type,
|
||||||
|
.get_value = _get_value,
|
||||||
|
.get_noskip_flag = _get_noskip_flag,
|
||||||
|
.set_noskip_flag = _set_noskip_flag,
|
||||||
|
.build = _build,
|
||||||
|
.process = _process,
|
||||||
|
.add_segment = _add_segment,
|
||||||
|
.get_ref = _get_ref,
|
||||||
|
.destroy = _destroy,
|
||||||
|
},
|
||||||
|
.get_symlinks = _get_symlinks,
|
||||||
|
},
|
||||||
|
.type = { PEN_ITA, ITA_ATTR_SYMLINKS },
|
||||||
|
.symlinks = symlinks->get_ref(symlinks),
|
||||||
|
.ref = 1,
|
||||||
|
);
|
||||||
|
|
||||||
|
return &this->public.pa_tnc_attribute;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Described in header.
|
||||||
|
*/
|
||||||
|
pa_tnc_attr_t *ita_attr_symlinks_create_from_data(size_t length, chunk_t data)
|
||||||
|
{
|
||||||
|
private_ita_attr_symlinks_t *this;
|
||||||
|
|
||||||
|
INIT(this,
|
||||||
|
.public = {
|
||||||
|
.pa_tnc_attribute = {
|
||||||
|
.get_type = _get_type,
|
||||||
|
.get_value = _get_value,
|
||||||
|
.get_noskip_flag = _get_noskip_flag,
|
||||||
|
.set_noskip_flag = _set_noskip_flag,
|
||||||
|
.build = _build,
|
||||||
|
.process = _process,
|
||||||
|
.add_segment = _add_segment,
|
||||||
|
.get_ref = _get_ref,
|
||||||
|
.destroy = _destroy,
|
||||||
|
},
|
||||||
|
.get_symlinks = _get_symlinks,
|
||||||
|
},
|
||||||
|
.type = { PEN_ITA, ITA_ATTR_SYMLINKS },
|
||||||
|
.length = length,
|
||||||
|
.segment = chunk_clone(data),
|
||||||
|
.ref = 1,
|
||||||
|
);
|
||||||
|
|
||||||
|
/* received either complete attribute value or first segment */
|
||||||
|
this->value = this->segment;
|
||||||
|
|
||||||
|
return &this->public.pa_tnc_attribute;
|
||||||
|
}
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2020 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 ita_attr_sysmlinks ita_attr_sysmlinks
|
||||||
|
* @{ @ingroup ita_attr
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ITA_ATTR_SYMLINKS_H_
|
||||||
|
#define ITA_ATTR_SYMLINKS_H_
|
||||||
|
|
||||||
|
typedef struct ita_attr_symlinks_t ita_attr_symlinks_t;
|
||||||
|
|
||||||
|
#include "ita/ita_attr.h"
|
||||||
|
#include "pa_tnc/pa_tnc_attr.h"
|
||||||
|
#include "pts/pts_symlinks.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class implementing the ITA Symlinks attribute
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
struct ita_attr_symlinks_t {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Public PA-TNC attribute interface
|
||||||
|
*/
|
||||||
|
pa_tnc_attr_t pa_tnc_attribute;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get list of symbolic links
|
||||||
|
*
|
||||||
|
* @return List of symbolic links pointing to directories
|
||||||
|
*/
|
||||||
|
pts_symlinks_t* (*get_symlinks)(ita_attr_symlinks_t *this);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an ita_attr_sysmlinks_t object
|
||||||
|
*/
|
||||||
|
pa_tnc_attr_t* ita_attr_symlinks_create(pts_symlinks_t *symlinks);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an ita_attr_sysmlinks_t object from received data
|
||||||
|
*
|
||||||
|
* @param length Total length of attribute value
|
||||||
|
* @param value Unparsed attribute value (might be a segment)
|
||||||
|
*/
|
||||||
|
pa_tnc_attr_t* ita_attr_symlinks_create_from_data(size_t length, chunk_t value);
|
||||||
|
|
||||||
|
#endif /** ITA_ATTR_SYMLINKS_H_ @}*/
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2011-2012 Sansar Choinyambuu
|
* Copyright (C) 2011-2012 Sansar Choinyambuu
|
||||||
* Copyright (C) 2011-2014 Andreas Steffen
|
* Copyright (C) 2011-2020 Andreas Steffen
|
||||||
* HSR Hochschule fuer Technik Rapperswil
|
* HSR Hochschule fuer Technik Rapperswil
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
@@ -24,6 +24,7 @@
|
|||||||
#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 <ietf/ietf_attr_assess_result.h>
|
#include <ietf/ietf_attr_assess_result.h>
|
||||||
|
#include <ita/ita_attr_symlinks.h>
|
||||||
#include <tcg/pts/tcg_pts_attr_proto_caps.h>
|
#include <tcg/pts/tcg_pts_attr_proto_caps.h>
|
||||||
#include <tcg/pts/tcg_pts_attr_meas_algo.h>
|
#include <tcg/pts/tcg_pts_attr_meas_algo.h>
|
||||||
#include <os_info/os_info.h>
|
#include <os_info/os_info.h>
|
||||||
@@ -200,6 +201,25 @@ static TNC_Result receive_message(imc_state_t *state, imc_msg_t *in_msg)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (type.vendor_id == PEN_ITA)
|
||||||
|
{
|
||||||
|
if (type.type == ITA_ATTR_GET_SYMLINKS)
|
||||||
|
{
|
||||||
|
pts_symlinks_t *symlinks;
|
||||||
|
chunk_t dir;
|
||||||
|
pts_t *pts;
|
||||||
|
|
||||||
|
dir = attr->get_value(attr);
|
||||||
|
attestation_state = (imc_attestation_state_t*)state;
|
||||||
|
pts = attestation_state->get_pts(attestation_state);
|
||||||
|
symlinks = pts->extract_symlinks(pts, dir);
|
||||||
|
if (symlinks)
|
||||||
|
{
|
||||||
|
attr = ita_attr_symlinks_create(symlinks);
|
||||||
|
out_msg->add_attribute(out_msg, attr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
enumerator->destroy(enumerator);
|
enumerator->destroy(enumerator);
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2011-2012 Sansar Choinyambuu
|
* Copyright (C) 2011-2012 Sansar Choinyambuu
|
||||||
* Copyright (C) 2011-2015 Andreas Steffen
|
* Copyright (C) 2011-2020 Andreas Steffen
|
||||||
* HSR Hochschule fuer Technik Rapperswil
|
* HSR Hochschule fuer Technik Rapperswil
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
@@ -34,6 +34,7 @@
|
|||||||
#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 <ita/ita_attr.h>
|
#include <ita/ita_attr.h>
|
||||||
|
#include <ita/ita_attr_symlinks.h>
|
||||||
#include <tcg/tcg_attr.h>
|
#include <tcg/tcg_attr.h>
|
||||||
#include <tcg/pts/tcg_pts_attr_meas_algo.h>
|
#include <tcg/pts/tcg_pts_attr_meas_algo.h>
|
||||||
#include <tcg/pts/tcg_pts_attr_proto_caps.h>
|
#include <tcg/pts/tcg_pts_attr_proto_caps.h>
|
||||||
@@ -44,6 +45,7 @@
|
|||||||
#include <pts/pts.h>
|
#include <pts/pts.h>
|
||||||
#include <pts/pts_database.h>
|
#include <pts/pts_database.h>
|
||||||
#include <pts/pts_creds.h>
|
#include <pts/pts_creds.h>
|
||||||
|
#include <pts/pts_symlinks.h>
|
||||||
#include <pts/components/ita/ita_comp_func_name.h>
|
#include <pts/components/ita/ita_comp_func_name.h>
|
||||||
|
|
||||||
#include <tncif_pa_subtypes.h>
|
#include <tncif_pa_subtypes.h>
|
||||||
@@ -287,6 +289,20 @@ static TNC_Result receive_msg(private_imv_attestation_agent_t *this,
|
|||||||
session->set_device_id(session, value);
|
session->set_device_id(session, value);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case ITA_ATTR_SYMLINKS:
|
||||||
|
{
|
||||||
|
imv_attestation_state_t *attestation_state;
|
||||||
|
ita_attr_symlinks_t *attr_cast;
|
||||||
|
pts_symlinks_t *symlinks;
|
||||||
|
pts_t *pts;
|
||||||
|
|
||||||
|
attr_cast = (ita_attr_symlinks_t*)attr;
|
||||||
|
symlinks = attr_cast->get_symlinks(attr_cast);
|
||||||
|
attestation_state = (imv_attestation_state_t*)state;
|
||||||
|
pts = attestation_state->get_pts(attestation_state);
|
||||||
|
pts->set_symlinks(pts, symlinks);
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2011-2012 Sansar Choinyambuu
|
* Copyright (C) 2011-2012 Sansar Choinyambuu
|
||||||
* Copyright (C) 2011-2014 Andreas Steffen
|
* Copyright (C) 2011-2020 Andreas Steffen
|
||||||
* HSR Hochschule fuer Technik Rapperswil
|
* HSR Hochschule fuer Technik Rapperswil
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify it
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
@@ -23,6 +23,8 @@
|
|||||||
#include <tcg/pts/tcg_pts_attr_get_aik.h>
|
#include <tcg/pts/tcg_pts_attr_get_aik.h>
|
||||||
#include <tcg/pts/tcg_pts_attr_req_func_comp_evid.h>
|
#include <tcg/pts/tcg_pts_attr_req_func_comp_evid.h>
|
||||||
#include <tcg/pts/tcg_pts_attr_gen_attest_evid.h>
|
#include <tcg/pts/tcg_pts_attr_gen_attest_evid.h>
|
||||||
|
#include <generic/generic_attr_string.h>
|
||||||
|
#include <ita/ita_attr.h>
|
||||||
|
|
||||||
#include <utils/debug.h>
|
#include <utils/debug.h>
|
||||||
|
|
||||||
@@ -138,6 +140,11 @@ bool imv_attestation_build(imv_msg_t *out_msg, imv_state_t *state,
|
|||||||
|
|
||||||
if (attr)
|
if (attr)
|
||||||
{
|
{
|
||||||
|
/* Send Get Symlinks attribute */
|
||||||
|
out_msg->add_attribute(out_msg, generic_attr_string_create(
|
||||||
|
chunk_from_str("/"),
|
||||||
|
pen_type_create(PEN_ITA, ITA_ATTR_GET_SYMLINKS)));
|
||||||
|
|
||||||
/* Send Request Functional Component Evidence attribute */
|
/* Send Request Functional Component Evidence attribute */
|
||||||
out_msg->add_attribute(out_msg, attr);
|
out_msg->add_attribute(out_msg, attr);
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,9 @@
|
|||||||
* for more details.
|
* for more details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define _GNU_SOURCE
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "ita_comp_ima.h"
|
#include "ita_comp_ima.h"
|
||||||
#include "ita_comp_func_name.h"
|
#include "ita_comp_func_name.h"
|
||||||
|
|
||||||
@@ -497,6 +500,123 @@ static pts_meas_algorithms_t parse_validation_uri(pts_comp_evidence_t *evidence,
|
|||||||
return hash_algo;
|
return hash_algo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Look up all hashes for a given file and OS in the database and check
|
||||||
|
* if one of them matches the IMA measurement
|
||||||
|
*/
|
||||||
|
static status_t verify_ima_measuremnt(pts_t *pts, pts_database_t *pts_db,
|
||||||
|
pts_meas_algorithms_t hash_algo,
|
||||||
|
pts_meas_algorithms_t algo,
|
||||||
|
bool pcr_padding, chunk_t measurement,
|
||||||
|
char* ima_algo, char* ima_name,
|
||||||
|
char *filename)
|
||||||
|
{
|
||||||
|
status_t status = NOT_FOUND;
|
||||||
|
pts_meas_algorithms_t meas_algo;
|
||||||
|
uint8_t *hex_digest_buf;
|
||||||
|
uint8_t digest_buf[HASH_SIZE_SHA512];
|
||||||
|
uint8_t hash_buf[HASH_SIZE_SHA512];
|
||||||
|
size_t hash_size;
|
||||||
|
chunk_t hash, digest, hex_digest;
|
||||||
|
enumerator_t *e;
|
||||||
|
|
||||||
|
hash_size = pts_meas_algo_hash_size(algo);
|
||||||
|
hash = chunk_create(hash_buf, hash_size);
|
||||||
|
|
||||||
|
if (pcr_padding)
|
||||||
|
{
|
||||||
|
memset(hash_buf, 0x00, hash_size);
|
||||||
|
meas_algo = PTS_MEAS_ALGO_SHA1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
meas_algo = algo;
|
||||||
|
}
|
||||||
|
|
||||||
|
e = pts_db->create_file_meas_enumerator(pts_db, pts->get_platform_id(pts),
|
||||||
|
hash_algo, filename);
|
||||||
|
if (!e)
|
||||||
|
{
|
||||||
|
return FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (e->enumerate(e, &hex_digest_buf))
|
||||||
|
{
|
||||||
|
hex_digest = chunk_from_str(hex_digest_buf);
|
||||||
|
digest = chunk_from_hex(hex_digest, digest_buf);
|
||||||
|
|
||||||
|
if (!pts_ima_event_hash(digest, ima_algo, ima_name, meas_algo, hash_buf))
|
||||||
|
{
|
||||||
|
status = FAILED;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (chunk_equals_const(measurement, hash))
|
||||||
|
{
|
||||||
|
status = SUCCESS;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
status = VERIFY_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
e->destroy(e);
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate an alternative pathname based on symbolic link info
|
||||||
|
*/
|
||||||
|
static char* alternative_pathname(pts_t * pts, char *path)
|
||||||
|
{
|
||||||
|
pts_symlinks_t *symlinks;
|
||||||
|
enumerator_t *enumerator;
|
||||||
|
chunk_t prefix1, prefix2;
|
||||||
|
char *alt_path = NULL;
|
||||||
|
size_t path_len = strlen(path);
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
symlinks = pts->get_symlinks(pts);
|
||||||
|
if (!symlinks || symlinks->get_count(symlinks) == 0)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
enumerator = symlinks->create_enumerator(symlinks);
|
||||||
|
while (enumerator->enumerate(enumerator, &prefix1, &prefix2))
|
||||||
|
{
|
||||||
|
/* replace prefix2 by prefix1*/
|
||||||
|
if (path_len > prefix2.len && path[prefix2.len] == '/' &&
|
||||||
|
memeq(path, prefix2.ptr, prefix2.len))
|
||||||
|
{
|
||||||
|
ret = asprintf(&alt_path, "%.*s%s", (int)prefix1.len, prefix1.ptr,
|
||||||
|
path + prefix2.len);
|
||||||
|
if (ret <= 0)
|
||||||
|
{
|
||||||
|
alt_path = NULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* replace prefix1 by prefix2 */
|
||||||
|
if (path_len > prefix1.len && path[prefix1.len] == '/' &&
|
||||||
|
memeq(path, prefix1.ptr, prefix1.len))
|
||||||
|
{
|
||||||
|
ret = asprintf(&alt_path, "%.*s%s", (int)prefix2.len, prefix2.ptr,
|
||||||
|
path + prefix1.len);
|
||||||
|
if (ret <= 0)
|
||||||
|
{
|
||||||
|
alt_path = NULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
enumerator->destroy(enumerator);
|
||||||
|
|
||||||
|
return alt_path;
|
||||||
|
}
|
||||||
|
|
||||||
METHOD(pts_component_t, verify, status_t,
|
METHOD(pts_component_t, verify, status_t,
|
||||||
pts_ita_comp_ima_t *this, uint8_t qualifier, pts_t *pts,
|
pts_ita_comp_ima_t *this, uint8_t qualifier, pts_t *pts,
|
||||||
pts_comp_evidence_t *evidence)
|
pts_comp_evidence_t *evidence)
|
||||||
@@ -665,14 +785,8 @@ METHOD(pts_component_t, verify, status_t,
|
|||||||
break;
|
break;
|
||||||
case IMA_STATE_RUNTIME:
|
case IMA_STATE_RUNTIME:
|
||||||
{
|
{
|
||||||
chunk_t hex_digest, digest, hash;
|
|
||||||
uint8_t digest_buf[HASH_SIZE_SHA512], *hex_digest_buf;
|
|
||||||
uint8_t hash_buf[HASH_SIZE_SHA512];
|
|
||||||
size_t hash_size;
|
|
||||||
pts_meas_algorithms_t meas_algo;
|
|
||||||
enumerator_t *e;
|
|
||||||
|
|
||||||
this->count++;
|
this->count++;
|
||||||
|
|
||||||
if (evidence->get_validation(evidence, NULL) !=
|
if (evidence->get_validation(evidence, NULL) !=
|
||||||
PTS_COMP_EVID_VALIDATION_PASSED)
|
PTS_COMP_EVID_VALIDATION_PASSED)
|
||||||
{
|
{
|
||||||
@@ -680,50 +794,30 @@ METHOD(pts_component_t, verify, status_t,
|
|||||||
this->count_failed++;
|
this->count_failed++;
|
||||||
return FAILED;
|
return FAILED;
|
||||||
}
|
}
|
||||||
hash_size = pts_meas_algo_hash_size(algo);
|
|
||||||
hash = chunk_create(hash_buf, hash_size);
|
|
||||||
|
|
||||||
if (this->pcr_padding)
|
status = verify_ima_measuremnt(pts, this->pts_db,
|
||||||
{
|
hash_algo, algo,
|
||||||
memset(hash_buf, 0x00, hash_size);
|
this->pcr_padding, measurement,
|
||||||
meas_algo = PTS_MEAS_ALGO_SHA1;
|
ima_algo, ima_name, ima_name);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
meas_algo = algo;
|
|
||||||
}
|
|
||||||
|
|
||||||
e = this->pts_db->create_file_meas_enumerator(this->pts_db,
|
if (status == NOT_FOUND || status == VERIFY_ERROR)
|
||||||
pts->get_platform_id(pts),
|
|
||||||
hash_algo, ima_name);
|
|
||||||
if (e)
|
|
||||||
{
|
{
|
||||||
while (e->enumerate(e, &hex_digest_buf))
|
status_t alt_status;
|
||||||
|
char *alt_path;
|
||||||
|
|
||||||
|
alt_path = alternative_pathname(pts, ima_name);
|
||||||
|
if (alt_path)
|
||||||
{
|
{
|
||||||
hex_digest = chunk_from_str(hex_digest_buf);
|
alt_status = verify_ima_measuremnt(pts, this->pts_db,
|
||||||
digest = chunk_from_hex(hex_digest, digest_buf);
|
hash_algo, algo,
|
||||||
|
this->pcr_padding, measurement,
|
||||||
if (!pts_ima_event_hash(digest, ima_algo, ima_name,
|
ima_algo, ima_name, alt_path);
|
||||||
meas_algo, hash_buf))
|
if (alt_status != NOT_FOUND)
|
||||||
{
|
{
|
||||||
status = FAILED;
|
status = alt_status;
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (chunk_equals_const(measurement, hash))
|
|
||||||
{
|
|
||||||
status = SUCCESS;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
status = VERIFY_ERROR;
|
|
||||||
}
|
}
|
||||||
|
free(alt_path);
|
||||||
}
|
}
|
||||||
e->destroy(e);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
status = FAILED;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (status)
|
switch (status)
|
||||||
|
|||||||
+111
-2
@@ -27,8 +27,10 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <libgen.h>
|
#include <libgen.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <dirent.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
|
|
||||||
#ifndef TPM_TAG_QUOTE_INFO2
|
#ifndef TPM_TAG_QUOTE_INFO2
|
||||||
#define TPM_TAG_QUOTE_INFO2 0x0036
|
#define TPM_TAG_QUOTE_INFO2 0x0036
|
||||||
#endif
|
#endif
|
||||||
@@ -89,6 +91,11 @@ struct private_pts_t {
|
|||||||
*/
|
*/
|
||||||
int platform_id;
|
int platform_id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of directory symlinks received from IMC
|
||||||
|
*/
|
||||||
|
pts_symlinks_t *symlinks;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TRUE if IMC-PTS, FALSE if IMV-PTS
|
* TRUE if IMC-PTS, FALSE if IMV-PTS
|
||||||
*/
|
*/
|
||||||
@@ -309,6 +316,104 @@ METHOD(pts_t, set_platform_id, void,
|
|||||||
this->platform_id = pid;
|
this->platform_id = pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
METHOD(pts_t, extract_symlinks, pts_symlinks_t*,
|
||||||
|
private_pts_t *this, chunk_t pathname)
|
||||||
|
{
|
||||||
|
#ifndef WIN32
|
||||||
|
char path[BUF_LEN], real_path[BUF_LEN];
|
||||||
|
size_t path_len, real_path_len;
|
||||||
|
struct dirent *entry;
|
||||||
|
struct stat st;
|
||||||
|
DIR *dir;
|
||||||
|
|
||||||
|
/* open directory and prepare pathnames */
|
||||||
|
snprintf(path, BUF_LEN-1, "%.*s", (int)pathname.len, pathname.ptr);
|
||||||
|
dir = opendir(path);
|
||||||
|
if (!dir)
|
||||||
|
{
|
||||||
|
DBG1(DBG_PTS, "opening directory '%s' failed: %s", path,
|
||||||
|
strerror(errno));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (pathname.len == 1 && path[0] == '/')
|
||||||
|
{
|
||||||
|
path_len = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
path[pathname.len] = '/';
|
||||||
|
path_len = pathname.len + 1;
|
||||||
|
}
|
||||||
|
real_path[0] = '/';
|
||||||
|
|
||||||
|
/* symlinks object is owned by pts object */
|
||||||
|
DESTROY_IF(this->symlinks);
|
||||||
|
this->symlinks = pts_symlinks_create();
|
||||||
|
|
||||||
|
while (TRUE)
|
||||||
|
{
|
||||||
|
|
||||||
|
entry = readdir(dir);
|
||||||
|
if (!entry)
|
||||||
|
{
|
||||||
|
/* no more entries -> exit */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (streq(entry->d_name, ".") || streq(entry->d_name, ".."))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* assemble absolute path */
|
||||||
|
snprintf(path + path_len, BUF_LEN - path_len, "%s", entry->d_name);
|
||||||
|
|
||||||
|
/* only evaluate symlinks pointing to directories */
|
||||||
|
if (lstat(path, &st) == -1 || !S_ISLNK(st.st_mode) ||
|
||||||
|
stat(path, &st) == -1 || !S_ISDIR(st.st_mode))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
real_path_len = readlink(path, real_path + 1, BUF_LEN - 1);
|
||||||
|
if (real_path_len <= 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
this->symlinks->add(this->symlinks, chunk_from_str(path),
|
||||||
|
chunk_create(real_path, 1 + real_path_len));
|
||||||
|
}
|
||||||
|
closedir(dir);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return this->symlinks;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
METHOD(pts_t, get_symlinks, pts_symlinks_t*,
|
||||||
|
private_pts_t *this)
|
||||||
|
{
|
||||||
|
return this->symlinks;
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(pts_t, set_symlinks, void,
|
||||||
|
private_pts_t *this, pts_symlinks_t *symlinks)
|
||||||
|
{
|
||||||
|
enumerator_t *enumerator;
|
||||||
|
chunk_t symlink, dir;
|
||||||
|
|
||||||
|
DESTROY_IF(this->symlinks);
|
||||||
|
this->symlinks = symlinks->get_ref(symlinks);
|
||||||
|
|
||||||
|
DBG2(DBG_PTS, "adding directory symlinks:");
|
||||||
|
enumerator = symlinks->create_enumerator(symlinks);
|
||||||
|
while (enumerator->enumerate(enumerator, &symlink, &dir))
|
||||||
|
{
|
||||||
|
DBG2(DBG_PTS, " %.*s -> %.*s", (int)symlink.len, symlink.ptr,
|
||||||
|
(int)dir.len, dir.ptr);
|
||||||
|
}
|
||||||
|
enumerator->destroy(enumerator);
|
||||||
|
}
|
||||||
|
|
||||||
METHOD(pts_t, get_tpm, tpm_tss_t*,
|
METHOD(pts_t, get_tpm, tpm_tss_t*,
|
||||||
private_pts_t *this)
|
private_pts_t *this)
|
||||||
{
|
{
|
||||||
@@ -354,7 +459,7 @@ METHOD(pts_t, set_tpm_version_info, void,
|
|||||||
{
|
{
|
||||||
DBG2(DBG_PTS, "%s 1.2 rev. %u.%u.%u.%u %.*s", TPM_VERSION_INFO_LABEL,
|
DBG2(DBG_PTS, "%s 1.2 rev. %u.%u.%u.%u %.*s", TPM_VERSION_INFO_LABEL,
|
||||||
(uint32_t)major, (uint32_t)minor, (uint32_t)rev_major,
|
(uint32_t)major, (uint32_t)minor, (uint32_t)rev_major,
|
||||||
(uint32_t)rev_minor, vendor.len, vendor.ptr);
|
(uint32_t)rev_minor, (int)vendor.len, vendor.ptr);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -377,7 +482,7 @@ METHOD(pts_t, set_tpm_version_info, void,
|
|||||||
{
|
{
|
||||||
DBG2(DBG_PTS, "%s 2.0 rev. %4.2f %u %.*s - startup locality: %u",
|
DBG2(DBG_PTS, "%s 2.0 rev. %4.2f %u %.*s - startup locality: %u",
|
||||||
TPM_VERSION_INFO_LABEL, revision/100.0, year,
|
TPM_VERSION_INFO_LABEL, revision/100.0, year,
|
||||||
vendor.len, vendor.ptr, (uint32_t)locality);
|
(int)vendor.len, vendor.ptr, (uint32_t)locality);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -873,6 +978,7 @@ METHOD(pts_t, destroy, void,
|
|||||||
DESTROY_IF(this->pcrs);
|
DESTROY_IF(this->pcrs);
|
||||||
DESTROY_IF(this->aik_cert);
|
DESTROY_IF(this->aik_cert);
|
||||||
DESTROY_IF(this->dh);
|
DESTROY_IF(this->dh);
|
||||||
|
DESTROY_IF(this->symlinks);
|
||||||
free(this->initiator_nonce.ptr);
|
free(this->initiator_nonce.ptr);
|
||||||
free(this->responder_nonce.ptr);
|
free(this->responder_nonce.ptr);
|
||||||
free(this->secret.ptr);
|
free(this->secret.ptr);
|
||||||
@@ -901,6 +1007,9 @@ pts_t *pts_create(bool is_imc)
|
|||||||
.calculate_secret = _calculate_secret,
|
.calculate_secret = _calculate_secret,
|
||||||
.get_platform_id = _get_platform_id,
|
.get_platform_id = _get_platform_id,
|
||||||
.set_platform_id = _set_platform_id,
|
.set_platform_id = _set_platform_id,
|
||||||
|
.extract_symlinks = _extract_symlinks,
|
||||||
|
.get_symlinks = _get_symlinks,
|
||||||
|
.set_symlinks = _set_symlinks,
|
||||||
.get_tpm = _get_tpm,
|
.get_tpm = _get_tpm,
|
||||||
.get_tpm_version_info = _get_tpm_version_info,
|
.get_tpm_version_info = _get_tpm_version_info,
|
||||||
.set_tpm_version_info = _set_tpm_version_info,
|
.set_tpm_version_info = _set_tpm_version_info,
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ typedef struct pts_t pts_t;
|
|||||||
#include "pts_dh_group.h"
|
#include "pts_dh_group.h"
|
||||||
#include "pts_pcr.h"
|
#include "pts_pcr.h"
|
||||||
#include "pts_req_func_comp_evid.h"
|
#include "pts_req_func_comp_evid.h"
|
||||||
|
#include "pts_symlinks.h"
|
||||||
#include "components/pts_comp_func_name.h"
|
#include "components/pts_comp_func_name.h"
|
||||||
|
|
||||||
#include <tpm_tss_quote_info.h>
|
#include <tpm_tss_quote_info.h>
|
||||||
@@ -175,6 +176,29 @@ struct pts_t {
|
|||||||
*/
|
*/
|
||||||
void (*set_platform_id)(pts_t *this, int pid);
|
void (*set_platform_id)(pts_t *this, int pid);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extract all directory symlinks contained in a directory
|
||||||
|
*
|
||||||
|
* @param pathname Absolute pathname of directory
|
||||||
|
* @return List of directory symlinks
|
||||||
|
*/
|
||||||
|
pts_symlinks_t* (*extract_symlinks)(pts_t *this, chunk_t pathname);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get list of directory symlinks received from IMC
|
||||||
|
*
|
||||||
|
* @return List of symbolic links
|
||||||
|
*/
|
||||||
|
pts_symlinks_t* (*get_symlinks)(pts_t *this);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set list of directory symlinks received from IMC
|
||||||
|
*
|
||||||
|
* @param symlinks List of symbolic links
|
||||||
|
*/
|
||||||
|
void (*set_symlinks)(pts_t *this, pts_symlinks_t *symlinks);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get TPM object handle
|
* Get TPM object handle
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -0,0 +1,149 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2020 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 "pts_symlinks.h"
|
||||||
|
|
||||||
|
#include <collections/linked_list.h>
|
||||||
|
#include <utils/debug.h>
|
||||||
|
|
||||||
|
typedef struct private_pts_symlinks_t private_pts_symlinks_t;
|
||||||
|
typedef struct entry_t entry_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Private data of a pts_symlinks_t object.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
struct private_pts_symlinks_t {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Public pts_symlinks_t interface.
|
||||||
|
*/
|
||||||
|
pts_symlinks_t public;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of symbolic links pointing to directories
|
||||||
|
*/
|
||||||
|
linked_list_t *list;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reference count
|
||||||
|
*/
|
||||||
|
refcount_t ref;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Symlink entry
|
||||||
|
*/
|
||||||
|
struct entry_t {
|
||||||
|
chunk_t symlink;
|
||||||
|
chunk_t dir;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Free an entry_t object
|
||||||
|
*/
|
||||||
|
static void free_entry(entry_t *entry)
|
||||||
|
{
|
||||||
|
if (entry)
|
||||||
|
{
|
||||||
|
free(entry->symlink.ptr);
|
||||||
|
free(entry->dir.ptr);
|
||||||
|
free(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(pts_symlinks_t, get_count, int,
|
||||||
|
private_pts_symlinks_t *this)
|
||||||
|
{
|
||||||
|
return this->list->get_count(this->list);
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(pts_symlinks_t, add, void,
|
||||||
|
private_pts_symlinks_t *this, chunk_t symlink, chunk_t dir)
|
||||||
|
{
|
||||||
|
entry_t *entry;
|
||||||
|
|
||||||
|
entry = malloc_thing(entry_t);
|
||||||
|
entry->symlink = chunk_clone(symlink);
|
||||||
|
entry->dir = chunk_clone(dir);
|
||||||
|
|
||||||
|
this->list->insert_last(this->list, entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
CALLBACK(symlink_filter, bool,
|
||||||
|
void *null, enumerator_t *orig, va_list args)
|
||||||
|
{
|
||||||
|
entry_t *entry;
|
||||||
|
chunk_t *symlink;
|
||||||
|
chunk_t *dir;
|
||||||
|
|
||||||
|
VA_ARGS_VGET(args, symlink, dir);
|
||||||
|
|
||||||
|
if (orig->enumerate(orig, &entry))
|
||||||
|
{
|
||||||
|
*symlink = entry->symlink;
|
||||||
|
*dir = entry->dir;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(pts_symlinks_t, create_enumerator, enumerator_t*,
|
||||||
|
private_pts_symlinks_t *this)
|
||||||
|
{
|
||||||
|
return enumerator_create_filter(this->list->create_enumerator(this->list),
|
||||||
|
symlink_filter, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(pts_symlinks_t, get_ref, pts_symlinks_t*,
|
||||||
|
private_pts_symlinks_t *this)
|
||||||
|
{
|
||||||
|
ref_get(&this->ref);
|
||||||
|
return &this->public;
|
||||||
|
}
|
||||||
|
|
||||||
|
METHOD(pts_symlinks_t, destroy, void,
|
||||||
|
private_pts_symlinks_t *this)
|
||||||
|
{
|
||||||
|
if (ref_put(&this->ref))
|
||||||
|
{
|
||||||
|
this->list->destroy_function(this->list, (void *)free_entry);
|
||||||
|
free(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See header
|
||||||
|
*/
|
||||||
|
pts_symlinks_t *pts_symlinks_create()
|
||||||
|
{
|
||||||
|
private_pts_symlinks_t *this;
|
||||||
|
|
||||||
|
INIT(this,
|
||||||
|
.public = {
|
||||||
|
.get_count = _get_count,
|
||||||
|
.add = _add,
|
||||||
|
.create_enumerator = _create_enumerator,
|
||||||
|
.get_ref = _get_ref,
|
||||||
|
.destroy = _destroy,
|
||||||
|
},
|
||||||
|
.list = linked_list_create(),
|
||||||
|
.ref = 1,
|
||||||
|
);
|
||||||
|
|
||||||
|
return &this->public;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2020 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 pts_symlinks pts_symlinks
|
||||||
|
* @{ @ingroup pts
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PTS_SYMLINKS_H_
|
||||||
|
#define PTS_SYMLINKS_H_
|
||||||
|
|
||||||
|
#include <library.h>
|
||||||
|
|
||||||
|
typedef struct pts_symlinks_t pts_symlinks_t;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class storing a list of symbolic links pointing to directories
|
||||||
|
*/
|
||||||
|
struct pts_symlinks_t {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the number of symbolic link entries
|
||||||
|
*
|
||||||
|
* @return Number of symbolic links
|
||||||
|
*/
|
||||||
|
int (*get_count)(pts_symlinks_t *this);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a symbolic link pointing to a directory
|
||||||
|
*
|
||||||
|
* @param symlink Pathname of symbolic link
|
||||||
|
* @param dir Pathname of directory the symlink points to
|
||||||
|
*/
|
||||||
|
void (*add)(pts_symlinks_t *this, chunk_t symlink, chunk_t dir);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a symlink enumerator
|
||||||
|
*
|
||||||
|
* @return Enumerator returning (chunk_t symlink, chunk_t dir)
|
||||||
|
*/
|
||||||
|
enumerator_t* (*create_enumerator)(pts_symlinks_t *this);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a new reference to the list of symbolic links
|
||||||
|
*
|
||||||
|
* @return this, with an increased refcount
|
||||||
|
*/
|
||||||
|
pts_symlinks_t* (*get_ref)(pts_symlinks_t *this);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroys a pts_symlinks_t object.
|
||||||
|
*/
|
||||||
|
void (*destroy)(pts_symlinks_t *this);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a pts_symlinks_t object
|
||||||
|
*/
|
||||||
|
pts_symlinks_t* pts_symlinks_create();
|
||||||
|
|
||||||
|
#endif /** PTS_SYMLINKS_H_ @}*/
|
||||||
Reference in New Issue
Block a user