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

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).

  • 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
    Nov 19 '15 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
    Nov 20 '15 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
    Nov 20 '15 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
    Nov 20 '15 at 23:13
  • Would you like to test support for CNRE tag? It would test $&{cn_subject} against your custom regular expression.
    – AnFi
    Jan 29 '16 at 15:00

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.

R$*     $: $&{cn_subject}
R$-.$+  $@ $(macro {cn1_subject}  $@ $2 $)
R$*     $@ $(macro {cn1_subject}  $@ $)    

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


  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

# -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
tls_rcpt user1@example.com
  • 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
    Mar 5 '16 at 23:42

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.

  • 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
    Jan 17 '16 at 15:45

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.