#!/usr/bin/env python # -*- coding: utf-8 -*- # # check_cert.py -- Petit mail de vérification du certificat d'un serveur # ce script vérifie principalement la date d'expiration et envoie un mail # d'avertissement si celle-ci est proche (paramétrable) # # Copyright (c) 2013 Daniel STAN # Authors: Daniel STAN # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from M2Crypto import SSL from M2Crypto import X509 import ssl import socket import time import datetime import sys # Envoyer des mails from email.mime.text import MIMEText import smtplib # # Config ! # host = 'localhost' port = 443 filename = False # if True, port ignored and host is in fact a path # afficher la sortie plutôt que l'envoyer: verb = False # delai d'avertissement delay = datetime.timedelta(days=15) # infos mails mail_src = 'root@crans.org' mail_dest = "roots@crans.org" mail_host = 'localhost' # # Argument parsing ! # # TODO argparse + doc for arg in sys.argv[1:]: if arg == '-v': verb = True continue if arg == '--filename': filename = True try: port = int(arg) except ValueError: host = arg # # Getting cert ! # if filename: cert = X509.load_cert(host) elif port != 25: conn = SSL.Connection(SSL.Context()) try: conn.connect((host, port)) except SSL.Checker.WrongHost: if host != 'localhost': raise cert = conn.get_peer_cert() conn.close() expire_date = cert.get_not_after().get_datetime() subject = cert.get_subject.as_text() try: altname = "(alt: %s)" % cert.get_ext('subjectAltName').get_value() except LookupError: altname = "" else: smtp = socket.socket() smtp.connect((host, port)) resp = smtp.recv(4096) smtp.send("EHLO localhost\n") resp = smtp.recv(4096) smtp.send("STARTTLS\n") resp = smtp.recv(4096) smtp = ssl.wrap_socket(smtp, cert_reqs=ssl.CERT_REQUIRED, ca_certs="/etc/ssl/certs/ca-certificates.crt") cert = smtp.getpeercert() # DROOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOGUES expire_date = datetime.datetime.fromtimestamp(time.mktime(time.strptime(cert['notAfter'], "%b %d %H:%M:%S %Y %Z"))) subject = cert["subject"][0][0][1].decode("UTF-8") altname = "" # # Real computation (woah !) # now = datetime.datetime.now(expire_date.tzinfo) if now + delay > expire_date or verb: short_sub = subject subject += altname msg = MIMEText(u"""Attention, le certificat suivant arrive bientôt à expiration :\n%s\n Temps avant expiration: %s""" % (subject,(expire_date - now)), _charset="utf-8") msg['From'] = mail_src msg['To'] = mail_dest msg['Subject'] = u"Expiration imminente du certificat %s" % short_sub if not verb: conn = smtplib.SMTP(mail_host) conn.sendmail(mail_src, mail_dest, msg.as_string()) conn.quit() else: print msg.get_payload(decode=True)