From 0dad87f035cafb651d816ef790b280259ea097db Mon Sep 17 00:00:00 2001 From: Vreixo Formoso Date: Sun, 24 Feb 2008 18:20:23 +0100 Subject: [PATCH] Filters definition. Example XOR_encrypt filter. --- Makefile.am | 3 + libisofs/filter.c | 43 ++++++++ libisofs/filter.h | 62 +++++++++++ libisofs/filters/xor_encrypt.c | 187 +++++++++++++++++++++++++++++++++ libisofs/fsource.h | 1 + 5 files changed, 296 insertions(+) create mode 100644 libisofs/filter.c create mode 100644 libisofs/filter.h create mode 100644 libisofs/filters/xor_encrypt.c diff --git a/Makefile.am b/Makefile.am index 6492a71..b4f7137 100644 --- a/Makefile.am +++ b/Makefile.am @@ -28,6 +28,9 @@ libisofs_libisofs_la_SOURCES = \ libisofs/libiso_msgs.c \ libisofs/stream.h \ libisofs/stream.c \ + libisofs/filter.h \ + libisofs/filter.c \ + libisofs/filters/xor_encrypt.c \ libisofs/util.h \ libisofs/util.c \ libisofs/util_rbtree.c \ diff --git a/libisofs/filter.c b/libisofs/filter.c new file mode 100644 index 0000000..90f2b84 --- /dev/null +++ b/libisofs/filter.c @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2008 Vreixo Formoso + * + * This file is part of the libisofs project; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. See COPYING file for details. + */ + +#include "libisofs.h" +#include "filter.h" +#include "node.h" + + +void iso_filter_ref(FilterContext *filter) +{ + ++filter->refcount; +} + +void iso_filter_unref(FilterContext *filter) +{ + if (--filter->refcount == 0) { + filter->free(filter); + free(filter); + } +} + +int iso_file_add_filter(IsoFile *file, FilterContext *filter, int flag) +{ + int ret; + IsoStream *original, *filtered; + if (file == NULL || filter == NULL) { + return ISO_NULL_POINTER; + } + + original = file->stream; + ret = filter->get_filter(filter, original, &filtered); + if (ret < 0) { + return ret; + } + iso_stream_unref(original); + file->stream = filtered; + return ISO_SUCCESS; +} diff --git a/libisofs/filter.h b/libisofs/filter.h new file mode 100644 index 0000000..f711fe3 --- /dev/null +++ b/libisofs/filter.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2008 Vreixo Formoso + * + * This file is part of the libisofs project; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. See COPYING file for details. + */ +#ifndef LIBISO_FILTER_H_ +#define LIBISO_FILTER_H_ + +/* + * Definitions of filters. + */ + +/* dev_id for stream identification */ +#define XOR_ENCRYPT_DEV_ID 1 + +typedef struct filter_context FilterContext; + +struct filter_context { + int version; /* reserved for future usage, set to 0 */ + int refcount; + + /** filter specific shared data */ + void *data; + + /** + * Factory method to create a filtered stream from another stream. + * + * @param original + * The original stream to be filtered. If the filter needs a ref to + * it (most cases), it should take a ref to it with iso_stream_ref(). + * @param filtered + * Will be filled with the filtered IsoStream (reference belongs to + * caller). + * @return + * 1 on success, < 0 on error + */ + int (*get_filter)(FilterContext *filter, IsoStream *original, + IsoStream **filtered); + + /** + * Free implementation specific data. Should never be called by user. + * Use iso_filter_unref() instead. + */ + void (*free)(FilterContext *filter); +}; + +/** + * + * @param flag + * Reserved for future usage, pass always 0 for now. + * TODO in a future a different value can mean filter caching, where + * the filter is applied once and the filtered file is stored in a temp + * dir. This prevent filter to be applied several times. + */ +int iso_file_add_filter(IsoFile *file, FilterContext *filter, int flag); + +void iso_filter_ref(FilterContext *filter); +void iso_filter_unref(FilterContext *filter); + +#endif /*LIBISO_FILTER_H_*/ diff --git a/libisofs/filters/xor_encrypt.c b/libisofs/filters/xor_encrypt.c new file mode 100644 index 0000000..be83f72 --- /dev/null +++ b/libisofs/filters/xor_encrypt.c @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2008 Vreixo Formoso + * + * This file is part of the libisofs project; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. See COPYING file for details. + */ + +#include "../libisofs.h" +#include "../filter.h" +#include "../fsource.h" + +/* + * A simple Filter implementation for example purposes. It encrypts a file + * by XORing each byte by a given key. + */ + +static ino_t xor_ino_id = 0; + +typedef struct +{ + IsoStream *orig; + uint8_t key; + ino_t id; +} XorEncryptStreamData; + +static +int xor_encrypt_stream_open(IsoStream *stream) +{ + XorEncryptStreamData *data; + if (stream == NULL) { + return ISO_NULL_POINTER; + } + data = (XorEncryptStreamData*)stream->data; + return iso_stream_open(data->orig); +} + +static +int xor_encrypt_stream_close(IsoStream *stream) +{ + XorEncryptStreamData *data; + if (stream == NULL) { + return ISO_NULL_POINTER; + } + data = stream->data; + return iso_stream_close(data->orig); +} + +static +off_t xor_encrypt_stream_get_size(IsoStream *stream) +{ + XorEncryptStreamData *data; + if (stream == NULL) { + return ISO_NULL_POINTER; + } + data = stream->data; + return iso_stream_get_size(data->orig); +} + +static +int xor_encrypt_stream_read(IsoStream *stream, void *buf, size_t count) +{ + int ret, len; + XorEncryptStreamData *data; + uint8_t *buffer = buf; + + if (stream == NULL) { + return ISO_NULL_POINTER; + } + data = stream->data; + ret = iso_stream_read(data->orig, buf, count); + if (ret < 0) { + return ret; + } + + /* xor */ + for (len = 0; len < ret; ++len) { + buffer[len] = buffer[len] ^ data->key; + } + + return ret; +} + +static +int xor_encrypt_stream_is_repeatable(IsoStream *stream) +{ + /* the filter can't be created if underlying stream is not repeatable */ + return 1; +} + +static +void xor_encrypt_stream_get_id(IsoStream *stream, unsigned int *fs_id, + dev_t *dev_id, ino_t *ino_id) +{ + XorEncryptStreamData *data = stream->data; + *fs_id = ISO_FILTER_FS_ID; + *dev_id = XOR_ENCRYPT_DEV_ID; + *ino_id = data->id; +} + +static +void xor_encrypt_stream_free(IsoStream *stream) +{ + XorEncryptStreamData *data = stream->data; + iso_stream_unref(data->orig); + free(data); +} + +IsoStreamIface xor_encrypt_stream_class = { + 0, + "xorf", + xor_encrypt_stream_open, + xor_encrypt_stream_close, + xor_encrypt_stream_get_size, + xor_encrypt_stream_read, + xor_encrypt_stream_is_repeatable, + xor_encrypt_stream_get_id, + xor_encrypt_stream_free +}; + + +static +void xor_encrypt_filter_free(FilterContext *filter) +{ + free(filter->data); +} + +static +int xor_encrypt_filter_get_filter(FilterContext *filter, IsoStream *original, + IsoStream **filtered) +{ + IsoStream *str; + XorEncryptStreamData *data; + + if (filter == NULL || original == NULL || filtered == NULL) { + return ISO_NULL_POINTER; + } + + str = malloc(sizeof(IsoStream)); + if (str == NULL) { + return ISO_OUT_OF_MEM; + } + data = malloc(sizeof(XorEncryptStreamData)); + if (str == NULL) { + free(str); + return ISO_OUT_OF_MEM; + } + + /* fill data */ + data->key = *((uint8_t*)filter->data); + data->id = xor_ino_id++; + + /* get reference to the source */ + data->orig = original; + iso_stream_ref(original); + + str->refcount = 1; + str->data = data; + str->class = &xor_encrypt_stream_class; + + *filtered = str; + return ISO_SUCCESS; +} + +int create_xor_encrypt_filter(uint8_t key, FilterContext **filter) +{ + FilterContext *f; + uint8_t *data; + + f = calloc(1, sizeof(FilterContext)); + if (f == NULL) { + return ISO_OUT_OF_MEM; + } + data = malloc(sizeof(uint8_t)); + if (data == NULL) { + free(f); + return ISO_OUT_OF_MEM; + } + f->refcount = 1; + f->version = 0; + *data = key; + f->data = data; + f->free = xor_encrypt_filter_free; + f->get_filter = xor_encrypt_filter_get_filter; + + return ISO_SUCCESS; +} diff --git a/libisofs/fsource.h b/libisofs/fsource.h index 44dda9a..1ee8b18 100644 --- a/libisofs/fsource.h +++ b/libisofs/fsource.h @@ -20,6 +20,7 @@ #define ISO_IMAGE_FS_ID 2 #define ISO_ELTORITO_FS_ID 3 #define ISO_MEM_FS_ID 4 +#define ISO_FILTER_FS_ID 5 /** * Create a new IsoFilesystem to deal with local filesystem.