Implemented PTS attributes Request File Metadata, Unix-Style File Metadata
authorSansar Choinyambuu <schoinya@hsr.ch>
Fri, 9 Sep 2011 13:48:16 +0000 (15:48 +0200)
committerAndreas Steffen <andreas.steffen@strongswan.org>
Sat, 10 Sep 2011 20:39:55 +0000 (22:39 +0200)
src/libpts/Makefile.am
src/libpts/pts/pts.c
src/libpts/pts/pts_file_meta.c [new file with mode: 0644]
src/libpts/pts/pts_file_meta.h [new file with mode: 0644]
src/libpts/pts/pts_file_type.h [new file with mode: 0644]
src/libpts/tcg/tcg_pts_attr_file_meas.c
src/libpts/tcg/tcg_pts_attr_req_file_meta.c [new file with mode: 0644]
src/libpts/tcg/tcg_pts_attr_req_file_meta.h [new file with mode: 0644]
src/libpts/tcg/tcg_pts_attr_unix_file_meta.c [new file with mode: 0644]
src/libpts/tcg/tcg_pts_attr_unix_file_meta.h [new file with mode: 0644]

index e7528f8..fde1790 100644 (file)
@@ -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
index 34d2283..8d118d3 100644 (file)
@@ -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 (file)
index 0000000..0924b3b
--- /dev/null
@@ -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 (file)
index 0000000..36a4b62
--- /dev/null
@@ -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 (file)
index 0000000..f3c5b94
--- /dev/null
@@ -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_ @}*/
index dc69807..fe559d0 100644 (file)
@@ -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 (file)
index 0000000..f42903e
--- /dev/null
@@ -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 (file)
index 0000000..7620c50
--- /dev/null
@@ -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 (file)
index 0000000..0f644fd
--- /dev/null
@@ -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 (file)
index 0000000..8a594ea
--- /dev/null
@@ -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_ @}*/