Skip to content

Sanitizing email recipient list

wordpress meta

title: 'Sanitizing Email Recipient List'
date: '2013-12-30T15:27:19-06:00'
status: publish
permalink: /sanitizing-email-recipient-list
author: admin
excerpt: ''
type: post
id: 524
category:
    - Python
    - Sendmail
tag: []
post_format: []

I wrote a couple articles on respectively using sendmail and postfix to block outbound email and only allow selective domains and selective email addresses. I ran into problems with both sendmail and postfix doing exactly what I want. Sendmail was fairly easy to satisfy the requirements for forwarding only to certain domains. Postfix got very close on doing domains plus a selective few email addresses. I could not get the multi instance postfix method working 100% with my header checks though.

Below is another method to sanitize outbound email addresses using python smtplib and sendmail.

Sendmail answer on non standard port:

root@myhost:/etc/mail/cf/cf# more usla-utility.mc
divert(-1)
...
divert(0)dnl
VERSIONID(`sendmail.mc (Sun)')
OSTYPE(`solaris11')dnl
DOMAIN(`solaris-generic')dnl
DAEMON_OPTIONS(`Port=10026,Addr=127.0.0.1, Name=MTA')dnl
MASQUERADE_AS(`arbonne.com')
FEATURE(masquerade_envelope)
FEATURE(`mailertable')
MAILER(`local')dnl<br />

root@myhost:/etc/mail/cf/cf# /usr/ccs/bin/m4 ../m4/cf.m4 myhost.mc > /etc/mail/sendmail.cf

I needed some specific transports so I have a mailertable:

root@myhost:/etc/mail# makemap hash mailertable < mailertable

Run a small python smtplib SMTP forwarder on port 25:

More information here: http://docs.python.org/2/library/smtplib.html#smtp-example

Run python in the background:

root@myhost:# nohup python sanitizer.py &

My code snippet to sanitize. Probably need to look at CC and BCC also.

...
allowedDomains = ['domain1.com','domain2.com','domain3.com','domain4.com']
      allowedRecipients = ['user@domain5.com']
      for rcpt in rcpttos[:]:
        user,domain = rcpt.split("@")
        if not (rcpt.lower() in allowedRecipients or domain.lower() in allowedDomains):
          #log.debug("%s not allowed per our policy" % rcpt)
          i = rcpttos[:].index(rcpt)
          del rcpttos[i]
      log.debug("sanitized list %s" % rcpttos)
...

Monitor the custom log:

root@myhost:~# tail -f sanitizer.log 
... DEBUG:__main__:Received message from: ('10.1.11.86', 32841). From: root@myclient | To: ['user1@domain1.com', 'user2@domain2.com', 'user3@domain3.com', 'user4@domain1.com'] DEBUG:__main__:sanitized list ['user3@domain3.com']

Inject a test from client:

root@myclient:/tmp# cat /tmp/test_all.eml
To: user1@domain1.com,user2@domain2.com,user3@domain3.com,user4@domain1.com 
Subject: MAILHOST TEST DL
From: luser@mydomain.com
body...

root@myclient:/tmp# sendmail -d7.99 -d38.99 -vt < /tmp/test_all.eml

Monitor the real maillog of sendmail to see what happened: