diff options
author | Sansar Choinyambuu <schoinya@hsr.ch> | 2011-09-09 15:48:16 +0200 |
---|---|---|
committer | Andreas Steffen <andreas.steffen@strongswan.org> | 2011-09-10 22:39:55 +0200 |
commit | d88349541835707bf6382f5ec4d6a6979a0e65e1 (patch) | |
tree | a16ce8962d16f4fcc764be7a8903b1a3db045e79 /src | |
parent | 31ac5b0d6bd964cb72a639ed72be244c3f8ebdec (diff) | |
download | strongswan-d88349541835707bf6382f5ec4d6a6979a0e65e1.tar.bz2 strongswan-d88349541835707bf6382f5ec4d6a6979a0e65e1.tar.xz |
Implemented PTS attributes Request File Metadata, Unix-Style File Metadata
Diffstat (limited to 'src')
-rw-r--r-- | src/libpts/Makefile.am | 6 | ||||
-rw-r--r-- | src/libpts/pts/pts.c | 4 | ||||
-rw-r--r-- | src/libpts/pts/pts_file_meta.c | 135 | ||||
-rw-r--r-- | src/libpts/pts/pts_file_meta.h | 91 | ||||
-rw-r--r-- | src/libpts/pts/pts_file_type.h | 49 | ||||
-rw-r--r-- | src/libpts/tcg/tcg_pts_attr_file_meas.c | 2 | ||||
-rw-r--r-- | src/libpts/tcg/tcg_pts_attr_req_file_meta.c | 268 | ||||
-rw-r--r-- | src/libpts/tcg/tcg_pts_attr_req_file_meta.h | 81 | ||||
-rw-r--r-- | src/libpts/tcg/tcg_pts_attr_unix_file_meta.c | 436 | ||||
-rw-r--r-- | src/libpts/tcg/tcg_pts_attr_unix_file_meta.h | 65 |
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_ @}*/ |