From a07580a1161995220e8f96c8bcc15305615a1ae2 Mon Sep 17 00:00:00 2001 From: Yannik Schmidt Date: Mon, 9 Jan 2023 17:08:16 +0100 Subject: [PATCH] feat: checkscript for imap & smpt --- check_smtp_imap.py | 108 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) create mode 100644 check_smtp_imap.py diff --git a/check_smtp_imap.py b/check_smtp_imap.py new file mode 100644 index 0000000..59439dd --- /dev/null +++ b/check_smtp_imap.py @@ -0,0 +1,108 @@ +#!/usr/bin/python3 + +import smtplib, ssl +import sys +import secrets +import datetime +import argparse +import socket +import time +import imaplib +import json + +def exit(status, info): + print("{}{}".format(status, info)) + if status == "OK": + sys.exit(0) + elif status == "WARNING": + sys.exit(2) + else: + sys.exit(1) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description='Email STMP/IMAP Monitor', + formatter_class=argparse.ArgumentDefaultsHelpFormatter) + + parser.add_argument("--target", required=True, help="Target Server to check") + parser.add_argument("--sender", required=True, help="Sender Email to use") + parser.add_argument("--receiver", required=True, help="Receiver Mail (must exits on target)") + parser.add_argument("--imap-user", help="IMAP User for receiver Mail") + parser.add_argument("--imap-pass", required=True, help="IMAP Password for receiver Mail") + parser.add_argument("--port", default=587, help="Target (START_TLS) port") + + args = parser.parse_args() + imap_user = args.imap_user + if not imap_user: + imap_user = args.receiver + + challenge = { + "time" : datetime.datetime.now().timestamp(), + "token" : secrets.token_urlsafe(), + "origin" : socket.gethostname(), + } + + message = message = 'Subject: Monitoring Challenge\n\n{}dd'.format(json.dumps(challenge)) + + context = ssl.create_default_context() + + # send mail # + server = smtplib.SMTP(args.target, args.port) + server.starttls(context=context) + server.sendmail(args.sender, args.receiver, message) + + # give server some time to deliver # + time.sleep(5) + + # check imap # + for x in range(0,5): + + with imaplib.IMAP4_SSL(args.target) as imap: + imap.login(imap_user, args.imap_pass) + imap.select('INBOX') + status, messages = imap.search(None, 'ALL') + + # check search status # + if not status == "OK": + exit("CRITICAL", "IMAP search failed") + + for message in messages[0].split(b' '): + + status, data = imap.fetch(message, '(RFC822)') + + # check search status # + if not status == "OK": + exit("CRITICAL", "IMAP fetch failed") + + # parse mail + info = None + body = None + + # ignore badly formated messages # + try: + body = data[0][1].decode("utf-8").split("\r\n")[-2] + except IndexError: + continue + + # ignore badly formated messages (json-body) # + try: + info = json.loads(body) + except json.decoder.JSONDecodeError: + continue + + # ignore mail if it's not ours otherwise cleanup # + if info["origin"] != challenge["origin"]: + continue + else: + imap.store(message, '+FLAGS', '\\Deleted') + + if info["token"] == challenge["token"]: + exit("OK", "") + + imap.logout() + + # backoff and try again # + time.sleep(10) + + # if we didn't find anything # + exit("CRITICAL", "Challange not found via IMAP")