Filters definition. Example XOR_encrypt filter.

This commit is contained in:
Vreixo Formoso 2008-02-24 18:20:23 +01:00
parent 37f69d5360
commit 0dad87f035
5 changed files with 296 additions and 0 deletions

View File

@ -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 \

43
libisofs/filter.c Normal file
View File

@ -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;
}

62
libisofs/filter.h Normal file
View File

@ -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_*/

View File

@ -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;
}

View File

@ -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.