Created
March 1, 2018 19:59
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
## 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