Skip to content

Commit

Permalink
Merge 7f50db1 into 47d112c
Browse files Browse the repository at this point in the history
  • Loading branch information
jsf9k committed Dec 4, 2017
2 parents 47d112c + 7f50db1 commit 5f07130
Show file tree
Hide file tree
Showing 4 changed files with 169 additions and 121 deletions.
10 changes: 6 additions & 4 deletions README.md
Expand Up @@ -143,10 +143,12 @@ The following values are returned in `results.csv`:
#### Etc.
* `Syntax Errors` - A list of syntax errors that were detected when
scanning DMARC or SPF records, or checking for STARTTLS support.
* `Errors` - A list of any other errors encountered, such as DNS
failures.
* `Syntax Errors` - A list of syntax errors that were encountered when
analyzing SPF records.
* `Debug` - A list of any other warnings or errors encountered, such
as DNS failures. These can be helpful when determining how
`trustymail` reached its conclusions, and are indispensible for bug
reports.
## Public domain
Expand Down
25 changes: 15 additions & 10 deletions trustymail/cli.py
Expand Up @@ -22,7 +22,7 @@
--spf Only check spf records
--dmarc Only check dmarc records
--json Output is in json format (default csv)
--debug Output should include error messages.
--debug Output should include more verbose logging.
--dns-hostnames=HOSTNAMES A comma-delimited list of DNS servers to query
against. For example, if you want to use
Google's DNS then you would use the
Expand All @@ -35,13 +35,16 @@
Notes:
If no scan type options are specified, all are run against a given domain/input.
"""
from trustymail import __version__

# Built-in imports
import errno
import logging
import docopt
import os
import errno

# Dependency imports
import docopt

# Local imports
from trustymail import __version__
from trustymail import trustymail

# The default ports to be checked to see if an SMTP server is listening.
Expand All @@ -51,8 +54,10 @@
def main():
args = docopt.docopt(__doc__, version=__version__)

log_level = logging.WARN
if args['--debug']:
logging.basicConfig(format='%(message)s', level=logging.DEBUG)
log_level = logging.DEBUG
logging.basicConfig(format='%(asctime)-15s %(message)s', level=log_level)

# Allow for user to input a csv for many domain names.
if args['INPUT'][0].endswith('.csv'):
Expand Down Expand Up @@ -91,10 +96,10 @@ def main():

# User might not want every scan performed.
scan_types = {
"mx": args["--mx"],
"starttls": args["--starttls"],
"spf": args["--spf"],
"dmarc": args["--dmarc"]
'mx': args['--mx'],
'starttls': args['--starttls'],
'spf': args['--spf'],
'dmarc': args['--dmarc']
}

domain_scans = []
Expand Down
66 changes: 33 additions & 33 deletions trustymail/domain.py
Expand Up @@ -17,7 +17,7 @@ def __init__(self, domain_name, timeout, smtp_timeout, smtp_localhost, smtp_port
if self.base_domain_name != self.domain_name:
if self.base_domain_name not in Domain.base_domains:
# Populate DMARC for parent.
domain = trustymail.scan(self.base_domain_name, timeout, smtp_timeout, smtp_localhost, smtp_ports, smtp_cache, {"mx": False, "starttls": False, "spf": False, "dmarc": True}, dns_hostnames)
domain = trustymail.scan(self.base_domain_name, timeout, smtp_timeout, smtp_localhost, smtp_ports, smtp_cache, {'mx': False, 'starttls': False, 'spf': False, 'dmarc': True}, dns_hostnames)
Domain.base_domains[self.base_domain_name] = domain
self.base_domain = Domain.base_domains[self.base_domain_name]
else:
Expand Down Expand Up @@ -47,8 +47,8 @@ def __init__(self, domain_name, timeout, smtp_timeout, smtp_localhost, smtp_port
# 3. Whether or not the server supports STARTTLS
self.starttls_results = {}

# A list of any errors that occurred while scanning records.
self.errors = []
# A list of any debugging information collected while scanning records.
self.debug_info = []

# A list of the ports tested for SMTP
self.ports_tested = set()
Expand All @@ -61,15 +61,15 @@ def has_supports_smtp(self):
Returns True if any of the mail servers associated with this
domain are listening and support SMTP.
"""
return len(filter(lambda x: self.starttls_results[x]["supports_smtp"],
return len(filter(lambda x: self.starttls_results[x]['supports_smtp'],
self.starttls_results.keys())) > 0

def has_starttls(self):
"""
Returns True if any of the mail servers associated with this
domain are listening and support STARTTLS.
"""
return len(filter(lambda x: self.starttls_results[x]["starttls"],
return len(filter(lambda x: self.starttls_results[x]['starttls'],
self.starttls_results.keys())) > 0

def has_spf(self):
Expand Down Expand Up @@ -101,49 +101,49 @@ def parent_dmarc_results(self):

def get_dmarc_policy(self):
# If the policy was never set, or isn't in the list of valid policies, check the parents.
if self.dmarc_policy is None or self.dmarc_policy.lower() not in ["quarantine", "reject", "none"]:
if self.dmarc_policy is None or self.dmarc_policy.lower() not in ['quarantine', 'reject', 'none']:
if self.base_domain is None:
return ""
return ''
else:
return self.base_domain.get_dmarc_policy()
return self.dmarc_policy

def generate_results(self):
mail_servers_that_support_smtp = [x for x in self.starttls_results.keys() if self.starttls_results[x]["supports_smtp"]]
mail_servers_that_support_starttls = [x for x in self.starttls_results.keys() if self.starttls_results[x]["starttls"]]
mail_servers_that_support_smtp = [x for x in self.starttls_results.keys() if self.starttls_results[x]['supports_smtp']]
mail_servers_that_support_starttls = [x for x in self.starttls_results.keys() if self.starttls_results[x]['starttls']]
domain_supports_smtp = bool(mail_servers_that_support_starttls)

results = {
"Domain": self.domain_name,
"Base Domain": self.base_domain_name,
"Live": self.is_live,

"MX Record": self.has_mail(),
"Mail Servers": self.format_list(self.mail_servers),
"Mail Server Ports Tested": self.format_list([str(port) for port in self.ports_tested]),
"Domain Supports SMTP Results": self.format_list(mail_servers_that_support_smtp),
'Domain': self.domain_name,
'Base Domain': self.base_domain_name,
'Live': self.is_live,

'MX Record': self.has_mail(),
'Mail Servers': self.format_list(self.mail_servers),
'Mail Server Ports Tested': self.format_list([str(port) for port in self.ports_tested]),
'Domain Supports SMTP Results': self.format_list(mail_servers_that_support_smtp),
# True if and only if at least one mail server speaks SMTP
"Domain Supports SMTP": domain_supports_smtp,
"Domain Supports STARTTLS Results": self.format_list(mail_servers_that_support_starttls),
'Domain Supports SMTP': domain_supports_smtp,
'Domain Supports STARTTLS Results': self.format_list(mail_servers_that_support_starttls),
# True if and only if all mail servers that speak SMTP
# also support STARTTLS
"Domain Supports STARTTLS": domain_supports_smtp and all([self.starttls_results[x]["starttls"] for x in mail_servers_that_support_smtp]),
'Domain Supports STARTTLS': domain_supports_smtp and all([self.starttls_results[x]['starttls'] for x in mail_servers_that_support_smtp]),

"SPF Record": self.has_spf(),
"Valid SPF": self.valid_spf,
"SPF Results": self.format_list(self.spf),
'SPF Record': self.has_spf(),
'Valid SPF': self.valid_spf,
'SPF Results': self.format_list(self.spf),

"DMARC Record": self.has_dmarc(),
"Valid DMARC": self.has_dmarc() and self.valid_dmarc,
"DMARC Results": self.format_list(self.dmarc),
'DMARC Record': self.has_dmarc(),
'Valid DMARC': self.has_dmarc() and self.valid_dmarc,
'DMARC Results': self.format_list(self.dmarc),

"DMARC Record on Base Domain": self.parent_has_dmarc(),
"Valid DMARC Record on Base Domain": self.parent_has_dmarc() and self.parent_valid_dmarc(),
"DMARC Results on Base Domain": self.parent_dmarc_results(),
"DMARC Policy": self.get_dmarc_policy(),
'DMARC Record on Base Domain': self.parent_has_dmarc(),
'Valid DMARC Record on Base Domain': self.parent_has_dmarc() and self.parent_valid_dmarc(),
'DMARC Results on Base Domain': self.parent_dmarc_results(),
'DMARC Policy': self.get_dmarc_policy(),

"Syntax Errors": self.format_list(self.syntax_errors),
"Errors": self.format_list(self.errors)
'Syntax Errors': self.format_list(self.syntax_errors),
'Debug Info': self.format_list(self.debug_info)
}

return results
Expand All @@ -157,4 +157,4 @@ def format_list(self, record_list):
if not record_list:
return None

return ", ".join(record_list)
return ', '.join(record_list)

0 comments on commit 5f07130

Please sign in to comment.