Mailing List Archive

Storing messages in Maildir format with symmetric encryption
Hello everyone,

I want to store the incoming e-mails using the Maildir file format
encrypted by using some symmetric encryption using the user's password
(e.g., AES). So in the end, Exim should write the encrypted files
directly on the disk. Furthermore, it would be convenient if the actual
password is solely persistent saved as a hash (for checking at
authentication), the real password - and therefore the en-/decryption
key - is only temporarily available during the login session.

Therefore, I wanted to modify the Exim source code directly but was
confronted with a large amount of code, e.g., the differentiation
between the different transport types or the many cases considered in
the appendfile protocol. So I have some questions, where you might help
me in the "big picture":
* How to enforce that a user has to authenticate him-/herself with a
password?
* Where is a good point of "grabbing out" the password from the user and
how to "carry" it to the point where the encryption happens?
* Where is a good point to add the encryption, e.g., by modifying the
transport_instance block or directly before the file is written?

Thanks for your help in advance!

Best regards,

Gabriel

--
## List details at https://lists.exim.org/mailman/listinfo/exim-users
## Exim details at http://www.exim.org/
## Please use the Wiki with this list - http://wiki.exim.org/
Re: Storing messages in Maildir format with symmetric encryption [ In reply to ]
Hi Gabriel,

Dengler, Gabriel via Exim-users <exim-users@exim.org> (Mi 23 Nov 2022 01:16:19 CET):
> I want to store the incoming e-mails using the Maildir file format encrypted
> by using some symmetric encryption using the user's password (e.g., AES). So
> in the end, Exim should write the encrypted files directly on the disk.
> Furthermore, it would be convenient if the actual password is solely
> persistent saved as a hash (for checking at authentication), the real
> password - and therefore the en-/decryption key - is only temporarily
> available during the login session.

Mybe I'm missing the point. The on-disk representation of the password
is a hash. That can't be used for symmetric encryption/decryption.

You want to "grab" the real password during user login, and save it
somewhere for later use as encryption/decryption key?

IMHO no source modification is necessary, $auth2, $auth3 (depending on
the AUTH scheme you use (needs to be PLAIN or LOGIN) contain the
password. You're free to save it whereever you want (using SQL, using
embedded Perl code, using any external command, using readsocket, …)

The encryption I'd do with a "transport_filter", which basically is
can be an "aes-pipe" or similiar.

> Therefore, I wanted to modify the Exim source code directly but was
> confronted with a large amount of code, e.g., the differentiation between
> the different transport types or the many cases considered in the appendfile
> protocol. So I have some questions, where you might help me in the "big
> picture":

As stated, all transports can use a "transport_filter", which should be
able to processing your message on-the-fly, while writing it to the
mailbox file.

> * How to enforce that a user has to authenticate him-/herself with a
> password?

Use ACL to check if the user is authenticated. You should find it in the
example config. Watch out for "authenticated = *".

> * Where is a good point of "grabbing out" the password from the user and how
> to "carry" it to the point where the encryption happens?

The authenticators (authenticators section of the config) have the
password, and the server_condition does string expansion, so you can do
whatever you need there.

# example, *unchecked*, just served from memory, likely to be
# wrong

begin authenticators

plain:
driver = plain
server_advertise_condition = ${if def:tls_in_cipher}
server_condition = use $auth2 (user name) and $auth3
(password) in a creative way

Best regards from Dresden/Germany
Viele Grüße aus Dresden
Heiko Schlittermann
--
SCHLITTERMANN.de ---------------------------- internet & unix support -
Heiko Schlittermann, Dipl.-Ing. (TU) - {fon,fax}: +49.351.802998{1,3} -
gnupg encrypted messages are welcome --------------- key ID: F69376CE -
Re: Storing messages in Maildir format with symmetric encryption [ In reply to ]
On Wed, 23 Nov 2022, Dengler, Gabriel via Exim-users wrote:

> I want to store the incoming e-mails using the Maildir file format
> encrypted by using some symmetric encryption using the user's password

Which user: the sender or the recipient ?

--
Andrew C. Aitchison Kendal, UK
andrew@aitchison.me.uk

--
## List details at https://lists.exim.org/mailman/listinfo/exim-users
## Exim details at http://www.exim.org/
## Please use the Wiki with this list - http://wiki.exim.org/
Re: Storing messages in Maildir format with symmetric encryption [ In reply to ]
On 23/11/2022 00:16, Dengler, Gabriel via Exim-users wrote:
> I want to store the incoming e-mails using the Maildir file format encrypted by using some symmetric encryption using the user's password

It seems like a generally valuable concept - but I'd think that assymetric encryption
of the data-at-rest is more appropriate than symmetric. The MDA (exim, here, receiving
a message and delivering to file) shou be able to encrypt for the destination user
but NOT decrypt. So it should have access to a public key and not a private key
for the destination mailbox - and this is entirely separate from notions of
SMTP authentication.

Where to implement it in the code? Probably pretty late in the appendfile
transport; about where it's doing actual writes to the file fd - and using
a public key supplied via a transport option (which the config pulls
from a database lookup using the username, or localpart, or whatever)
and perhaps another giving the cipher scheme.
--
Cheers,
Jeremy


--
## List details at https://lists.exim.org/mailman/listinfo/exim-users
## Exim details at http://www.exim.org/
## Please use the Wiki with this list - http://wiki.exim.org/
Re: Storing messages in Maildir format with symmetric encryption [ In reply to ]
Hi Heiko, Hi Andrew,

thanks for your answers! At first, I wasn't aware that Exim has such
fancy concepts for on-the-fly modification of messages.

> Mybe I'm missing the point. The on-disk representation of the password
> is a hash. That can't be used for symmetric encryption/decryption.
>
> You want to "grab" the real password during user login, and save it
> somewhere for later use as encryption/decryption key?
yeah, that's my main idea. For clearness, a "normal" communication
profile would look like this:
* An external sender sends an e-mail to our local Exim Server.
* The Exim Server saves the message, e.g. via Maildir, encrypted with
the password of the receiver.
* When the receiver wants to access the message, e.g., via IMAP, he/she
encrypts the saved message again via its private password.
The goal is therefore that the messages are only encrypt-able when you
have access to the password of the receiver. And of course, a secure and
private password is necessary to prevent easy brute-force attacks.

> Which user: the sender or the recipient ?
Intentionally, I wanted to encrypt the file with the password of the
recipient, so that an IMAP server can again decrypt the message. But now
as you ask: I think this is not possible, as you can only "grab" the
password when the "receiver" sends a message him-/herself and needs to
expose the password.

I think I have to sleep about this concept one more night, but besides:
would the general setup be possible with transport_filter if the
passwords are not hashed (although this is obviously a security issue)?

Best regards,
Gabriel


Am 2022-11-23 23:22, schrieb Heiko Schlittermann via Exim-users:
> Hi Gabriel,
>
> Dengler, Gabriel via Exim-users <exim-users@exim.org> (Mi 23 Nov 2022
> 01:16:19 CET):
>> I want to store the incoming e-mails using the Maildir file format
>> encrypted
>> by using some symmetric encryption using the user's password (e.g.,
>> AES). So
>> in the end, Exim should write the encrypted files directly on the
>> disk.
>> Furthermore, it would be convenient if the actual password is solely
>> persistent saved as a hash (for checking at authentication), the real
>> password - and therefore the en-/decryption key - is only temporarily
>> available during the login session.
>
> Mybe I'm missing the point. The on-disk representation of the password
> is a hash. That can't be used for symmetric encryption/decryption.
>
> You want to "grab" the real password during user login, and save it
> somewhere for later use as encryption/decryption key?
>
> IMHO no source modification is necessary, $auth2, $auth3 (depending on
> the AUTH scheme you use (needs to be PLAIN or LOGIN) contain the
> password. You're free to save it whereever you want (using SQL, using
> embedded Perl code, using any external command, using readsocket, …)
>
> The encryption I'd do with a "transport_filter", which basically is
> can be an "aes-pipe" or similiar.
>
>> Therefore, I wanted to modify the Exim source code directly but was
>> confronted with a large amount of code, e.g., the differentiation
>> between
>> the different transport types or the many cases considered in the
>> appendfile
>> protocol. So I have some questions, where you might help me in the
>> "big
>> picture":
>
> As stated, all transports can use a "transport_filter", which should be
> able to processing your message on-the-fly, while writing it to the
> mailbox file.
>
>> * How to enforce that a user has to authenticate him-/herself with a
>> password?
>
> Use ACL to check if the user is authenticated. You should find it in
> the
> example config. Watch out for "authenticated = *".
>
>> * Where is a good point of "grabbing out" the password from the user
>> and how
>> to "carry" it to the point where the encryption happens?
>
> The authenticators (authenticators section of the config) have the
> password, and the server_condition does string expansion, so you can do
> whatever you need there.
>
> # example, *unchecked*, just served from memory, likely to be
> # wrong
>
> begin authenticators
>
> plain:
> driver = plain
> server_advertise_condition = ${if def:tls_in_cipher}
> server_condition = use $auth2 (user name) and $auth3
> (password) in a creative way
>
> Best regards from Dresden/Germany
> Viele Grüße aus Dresden
> Heiko Schlittermann
> --
> SCHLITTERMANN.de ---------------------------- internet & unix support
> -
> Heiko Schlittermann, Dipl.-Ing. (TU) - {fon,fax}: +49.351.802998{1,3}
> -
> gnupg encrypted messages are welcome --------------- key ID: F69376CE
> -

--
## List details at https://lists.exim.org/mailman/listinfo/exim-users
## Exim details at http://www.exim.org/
## Please use the Wiki with this list - http://wiki.exim.org/
Re: Storing messages in Maildir format with symmetric encryption [ In reply to ]
On 2022-11-23, Jeremy Harris via Exim-users <exim-users@exim.org> wrote:
> On 23/11/2022 00:16, Dengler, Gabriel via Exim-users wrote:
>> I want to store the incoming e-mails using the Maildir file format encrypted by using some symmetric encryption using the user's password
>
> It seems like a generally valuable concept - but I'd think that assymetric encryption
> of the data-at-rest is more appropriate than symmetric. The MDA (exim, here, receiving
> a message and delivering to file) shou be able to encrypt for the destination user
> but NOT decrypt. So it should have access to a public key and not a private key
> for the destination mailbox - and this is entirely separate from notions of
> SMTP authentication.
>
> Where to implement it in the code? Probably pretty late in the appendfile
> transport; about where it's doing actual writes to the file fd - and using
> a public key supplied via a transport option (which the config pulls
> from a database lookup using the username, or localpart, or whatever)
> and perhaps another giving the cipher scheme.

Perhaps use some sort of GPG wrapper as a transport_filter,
and do decryption client-side?

--
Jasen.

--
## List details at https://lists.exim.org/mailman/listinfo/exim-users
## Exim details at http://www.exim.org/
## Please use the Wiki with this list - http://wiki.exim.org/
Re: Storing messages in Maildir format with symmetric encryption [ In reply to ]
On Thu, 24 Nov 2022, Jasen Betts via Exim-users wrote:

> On 2022-11-23, Jeremy Harris via Exim-users <exim-users@exim.org> wrote:
>> On 23/11/2022 00:16, Dengler, Gabriel via Exim-users wrote:
>>> I want to store the incoming e-mails using the Maildir file format encrypted by using some symmetric encryption using the user's password
>>
>> It seems like a generally valuable concept - but I'd think that assymetric encryption
>> of the data-at-rest is more appropriate than symmetric. The MDA (exim, here, receiving
>> a message and delivering to file) shou be able to encrypt for the destination user
>> but NOT decrypt. So it should have access to a public key and not a private key
>> for the destination mailbox - and this is entirely separate from notions of
>> SMTP authentication.
>>
>> Where to implement it in the code? Probably pretty late in the appendfile
>> transport; about where it's doing actual writes to the file fd - and using
>> a public key supplied via a transport option (which the config pulls
>> from a database lookup using the username, or localpart, or whatever)
>> and perhaps another giving the cipher scheme.
>
> Perhaps use some sort of GPG wrapper as a transport_filter,
> and do decryption client-side?

Ah.
If we use OpenPGP format then the recipient can use any
PGP-aware client to read the message.

--
Andrew C. Aitchison Kendal, UK
andrew@aitchison.me.uk

--
## List details at https://lists.exim.org/mailman/listinfo/exim-users
## Exim details at http://www.exim.org/
## Please use the Wiki with this list - http://wiki.exim.org/
Re: Storing messages in Maildir format with symmetric encryption [ In reply to ]
• Dengler, Gabriel via Exim-users [2022-11-23 01:16]:
> Hello everyone,
>
> I want to store the incoming e-mails using the Maildir file format encrypted
> by using some symmetric encryption using the user's password (e.g., AES). So
> in the end, Exim should write the encrypted files directly on the disk.
> Furthermore, it would be convenient if the actual password is solely
> persistent saved as a hash (for checking at authentication), the real
> password - and therefore the en-/decryption key - is only temporarily
> available during the login session.

Why do you have Exim to make this? Why not use Dovecot's delivery
facilities to make Dovecot encrypt and store in Maildir?

https://doc.dovecot.org/configuration_manual/mail_crypt_plugin/#functional-overview

> Therefore, I wanted to modify the Exim source code directly but was
> confronted with a large amount of code, e.g., the differentiation between
> the different transport types or the many cases considered in the appendfile
> protocol. So I have some questions, where you might help me in the "big
> picture":
> * How to enforce that a user has to authenticate him-/herself with a
> password?
> * Where is a good point of "grabbing out" the password from the user and how
> to "carry" it to the point where the encryption happens?
> * Where is a good point to add the encryption, e.g., by modifying the
> transport_instance block or directly before the file is written?
>
> Thanks for your help in advance!
>
> Best regards,
>
> Gabriel
>
> --
> ## List details at https://lists.exim.org/mailman/listinfo/exim-users
> ## Exim details at http://www.exim.org/
> ## Please use the Wiki with this list - http://wiki.exim.org/

--
-- Kirill Miazine <km@krot.org>

--
## List details at https://lists.exim.org/mailman/listinfo/exim-users
## Exim details at http://www.exim.org/
## Please use the Wiki with this list - http://wiki.exim.org/
Re: Storing messages in Maildir format with symmetric encryption [ In reply to ]
Dengler, Gabriel <gabriel.dengler@fau.de> (Do 24 Nov 2022 00:19:42 CET):
> > somewhere for later use as encryption/decryption key?
> yeah, that's my main idea. For clearness, a "normal" communication profile
> would look like this:
> * An external sender sends an e-mail to our local Exim Server.
> * The Exim Server saves the message, e.g. via Maildir, encrypted with the
> password of the receiver.

Ok, but how does Exim know the password of the receiver? You've access
to the password hashes only, I suppose.

> * When the receiver wants to access the message, e.g., via IMAP, he/she
> encrypts the saved message again via its private password.

Wouldn't it be better to use asymmetric encryption, then Exim doesn't
need to know a shared secret, but only a public key. The mailbox user
then can decrypt the message using a private key.

Having a shared secret that's known to Exim (except during the
verification of a PLAIN or LOGIN auth), creates an unnecessary attack
surface.

> I think I have to sleep about this concept one more night, but besides:
> would the general setup be possible with transport_filter if the passwords
> are not hashed (although this is obviously a security issue)?

BTW, I *think* I read that Dovecot supports encrypted mailboxes. And in
the ideal world Exim doesn't know anything about how to store messages,
but simply passes the messages to a MDA (mail delivery agent), e.g.
directly via a local pipe (dovecot-deliver, cyrdeliver, …), or via a protocol like LMTP
(which is supported by Dovecot and Cyrus too).

Best regards from Dresden/Germany
Viele Grüße aus Dresden
Heiko Schlittermann
--
SCHLITTERMANN.de ---------------------------- internet & unix support -
Heiko Schlittermann, Dipl.-Ing. (TU) - {fon,fax}: +49.351.802998{1,3} -
gnupg encrypted messages are welcome --------------- key ID: F69376CE -
Re: Storing messages in Maildir format with symmetric encryption [ In reply to ]
• Heiko Schlittermann via Exim-users [2022-11-24 10:51]:
[...]
> BTW, I *think* I read that Dovecot supports encrypted mailboxes.

See my earlier post today:

https://marc.info/?l=exim-users&m=166928008225533&w=2

--
## List details at https://lists.exim.org/mailman/listinfo/exim-users
## Exim details at http://www.exim.org/
## Please use the Wiki with this list - http://wiki.exim.org/
Re: Storing messages in Maildir format with symmetric encryption [ In reply to ]
Am 24.11.22 um 09:23 schrieb Andrew C Aitchison via Exim-users:
>
>> Perhaps use some sort of GPG wrapper as a transport_filter,
>> and do decryption client-side?
>
> Ah.
> If we use OpenPGP format then the recipient can use any
> PGP-aware client to read the message.
>

Tried it.. It's complex and it ended with all sorts of charset issues
within the pgp mails.

But, yes, it's the only imaginable way to make it secure for all
local/remote attack scenarios,
after it got encrypted.

Everything else, like the dovecot mailcrypt plugin, has loopholes:

- no protection of physical theft, except password for keys is used and
database for password was not stolen too.
- no protection against rogue admins
- no protection against system breaches
- no protection against stolen/bruteforced credentials --> imap login

- only working scenario:
  Attacker with none-root privileges on system side, with read access
to mailbox files.
  Access should be only valid for exim and dovecot itself anyway, so
encryption is obsolete, if access rights are restricted correctly.

Of course, these are only my opinions on the topic.

best regards,
Marius
Re: Storing messages in Maildir format with symmetric encryption [ In reply to ]
Hey Heiko,

in the meantime, I made great progress with the "transport_filter" tool.
That was exactly what I was looking for.

In the current setup, I want to store a public and a private key for
each user, whereas the private key is encrypted by a password that is
only known by the user. For incoming messages, I use the public key to
encrypt them, for accessing those messages you need the private key,
respectively.

As mentioned in the documentation [1], you can use expansion variables
to pass to the "transport_filter". Is there an easy way to access the
user name or do you have to filter it out of the headers, e.g. by
accessing "Envelope-to:"? I thought about $recipients [2], but this is
not available for "transport_filter".

Best regards,
Gabriel

Quotes:
[1]
https://www.exim.org/exim-html-current/doc/html/spec_html/ch-generic_options_for_transports.html
[2]
https://www.exim.org/exim-html-current/doc/html/spec_html/ch-string_expansions.html


Am 2022-11-23 23:22, schrieb Heiko Schlittermann via Exim-users:
> Hi Gabriel,
>
> Dengler, Gabriel via Exim-users <exim-users@exim.org> (Mi 23 Nov 2022
> 01:16:19 CET):
>> I want to store the incoming e-mails using the Maildir file format
>> encrypted
>> by using some symmetric encryption using the user's password (e.g.,
>> AES). So
>> in the end, Exim should write the encrypted files directly on the
>> disk.
>> Furthermore, it would be convenient if the actual password is solely
>> persistent saved as a hash (for checking at authentication), the real
>> password - and therefore the en-/decryption key - is only temporarily
>> available during the login session.
>
> Mybe I'm missing the point. The on-disk representation of the password
> is a hash. That can't be used for symmetric encryption/decryption.
>
> You want to "grab" the real password during user login, and save it
> somewhere for later use as encryption/decryption key?
>
> IMHO no source modification is necessary, $auth2, $auth3 (depending on
> the AUTH scheme you use (needs to be PLAIN or LOGIN) contain the
> password. You're free to save it whereever you want (using SQL, using
> embedded Perl code, using any external command, using readsocket, …)
>
> The encryption I'd do with a "transport_filter", which basically is
> can be an "aes-pipe" or similiar.
>
>> Therefore, I wanted to modify the Exim source code directly but was
>> confronted with a large amount of code, e.g., the differentiation
>> between
>> the different transport types or the many cases considered in the
>> appendfile
>> protocol. So I have some questions, where you might help me in the
>> "big
>> picture":
>
> As stated, all transports can use a "transport_filter", which should be
> able to processing your message on-the-fly, while writing it to the
> mailbox file.
>
>> * How to enforce that a user has to authenticate him-/herself with a
>> password?
>
> Use ACL to check if the user is authenticated. You should find it in
> the
> example config. Watch out for "authenticated = *".
>
>> * Where is a good point of "grabbing out" the password from the user
>> and how
>> to "carry" it to the point where the encryption happens?
>
> The authenticators (authenticators section of the config) have the
> password, and the server_condition does string expansion, so you can do
> whatever you need there.
>
> # example, *unchecked*, just served from memory, likely to be
> # wrong
>
> begin authenticators
>
> plain:
> driver = plain
> server_advertise_condition = ${if def:tls_in_cipher}
> server_condition = use $auth2 (user name) and $auth3
> (password) in a creative way
>
> Best regards from Dresden/Germany
> Viele Grüße aus Dresden
> Heiko Schlittermann
> --
> SCHLITTERMANN.de ---------------------------- internet & unix support
> -
> Heiko Schlittermann, Dipl.-Ing. (TU) - {fon,fax}: +49.351.802998{1,3}
> -
> gnupg encrypted messages are welcome --------------- key ID: F69376CE
> -

