I frequently encounter software that allows me to send mails, but has no GPG support out of the box (sometimes not even using plugins). This annoys me greatly, especially if it is software like FusionInvoice, which may transport sensitive information in its mail messages. Since FusionInvoice (and many other programs) support SMTP for sending their mail, and since I had a few spare hours, I decided to see if I could hack something together to add GPG support to those programs. And the result was…
…the SMTP GPG Proxy
The SMTP GPG Proxy, besides having an awful name (name proposals welcome), is a Python program. It provides an SMTP Server and will accept incoming mail messages, encrypt / sign them according to its settings and magic strings in the mail subject, and then forward them to the upstream SMTP server.
Since the basic python smtpd-Module does not support encrypted connections, I used the modified “secure-smtpd”-Module by bcoe. It extends the basic smtpd with support for SSL-encrypted connections while providing an almost identical interface. For the encryption itself, I used the standard “python-gnupg”-wrapper, which isn’t ideal but gets the job done most of the time.
Setting up the SMTP GPG Proxy is quite easy. Just grab the latest version from the GitHub-Repository, install the dependencies, rename the config.py.example to config.py and fill in the settings (everything should be documented in there), and then launch the main program. Next, point your SMTP-speaking program at the IP and port you just configured (it is highly recommended to do this via localhost only, as incoming connections into the Proxy are, as of right now, not encrypted), and mail away.
To get the SMTP Proxy to encrypt a message, just send the mail and add the KeyIDs (including the “0x”) to the subject line, seperated by whitespaces. They will be automatically parsed and removed from the subject, so if you want to send a message with the subject “Invoice #23”, encrypted with 0x12345678 and 0x13374242, you would choose the subject “Invoice #23 0x12345678 0x13374242”. KeyIDs can be in short (8 characters) or long (16 characters) form, as well as full fingerprints (without whitespaces and prefixed by “0x”).
Depending on the settings, missing public keys will either lead to the message being rejected, sent unencrypted, or keyservers may be polled before rejecting or sending unencrypted if no public keys are found. You can also configure the program to GPG-sign all messages, or only encrypted messages, or no messages at all.
The program is currently in alpha, but it works very well for me. Still, as of right now there are some open issues with it, which I may or may not be working on. If you set up everything correctly, you should not encounter any problems. It is the border cases like incorrect SMTP passwords that are currently not dealt with very well.
If I find the time, I will keep developing the program, removing bugs, making it more stable, and adding more features like opportunistic encryption. However, I may not have the time to fully fix everything, and bugs that are annoying me will obviously be fixed faster than those I will never encounter in my usage.
However, as the program is open source and on GitHub, feel free to fork and submit pull requests. The code is, as of right now, shamefully undocumented, but as it has only about 200 lines, it should still be fairly easy to understand.
Like almost all my projects, I am releasing this program under the BSD 2-Clause License.