Skip to content

Instantly share code, notes, and snippets.

@jpluimers
Created March 1, 2018 19:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jpluimers/b0771666bd5942352afdc84ae8c37489 to your computer and use it in GitHub Desktop.
Save jpluimers/b0771666bd5942352afdc84ae8c37489 to your computer and use it in GitHub Desktop.
Gets SMTP message size for the MX servers for one or more domains using the EHLO command
## Based on
## - https://erlerobotics.gitbooks.io/erle-robotics-python-gitbook-free/smtp/getting_information_from_ehlo.html
## - https://programtalk.com/python-examples/dns.resolver.query/
## Example usage:
## python ehlo-size.py google.com outlook.com
## python ehlo-size.py aol.com
## Requires:
## pip install dnspython
## On Mac OS X, do not use `brew install pip` as then you have two different Python installations
## Instead:
## sudo easy_install pip
## sudo pip install --update pip
## sudo pip install dnspython
import sys, smtplib, socket, dns.resolver
if len(sys.argv) < 2:
print "usage: %s domain..." % sys.argv[0]
sys.exit(1)
domains = sys.argv[1:]
domainsLength = len(domains)
singleDomain = domainsLength == 1
for domain in domains:
try:
## use `answers` outside and `rdata` in the loop as that is what DNS folks call it:
## - http://www.zytrax.com/books/dns/ch15/#rdata
answers = dns.resolver.query(domain, 'MX')
answers = sorted(answers) ## sorts on preference; might want this more clear using https://github.com/linkedin/iris/blob/master/src/iris/vendors/iris_smtp.py#L46 or https://developers.google.com/edu/python/sorting
for rdata in answers:
allMxForDomainFailed = True
try:
mx = rdata.exchange
priority = rdata.preference
server = mx.to_text() ## to prevent 'Name' object has no attribute 'find', see https://stackoverflow.com/questions/48071359/why-do-mxrecord-should-be-change-to-string
s = smtplib.SMTP(server)
code = s.ehlo()[0]
uses_esmtp = (200 <= code <= 299)
if not uses_esmtp:
code = s.helo()[0]
if not (200 <= code <= 299):
print "Remote server refused HELO; code:", code
sys.exit(1)
if uses_esmtp and s.has_extn('size'):
maximumMessageSize = s.esmtp_features['size']
if maximumMessageSize == '':
print("Undefined aximum message size for domain {0} MX priority {1} SMTP server {2}".format(domain, priority, server))
else:
print("Maximum message size is {0} bytes for domain {1} MX priority {2} SMTP server {3}".format(maximumMessageSize, domain, priority, server))
else:
print("No defined maximum message size for domain {0} MX priority {1} SMTP server {2}".format(domain, priority, server))
allMxForDomainFailed = False
except (socket.gaierror, socket.error, socket.herror,
smtplib.SMTPException), e:
print("Error when executing EHLO command for domain {0} on SMTP server {1}".format(domain, server))
print e
if singleDomain:
sys.exit(2)
if allMxForDomainFailed:
print("All MX for domain {0} failed.".format(domain))
sys.exit(1)
except Exception as e:
print("Error when querying MX records to obtain SMTP servers for domain {0}".format(domain))
print e
if singleDomain:
sys.exit(4)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment