From 983362a69a31b6ea5d8b42b1934d22cf42839788 Mon Sep 17 00:00:00 2001 From: Thomas Oettli Date: Wed, 29 Jan 2020 21:35:37 +0100 Subject: [PATCH] Add decoding of mail headers --- README.md | 12 +++++++----- pyquarantine/cli.py | 8 ++++++-- pyquarantine/notifications.py | 26 ++++++++++++++++---------- 3 files changed, 29 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 9560bf3..7fc42de 100644 --- a/README.md +++ b/README.md @@ -77,15 +77,17 @@ The following configuration options are optional in each quarantine section: The following template variables are available: * **{EMAIL_ENVELOPE_FROM}** - E-mail from address received by the milter. + E-mail sender address received by the milter. * **{EMAIL_ENVELOPE_FROM_URL}** Like EMAIL_ENVELOPE_FROM, but URL encoded * **{EMAIL_FROM}** - Value of the from header of the original e-mail. - * **{EMAIL_TO}** + Value of the FROM header of the original e-mail. + * **{EMAIL_ENVELOPE_TO}** E-mail recipient address of this notification. - * **{EMAIL_TO_URL}** - Like EMAIL_TO, but URL encoded + * **{EMAIL_ENVELOPE_TO_URL}** + Like EMAIL_ENVELOPE_TO, but URL encoded + * **{EMAIL_TO}** + Value of the TO header of the original e-mail. * **{EMAIL_SUBJECT}** Configured e-mail subject. * **{EMAIL_QUARANTINE_ID}** diff --git a/pyquarantine/cli.py b/pyquarantine/cli.py index 802648d..3fb0701 100644 --- a/pyquarantine/cli.py +++ b/pyquarantine/cli.py @@ -20,6 +20,8 @@ import logging.handlers import sys import time +from email.header import decode_header, make_header + import pyquarantine from pyquarantine.version import __version__ as version @@ -56,7 +58,7 @@ def print_table(columns, rows): # get the length of the longest value lengths.append( len(str(max(rows, key=lambda x: len(str(x[key])))[key]))) - # use the the longer one + # use the longer one length = max(lengths) column_lengths.append(length) column_formats.append("{{:<{}}}".format(length)) @@ -120,7 +122,9 @@ def list_quarantine_emails(config, args): row["recipient"] = metadata["recipients"].pop(0) if "subject" not in emails[quarantine_id]["headers"].keys(): emails[quarantine_id]["headers"]["subject"] = "" - row["subject"] = emails[quarantine_id]["headers"]["subject"][:60] + row["subject"] = str(make_header(decode_header( + emails[quarantine_id]["headers"]["subject"])))[:60].replace( + "\r", "").replace("\n", "").strip() rows.append(row) if metadata["recipients"]: diff --git a/pyquarantine/notifications.py b/pyquarantine/notifications.py index d2b9a60..592ea5d 100644 --- a/pyquarantine/notifications.py +++ b/pyquarantine/notifications.py @@ -19,6 +19,7 @@ import re from bs4 import BeautifulSoup from cgi import escape from collections import defaultdict +from email.header import decode_header, make_header from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from email.mime.image import MIMEImage @@ -351,21 +352,26 @@ class EMailNotification(BaseNotification): "{}: generating notification email for '{}'".format( queueid, recipient)) self.logger.debug("{}: parsing email template".format(queueid)) - if "from" not in headers.keys(): - headers["from"] = "" - if "to" not in headers.keys(): - headers["to"] = "" - if "subject" not in headers.keys(): - headers["subject"] = "" + # decode some headers + decoded_headers = {} + for var in ["from", "to", "subject"]: + if header in headers: + decoded_headers[header] = str( + make_header(decode_header(headers[header]))) + else: + headers[var] = "" + decoded_headers[var] = "" + # generate dict containing all template variables variables = defaultdict(str, EMAIL_HTML_TEXT=sanitized_text, - EMAIL_FROM=escape(headers["from"]), + EMAIL_FROM=escape(decoded_headers["from"]), EMAIL_ENVELOPE_FROM=escape(mailfrom), EMAIL_ENVELOPE_FROM_URL=escape(quote(mailfrom)), - EMAIL_TO=escape(recipient), - EMAIL_TO_URL=escape(quote(recipient)), - EMAIL_SUBJECT=escape(headers["subject"]), + EMAIL_TO=escape(decoded_headers["to"]), + EMAIL_ENVELOPE_TO=escape(recipient), + EMAIL_ENVELOPE_TO_URL=escape(quote(recipient)), + EMAIL_SUBJECT=escape(decoded_headers["subject"]), EMAIL_QUARANTINE_ID=quarantine_id) if subgroups: