optimized handling of UNIX file metadata

This commit is contained in:
Andreas Steffen
2011-11-28 14:39:52 +01:00
parent fbeb94544c
commit 63ca82e56d
4 changed files with 63 additions and 157 deletions
@@ -32,6 +32,8 @@
#include <debug.h> #include <debug.h>
#include <crypto/hashers/hasher.h> #include <crypto/hashers/hasher.h>
#include <inttypes.h>
bool imv_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list, bool imv_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
imv_attestation_state_t *attestation_state, imv_attestation_state_t *attestation_state,
pts_meas_algorithms_t supported_algorithms, pts_meas_algorithms_t supported_algorithms,
@@ -404,8 +406,9 @@ bool imv_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
int file_count; int file_count;
pts_file_meta_t *metadata; pts_file_meta_t *metadata;
pts_file_metadata_t *entry; pts_file_metadata_t *entry;
enumerator_t *e; time_t created, modified, accessed;
bool utc = FALSE; bool utc = FALSE;
enumerator_t *e;
attr_cast = (tcg_pts_attr_file_meta_t*)attr; attr_cast = (tcg_pts_attr_file_meta_t*)attr;
metadata = attr_cast->get_metadata(attr_cast); metadata = attr_cast->get_metadata(attr_cast);
@@ -417,16 +420,17 @@ bool imv_attestation_process(pa_tnc_attr_t *attr, linked_list_t *attr_list,
e = metadata->create_enumerator(metadata); e = metadata->create_enumerator(metadata);
while (e->enumerate(e, &entry)) while (e->enumerate(e, &entry))
{ {
DBG1(DBG_IMV, " '%s' (%d bytes) owner %d, group %d, type %d", DBG1(DBG_IMV, " '%s' (%"PRIu64" bytes)"
entry->filename, " owner %"PRIu64", group %"PRIu64", type %d",
entry->filesize, entry->filename, entry->filesize, entry->owner,
entry->owner, entry->group, entry->type);
entry->group,
entry->type); created = entry->created;
modified = entry->modified;
accessed = entry->accessed;
DBG1(DBG_IMV, " created %T, modified %T, accessed %T", DBG1(DBG_IMV, " created %T, modified %T, accessed %T",
&entry->created, utc, &created, utc, &modified, utc, &accessed, utc);
&entry->modified, utc,
&entry->accessed, utc);
} }
e->destroy(e); e->destroy(e);
break; break;
-1
View File
@@ -598,7 +598,6 @@ static bool file_metadata(char *pathname, pts_file_metadata_t **entry)
} }
this->filename = strdup(pathname); this->filename = strdup(pathname);
this->meta_length = PTS_FILE_METADATA_SIZE + strlen(this->filename);
if (S_ISREG(st.st_mode)) if (S_ISREG(st.st_mode))
{ {
+8 -12
View File
@@ -29,22 +29,18 @@
typedef struct pts_file_meta_t pts_file_meta_t; typedef struct pts_file_meta_t pts_file_meta_t;
typedef struct pts_file_metadata_t pts_file_metadata_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 * Structure holding file metadata
*/ */
struct pts_file_metadata_t { struct pts_file_metadata_t {
u_int16_t meta_length; pts_file_type_t type;
pts_file_type_t type; u_int64_t filesize;
u_int64_t filesize; u_int64_t created;
time_t created; u_int64_t modified;
time_t modified; u_int64_t accessed;
time_t accessed; u_int64_t owner;
u_int64_t owner; u_int64_t group;
u_int64_t group; char *filename;
char *filename;
}; };
/** /**
+41 -134
View File
@@ -67,6 +67,7 @@ typedef struct private_tcg_pts_attr_file_meta_t private_tcg_pts_attr_file_meta_t
#define PTS_FILE_META_SIZE 8 #define PTS_FILE_META_SIZE 8
#define PTS_FILE_MEAS_RESERVED 0x00 #define PTS_FILE_MEAS_RESERVED 0x00
#define PTS_FILE_METADATA_SIZE 52
/** /**
* Private data of an tcg_pts_attr_file_meta_t object. * Private data of an tcg_pts_attr_file_meta_t object.
@@ -146,32 +147,23 @@ METHOD(pa_tnc_attr_t, build, void,
number_of_files = this->metadata->get_file_count(this->metadata); number_of_files = this->metadata->get_file_count(this->metadata);
writer = bio_writer_create(PTS_FILE_META_SIZE); writer = bio_writer_create(PTS_FILE_META_SIZE);
/* Write the 64 bit integer field - number of files as two 32 bit parts */ writer->write_uint64(writer, number_of_files);
writer->write_uint32(writer, number_of_files >> 32);
writer->write_uint32(writer, number_of_files & 0xffffffff);
enumerator = this->metadata->create_enumerator(this->metadata); enumerator = this->metadata->create_enumerator(this->metadata);
while (enumerator->enumerate(enumerator, &entry)) while (enumerator->enumerate(enumerator, &entry))
{ {
writer->write_uint16(writer, PTS_FILE_METADATA_SIZE + strlen(entry->filename)); writer->write_uint16(writer, PTS_FILE_METADATA_SIZE +
strlen(entry->filename));
writer->write_uint8 (writer, entry->type); writer->write_uint8 (writer, entry->type);
writer->write_uint8 (writer, PTS_FILE_MEAS_RESERVED); writer->write_uint8 (writer, PTS_FILE_MEAS_RESERVED);
writer->write_uint64(writer, entry->filesize);
/* Write the 64 bit integer fields as two 32 bit parts */ writer->write_uint64(writer, entry->created);
writer->write_uint32(writer, entry->filesize >> 32); writer->write_uint64(writer, entry->modified);
writer->write_uint32(writer, entry->filesize & 0xffffffff); writer->write_uint64(writer, entry->accessed);
writer->write_uint32(writer, ((u_int64_t)entry->created) >> 32); writer->write_uint64(writer, entry->owner);
writer->write_uint32(writer, ((u_int64_t)entry->created) & 0xffffffff); writer->write_uint64(writer, entry->group);
writer->write_uint32(writer, ((u_int64_t)entry->modified) >> 32); writer->write_data (writer, chunk_create(entry->filename,
writer->write_uint32(writer, ((u_int64_t)entry->modified) & 0xffffffff); strlen(entry->filename)));
writer->write_uint32(writer, ((u_int64_t)entry->accessed) >> 32);
writer->write_uint32(writer, ((u_int64_t)entry->accessed) & 0xffffffff);
writer->write_uint32(writer, entry->owner >> 32);
writer->write_uint32(writer, entry->owner & 0xffffffff);
writer->write_uint32(writer, entry->group >> 32);
writer->write_uint32(writer, entry->group & 0xffffffff);
writer->write_data (writer, chunk_create(entry->filename, strlen(entry->filename)));
} }
enumerator->destroy(enumerator); enumerator->destroy(enumerator);
@@ -184,37 +176,11 @@ METHOD(pa_tnc_attr_t, process, status_t,
{ {
bio_reader_t *reader; bio_reader_t *reader;
pts_file_metadata_t *entry; pts_file_metadata_t *entry;
u_int8_t type, reserved;
int number_of_files; u_int16_t len;
u_int32_t number_of_files32; u_int64_t number_of_files, filesize, created, modified, accessed;
u_int64_t owner, group;
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; chunk_t filename;
char buf[BUF_LEN];
status_t status = FAILED; status_t status = FAILED;
if (this->value.len < PTS_FILE_META_SIZE) if (this->value.len < PTS_FILE_META_SIZE)
@@ -224,134 +190,75 @@ METHOD(pa_tnc_attr_t, process, status_t,
return FAILED; return FAILED;
} }
reader = bio_reader_create(this->value); reader = bio_reader_create(this->value);
reader->read_uint64(reader, &number_of_files);
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(); this->metadata = pts_file_meta_create();
while (number_of_files--) while (number_of_files--)
{ {
if (!reader->read_uint16(reader, &meta_length)) if (!reader->read_uint16(reader, &len))
{ {
DBG1(DBG_TNC, "insufficient data for PTS file metadata length"); DBG1(DBG_TNC, "insufficient data for PTS file metadata length");
goto end; goto end;
} }
if (!reader->read_uint8 (reader, &type8)) if (!reader->read_uint8(reader, &type))
{ {
DBG1(DBG_TNC, "insufficient data for file type"); DBG1(DBG_TNC, "insufficient data for file type");
goto end; goto end;
} }
type = (pts_file_type_t)type8; if (!reader->read_uint8(reader, &reserved))
if (!reader->read_uint8 (reader, &reserved))
{ {
DBG1(DBG_TNC, "insufficient data for reserved field"); DBG1(DBG_TNC, "insufficient data for reserved field");
goto end; goto end;
} }
if (!reader->read_uint32(reader, &filesize32)) if (!reader->read_uint64(reader, &filesize))
{ {
DBG1(DBG_TNC, "insufficient data for file size"); DBG1(DBG_TNC, "insufficient data for file size");
goto end; goto end;
} }
filesize = (sizeof(filesize) > 4) ? filesize32 << 32 : 0; if (!reader->read_uint64(reader, &created))
if (!reader->read_uint32(reader, &filesize32))
{ {
DBG1(DBG_TNC, "insufficient data for file size"); DBG1(DBG_TNC, "insufficient data for file create time");
goto end; goto end;
} }
filesize += filesize32; if (!reader->read_uint64(reader, &modified))
if (!reader->read_uint32(reader, &create_time32))
{ {
DBG1(DBG_TNC, "insufficient data for file size"); DBG1(DBG_TNC, "insufficient data for last modify time");
goto end; goto end;
} }
create_time = (sizeof(create_time) > 4) ? create_time32 << 32 : 0; if (!reader->read_uint64(reader, &accessed))
if (!reader->read_uint32(reader, &create_time32))
{ {
DBG1(DBG_TNC, "insufficient data for file size"); DBG1(DBG_TNC, "insufficient data for last access time");
goto end; goto end;
} }
create_time += create_time32; if (!reader->read_uint64(reader, &owner))
create_time_t = (time_t)create_time;
if (!reader->read_uint32(reader, &modify_time32))
{ {
DBG1(DBG_TNC, "insufficient data for file size"); DBG1(DBG_TNC, "insufficient data for owner id");
goto end; goto end;
} }
modify_time = (sizeof(modify_time) > 4) ? modify_time32 << 32 : 0; if (!reader->read_uint64(reader, &group))
if (!reader->read_uint32(reader, &modify_time32))
{ {
DBG1(DBG_TNC, "insufficient data for file size"); DBG1(DBG_TNC, "insufficient data for group id");
goto end; goto end;
} }
modify_time += modify_time32; if (!reader->read_data(reader, len - PTS_FILE_METADATA_SIZE, &filename))
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"); DBG1(DBG_TNC, "insufficient data for filename");
goto end; goto end;
} }
len = min(filename.len, BUF_LEN - 1);
memcpy(buf, filename.ptr, len);
buf[len] = '\0';
entry = malloc_thing(pts_file_metadata_t); entry = malloc_thing(pts_file_metadata_t);
entry->filename = strdup(buf);
entry->meta_length = PTS_FILE_METADATA_SIZE + strlen(entry->filename);
entry->type = type; entry->type = type;
entry->filesize = filesize; entry->filesize = filesize;
entry->created = create_time_t; entry->created = created;
entry->modified = modify_time_t; entry->modified = modified;
entry->accessed = access_time_t; entry->accessed = accessed;
entry->owner = owner_id; entry->owner = owner;
entry->group = group_id; entry->group = group;
entry->filename = malloc(filename.len + 1);
entry->filename[filename.len] = '\0';
memcpy(entry->filename, filename.ptr, filename.len);
this->metadata->add(this->metadata, entry); this->metadata->add(this->metadata, entry);
} }
status = SUCCESS; status = SUCCESS;