Email-based exception handler
This commit is contained in:
@@ -8,7 +8,7 @@ from lxml.etree import parse as parse_xml
|
|||||||
from dmarcreceiver.model import DBSession, Report, ReportError, ReportRecord, OverrideReason, DKIMResult, SPFResult, metadata, init_model
|
from dmarcreceiver.model import DBSession, Report, ReportError, ReportRecord, OverrideReason, DKIMResult, SPFResult, metadata, init_model
|
||||||
import transaction
|
import transaction
|
||||||
|
|
||||||
from .util import sendmail
|
from .util import sendmail, install_exception_handler
|
||||||
from .config import config
|
from .config import config
|
||||||
|
|
||||||
def parse_metadata(tree):
|
def parse_metadata(tree):
|
||||||
@@ -89,6 +89,10 @@ def receive_report(args):
|
|||||||
# read email message from stdin
|
# read email message from stdin
|
||||||
msg = message_from_file(sys.stdin)
|
msg = message_from_file(sys.stdin)
|
||||||
|
|
||||||
|
# if not running on a tty, install email-based exception handler
|
||||||
|
if not sys.stderr.isatty():
|
||||||
|
install_exception_handler(msg)
|
||||||
|
|
||||||
# check for zip file
|
# check for zip file
|
||||||
content_type = msg['content-type']
|
content_type = msg['content-type']
|
||||||
if content_type.find(';') != -1:
|
if content_type.find(';') != -1:
|
||||||
|
|||||||
@@ -1,5 +1,11 @@
|
|||||||
import os
|
import sys, os
|
||||||
import subprocess
|
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):
|
def sendmail(msg):
|
||||||
sendmail_executable = None
|
sendmail_executable = None
|
||||||
@@ -11,6 +17,30 @@ def sendmail(msg):
|
|||||||
raise FileNotFoundError('Could not find sendmail executable')
|
raise FileNotFoundError('Could not find sendmail executable')
|
||||||
|
|
||||||
pipe = subprocess.Popen([ sendmail_executable, '-t' ], stdin=subprocess.PIPE)
|
pipe = subprocess.Popen([ sendmail_executable, '-t' ], stdin=subprocess.PIPE)
|
||||||
stdout, stderr = pipe.communicate(msg.as_bytes)
|
stdout, stderr = pipe.communicate(msg.as_bytes())
|
||||||
return pipe.wait()
|
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
|
||||||
|
|
||||||
|
|||||||
2
setup.py
2
setup.py
@@ -16,7 +16,7 @@ install_requires=[
|
|||||||
|
|
||||||
setup(
|
setup(
|
||||||
name='DMARCReceiver',
|
name='DMARCReceiver',
|
||||||
version='0.9',
|
version='1.0',
|
||||||
description='Receive DMARC reports',
|
description='Receive DMARC reports',
|
||||||
author='David Baer',
|
author='David Baer',
|
||||||
author_email='david@amyanddavid.net',
|
author_email='david@amyanddavid.net',
|
||||||
|
|||||||
Reference in New Issue
Block a user