mirror of https://github.com/CIRCL/AIL-framework
fix: [MailExporter] improve logs + SMTP over SSL: add an option to validate self signed CA
This exporter use STARTTLS by defaults. If the SMTP server does not support the STARTTLS extension, the client will switch to SSL instead.pull/604/head
parent
4f79944b24
commit
4eb5b4c4b9
|
@ -8,9 +8,12 @@ Import Content
|
||||||
|
|
||||||
"""
|
"""
|
||||||
import os
|
import os
|
||||||
|
import logging
|
||||||
|
import logging.config
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from abc import ABC
|
from abc import ABC
|
||||||
|
from ssl import create_default_context
|
||||||
|
|
||||||
import smtplib
|
import smtplib
|
||||||
from email.mime.multipart import MIMEMultipart
|
from email.mime.multipart import MIMEMultipart
|
||||||
|
@ -22,17 +25,22 @@ sys.path.append(os.environ['AIL_BIN'])
|
||||||
##################################
|
##################################
|
||||||
# Import Project packages
|
# Import Project packages
|
||||||
##################################
|
##################################
|
||||||
|
from lib import ail_logger
|
||||||
from exporter.abstract_exporter import AbstractExporter
|
from exporter.abstract_exporter import AbstractExporter
|
||||||
from lib.ConfigLoader import ConfigLoader
|
from lib.ConfigLoader import ConfigLoader
|
||||||
# from lib.objects.abstract_object import AbstractObject
|
# from lib.objects.abstract_object import AbstractObject
|
||||||
# from lib.Tracker import Tracker
|
# from lib.Tracker import Tracker
|
||||||
|
|
||||||
|
logging.config.dictConfig(ail_logger.get_config(name='modules'))
|
||||||
|
|
||||||
|
|
||||||
class MailExporter(AbstractExporter, ABC):
|
class MailExporter(AbstractExporter, ABC):
|
||||||
def __init__(self, host=None, port=None, password=None, user='', sender=''):
|
def __init__(self, host=None, port=None, password=None, user='', sender='', cert_required=None, ca_file=None):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
config_loader = ConfigLoader()
|
config_loader = ConfigLoader()
|
||||||
|
|
||||||
|
self.logger = logging.getLogger(f'{self.__class__.__name__}')
|
||||||
|
|
||||||
if host:
|
if host:
|
||||||
self.host = host
|
self.host = host
|
||||||
self.port = port
|
self.port = port
|
||||||
|
@ -45,6 +53,15 @@ class MailExporter(AbstractExporter, ABC):
|
||||||
self.pw = config_loader.get_config_str("Notifications", "sender_pw")
|
self.pw = config_loader.get_config_str("Notifications", "sender_pw")
|
||||||
if self.pw == 'None':
|
if self.pw == 'None':
|
||||||
self.pw = None
|
self.pw = None
|
||||||
|
if cert_required is not None:
|
||||||
|
self.cert_required = bool(cert_required)
|
||||||
|
self.ca_file = ca_file
|
||||||
|
else:
|
||||||
|
self.cert_required = config_loader.get_config_boolean("Notifications", "cert_required")
|
||||||
|
if self.cert_required:
|
||||||
|
self.ca_file = config_loader.get_config_str("Notifications", "ca_file")
|
||||||
|
else:
|
||||||
|
self.ca_file = None
|
||||||
if user:
|
if user:
|
||||||
self.user = user
|
self.user = user
|
||||||
else:
|
else:
|
||||||
|
@ -67,8 +84,12 @@ class MailExporter(AbstractExporter, ABC):
|
||||||
smtp_server = smtplib.SMTP(self.host, self.port)
|
smtp_server = smtplib.SMTP(self.host, self.port)
|
||||||
smtp_server.starttls()
|
smtp_server.starttls()
|
||||||
except smtplib.SMTPNotSupportedError:
|
except smtplib.SMTPNotSupportedError:
|
||||||
print("The server does not support the STARTTLS extension.")
|
self.logger.info(f"The server {self.host}:{self.port} does not support the STARTTLS extension.")
|
||||||
smtp_server = smtplib.SMTP_SSL(self.host, self.port)
|
if self.cert_required:
|
||||||
|
context = create_default_context(cafile=self.ca_file)
|
||||||
|
else:
|
||||||
|
context = None
|
||||||
|
smtp_server = smtplib.SMTP_SSL(self.host, self.port, context=context)
|
||||||
|
|
||||||
smtp_server.ehlo()
|
smtp_server.ehlo()
|
||||||
if self.user is not None:
|
if self.user is not None:
|
||||||
|
@ -80,7 +101,7 @@ class MailExporter(AbstractExporter, ABC):
|
||||||
return smtp_server
|
return smtp_server
|
||||||
# except Exception as err:
|
# except Exception as err:
|
||||||
# traceback.print_tb(err.__traceback__)
|
# traceback.print_tb(err.__traceback__)
|
||||||
# logger.warning(err)
|
# self.logger.warning(err)
|
||||||
|
|
||||||
def _export(self, recipient, subject, body):
|
def _export(self, recipient, subject, body):
|
||||||
mime_msg = MIMEMultipart()
|
mime_msg = MIMEMultipart()
|
||||||
|
@ -95,8 +116,8 @@ class MailExporter(AbstractExporter, ABC):
|
||||||
smtp_client.quit()
|
smtp_client.quit()
|
||||||
# except Exception as err:
|
# except Exception as err:
|
||||||
# traceback.print_tb(err.__traceback__)
|
# traceback.print_tb(err.__traceback__)
|
||||||
# logger.warning(err)
|
# self.logger.warning(err)
|
||||||
print(f'Send notification: {subject} to {recipient}')
|
self.logger.info(f'Send notification: {subject} to {recipient}')
|
||||||
|
|
||||||
class MailExporterTracker(MailExporter):
|
class MailExporterTracker(MailExporter):
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,10 @@ sender = sender@example.com
|
||||||
sender_host = smtp.example.com
|
sender_host = smtp.example.com
|
||||||
sender_port = 1337
|
sender_port = 1337
|
||||||
sender_pw = None
|
sender_pw = None
|
||||||
|
# Only needed for SSL if the mail server don't support TLS (used by default). use this option to validate the server certificate.
|
||||||
|
cert_required = False
|
||||||
|
# Only needed for the SSL if you want to validate your self signed certificate for SSL
|
||||||
|
ca_file =
|
||||||
# Only needed when the credentials for email server needs a username instead of an email address
|
# Only needed when the credentials for email server needs a username instead of an email address
|
||||||
#sender_user = sender
|
#sender_user = sender
|
||||||
sender_user =
|
sender_user =
|
||||||
|
|
Loading…
Reference in New Issue