From: Timo Sirainen Date: Mon, 9 Sep 2013 21:27:12 +0000 (+0300) Subject: lib-fs: Added support for giving a hash of the written data to be verified by storage. X-Git-Tag: 2.2.6~103 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=67a163f3a07593446fab1cbbb8f92a89d4c6cb57;p=thirdparty%2Fdovecot%2Fcore.git lib-fs: Added support for giving a hash of the written data to be verified by storage. --- diff --git a/src/lib-fs/fs-api-private.h b/src/lib-fs/fs-api-private.h index f88a2d8c99..d1acff6b94 100644 --- a/src/lib-fs/fs-api-private.h +++ b/src/lib-fs/fs-api-private.h @@ -75,6 +75,9 @@ struct fs_file { struct istream *pending_read_input; bool write_pending; + const struct hash_method *write_digest_method; + void *write_digest; + pool_t metadata_pool; ARRAY_TYPE(fs_metadata) metadata; diff --git a/src/lib-fs/fs-api.c b/src/lib-fs/fs-api.c index a9fe3aab0c..3554e6d32f 100644 --- a/src/lib-fs/fs-api.c +++ b/src/lib-fs/fs-api.c @@ -4,6 +4,7 @@ #include "array.h" #include "module-dir.h" #include "str.h" +#include "hash-method.h" #include "istream.h" #include "istream-seekable.h" #include "ostream.h" @@ -199,6 +200,7 @@ void fs_file_close(struct fs_file *file) i_stream_unref(&file->copy_input); (void)fs_write_stream_abort(file, &file->copy_output); } + i_free_and_null(file->write_digest); if (file->fs->v.file_close != NULL) T_BEGIN { file->fs->v.file_close(file); } T_END; @@ -251,6 +253,11 @@ const char *fs_file_path(struct fs_file *file) file->fs->v.get_path(file); } +struct fs *fs_file_fs(struct fs_file *file) +{ + return file->fs; +} + static void ATTR_FORMAT(2, 0) fs_set_verror(struct fs *fs, const char *fmt, va_list args) { @@ -475,6 +482,16 @@ void fs_write_stream_abort(struct fs_file *file, struct ostream **output) } T_END; } +void fs_write_set_hash(struct fs_file *file, const struct hash_method *method, + const void *digest) +{ + file->write_digest_method = method; + + i_free(file->write_digest); + file->write_digest = i_malloc(method->digest_size); + memcpy(file->write_digest, digest, method->digest_size); +} + void fs_file_set_async_callback(struct fs_file *file, fs_file_async_callback_t *callback, void *context) diff --git a/src/lib-fs/fs-api.h b/src/lib-fs/fs-api.h index d2d9a1dd61..228bb6f39c 100644 --- a/src/lib-fs/fs-api.h +++ b/src/lib-fs/fs-api.h @@ -5,6 +5,7 @@ struct stat; struct fs; struct fs_file; struct fs_lock; +struct hash_method; enum fs_properties { FS_PROPERTY_METADATA = 0x01, @@ -19,7 +20,9 @@ enum fs_properties { FS_PROPERTY_RELIABLEITER= 0x40, /* Backend uses directories, which aren't automatically deleted when its children are deleted. */ - FS_PROPERTY_DIRECTORIES = 0x80 + FS_PROPERTY_DIRECTORIES = 0x80, + FS_PROPERTY_WRITE_HASH_MD5 = 0x100, + FS_PROPERTY_WRITE_HASH_SHA256 = 0x200 }; enum fs_open_mode { @@ -115,6 +118,8 @@ int fs_get_metadata(struct fs_file *file, FS_OPEN_MODE_CREATE_UNIQUE_128 and the write has already finished, return the path including the generated filename. */ const char *fs_file_path(struct fs_file *file); +/* Returns the file's fs. */ +struct fs *fs_file_fs(struct fs_file *file); /* Return the error message for the last failed operation. */ const char *fs_last_error(struct fs *fs); @@ -151,6 +156,12 @@ int fs_write_stream_finish_async(struct fs_file *file); /* Abort writing via stream. Anything written to the stream is discarded. */ void fs_write_stream_abort(struct fs_file *file, struct ostream **output); +/* Set a hash to the following write. The storage can then verify that the + input data matches the specified hash, or fail if it doesn't. Typically + implemented by Content-MD5 header. */ +void fs_write_set_hash(struct fs_file *file, const struct hash_method *method, + const void *digest); + /* Call the specified callback whenever the file can be read/written to. May call the callback immediately. */ void fs_file_set_async_callback(struct fs_file *file,