104 lines
2.3 KiB
Python
Executable File
104 lines
2.3 KiB
Python
Executable File
#!/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 <url>" % 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()
|