aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/libpts/Makefile.am6
-rw-r--r--src/libpts/pts/pts.c4
-rw-r--r--src/libpts/pts/pts_file_meta.c135
-rw-r--r--src/libpts/pts/pts_file_meta.h91
-rw-r--r--src/libpts/pts/pts_file_type.h49
-rw-r--r--src/libpts/tcg/tcg_pts_attr_file_meas.c2
-rw-r--r--src/libpts/tcg/tcg_pts_attr_req_file_meta.c268
-rw-r--r--src/libpts/tcg/tcg_pts_attr_req_file_meta.h81
-rw-r--r--src/libpts/tcg/tcg_pts_attr_unix_file_meta.c436
-rw-r--r--src/libpts/tcg/tcg_pts_attr_unix_file_meta.h65
10 files changed, 1132 insertions, 5 deletions
diff --git a/src/libpts/Makefile.am b/src/libpts/Makefile.am
index e7528f823..fde1790c6 100644
--- a/src/libpts/Makefile.am
+++ b/src/libpts/Makefile.am
@@ -8,10 +8,11 @@ libpts_la_LIBADD = -ltspi
libpts_la_SOURCES = \
pts/pts.h pts/pts.c \
pts/pts_error.h pts/pts_error.c \
- pts/pts_proto_caps.h pts/pts_funct_comp_name.h \
+ pts/pts_proto_caps.h pts/pts_funct_comp_name.h pts/pts_file_type.h \
pts/pts_creds.h pts/pts_creds.c \
pts/pts_database.h pts/pts_database.c \
pts/pts_file_meas.h pts/pts_file_meas.c \
+ pts/pts_file_meta.h pts/pts_file_meta.c \
pts/pts_meas_algo.h pts/pts_meas_algo.c \
tcg/tcg_attr.h tcg/tcg_attr.c \
tcg/tcg_pts_attr_proto_caps.h tcg/tcg_pts_attr_proto_caps.c \
@@ -25,4 +26,5 @@ libpts_la_SOURCES = \
tcg/tcg_pts_attr_simple_comp_evid.h tcg/tcg_pts_attr_simple_comp_evid.c \
tcg/tcg_pts_attr_simple_evid_final.h tcg/tcg_pts_attr_simple_evid_final.c \
tcg/tcg_pts_attr_req_file_meas.h tcg/tcg_pts_attr_req_file_meas.c \
- tcg/tcg_pts_attr_file_meas.h tcg/tcg_pts_attr_file_meas.c
+ tcg/tcg_pts_attr_file_meas.h tcg/tcg_pts_attr_file_meas.c \
+ tcg/tcg_pts_attr_unix_file_meta.h tcg/tcg_pts_attr_unix_file_meta.c
diff --git a/src/libpts/pts/pts.c b/src/libpts/pts/pts.c
index 34d228354..8d118d313 100644
--- a/src/libpts/pts/pts.c
+++ b/src/libpts/pts/pts.c
@@ -463,6 +463,7 @@ static bool has_tpm(private_pts_t *this)
TSS_HCONTEXT hContext;
TSS_HTPM hTPM;
TSS_RESULT result;
+ u_int32_t version_info_len;
result = Tspi_Context_Create(&hContext);
if (result != TSS_SUCCESS)
@@ -480,8 +481,9 @@ static bool has_tpm(private_pts_t *this)
goto err;
}
result = Tspi_TPM_GetCapability(hTPM, TSS_TPMCAP_VERSION_VAL, 0, NULL,
- &this->tpm_version_info.len,
+ &version_info_len,
&this->tpm_version_info.ptr);
+ this->tpm_version_info.len = version_info_len;
if (result != TSS_SUCCESS)
{
goto err;
diff --git a/src/libpts/pts/pts_file_meta.c b/src/libpts/pts/pts_file_meta.c
new file mode 100644
index 000000000..0924b3b25
--- /dev/null
+++ b/src/libpts/pts/pts_file_meta.c
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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_file_meta.h"
+
+#include <utils/linked_list.h>
+#include <debug.h>
+
+typedef struct private_pts_file_meta_t private_pts_file_meta_t;
+
+/**
+ * Private data of a pts_file_meta_t object.
+ *
+ */
+struct private_pts_file_meta_t {
+
+ /**
+ * Public pts_file_meta_t interface.
+ */
+ pts_file_meta_t public;
+
+ /**
+ * List of File Metadata
+ */
+ linked_list_t *list;
+};
+
+/**
+ * Free an pts_file_metadata_t object
+ */
+static void free_entry(pts_file_metadata_t *entry)
+{
+ if (entry)
+ {
+ free(entry->filename);
+ free(entry);
+ }
+}
+
+METHOD(pts_file_meta_t, get_file_count, int,
+ private_pts_file_meta_t *this)
+{
+ return this->list->get_count(this->list);
+}
+
+METHOD(pts_file_meta_t, add, void,
+ private_pts_file_meta_t *this, char *filename, pts_file_type_t type,
+ u_int64_t filesize, time_t create_time, time_t last_modify_time, time_t last_access_time,
+ u_int64_t owner_id, u_int64_t group_id)
+{
+ pts_file_metadata_t *entry;
+
+ entry = malloc_thing(pts_file_metadata_t);
+
+ entry->filename = strdup(filename);
+ entry->meta_length = PTS_FILE_METADATA_SIZE + strlen(entry->filename);
+ entry->type = type;
+ entry->filesize = filesize;
+ entry->create_time = create_time;
+ entry->last_modify_time = last_modify_time;
+ entry->last_access_time = last_access_time;
+ entry->owner_id = owner_id;
+ entry->group_id = group_id;
+
+ this->list->insert_last(this->list, entry);
+}
+
+/**
+ * Enumerate file metadata entries
+ */
+static bool entry_filter(void *null, pts_file_metadata_t **entry,
+ char **filename, void *i2, u_int16_t *meta_length, void *i3,
+ pts_file_type_t *type, void *i4, u_int64_t *filesize, void *i5,
+ time_t *create_time, void *i6, time_t *last_modify_time, void *i7,
+ time_t *last_access_time, void *i8, u_int64_t *owner_id, void *i9,
+ u_int64_t *group_id)
+{
+ *filename = (*entry)->filename;
+ *meta_length = (*entry)->meta_length;
+ *type = (*entry)->type;
+ *filesize = (*entry)->filesize;
+ *create_time = (*entry)->create_time;
+ *last_modify_time = (*entry)->last_modify_time;
+ *last_access_time = (*entry)->last_access_time;
+ *owner_id = (*entry)->owner_id;
+ *group_id = (*entry)->group_id;
+ return TRUE;
+}
+
+METHOD(pts_file_meta_t, create_enumerator, enumerator_t*,
+ private_pts_file_meta_t *this)
+{
+ return enumerator_create_filter(this->list->create_enumerator(this->list),
+ (void*)entry_filter, NULL, NULL);
+}
+
+METHOD(pts_file_meta_t, destroy, void,
+ private_pts_file_meta_t *this)
+{
+ this->list->destroy_function(this->list, (void *)free_entry);
+ free(this);
+}
+
+/**
+ * See header
+ */
+pts_file_meta_t *pts_file_meta_create()
+{
+ private_pts_file_meta_t *this;
+
+ INIT(this,
+ .public = {
+ .get_file_count = _get_file_count,
+ .add = _add,
+ .create_enumerator = _create_enumerator,
+ .destroy = _destroy,
+ },
+ .list = linked_list_create(),
+ );
+
+ return &this->public;
+}
+
diff --git a/src/libpts/pts/pts_file_meta.h b/src/libpts/pts/pts_file_meta.h
new file mode 100644
index 000000000..36a4b6294
--- /dev/null
+++ b/src/libpts/pts/pts_file_meta.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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_file_meta pts_file_meta
+ * @{ @ingroup pts
+ */
+
+#ifndef PTS_FILE_META_H_
+#define PTS_FILE_META_H_
+
+#include "pts_file_type.h"
+
+#include <time.h>
+#include <library.h>
+
+typedef struct pts_file_meta_t pts_file_meta_t;
+typedef struct pts_file_metadata_t pts_file_metadata_t;
+
+/* Without filename field included */
+#define PTS_FILE_METADATA_SIZE 52
+
+/**
+ * Structure holding file metadata
+ */
+struct pts_file_metadata_t {
+ u_int16_t meta_length;
+ pts_file_type_t type;
+ u_int64_t filesize;
+ time_t create_time;
+ time_t last_modify_time;
+ time_t last_access_time;
+ u_int64_t owner_id;
+ u_int64_t group_id;
+ char *filename;
+};
+
+/**
+ * Class storing PTS File Metadata
+ */
+struct pts_file_meta_t {
+
+ /**
+ * Get the number of files
+ *
+ * @return Number of files
+ */
+ int (*get_file_count)(pts_file_meta_t *this);
+
+ /**
+ * Add a PTS File Metadata
+ *
+ * @param filename Name of measured file or directory
+ * @param metadata File metadata
+ */
+ void (*add)(pts_file_meta_t *this, char *filename, pts_file_type_t type,
+ u_int64_t filesize, time_t create_time, time_t last_modfy_time, time_t last_access_time,
+ u_int64_t owner_id, u_int64_t group_id);
+
+ /**
+ * Create a PTS File Metadata enumerator
+ *
+ * @return Enumerator returning file metadata
+ */
+ enumerator_t* (*create_enumerator)(pts_file_meta_t *this);
+
+ /**
+ * Destroys a pts_file_meta_t object.
+ */
+ void (*destroy)(pts_file_meta_t *this);
+
+};
+
+/**
+ * Creates a pts_file_meta_t object
+ */
+pts_file_meta_t* pts_file_meta_create();
+
+#endif /** PTS_FILE_MEAS_H_ @}*/
diff --git a/src/libpts/pts/pts_file_type.h b/src/libpts/pts/pts_file_type.h
new file mode 100644
index 000000000..f3c5b94dd
--- /dev/null
+++ b/src/libpts/pts/pts_file_type.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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_file_type pts_file_type
+ * @{ @ingroup pts
+ */
+
+#ifndef PTS_FILE_TYPE_H_
+#define PTS_FILE_TYPE_H_
+
+typedef enum pts_file_type_t pts_file_type_t;
+
+/**
+ * PTS File Type
+ * see section 3.17.3 of PTS Protocol: Binding to TNC IF-M Specification
+ */
+enum pts_file_type_t {
+ /** Ignore */
+ PTS_FILE_OTHER = 0x0000,
+ /** CRTM */
+ PTS_FILE_FIFO = 0x0001,
+ /** BIOS */
+ PTS_FILE_CHAR_SPEC = 0x0002,
+ /** Platform Extensions */
+ PTS_FILE_DIRECTORY = 0x0004,
+ /** Motherboard firmware */
+ PTS_FILE_BLOCK_SPEC = 0x0006,
+ /** Initial Program Loader */
+ PTS_FILE_REGULAR = 0x0008,
+ /** Option ROMs */
+ PTS_FILE_SYM_LINK = 0x000A,
+ /** Option ROMs */
+ PTS_FILE_SOCKET = 0x000C,
+};
+
+#endif /** PTS_FILE_TYPE_H_ @}*/
diff --git a/src/libpts/tcg/tcg_pts_attr_file_meas.c b/src/libpts/tcg/tcg_pts_attr_file_meas.c
index dc6980772..fe559d004 100644
--- a/src/libpts/tcg/tcg_pts_attr_file_meas.c
+++ b/src/libpts/tcg/tcg_pts_attr_file_meas.c
@@ -19,8 +19,6 @@
#include <bio/bio_writer.h>
#include <bio/bio_reader.h>
#include <utils/linked_list.h>
-/* For pow function */
-#include <math.h>
#include <debug.h>
typedef struct private_tcg_pts_attr_file_meas_t private_tcg_pts_attr_file_meas_t;
diff --git a/src/libpts/tcg/tcg_pts_attr_req_file_meta.c b/src/libpts/tcg/tcg_pts_attr_req_file_meta.c
new file mode 100644
index 000000000..f42903e03
--- /dev/null
+++ b/src/libpts/tcg/tcg_pts_attr_req_file_meta.c
@@ -0,0 +1,268 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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 "tcg_pts_attr_req_file_meta.h"
+
+#include <pa_tnc/pa_tnc_msg.h>
+#include <bio/bio_writer.h>
+#include <bio/bio_reader.h>
+#include <debug.h>
+
+typedef struct private_tcg_pts_attr_req_file_meta_t private_tcg_pts_attr_req_file_meta_t;
+
+/**
+ * Request File Metadata
+ * see section 3.17.1 of PTS Protocol: Binding to TNC IF-M Specification
+ *
+ * 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
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Flags | Delimiter | Reserved |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * ~ Fully Qualified File Pathname (Variable Length) ~
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+#define PTS_REQ_FILE_META_SIZE 4
+#define PTS_REQ_FILE_META_RESERVED 0x00
+#define PTS_REQ_FILE_META_NO_FLAGS 0x00
+
+#define DIRECTORY_CONTENTS_FLAG (1<<7)
+
+/**
+ * Private data of an tcg_pts_attr_req_file_meta_t object.
+ */
+struct private_tcg_pts_attr_req_file_meta_t {
+
+ /**
+ * Public members of tcg_pts_attr_req_file_meta_t
+ */
+ tcg_pts_attr_req_file_meta_t public;
+
+ /**
+ * Attribute vendor ID
+ */
+ pen_t vendor_id;
+
+ /**
+ * Attribute type
+ */
+ u_int32_t type;
+
+ /**
+ * Attribute value
+ */
+ chunk_t value;
+
+ /**
+ * Noskip flag
+ */
+ bool noskip_flag;
+
+ /**
+ * Directory Contents flag
+ */
+ bool directory_flag;
+
+ /**
+ * UTF8 Encoding of Delimiter Character
+ */
+ u_int8_t delimiter;
+
+ /**
+ * Fully Qualified File Pathname
+ */
+ char *pathname;
+
+};
+
+METHOD(pa_tnc_attr_t, get_vendor_id, pen_t,
+ private_tcg_pts_attr_req_file_meta_t *this)
+{
+ return this->vendor_id;
+}
+
+METHOD(pa_tnc_attr_t, get_type, u_int32_t,
+ private_tcg_pts_attr_req_file_meta_t *this)
+{
+ return this->type;
+}
+
+METHOD(pa_tnc_attr_t, get_value, chunk_t,
+ private_tcg_pts_attr_req_file_meta_t *this)
+{
+ return this->value;
+}
+
+METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
+ private_tcg_pts_attr_req_file_meta_t *this)
+{
+ return this->noskip_flag;
+}
+
+METHOD(pa_tnc_attr_t, set_noskip_flag,void,
+ private_tcg_pts_attr_req_file_meta_t *this, bool noskip)
+{
+ this->noskip_flag = noskip;
+}
+
+METHOD(pa_tnc_attr_t, build, void,
+ private_tcg_pts_attr_req_file_meta_t *this)
+{
+ u_int8_t flags = PTS_REQ_FILE_META_NO_FLAGS;
+ chunk_t pathname;
+ bio_writer_t *writer;
+
+ if (this->directory_flag)
+ {
+ flags |= DIRECTORY_CONTENTS_FLAG;
+ }
+ pathname = chunk_create(this->pathname, strlen(this->pathname));
+
+ writer = bio_writer_create(PTS_REQ_FILE_META_SIZE);
+ writer->write_uint8 (writer, flags);
+ writer->write_uint8 (writer, this->delimiter);
+ writer->write_uint16(writer, PTS_REQ_FILE_META_RESERVED);
+
+ writer->write_data (writer, pathname);
+ this->value = chunk_clone(writer->get_buf(writer));
+ writer->destroy(writer);
+}
+
+METHOD(pa_tnc_attr_t, process, status_t,
+ private_tcg_pts_attr_req_file_meta_t *this, u_int32_t *offset)
+{
+ bio_reader_t *reader;
+ u_int8_t flags;
+ u_int16_t reserved;
+ chunk_t pathname;
+
+ if (this->value.len < PTS_REQ_FILE_META_SIZE)
+ {
+ DBG1(DBG_TNC, "insufficient data for Request File Metadata");
+ *offset = 0;
+ return FAILED;
+ }
+
+ reader = bio_reader_create(this->value);
+ reader->read_uint8 (reader, &flags);
+ reader->read_uint8 (reader, &this->delimiter);
+ reader->read_uint16(reader, &reserved);
+
+ reader->read_data (reader, reader->remaining(reader), &pathname);
+
+ this->directory_flag = (flags & DIRECTORY_CONTENTS_FLAG) !=
+ PTS_REQ_FILE_META_NO_FLAGS;
+
+ this->pathname = malloc(pathname.len + 1);
+ memcpy(this->pathname, pathname.ptr, pathname.len);
+ this->pathname[pathname.len] = '\0';
+
+ reader->destroy(reader);
+ return SUCCESS;
+}
+
+METHOD(pa_tnc_attr_t, destroy, void,
+ private_tcg_pts_attr_req_file_meta_t *this)
+{
+ free(this->pathname);
+ free(this->value.ptr);
+ free(this);
+}
+
+METHOD(tcg_pts_attr_req_file_meta_t, get_directory_flag, bool,
+ private_tcg_pts_attr_req_file_meta_t *this)
+{
+ return this->directory_flag;
+}
+
+METHOD(tcg_pts_attr_req_file_meta_t, get_delimiter, u_int32_t,
+ private_tcg_pts_attr_req_file_meta_t *this)
+{
+ return this->delimiter;
+}
+
+METHOD(tcg_pts_attr_req_file_meta_t, get_pathname, char*,
+ private_tcg_pts_attr_req_file_meta_t *this)
+{
+ return this->pathname;
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_req_file_meas_create(bool directory_flag,
+ u_int8_t delimiter,
+ char *pathname)
+{
+ private_tcg_pts_attr_req_file_meta_t *this;
+
+ INIT(this,
+ .public = {
+ .pa_tnc_attribute = {
+ .get_vendor_id = _get_vendor_id,
+ .get_type = _get_type,
+ .get_value = _get_value,
+ .get_noskip_flag = _get_noskip_flag,
+ .set_noskip_flag = _set_noskip_flag,
+ .build = _build,
+ .process = _process,
+ .destroy = _destroy,
+ },
+ .get_directory_flag = _get_directory_flag,
+ .get_delimiter = _get_delimiter,
+ .get_pathname = _get_pathname,
+ },
+ .vendor_id = PEN_TCG,
+ .type = TCG_PTS_REQ_FILE_META,
+ .directory_flag = directory_flag,
+ .delimiter = delimiter,
+ .pathname = strdup(pathname),
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
+
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_req_file_meas_create_from_data(chunk_t data)
+{
+ private_tcg_pts_attr_req_file_meta_t *this;
+
+ INIT(this,
+ .public = {
+ .pa_tnc_attribute = {
+ .get_vendor_id = _get_vendor_id,
+ .get_type = _get_type,
+ .get_value = _get_value,
+ .get_noskip_flag = _get_noskip_flag,
+ .set_noskip_flag = _set_noskip_flag,
+ .build = _build,
+ .process = _process,
+ .destroy = _destroy,
+ },
+ .get_directory_flag = _get_directory_flag,
+ .get_delimiter = _get_delimiter,
+ .get_pathname = _get_pathname,
+ },
+ .vendor_id = PEN_TCG,
+ .type = TCG_PTS_REQ_FILE_META,
+ .value = chunk_clone(data),
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
diff --git a/src/libpts/tcg/tcg_pts_attr_req_file_meta.h b/src/libpts/tcg/tcg_pts_attr_req_file_meta.h
new file mode 100644
index 000000000..7620c50ab
--- /dev/null
+++ b/src/libpts/tcg/tcg_pts_attr_req_file_meta.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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 tcg_pts_attr_req_file_meta tcg_pts_attr_req_file_meta
+ * @{ @ingroup tcg_pts_attr_req_file_meta
+ */
+
+#ifndef TCG_PTS_ATTR_REQ_FILE_META_H_
+#define TCG_PTS_ATTR_REQ_FILE_META_H_
+
+typedef struct tcg_pts_attr_req_file_meta_t tcg_pts_attr_req_file_meta_t;
+
+#include "tcg_attr.h"
+#include "pa_tnc/pa_tnc_attr.h"
+
+/**
+ * Class implementing the TCG PTS Request File Metadata attribute
+ *
+ */
+struct tcg_pts_attr_req_file_meta_t {
+
+ /**
+ * Public PA-TNC attribute interface
+ */
+ pa_tnc_attr_t pa_tnc_attribute;
+
+ /**
+ * Get directory flag for PTS Request File Metadata
+ *
+ * @return Directory Contents flag
+ */
+ bool (*get_directory_flag)(tcg_pts_attr_req_file_meta_t *this);
+
+ /**
+ * Get Delimiter
+ *
+ * @return UTF-8 encoding of a Delimiter Character
+ */
+ u_int8_t (*get_delimiter)(tcg_pts_attr_req_file_meta_t *this);
+
+ /**
+ * Get Fully Qualified File Pathname
+ *
+ * @return Pathname
+ */
+ char* (*get_pathname)(tcg_pts_attr_req_file_meta_t *this);
+
+};
+
+/**
+ * Creates an tcg_pts_attr_req_file_meta_t object
+ *
+ * @param directory_flag Directory Contents Flag
+ * @param delimiter Delimiter Character
+ * @param pathname File Pathname
+ */
+pa_tnc_attr_t* tcg_pts_attr_req_file_meta_create(bool directory_flag,
+ u_int8_t delimiter,
+ char *pathname);
+
+/**
+ * Creates an tcg_pts_attr_req_file_meta_t object from received data
+ *
+ * @param value unparsed attribute value
+ */
+pa_tnc_attr_t* tcg_pts_attr_req_file_meta_create_from_data(chunk_t value);
+
+#endif /** TCG_PTS_ATTR_REQ_FILE_META_H_ @}*/
diff --git a/src/libpts/tcg/tcg_pts_attr_unix_file_meta.c b/src/libpts/tcg/tcg_pts_attr_unix_file_meta.c
new file mode 100644
index 000000000..0f644fdf9
--- /dev/null
+++ b/src/libpts/tcg/tcg_pts_attr_unix_file_meta.c
@@ -0,0 +1,436 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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 "tcg_pts_attr_unix_file_meta.h"
+
+#include <pa_tnc/pa_tnc_msg.h>
+#include <bio/bio_writer.h>
+#include <bio/bio_reader.h>
+#include <utils/linked_list.h>
+#include <debug.h>
+
+typedef struct private_tcg_pts_attr_file_meta_t private_tcg_pts_attr_file_meta_t;
+
+/**
+ * Unix-Style File Metadata
+ * see section 3.17.3 of PTS Protocol: Binding to TNC IF-M Specification
+ *
+ * 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 Files included |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Number of Files included |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | File metadata Length | Type | Reserved |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | File Size |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | File Size |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | File Create Time |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | File Create Time |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Last Modify Time |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Last Modify Time |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Last Access Time |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Last Access Time |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | File Owner ID |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | File Owner ID |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | File Group ID |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | File Group ID |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * ~ Filename (Variable Length) ~
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * ...........................
+ */
+
+#define PTS_FILE_META_SIZE 8
+#define PTS_FILE_MEAS_RESERVED 0x00
+
+/**
+ * Private data of an tcg_pts_attr_file_meta_t object.
+ */
+struct private_tcg_pts_attr_file_meta_t {
+
+ /**
+ * Public members of tcg_pts_attr_file_meta_t
+ */
+ tcg_pts_attr_file_meta_t public;
+
+ /**
+ * Attribute vendor ID
+ */
+ pen_t vendor_id;
+
+ /**
+ * Attribute type
+ */
+ u_int32_t type;
+
+ /**
+ * Attribute value
+ */
+ chunk_t value;
+
+ /**
+ * Noskip flag
+ */
+ bool noskip_flag;
+
+ /**
+ * PTS File Metadata
+ */
+ pts_file_meta_t *metadata;
+
+};
+
+METHOD(pa_tnc_attr_t, get_vendor_id, pen_t,
+ private_tcg_pts_attr_file_meta_t *this)
+{
+ return this->vendor_id;
+}
+
+METHOD(pa_tnc_attr_t, get_type, u_int32_t,
+ private_tcg_pts_attr_file_meta_t *this)
+{
+ return this->type;
+}
+
+METHOD(pa_tnc_attr_t, get_value, chunk_t,
+ private_tcg_pts_attr_file_meta_t *this)
+{
+ return this->value;
+}
+
+METHOD(pa_tnc_attr_t, get_noskip_flag, bool,
+ private_tcg_pts_attr_file_meta_t *this)
+{
+ return this->noskip_flag;
+}
+
+METHOD(pa_tnc_attr_t, set_noskip_flag,void,
+ private_tcg_pts_attr_file_meta_t *this, bool noskip)
+{
+ this->noskip_flag = noskip;
+}
+
+METHOD(pa_tnc_attr_t, build, void,
+ private_tcg_pts_attr_file_meta_t *this)
+{
+ bio_writer_t *writer;
+ enumerator_t *enumerator;
+ u_int64_t number_of_files;
+ char *filename;
+ u_int16_t meta_length;
+ pts_file_type_t type;
+ u_int64_t filesize;
+ time_t create_time;
+ time_t last_modify_time;
+ time_t last_access_time;
+ u_int64_t owner_id;
+ u_int64_t group_id;
+
+ number_of_files = this->metadata->get_file_count(this->metadata);
+ writer = bio_writer_create(PTS_FILE_META_SIZE);
+
+ /* Write the 64 bit integer field - number of files as two 32 bit parts */
+ writer->write_uint32(writer, number_of_files >> 32);
+ writer->write_uint32(writer, number_of_files & 0xffffffff);
+
+ enumerator = this->metadata->create_enumerator(this->metadata);
+ while (enumerator->enumerate(enumerator, &filename, &meta_length, &type,
+ &filesize, &filesize, &create_time, &last_modify_time, &last_access_time,
+ &owner_id, &group_id))
+ {
+ u_int64_t create_time64 = (u_int64_t)create_time;
+ u_int64_t modify_time64 = (u_int64_t)last_modify_time;
+ u_int64_t access_time64 = (u_int64_t)last_access_time;
+
+ writer->write_uint16(writer, PTS_FILE_METADATA_SIZE + strlen(filename));
+ writer->write_uint8 (writer, type);
+ writer->write_uint8 (writer, PTS_FILE_MEAS_RESERVED);
+
+ /* Write the 64 bit integer fields as two 32 bit parts */
+ writer->write_uint32(writer, filesize >> 32);
+ writer->write_uint32(writer, filesize & 0xffffffff);
+ writer->write_uint32(writer, create_time64 >> 32);
+ writer->write_uint32(writer, create_time64 & 0xffffffff);
+ writer->write_uint32(writer, modify_time64 >> 32);
+ writer->write_uint32(writer, modify_time64 & 0xffffffff);
+ writer->write_uint32(writer, access_time64 >> 32);
+ writer->write_uint32(writer, access_time64 & 0xffffffff);
+ writer->write_uint32(writer, owner_id >> 32);
+ writer->write_uint32(writer, owner_id & 0xffffffff);
+ writer->write_uint32(writer, group_id >> 32);
+ writer->write_uint32(writer, group_id & 0xffffffff);
+
+ writer->write_data (writer, chunk_create(filename, strlen(filename)));
+ }
+ enumerator->destroy(enumerator);
+
+ this->value = chunk_clone(writer->get_buf(writer));
+ writer->destroy(writer);
+}
+
+METHOD(pa_tnc_attr_t, process, status_t,
+ private_tcg_pts_attr_file_meta_t *this, u_int32_t *offset)
+{
+ bio_reader_t *reader;
+ int number_of_files;
+ u_int32_t number_of_files32;
+
+ u_int16_t meta_length;
+ pts_file_type_t type;
+ u_int8_t type8;
+ u_int8_t reserved;
+
+ int filesize;
+ u_int32_t filesize32;
+
+ int create_time;
+ u_int32_t create_time32;
+ time_t create_time_t;
+ int modify_time;
+ u_int32_t modify_time32;
+ time_t modify_time_t;
+ int access_time;
+ u_int32_t access_time32;
+ time_t access_time_t;
+
+ int owner_id;
+ u_int32_t owner_id32;
+
+ int group_id;
+ u_int32_t group_id32;
+
+ size_t len;
+ chunk_t filename;
+ char buf[BUF_LEN];
+ status_t status = FAILED;
+
+ if (this->value.len < PTS_FILE_META_SIZE)
+ {
+ DBG1(DBG_TNC, "insufficient data for PTS Unix-Style file metadata header");
+ *offset = 0;
+ return FAILED;
+ }
+ reader = bio_reader_create(this->value);
+
+ reader->read_uint32(reader, &number_of_files32);
+ number_of_files = (sizeof(number_of_files) > 4) ? number_of_files32 << 32 : 0;
+ reader->read_uint32(reader, &number_of_files32);
+ number_of_files += number_of_files32;
+
+ this->metadata = pts_file_meta_create();
+
+ while (number_of_files--)
+ {
+ if (!reader->read_uint16(reader, &meta_length))
+ {
+ DBG1(DBG_TNC, "insufficient data for PTS file metadata length");
+ goto end;
+ }
+ if (!reader->read_uint8 (reader, &type8))
+ {
+ DBG1(DBG_TNC, "insufficient data for file type");
+ goto end;
+ }
+ type = (pts_file_type_t)type8;
+ if (!reader->read_uint8 (reader, &reserved))
+ {
+ DBG1(DBG_TNC, "insufficient data for reserved field");
+ goto end;
+ }
+ if (!reader->read_uint32(reader, &filesize32))
+ {
+ DBG1(DBG_TNC, "insufficient data for file size");
+ goto end;
+ }
+ filesize = (sizeof(filesize) > 4) ? filesize32 << 32 : 0;
+ if (!reader->read_uint32(reader, &filesize32))
+ {
+ DBG1(DBG_TNC, "insufficient data for file size");
+ goto end;
+ }
+ filesize += filesize32;
+
+ if (!reader->read_uint32(reader, &create_time32))
+ {
+ DBG1(DBG_TNC, "insufficient data for file size");
+ goto end;
+ }
+ create_time = (sizeof(create_time) > 4) ? create_time32 << 32 : 0;
+ if (!reader->read_uint32(reader, &create_time32))
+ {
+ DBG1(DBG_TNC, "insufficient data for file size");
+ goto end;
+ }
+ create_time += create_time32;
+ create_time_t = (time_t)create_time;
+
+ if (!reader->read_uint32(reader, &modify_time32))
+ {
+ DBG1(DBG_TNC, "insufficient data for file size");
+ goto end;
+ }
+ modify_time = (sizeof(modify_time) > 4) ? modify_time32 << 32 : 0;
+ if (!reader->read_uint32(reader, &modify_time32))
+ {
+ DBG1(DBG_TNC, "insufficient data for file size");
+ goto end;
+ }
+ modify_time += modify_time32;
+ modify_time_t = (time_t)modify_time;
+
+ if (!reader->read_uint32(reader, &access_time32))
+ {
+ DBG1(DBG_TNC, "insufficient data for file size");
+ goto end;
+ }
+ access_time = (sizeof(access_time) > 4) ? access_time32 << 32 : 0;
+ if (!reader->read_uint32(reader, &access_time32))
+ {
+ DBG1(DBG_TNC, "insufficient data for file size");
+ goto end;
+ }
+ access_time += access_time32;
+ access_time_t = (time_t)access_time;
+
+ if (!reader->read_uint32(reader, &owner_id32))
+ {
+ DBG1(DBG_TNC, "insufficient data for file size");
+ goto end;
+ }
+ owner_id = (sizeof(owner_id) > 4) ? owner_id32 << 32 : 0;
+ if (!reader->read_uint32(reader, &owner_id32))
+ {
+ DBG1(DBG_TNC, "insufficient data for file size");
+ goto end;
+ }
+ owner_id += owner_id32;
+
+ if (!reader->read_uint32(reader, &group_id32))
+ {
+ DBG1(DBG_TNC, "insufficient data for file size");
+ goto end;
+ }
+ group_id = (sizeof(group_id) > 4) ? group_id32 << 32 : 0;
+ if (!reader->read_uint32(reader, &group_id32))
+ {
+ DBG1(DBG_TNC, "insufficient data for file size");
+ goto end;
+ }
+ group_id += group_id32;
+
+ if (!reader->read_data(reader, meta_length - PTS_FILE_METADATA_SIZE, &filename))
+ {
+ DBG1(DBG_TNC, "insufficient data for filename");
+ goto end;
+ }
+
+ len = min(filename.len, BUF_LEN-1);
+ memcpy(buf, filename.ptr, len);
+ buf[len] = '\0';
+ this->metadata->add(this->metadata, buf, type, filesize, create_time_t,
+ modify_time_t, access_time_t, owner_id, group_id);
+ }
+ status = SUCCESS;
+
+end:
+ reader->destroy(reader);
+ return status;
+}
+
+METHOD(pa_tnc_attr_t, destroy, void,
+ private_tcg_pts_attr_file_meta_t *this)
+{
+ this->metadata->destroy(this->metadata);
+ free(this->value.ptr);
+ free(this);
+}
+
+METHOD(tcg_pts_attr_file_meta_t, get_metadata, pts_file_meta_t*,
+ private_tcg_pts_attr_file_meta_t *this)
+{
+ return this->metadata;
+}
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_unix_file_meta_create(pts_file_meta_t *metadata)
+{
+ private_tcg_pts_attr_file_meta_t *this;
+
+ INIT(this,
+ .public = {
+ .pa_tnc_attribute = {
+ .get_vendor_id = _get_vendor_id,
+ .get_type = _get_type,
+ .get_value = _get_value,
+ .get_noskip_flag = _get_noskip_flag,
+ .set_noskip_flag = _set_noskip_flag,
+ .build = _build,
+ .process = _process,
+ .destroy = _destroy,
+ },
+ .get_metadata = _get_metadata,
+ },
+ .vendor_id = PEN_TCG,
+ .type = TCG_PTS_UNIX_FILE_META,
+ .metadata = metadata,
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
+
+
+/**
+ * Described in header.
+ */
+pa_tnc_attr_t *tcg_pts_attr_unix_file_meta_create_from_data(chunk_t data)
+{
+ private_tcg_pts_attr_file_meta_t *this;
+
+ INIT(this,
+ .public = {
+ .pa_tnc_attribute = {
+ .get_vendor_id = _get_vendor_id,
+ .get_type = _get_type,
+ .get_value = _get_value,
+ .get_noskip_flag = _get_noskip_flag,
+ .set_noskip_flag = _set_noskip_flag,
+ .build = _build,
+ .process = _process,
+ .destroy = _destroy,
+ },
+ .get_metadata = _get_metadata,
+ },
+ .vendor_id = PEN_TCG,
+ .type = TCG_PTS_UNIX_FILE_META,
+ .value = chunk_clone(data),
+ );
+
+ return &this->public.pa_tnc_attribute;
+}
diff --git a/src/libpts/tcg/tcg_pts_attr_unix_file_meta.h b/src/libpts/tcg/tcg_pts_attr_unix_file_meta.h
new file mode 100644
index 000000000..8a594eab5
--- /dev/null
+++ b/src/libpts/tcg/tcg_pts_attr_unix_file_meta.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2011 Sansar Choinyambuu
+ * 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 tcg_pts_attr_unix_file_meta tcg_pts_attr_unix_file_meta
+ * @{ @ingroup tcg_pts_attr_unix_file_meta
+ */
+
+#ifndef TCG_PTS_ATTR_UNIX_FILE_META_H_
+#define TCG_PTS_ATTR_UNIX_FILE_META_H_
+
+typedef struct tcg_pts_attr_file_meta_t tcg_pts_attr_file_meta_t;
+
+#include "tcg_attr.h"
+#include "pa_tnc/pa_tnc_attr.h"
+#include "pts/pts.h"
+#include "pts/pts_file_meta.h"
+
+/**
+ * Class implementing the TCG PTS File Measurement attribute
+ *
+ */
+struct tcg_pts_attr_file_meta_t {
+
+ /**
+ * Public PA-TNC attribute interface
+ */
+ pa_tnc_attr_t pa_tnc_attribute;
+
+ /**
+ * Get PTS File Metadata
+ *
+ * @return PTS File Metadata
+ */
+ pts_file_meta_t* (*get_metadata)(tcg_pts_attr_file_meta_t *this);
+
+};
+
+/**
+ * Creates an tcg_pts_attr_file_meta_t object
+ *
+ * @param metadata PTS File Metadata
+ */
+pa_tnc_attr_t* tcg_pts_attr_unix_file_meta_create(pts_file_meta_t *metadata);
+
+/**
+ * Creates an tcg_pts_attr_file_meta_t object from received data
+ *
+ * @param value unparsed attribute value
+ */
+pa_tnc_attr_t* tcg_pts_attr_unix_file_meta_create_from_data(chunk_t value);
+
+#endif /** TCG_PTS_ATTR_UNIX_FILE_META_H_ @}*/