#!/usr/bin/env python import sys from pprint import pformat import requests import pyquery import ssl import OpenSSL from urlparse import urlparse, urljoin from datetime import datetime, timedelta from pytz import UTC import logging logging.getLogger().setLevel(logging.DEBUG) class AttrDict(dict): def __init__(self, *a, **kw): dict.__init__(self, *a, **kw) self.__dict__ = self derp = AttrDict() def die(reason): raise SystemExit(reason) def interact(): import code code.InteractiveConsole(locals=globals()).interact() class CertificateProblem(Exception): pass class ReachabilityProblem(Exception): pass def decode_ossl_time(t): f = '%Y%m%d%H%M%SZ' return datetime.strptime(t, f) class SSLCert(object): def __init__(self,x): self.x = x def notBefore(self): return decode_ossl_time(self.x.get_notBefore()) def notAfter(self): return decode_ossl_time(self.x.get_notAfter()) def commonName(self): t = self.x.get_subject().get_components() for x in t: if x[0] == "CN": return x[1] def expired(self): return datetime.utcnow() > self.notAfter() def tooEarly(self): return datetime.utcnow() < self.notBefore() def validTime(self): if not self.expired() and not self.tooEarly(): return True return False def expiresSoon(self): week = timedelta(days=7) then = datetime.utcnow() + week return then > self.notAfter() def check_url(url): r = requests.get(url,verify=True) if r.status_code is not 200: raise ReachabilityProblem cert = cert_for_url(url) def cert_for_url(url): o = urlparse(url) if o.scheme != 'https': return None if not o.port: p = 443 else: p = o.port c = ssl.get_server_certificate((o.hostname, p)) return SSLCert( OpenSSL.crypto.load_certificate( OpenSSL.crypto.FILETYPE_PEM, c ) ) def main(): if len(sys.argv) < 2: print "usage: %s " % sys.argv[0] sys.exit(1) do_checks(sys.argv[1]) def do_checks(starturl): urlqueue = [] urlqueue.append(starturl) while len(urlqueue): urlqueue.extend(check_url(urlqueue.pop())) if __name__ == '__main__': main()