2

I want to sign outgoing mails automatically with postfix. I've found a script and integrated it into postfix. That works mostly like expected, but it has two bugs and I hope you can help me to fix those.

/home/xxx/sign.sh

#!/bin/bash
WORKDIR="/tmp"
SENDMAIL="/usr/sbin/sendmail -G -i"
EX_UNAVAILABLE=69
SENDER="$2"; RECIPIENT="$4"

MESSAGEFILE="$WORKDIR/message.$$"
trap "rm -f $MESSAGEFILE; rm -f $MESSAGEFILE.signed" 0 1 2 3 15
umask 077
cat > $MESSAGEFILE || { echo Cannot save mail to file; exit $EX_UNAVAILABLE;}
SUBJECT=$(reformail -x "Subject:" < $MESSAGEFILE)
openssl smime -sign -in $MESSAGEFILE -out $MESSAGEFILE.signed -from $SENDER -to $RECIPIENT -subject "$SUBJECT" -signer /home/xxx/sign.crt -inkey /home/xxx/sign_key.crt -text || { echo Problem signing message; exit $EX_UNAVAILABLE; }
$SENDMAIL "$@" < $MESSAGEFILE.signed
exit $?

This is the implementation into postfix:

smtp      inet  n       -       -       -       -       smtpd
  -o content_filter=spamassassin
  -o content_filter=meinfilter:dummy

meinfilter      unix    -       n       n       -       2       pipe
  flags=Rq user=xxx null_sender=
  argv=/home/xxx/sign.sh -f ${sender} -- ${recipient}

The bugs are

  • the subject line is always empty this is caused by missing software dependencies
  • the delivered message has the header doubled (in the normal header and in the message)

Here the raw email header and body. You can notice the double header below

To: xxx
From: xxx
Subject: Testsubject
MIME-Version: 1.0
Content-Type: multipart/signed; protocol="application/x-pkcs7-signature"; micalg="sha-256"; boundary="----2466B05A8CF1ACF5CD6D9B7B8AE72747"

This is an S/MIME signed message

------2466B05A8CF1ACF5CD6D9B7B8AE72747
Content-Type: text/plain

Return-Path: <xxx>
Received: from [127.0.0.1] (xxx [xxx])
    by xxx (Postfix) with ESMTPSA id xxx
    for <xxx>; Fri, 13 Sep 2013 02:49:22 +0000 (UTC)
Message-ID: <xxx>
Date: Fri, 13 Sep 2013 04:49:21 +0200
From: xxx
User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64; rv:17.0) Gecko/20130801 Thunderbird/17.0.8
MIME-Version: 1.0
To: xxx
Subject: Testsubject
Content-Type: text/plain; charset=ISO-8859-15; format=flowed
Content-Transfer-Encoding: 7bit

Testmessage

------2466B05A8CF1ACF5CD6D9B7B8AE72747
Content-Type: application/x-pkcs7-signature; name="smime.p7s"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="smime.p7s"

LONGTEXTLONGTEXTWITHPUBLICKEYLONGTEXTLONGTEXTWITHPUBLICKEY
LONGTEXTLONGTEXTWITHPUBLICKEYLONGTEXTLONGTEXTWITHPUBLICKEY
LONGTEXTLONGTEXTWITHPUBLICKEYLONGTEXTLONGTEXTWITHPUBLICKEY
...
LONGTEXTLONGTEXTWITHPUBLICKEYLONGTEXTLONGTEXTWITHPUBLICKEY
LONGTEXTLONGTEXTWITHPUBLICKEYLONGTEXTLONGTEXTWITHPUBLICKEY
LONGTEXTLONGTEXTWITHPUBLICKEYLONGTEXTLONGTEXTWITHPUBLICKEY

How could these two problems this problem be solved?

  • I don't see any missing or duplicate headers in your paste. That said, I'm not entirely sure why you would need to explicitely pass "-to", "-from" and "-subject" to openssl smime. Did you try simply leaving these out: openssl smime -sign -in $MESSAGEFILE -out $MESSAGEFILE.signed -signer ...? – Stefan Förster Sep 13 '13 at 10:32
  • I've only posted the displayed message. The "normal" header is not displayed in the message. Now I've found out, that the script is also signing incoming emails, is there any possibility to sign only outgoing mails? The empty subject line was just a problem of missing software which was not described in the logfiles. – user2626702 Sep 13 '13 at 12:34
1

If you do not want the plain text headers added to your signed email remove the -text option from the openssl command in the sign.sh script. As stated here

-text this option adds plain text (text/plain) MIME headers to the supplied message if encrypting or signing. If decrypting or verifying it strips off text headers: if the decrypted or verified message is not of MIME type text/plain then an error occurs.

To only sign outgoing email, I think what you'll want to do is enable the submission port (587) or smtps (465) in your master.cf and move the -o content_filter=meinfilter:dummy to that port only

#submission
submission inet n - n - - smtpd
-o content_filter=meinfilter:dummy

That means only mail that is submitted on that port, which is usually associated with TLS and authentication, will be signed by your script. You might also want to ensure that only authenticated, TLS encrypted connections are allowed to relay through your server.

  • The duplication was result of the script provided by OP. You can try to execute the script yourself. – tpml7 Jan 2 '15 at 13:49
  • So, you're saying that Stefan's assumption is correct? That he is passing too many variables to openssl smime? – NickW Jan 2 '15 at 14:00
  • I don't have any experience with S/MIME-signing by MTA. Usually (1) this signing happened at MUA level and (2) MUA just sign the body not the header too. You can track the article where the script origin at softed.de/blog/index.php/… – tpml7 Jan 2 '15 at 14:07
  • I've seen signing on the MTA level, and the MUA level, the problem is this option here -text this option adds plain text (text/plain) MIME headers to the supplied message if encrypting or signing. If decrypting or verifying it strips off text headers: if the decrypted or verified message is not of MIME type text/plain then an error occurs. as per the openssl smime page openssl.org/docs/apps/smime.html – NickW Jan 2 '15 at 14:24
  • Using the same method, "-text" thwarts correct display of HTML emails. If you drop "-text", the signature refers to different content, and the receiving MUA reports “bad signature”. – Torsten Bronger Jan 16 '18 at 11:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.