From 8857302347afacff6673fcabadde713126c012ca Mon Sep 17 00:00:00 2001 From: Jacob Hoffman-Andrews Date: Wed, 4 Jun 2014 14:41:18 -0700 Subject: [PATCH] check-starttls and process-google-starttls-domains.py --- check-starttls.py | 94 ++++++++++++++++++++++++++++++ process-google-starttls-domains.py | 18 ++++++ 2 files changed, 112 insertions(+) create mode 100755 check-starttls.py create mode 100755 process-google-starttls-domains.py diff --git a/check-starttls.py b/check-starttls.py new file mode 100755 index 000000000..15bc7ce64 --- /dev/null +++ b/check-starttls.py @@ -0,0 +1,94 @@ +#!/usr/bin/python +import sys +import os +import errno +import smtplib +import socket +import subprocess +import re + +import dns.resolver +from M2Crypto import X509 + +def mkdirp(path): + try: + os.makedirs(path) + except OSError as exc: + if exc.errno == errno.EEXIST and os.path.isdir(path): + pass + else: raise + +def extract_names(pem): + leaf = X509.load_cert_string(pem, X509.FORMAT_PEM) + + """Extracts a list of DNS names associated with the leaf cert.""" + subj = leaf.get_subject() + # Certs have a "subject" identified by a Distingushed Name (DN). + # Host certs should also have a Common Name (CN) with a DNS name. + common_names = subj.get_entries_by_nid(subj.nid['CN']) + common_names = [name.get_data().as_text() for name in common_names] + try: + # The SAN extension allows one cert to cover multiple domains + # and permits DNS wildcards. + # http://www.digicert.com/subject-alternative-name.htm + # The field is a comma delimited list, e.g.: + # >>> twitter_cert.get_ext('subjectAltName').get_value() + # 'DNS:www.twitter.com, DNS:twitter.com' + alt_names = leaf.get_ext('subjectAltName').get_value() + alt_names = alt_names.split(',') + alt_names = [name.partition(':') for name in alt_names] + alt_names = [name for prot, _, name in alt_names if prot == 'DNS'] + except: + alt_names = [] + return set(common_names + alt_names) + +def tls_connect(mx_host, mail_domain): + # smtplib doesn't let us access certificate information, + # so shell out to openssl. + output = subprocess.check_output( + """openssl s_client \ + -CApath /usr/share/ca-certificates/mozilla/ \ + -starttls smtp -connect %s:25 -showcerts 0: + print "iiii ", len(cert) + print extract_names(cert[0]) + #lines = output.split("\n") + #for i in range(0, len(lines)): + #line = lines[i] + #if re.search("Subject:.* CN=(.*)", line): + #m = re.search("Subject:.* CN=(.*)", line) + #print "CN=", m.group(1) + #elif re.search("Subject Alternative Name:", line): + #dns = re.findall("DNS:([^,]*),", lines[i+1]) + #for d in dns: + #print d + +# try: +# smtpserver = smtplib.SMTP(mx_host, 25, timeout = 2) +# smtpserver.ehlo() +# smtpserver.starttls() +# print "Success: %s" % mx_host +# except socket.error as e: +# print "Connection to %s failed: %s" % (mx_host, e.strerror) +# pass + +def check(mail_domain): + mkdirp(mail_domain) + answers = dns.resolver.query(mail_domain, 'MX') + for rdata in answers: + mx_host = str(rdata.exchange) + print 'Host', rdata.exchange, 'has preference', rdata.preference + tls_connect(mx_host, mail_domain) + +if len(sys.argv) == 1: + print("Please pass at least one mail domain as an argument") + +for domain in sys.argv[1:]: + check(domain) diff --git a/process-google-starttls-domains.py b/process-google-starttls-domains.py new file mode 100755 index 000000000..0a0201875 --- /dev/null +++ b/process-google-starttls-domains.py @@ -0,0 +1,18 @@ +#!/usr/bin/python +import csv +import codecs +import sys +from collections import defaultdict + +csvreader = csv.reader(codecs.open(sys.argv[1], "rU", "utf-8"), delimiter=',', quotechar='"') +d = defaultdict(set) +for (address_suffix, hostname_suffix, direction, region, fraction_encrypted) in csvreader: + if direction == "outbound": + try: + d[address_suffix].add(float(fraction_encrypted)) + except ValueError: + pass + +for address_suffix, fraction_encrypted in d.iteritems(): + if min(fraction_encrypted) >= 0.50: + print min(fraction_encrypted), address_suffix