import sys, os import subprocess from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart from email.mime.message import MIMEMessage from traceback import format_exception, format_exception_only from .config import config def sendmail(msg): sendmail_executable = None for pth in ( '/usr/sbin', '/usr/bin', '/usr/local/sbin', '/usr/local/bin', '/sbin', '/bin'): if os.access(os.path.join(pth, 'sendmail'), os.X_OK): sendmail_executable = os.path.join(pth, 'sendmail') break if sendmail_executable is None: raise FileNotFoundError('Could not find sendmail executable') pipe = subprocess.Popen([ sendmail_executable, '-t' ], stdin=subprocess.PIPE) stdout, stderr = pipe.communicate(msg.as_bytes()) return pipe.wait() def install_exception_handler(incoming_msg): bounce_address = config.get('bounce_address') if bounce_address is None: return def exception_handler(exctype, value, traceback): exc_text = ''.join(format_exception(exctype, value, traceback)) msg = MIMEMultipart() txt_msg = MIMEText('''There was a problem processing an incoming DMARC report: {}'''.format(exc_text)) txt_msg['Content-Disposition'] = 'inline' msg.attach(txt_msg) att = MIMEMessage(incoming_msg) att['Content-Disposition'] = 'attachment' att['Content-Description'] = 'Original DMARC report message' msg.attach(att) msg['To'] = bounce_address msg['From'] = bounce_address msg['Subject'] = 'Exception: ' + format_exception_only(exctype, value)[-1][:70] sendmail(msg) sys.excepthook = exception_handler