From: Marco Bettini Date: Tue, 1 Feb 2022 13:22:31 +0000 (+0100) Subject: mail-crypt: Fix for mail being wrongly storing encrypted via LMTP X-Git-Tag: 2.3.19~75 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=12a751615b5c9c816d9d9540b1642e2ca0b1fa98;p=thirdparty%2Fdovecot%2Fcore.git mail-crypt: Fix for mail being wrongly storing encrypted via LMTP If 1st recipient has mail_crypt_save_version=2, and 2nd recipient has mail_crypt_save_version=0, the mail for 2nd recipient is wrongly stored encrypted. Same happens if 2nd recipient has mail_crypt disabled --- diff --git a/src/plugins/mail-crypt/mail-crypt-plugin.c b/src/plugins/mail-crypt/mail-crypt-plugin.c index 4d09b66834..21da3481f2 100644 --- a/src/plugins/mail-crypt/mail-crypt-plugin.c +++ b/src/plugins/mail-crypt/mail-crypt-plugin.c @@ -255,23 +255,25 @@ mail_crypt_mail_save_begin(struct mail_save_context *ctx, const char *pubid; struct mailbox *box = ctx->transaction->box; struct mail_crypt_mailbox *mbox = MAIL_CRYPT_CONTEXT(box); - struct mail_crypt_user *muser = - MAIL_CRYPT_USER_CONTEXT_REQUIRE(box->storage->user); - - enum io_stream_encrypt_flags enc_flags; - if (muser->save_version == 1) { - enc_flags = IO_STREAM_ENC_VERSION_1; - } else if (muser->save_version == 2) { - enc_flags = IO_STREAM_ENC_INTEGRITY_AEAD; - } else { - i_assert(muser->save_version == 0); - i_panic("mail_crypt_mail_save_begin not supposed to be called" - "when mail_crypt_save_version is 0"); + struct mail_crypt_user *muser = MAIL_CRYPT_USER_CONTEXT(box->storage->user); + + enum io_stream_encrypt_flags enc_flags = 0; + if (muser != NULL) { + if (muser->save_version == 1) { + enc_flags = IO_STREAM_ENC_VERSION_1; + } else if (muser->save_version == 2) { + enc_flags = IO_STREAM_ENC_INTEGRITY_AEAD; + } else { + i_assert(muser->save_version == 0); + } } if (mbox->module_ctx.super.save_begin(ctx, input) < 0) return -1; + if (enc_flags == 0) + return 0; + struct dcrypt_public_key *pub_key; if (muser->global_keys.public_key != NULL) pub_key = muser->global_keys.public_key; @@ -370,20 +372,17 @@ static void mail_crypt_mailbox_allocated(struct mailbox *box) MODULE_CONTEXT_SET(box, mail_crypt_storage_module, mbox); if ((class_flags & MAIL_STORAGE_CLASS_FLAG_BINARY_DATA) != 0) { - if (muser != NULL) { - if (muser->save_version > 0) { - v->save_begin = mail_crypt_mail_save_begin; - /* if global keys are used, re-encrypting on copy/move - is not necessary, so do not attempt to do it. - - with per-folder keys, emails must be re-encrypted - when moving to another folder */ - if (muser->global_keys.public_key == NULL) - v->copy = mail_crypt_mailbox_copy; - } - } else { + v->save_begin = mail_crypt_mail_save_begin; + + /* if global keys are used, re-encrypting on copy/move + is not necessary, so do not attempt to do it. + with per-folder keys, emails must be re-encrypted + when moving to another folder */ + if (muser == NULL || muser->save_version == 0 || + muser->global_keys.public_key == NULL) + v->copy = mail_crypt_mailbox_copy; + if (muser == NULL || muser->save_version == 0) v->save_finish = mail_crypt_mail_save_finish; - } } } @@ -470,10 +469,11 @@ void mail_crypt_plugin_init(struct module *module) if (!dcrypt_initialize("openssl", NULL, &error)) i_fatal("dcrypt_initialize(): %s", error); mail_storage_hooks_add(module, &mail_crypt_mail_storage_hooks); - /* rather kludgy. we need to hook into mail reading as early as - possible, but we need to hook into mail writing as late as - possible. we could create just two real plugins, but that's a bit - annoying to configure. */ + /* when this plugin is loaded, there's the potential chance for + mixed delivery between encrypted and non-encrypted recipients. + The mail_crypt_mailbox_allocated() hook ensures encrypted + content isn't copied as such into cleartext recipients + (and the other way around) */ mail_storage_hooks_add_forced(&crypto_post_module, &mail_crypt_mail_storage_hooks_post); mail_crypt_key_register_mailbox_internal_attributes();