#!/usr/bin/python3

import sys
import os
from subprocess import Popen, PIPE
from datetime import datetime, timedelta

default_pki_dirs = [
    "/etc/pki/httpd",
    "/etc/pki/dovecot",
    "/etc/pki/postfix",
    "/etc/pki/mysql"
]

def ssl_end_date(crt):
    cert = open(crt, "rb").read()
    end_date = Popen(
        "openssl x509 -enddate -noout".split(),
        stdin=PIPE, stdout=PIPE
    ).communicate(cert)[0]
    # notAfter=May 12 05:19:41 2032 GMT
    return datetime.strptime(
        end_date.strip().decode("utf8").split("=", 1)[-1],
        "%b %d %H:%M:%S %Y GMT"
    )

def kv_str(d):
    return ", ".join(["%s:%s" % (k, v) for k, v in d.items()])

if __name__ == "__main__":
    rets = dict(
        ok = {},
        warning = {},
        critical = {}
    )

    if sys.argv[1:]:
        default_pki_dirs = sys.argv[1:]
    #else:
    #    # add mod_md domains
    #    mod_md_dir = "/var/lib/httpd/md/domains"
    #    if os.path.isdir(mod_md_dir):
    #        default_pki_dirs.extend([
    #            os.path.join(mod_md_dir, x)
    #            for x in os.listdir(mod_md_dir)
    #        ])

    for pki_dir in default_pki_dirs:
        if not os.path.isdir(pki_dir):
            continue  # skip missing directories
        try:
            subdirs = os.listdir(pki_dir)
        except IOError as err:
            print("CRT CRITICAL - %s" % err.strerror)
            sys.exit(2)
        except OSError as err:
            print("CRT CRITICAL - %s" % err.strerror)
            sys.exit(2)
        for crtfn in subdirs:
            if crtfn.endswith(".crt") or crtfn=="pubcert.pem":
                crt = os.path.join(os.path.basename(pki_dir), crtfn)
                try:
                    dt_end = ssl_end_date(os.path.join(pki_dir, crtfn))
                    dt_now = datetime.now()
                    diff = (dt_end-dt_now).days
                except IOError as err:
                    rets["critical"][crt] = err.strerror
                    continue
                except OSError as err:
                    rets["critical"][crt] = err.strerror
                    continue
                if diff<=14:
                    rets["critical"][crt] = diff
                elif diff<=31:
                    rets["warning"][crt] = diff
                else:
                    rets["ok"][crt] = diff
    #print(default_pki_dirs)
    #print(rets)

    if rets["critical"]:
        print("CRT CRITICAL - %s" % kv_str(rets["critical"]))
        sys.exit(2)
    elif rets["warning"]:
        print("CRT WARNING - %s" % kv_str(rets["warning"]))
        sys.exit(1)
    else:
        print("CRT OK - %s" % kv_str(rets["ok"]))
        sys.exit(0)

