Mercurial > dovecot > core-2.2
changeset 22981:acc052049f0b
lib-dcrypt: istream-decrypt - Add support for seeking
author | Timo Sirainen <timo.sirainen@dovecot.fi> |
---|---|
date | Tue, 05 Jun 2018 13:34:02 +0300 |
parents | fed657e0b156 |
children | 697e36c7feae |
files | src/lib-dcrypt/istream-decrypt.c src/lib-dcrypt/test-stream.c |
diffstat | 2 files changed, 51 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-dcrypt/istream-decrypt.c Tue Jun 05 13:25:30 2018 +0300 +++ b/src/lib-dcrypt/istream-decrypt.c Tue Jun 05 13:34:02 2018 +0300 @@ -21,6 +21,7 @@ struct decrypt_istream { struct istream_private istream; buffer_t *buf; + bool symmetric; i_stream_decrypt_get_key_callback_t *key_callback; void *key_context; @@ -41,6 +42,26 @@ enum decrypt_istream_format format; }; +static void i_stream_decrypt_reset(struct decrypt_istream *dstream) +{ + dstream->finalized = FALSE; + dstream->use_mac = FALSE; + + dstream->ftr = 0; + dstream->pos = 0; + dstream->flags = 0; + + if (!dstream->symmetric) { + dstream->initialized = FALSE; + if (dstream->ctx_sym != NULL) + dcrypt_ctx_sym_destroy(&dstream->ctx_sym); + if (dstream->ctx_mac != NULL) + dcrypt_ctx_hmac_destroy(&dstream->ctx_mac); + } + i_free(dstream->iv); + dstream->format = DECRYPT_FORMAT_V1; +} + enum decrypt_istream_format i_stream_encrypt_get_format(const struct istream *input) { return ((const struct decrypt_istream*)input->real_stream)->format; @@ -818,6 +839,22 @@ } } +static void +i_stream_decrypt_seek(struct istream_private *stream, uoff_t v_offset, + bool mark ATTR_UNUSED) +{ + struct decrypt_istream *dstream = + (struct decrypt_istream *)stream; + + if (i_stream_nonseekable_try_seek(stream, v_offset)) + return; + + /* have to seek backwards - reset crypt state and retry */ + i_stream_decrypt_reset(dstream); + if (!i_stream_nonseekable_try_seek(stream, v_offset)) + i_unreached(); +} + static void i_stream_decrypt_close(struct iostream_private *stream, bool close_parent) @@ -857,12 +894,14 @@ dstream = i_new(struct decrypt_istream, 1); dstream->istream.max_buffer_size = input->real_stream->max_buffer_size; dstream->istream.read = i_stream_decrypt_read; + if (input->seekable) + dstream->istream.seek = i_stream_decrypt_seek; dstream->istream.iostream.close = i_stream_decrypt_close; dstream->istream.iostream.destroy = i_stream_decrypt_destroy; dstream->istream.istream.readable_fd = FALSE; dstream->istream.istream.blocking = input->blocking; - dstream->istream.istream.seekable = FALSE; + dstream->istream.istream.seekable = input->seekable; dstream->buf = buffer_create_dynamic(default_pool, 512); @@ -891,6 +930,7 @@ dstream = i_stream_create_decrypt_common(input); dstream->use_mac = FALSE; dstream->initialized = TRUE; + dstream->symmetric = TRUE; if (!dcrypt_ctx_sym_init(ctx, &error)) ec = -1; else ec = 0;
--- a/src/lib-dcrypt/test-stream.c Tue Jun 05 13:25:30 2018 +0300 +++ b/src/lib-dcrypt/test-stream.c Tue Jun 05 13:34:02 2018 +0300 @@ -367,6 +367,16 @@ if (is_2->stream_errno != 0) i_debug("error: %s", i_stream_get_error(is_2)); + /* test seeking */ + for (size_t i = sizeof(payload)-100; i > 100; i -= 100) { + i_stream_seek(is_2, i); + test_assert_idx(i_stream_read_data(is_2, &ptr, &siz, 0) == 1, i); + test_assert_idx(memcmp(ptr, payload + i, siz) == 0, i); + } + i_stream_seek(is_2, 0); + test_assert(i_stream_read_data(is_2, &ptr, &siz, 0) == 1); + test_assert(memcmp(ptr, payload, siz) == 0); + i_stream_unref(&is); i_stream_unref(&is_2); buffer_free(&buf);