--
## List details at https://lists.exim.org/mailman/listinfo/exim-users
## Exim details at http://www.exim.org/
## Please use the Wiki with this list - http://wiki.exim.org/
Re: Storing messages in Maildir format with symmetric encryption [ In reply to ]
On 2022-12-11, Dengler, Gabriel via Exim-users <exim-users@exim.org> wrote:
> Hey Heiko,
>
> in the meantime, I made great progress with the "transport_filter" tool.
> That was exactly what I was looking for.
>
> In the current setup, I want to store a public and a private key for
> each user, whereas the private key is encrypted by a password that is
> only known by the user. For incoming messages, I use the public key to
> encrypt them, for accessing those messages you need the private key,
> respectively.
>
> As mentioned in the documentation [1], you can use expansion variables
> to pass to the "transport_filter". Is there an easy way to access the
> user name or do you have to filter it out of the headers, e.g. by
> accessing "Envelope-to:"? I thought about $recipients [2], but this is
> not available for "transport_filter".

You can save $recipients into an $acl_m_ variable in the data
acl and thus have the value available when doing delivery, but how
will that help? - recipients may be multiple...


When encrypting you need a single. if it's handling a single recipinet
you get you get $domain ansd $local_part which are probably what you
want. They're tainted so use them in a lookup to find the public key
(or the filename). some transports can handle muiltipe recipients in
a single transaction. they'll need to be configured to not attempt
that.

--
Jasen.

--
## List details at https://lists.exim.org/mailman/listinfo/exim-users
## Exim details at http://www.exim.org/
## Please use the Wiki with this list - http://wiki.exim.org/
Re: Storing messages in Maildir format with symmetric encryption [ In reply to ]
Hey Jasen,

ok, I ended up with $local_part_data which is also used for determining
the folder structure when using Maildir.

Best regards,
Gabriel


Am 2022-12-11 03:43, schrieb Jasen Betts via Exim-users:
> On 2022-12-11, Dengler, Gabriel via Exim-users <exim-users@exim.org>
> wrote:
>> Hey Heiko,
>>
>> in the meantime, I made great progress with the "transport_filter"
>> tool.
>> That was exactly what I was looking for.
>>
>> In the current setup, I want to store a public and a private key for
>> each user, whereas the private key is encrypted by a password that is
>> only known by the user. For incoming messages, I use the public key to
>> encrypt them, for accessing those messages you need the private key,
>> respectively.
>>
>> As mentioned in the documentation [1], you can use expansion variables
>> to pass to the "transport_filter". Is there an easy way to access the
>> user name or do you have to filter it out of the headers, e.g. by
>> accessing "Envelope-to:"? I thought about $recipients [2], but this is
>> not available for "transport_filter".
>
> You can save $recipients into an $acl_m_ variable in the data
> acl and thus have the value available when doing delivery, but how
> will that help? - recipients may be multiple...
>
>
> When encrypting you need a single. if it's handling a single recipinet
> you get you get $domain ansd $local_part which are probably what you
> want. They're tainted so use them in a lookup to find the public key
> (or the filename). some transports can handle muiltipe recipients in
> a single transaction. they'll need to be configured to not attempt
> that.
>
> --
> Jasen.

--
## List details at https://lists.exim.org/mailman/listinfo/exim-users
## Exim details at http://www.exim.org/
## Please use the Wiki with this list - http://wiki.exim.org/