dovecot-2.0: Added mail_attachment_hash setting.

dovecot at dovecot.org dovecot at dovecot.org
Sat Oct 2 14:34:04 EEST 2010


details:   http://hg.dovecot.org/dovecot-2.0/rev/0754787eb000
changeset: 12264:0754787eb000
user:      Timo Sirainen <tss at iki.fi>
date:      Thu Sep 16 19:14:35 2010 +0100
description:
Added mail_attachment_hash setting.

diffstat:

 src/lib-storage/index/index-attachment.c |  55 ++++++++++++++++++++-------
 src/lib-storage/mail-storage-settings.c  |  13 ++++++-
 src/lib-storage/mail-storage-settings.h  |   1 +
 3 files changed, 53 insertions(+), 16 deletions(-)

diffs (216 lines):

diff -r 3bd4d0a65070 -r 0754787eb000 src/lib-storage/index/index-attachment.c
--- a/src/lib-storage/index/index-attachment.c	Thu Sep 16 19:14:22 2010 +0100
+++ b/src/lib-storage/index/index-attachment.c	Thu Sep 16 19:14:35 2010 +0100
@@ -6,9 +6,8 @@
 #include "istream.h"
 #include "ostream.h"
 #include "base64.h"
-#include "sha1.h"
+#include "hash-format.h"
 #include "str.h"
-#include "hex-binary.h"
 #include "message-parser.h"
 #include "rfc822-parser.h"
 #include "mail-user.h"
@@ -49,7 +48,7 @@
 
 	int temp_fd;
 	struct ostream *output;
-	struct sha1_ctxt part_hash;
+	struct hash_format *part_hash;
 	buffer_t *part_buf;
 };
 
@@ -189,6 +188,22 @@
 	return fd;
 }
 
+static struct hash_format *
+index_attachment_hash_format_init(struct mail_save_context *ctx)
+{
+	struct mail_storage *storage = ctx->transaction->box->storage;
+	struct hash_format *format;
+	const char *error;
+
+	if (hash_format_init(storage->set->mail_attachment_hash,
+			     &format, &error) < 0) {
+		/* we already checked this when verifying settings */
+		i_panic("mail_attachment_hash=%s unexpectedly failed: %s",
+			storage->set->mail_attachment_hash, error);
+	}
+	return format;
+}
+
 static int index_attachment_save_temp_open(struct mail_save_context *ctx)
 {
 	int fd;
@@ -200,7 +215,8 @@
 	ctx->attach->part.temp_fd = fd;
 	ctx->attach->part.output = o_stream_create_fd(fd, 0, FALSE);
 	o_stream_cork(ctx->attach->part.output);
-	sha1_init(&ctx->attach->part.part_hash);
+
+	ctx->attach->part.part_hash = index_attachment_hash_format_init(ctx);
 	return 0;
 }
 
@@ -225,7 +241,7 @@
 	buffer_t *extra_buf = NULL;
 	struct istream *input, *base64_input;
 	struct ostream *output;
-	struct sha1_ctxt hash;
+	struct hash_format *hash;
 	const unsigned char *data;
 	size_t size;
 	ssize_t ret;
@@ -251,7 +267,7 @@
 	if (outfd == -1)
 		return -1;
 
-	sha1_init(&hash);
+	hash = index_attachment_hash_format_init(ctx);
 	buf = buffer_create_dynamic(default_pool, 1024);
 	input = i_stream_create_fd(part->temp_fd, IO_BLOCK_SIZE, FALSE);
 	base64_input = i_stream_create_limit(input, part->base64_bytes);
@@ -269,7 +285,7 @@
 		}
 		i_stream_skip(base64_input, size);
 		o_stream_send(output, buf->data, buf->used);
