
Le commit introduisait starttls mait pétait tout le reste ... Rajouts de commentaires pour espérer qu'on ne casse plus ce script...
135 lines
3.9 KiB
Python
Executable file
135 lines
3.9 KiB
Python
Executable file
#!/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 <daniel.stan@crans.org>
|
|
#
|
|
# 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 <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
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
|
|
|
|
# Va-t-on faire du starttls ?
|
|
# pour l'instant, uniquement pour smtp, mais on peut imaginer étendre à
|
|
# l'avenir à d'autre protocole (xmpp en aurait bien besoin par exemple)
|
|
starttls = (port == 25)
|
|
|
|
#
|
|
# Getting cert ! (sauf starttls)
|
|
#
|
|
if filename:
|
|
cert = X509.load_cert(host)
|
|
elif not starttls:
|
|
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()
|
|
#
|
|
# Getting subject, altname et expire_date
|
|
#
|
|
# Sans starttls, pour les fichiers simples comme pour les connexions
|
|
if not starttls:
|
|
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 = ""
|
|
# Avec starttls, on fait totalement autre chose (et on n'utilise pas la variable
|
|
# cert d'au dessus)
|
|
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)
|
|
|