9

sendmail lets one place restrictions on TLS conversations. I want to check that messages sent to example.com are sent to a server that has a *.messagelabs.com certificate. I want to protect against DNS spoofing and MitM. If messagelabs only had one server that would be easy:

TLS_Rcpt:example.com VERIFY:256+CN:mx.messagelabs.com

However messagelabs has a lot of servers and clusters of different servers with unique IPs and certs for the same name. All that is fine, I just want to check that server I'm giving the mail to is certified to belong to messagelabs.

I have tried

TLS_Rcpt:example.com VERIFY:256+CN:messagelabs.com
TLS_Rcpt:example.com VERIFY:256+CN:*.messagelabs.com
TLS_Rcpt:example.com VERIFY:256+CN:.*.messagelabs.com

but I get errors like

CN mail31.messagelabs.com does not match .*.messagelabs.com

How can I do this? This is a recurrent request for us (mostly for configs like TLS_Rcpt:example.com VERIFY:256+CN:*.example.com), so I'd be ready to modify sendmail.cf, but I can't make sense of

STLS_req
R $| $+         $@ OK
R<CN> $* $| <$+>                $: <CN:$&{TLS_Name}> $1 $| <$2>
R<CN:$&{cn_subject}> $* $| <$+>         $@ $>"TLS_req" $1 $| <$2>
R<CN:$+> $* $| <$-:$+>  $#error $@ $4 $: $3 " CN " $&{cn_subject} " does not match " $1
R<CS:$&{cert_subject}> $* $| <$+>       $@ $>"TLS_req" $1 $| <$2>
R<CS:$+> $* $| <$-:$+>  $#error $@ $4 $: $3 " Cert Subject " $&{cert_subject} " does not match " $1
R<CI:$&{cert_issuer}> $* $| <$+>        $@ $>"TLS_req" $1 $| <$2>
R<CI:$+> $* $| <$-:$+>  $#error $@ $4 $: $3 " Cert Issuer " $&{cert_issuer} " does not match " $1
ROK                     $@ OK

Sendmail 8.14.7 (upgrading to 8.15.2 soon).

8
  • So, no answers (yet?) I'd try to answer it myself, but I'm not sure if a day or so to integrate chapter 28 of the sendmail book is enough time or would even yield the answer.
    – Law29
    Commented Nov 19, 2015 at 23:25
  • 2
    I don't have enough confidence to provide a definitive answer but I don't think wildcards are supported as per the "Limitation in current implementation" section of this blog post: security-skywalker.blogspot.com/2013/01/…
    – Mike B
    Commented Nov 20, 2015 at 16:49
  • ...and yes, I'm aware that "wildcard certs" are different from wildcard matching pattern functionality that you're looking for but the article highlights the static nature of that feature. :-)
    – Mike B
    Commented Nov 20, 2015 at 16:58
  • Maybe your answer is not definitive, but it's the best I've found (for some reason I hadn't found that that blog post, thank you for bringing it to my attention)
    – Law29
    Commented Nov 20, 2015 at 23:13
  • Would you like to test support for CNRE tag? It would test $&{cn_subject} against your custom regular expression. Commented Jan 29, 2016 at 15:00

2 Answers 2

1

Make sendmail.cf store ${cn_subject} with host part stripped in ${cn1_subject}.
It makes finishing the implementation almost trivial.

WARNING: Ask for opinions at news:comp.mail.sendmail before deploying it in not test environment. It MAY work but sendmail makes avoiding "unexpected side effects" MUCH MORE painstaking than I am ready to "invest". I "dry tested" it with sendmail-8.15.2.

access entry:

TLS_Rcpt:example.com VERIFY:256+CN1:messagelabs.com

sendmail.mc fix to support above entry

WARNING: remember about TAB (\t) between RHS and LHS in R lines.
It is more dirty implementation via sendmail.mc only.

define(`_LOCAL_TLS_RCPT_')dnl
LOCAL_RULESETS
SLocal_tls_rcpt
R$*     $: $&{cn_subject}
R$-.$+  $@ $(macro {cn1_subject}  $@ $2 $)
R$*     $@ $(macro {cn1_subject}  $@ $)    

# Ruleset continued
STLS_req
R<CN1:$&{cn1_subject}> $* $| <$+>               $@ $>"TLS_req" $1 $| <$2>
R<CN1:$+> $* $| <$-:$+> $#error $@ $4 $: $3 " CN-1 " $&{cn_subject} " does not match " $1
ROK                     $@ OK
divert(0)dnl

Explanation:

  1. Make Local_tls_rcpt rule-set store ${cn_subject} with "before first dot" part stripped in ${cn1_subject}
  2. Add checks of ${cn1_subject} triggered by CN1 prefix in "extra part" of TLS_req rule-set

Sample script to test it

#!/bin/sh
# -C sendmail-test.cf -- use non standard cf file
# -d60.5 -- trace (access) map lookus
# -d21.12 -- trace R lines rewriting 
sendmail -C sendmail-test.cf -bt -d60.5 <<END
.D{verify}OK
.D{cn_subject}mail31.messagelabs.com
.D{server_name}mail31.messagelabs.com
tls_rcpt [email protected]
END
1
  • Accepted this even though I haven't tested it yet; it was exactly what I believed must be possible but couldn't manage to find out how to do.
    – Law29
    Commented Mar 5, 2016 at 23:42
1

This isn't exactly an answer to the question as posed, but it looks to me like you are doing things the hard way.

The Sendmail configuration was written in a way that prioritises ease and efficiency for the software parsing that configuration, not for easy configuration and maintenance by humans. There's simply been no good reason to do that in recent decades.

Sendmail was a horribly arcane relic 15 years ago. Some linux distribbutions still provide it by default, and that's fine if the default config works for you, but as soon as you find yourself doing anything that takes more than a few minutes, you're best to throw sendmail out and install a modern MTA.

About 15 years ago, qmail might still have been a sensible replacement, but for almost that long I've considered postfix a better choice. The documentation from the postfix.org site is good once you find the bit you need. In your case you'll want http://www.postfix.org/TLS_README.html for this problem.

I realise you'll quite likely have spent some time solving a few problems in sendmail already, but rather than throwing more time down that hole, switch at the earliest opportunity. If you ever look back you'll cringe.

1
  • Actually I've been administering postfix longer than I have been administering sendmail, for $reasons, and I today have some 16 core sendmail servers in a passably customized environment that's not that easy to change. Upgrading to the last version is a matter of minutes, but changing is another matter. However you are correct that using a postfix "smtp_tls_policy_maps" containing "example.com secure match=.messagelabs.com" does seem like it would provide the security I'm looking for. That use case might actually provide me the reason I need to spend the time necessary to change over.
    – Law29
    Commented Jan 17, 2016 at 15:45

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .