Postmark and Encrypted Emails
21/09/2022 Article
Postmark is an email distribution company. They provide SMTP relay services for transactional and bulk email messaging. Transactional is a bit of a confusing concept in this space as they are actively marketing for web application integration opportunities. They also provide an API that is compatible with things like Postfix and so it is also possible to use Postmark as your normal, boring, everyday, business, personal (however you describe it) outbound email provider. This means it is possible to run your own infrastructure, but, offload the difficult bit of maintaining a reputation to someone else.
This post doesn’t go into the detail about how to set that up as there is plenty online about that already and the guys at Postmark are pretty helpful in getting up and running. Instead, this post is specifically about how to deal with using Postmark when sending GPG encrypted emails.
Modern GPG usage encapsulates the encrypted portion of the message into a multipart mime envelope. You might have seen something like this before:
Content-Type: multipart/encrypted;
protocol="application/pgp-encrypted";
boundary="------------rOANLThIL6qhf9A1ZqSvr0h1"
This is an OpenPGP/MIME encrypted message (RFC 4880 and 3156)
--------------rOANLThIL6qhf9A1ZqSvr0h1
Content-Type: application/pgp-encrypted
Content-Description: PGP/MIME version identification
Version: 1
--------------rOANLThIL6qhf9A1ZqSvr0h1
Content-Type: application/octet-stream; name="encrypted.asc"
Content-Description: OpenPGP encrypted message
Content-Disposition: inline; filename="encrypted.asc"
-----BEGIN PGP MESSAGE-----
The above is the structure definition of the encrypted portions on the email. There is no plaintext or HTML elements that get sent with such an email. Unfortunately Postmark errors when sending messages that it perceives as having no content. Makes sense, but, their definition of no-content is perhaps a little narrow.
One of the support desk guys at Postmark and I did a bit of Googling and came across someone dealing with a similar situation. That guide uses a tool called ‘altermime’ and essentially gets Postfix to allow Altermime to add a disclaimer / footer to the end of the message thus meaning that there is content. Sadly this does not work for GPG encrypted emails as altermime can’t cope with encrypted multipart messages either.
I set to work and using the same principals I modified their altermime handler script to do what I needed:
#!/bin/sh
# enable debug or not
DEBUG=false
# Localize these.
INSPECT_DIR=/var/spool/filter
SENDMAIL=/usr/sbin/sendmail
# Exit codes from <sysexits.h>
EX_TEMPFAIL=75
# Clean up when done or when aborting.
trap "rm -f in.$$" 0 1 2 3 15
# Start processing.
cd $INSPECT_DIR || { echo $INSPECT_DIR does not exist; exit
$EX_TEMPFAIL; }
cat >in.$$ || { echo Cannot save mail to file; exit $EX_TEMPFAIL; }
# check if message is has a mimetype that indicates it is encrypted
## get content type
content_type=`grep -m 1 "Content-Type:" in.$$`
boundary_flag=`grep -m 1 "boundary=" in.$$ | cut -d "=" -f 2 | cut -d '"' -f 2`
## debug output
if $DEBUG; then
cp in.$$ /tmp/disclaimer.in.$$
echo `date` >> /tmp/disclaimer
echo "Temp file is: " in.$$ >> /tmp/disclaimer
echo "Content type is: " $content_type >> /tmp/disclaimer
echo "Boundary is: " $boundary_flag >> /tmp/disclaimer
fi
if echo ${content_type} | grep -iqF encrypted; then
if $DEBUG; then
echo "Found mimetype for an encrypted email" >> /tmp/disclaimer
echo "Replacement command: sed -i "s/$boundary_flag--/$boundary_flag\n\nEncrypted email\n\n$boundary_flag--/" /tmp/disclaimer.in.$$ " >> /tmp/disclaimer
fi
# add the extra mime boundary with content
`sed -i "s/$boundary_flag--/$boundary_flagnnEncrypted emailnn$boundary_flag--/" in.$$`
fi
$SENDMAIL "$@" <in.$$
exit $?
This script doesn’t use altermime at all, so you don’t need that tool. Instead it does some string manipulation to add an additional multipart section with the plaintext “Encrypted email” and then hands the mail back over to Postfix.
To make this work, follow this guide, but don’t install altermime, ignore the stuff about addresses, you don’t need /etc/postfix/disclaimer.txt and in /etc/postfix/disclaimer, use the above script instead.