5 changed files with 296 additions and 0 deletions
@ -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; |
||||
} |
@ -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_*/ |
@ -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; |
||||
} |
Loading…
Reference in new issue