-		sha1_loop(&hash, buf->data, buf->used);
+		hash_format_loop(hash, buf->data, buf->used);
 	}
 	if (ret != -1) {
 		i_assert(failed);
@@ -304,6 +320,7 @@
 	i_stream_unref(&input);
 
 	if (failed) {
+		hash_format_deinit_free(&hash);
 		if (close(outfd) < 0) {
 			mail_storage_set_critical(storage,
 				"close(attachment-temp) failed: %m");
@@ -323,6 +340,7 @@
 		o_stream_send(ctx->output, extra_buf->data, extra_buf->used);
 		buffer_free(&extra_buf);
 	}
+	hash_format_deinit_free(&part->part_hash);
 	part->part_hash = hash;
 	return 0;
 }
@@ -334,9 +352,9 @@
 	struct fs_file *file;
 	struct istream *input;
 	struct ostream *output;
-	unsigned char digest[SHA1_RESULTLEN];
 	uint8_t guid_128[MAIL_GUID_128_SIZE];
-	const char *attachment_dir, *path, *digest_str;
+	const char *attachment_dir, *path, *digest;
+	string_t *digest_str;
 	const unsigned char *data;
 	size_t size;
 	uoff_t attachment_size;
@@ -366,14 +384,20 @@
 	if (storage->set->parsed_fsync_mode != FSYNC_MODE_NEVER)
 		flags |= FS_OPEN_FLAG_FDATASYNC;
 
-	sha1_result(&part->part_hash, digest);
-	digest_str = binary_to_hex(digest, sizeof(digest));
+	digest_str = t_str_new(128);
+	hash_format_deinit(&part->part_hash, digest_str);
+	digest = str_c(digest_str);
+	if (strlen(digest) < 4) {
+		/* make sure we can access first 4 bytes without accessing
+		   out of bounds memory */
+		digest = t_strconcat(digest, "\0\0\0\0", NULL);
+	}
 
 	mail_generate_guid_128(guid_128);
 	attachment_dir = index_attachment_dir_get(storage);
 	path = t_strdup_printf("%s/%c%c/%c%c/%s-%s", attachment_dir,
-			       digest_str[0], digest_str[1],
-			       digest_str[2], digest_str[3], digest_str,
+			       digest[0], digest[1],
+			       digest[2], digest[3], digest,
 			       mail_guid_128_to_string(guid_128));
 	if (fs_open(ctx->attach->fs, path,
 		    FS_OPEN_MODE_CREATE | flags, &file) < 0) {
@@ -570,14 +594,15 @@
 		part->state = MAIL_ATTACHMENT_STATE_YES;
 		index_attachment_try_base64_decode(part, part_buf->data,
 						   part_buf->used);
-		sha1_loop(&part->part_hash, part_buf->data, part_buf->used);
+		hash_format_loop(part->part_hash,
+				 part_buf->data, part_buf->used);
 		o_stream_send(part->output, part_buf->data, part_buf->used);
 		buffer_set_used_size(part_buf, 0);
 		/* fall through */
 	case MAIL_ATTACHMENT_STATE_YES:
 		index_attachment_try_base64_decode(part, block->data,
 						   block->size);
-		sha1_loop(&part->part_hash, block->data, block->size);
+		hash_format_loop(part->part_hash, block->data, block->size);
 		o_stream_send(part->output, block->data, block->size);
 		break;
 	}
diff -r 3bd4d0a65070 -r 0754787eb000 src/lib-storage/mail-storage-settings.c
--- a/src/lib-storage/mail-storage-settings.c	Thu Sep 16 19:14:22 2010 +0100
+++ b/src/lib-storage/mail-storage-settings.c	Thu Sep 16 19:14:35 2010 +0100
@@ -2,6 +2,7 @@
 
 #include "lib.h"
 #include "array.h"
+#include "hash-format.h"
 #include "var-expand.h"
 #include "settings-parser.h"
 #include "mail-index.h"
@@ -25,6 +26,7 @@
 	{ SET_ALIAS, "mail", 0, NULL },
 	DEF(SET_STR_VARS, mail_attachment_fs),
 	DEF(SET_STR_VARS, mail_attachment_dir),
+	DEF(SET_STR, mail_attachment_hash),
 	DEF(SET_SIZE, mail_attachment_min_size),
 	DEF(SET_STR, mail_cache_fields),
 	DEF(SET_STR, mail_never_cache_fields),
@@ -52,6 +54,7 @@
 	.mail_location = "",
 	.mail_attachment_fs = "sis posix",
 	.mail_attachment_dir = "",
+	.mail_attachment_hash = "%{sha1}",
 	.mail_attachment_min_size = 1024*128,
 	.mail_cache_fields = "flags",
 	.mail_never_cache_fields = "imap.envelope",
@@ -293,7 +296,8 @@
 					const char **error_r)
 {
 	struct mail_storage_settings *set = _set;
-	const char *p;
+	struct hash_format *format;
+	const char *p, *error;
 	bool uidl_format_ok;
 	char c;
 
@@ -353,6 +357,13 @@
 			"%% variables.";
 		return FALSE;
 	}
+
+	if (hash_format_init(set->mail_attachment_hash, &format, &error) < 0) {
+		*error_r = t_strconcat("Invalid mail_attachment_hash setting: ",
+				       error, NULL);
+		return FALSE;
+	}
+	hash_format_deinit_free(&format);
 	return TRUE;
 }
 
diff -r 3bd4d0a65070 -r 0754787eb000 src/lib-storage/mail-storage-settings.h
--- a/src/lib-storage/mail-storage-settings.h	Thu Sep 16 19:14:22 2010 +0100
+++ b/src/lib-storage/mail-storage-settings.h	Thu Sep 16 19:14:35 2010 +0100
@@ -13,6 +13,7 @@
 	const char *mail_location;
 	const char *mail_attachment_fs;
 	const char *mail_attachment_dir;
+	const char *mail_attachment_hash;
 	uoff_t mail_attachment_min_size;
 	const char *mail_cache_fields;
 	const char *mail_never_cache_fields;


More information about the dovecot-cvs mailing list