aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2023-06-09 23:12:58 +0200
committerThomas Gleixner <tglx@linutronix.de>2023-06-20 23:43:23 +0200
commit424944ad36e9925a9d3856b7054ca7fcc26f1ea6 (patch)
treef19760e9ccda1034a904a4eed603b992a01056d3
parentea4b0b46321ff88bccf30f74cfc3fc540574eff8 (diff)
downloadremail-424944ad36e9925a9d3856b7054ca7fcc26f1ea6.tar.gz
remail: Add X-Original-From header
The 'From:' header mangling makes it unnecessarily hard to figure out the name and email address of the person who posted to a list. Save the original sender in the 'X-Original-From:' header. Suggested-by: Linus Torvalds <torvalds@linux-foundation.org> Suggested-by: Konstantin Ryabitsev <konstantin@linuxfoundation.org> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Link: https://wiki.ietf.org/group/dmarc/XOriginalFrom
-rw-r--r--remail/mail.py17
-rw-r--r--remail/maillist.py10
2 files changed, 21 insertions, 6 deletions
diff --git a/remail/mail.py b/remail/mail.py
index 1dd6860..83b55cc 100644
--- a/remail/mail.py
+++ b/remail/mail.py
@@ -11,6 +11,7 @@ from email.generator import Generator
from email.message import Message, EmailMessage
from email.policy import EmailPolicy
from email.policy import default as DefaultPolicy
+from email.headerregistry import UniqueSingleAddressHeader
import smtplib
import mailbox
@@ -75,13 +76,21 @@ def msg_copy_headers(msgout, msg, headers):
if val:
msgout[key] = val
-def send_mail(msg, account, mfrom, sender, listheaders, use_smtp, logger):
+def send_mail(msg, account, mfrom, sender, listheaders, use_smtp, logger,
+ origfrom=None):
'''
Send mail to the account. Make sure that the message is correct and all
required headers and only necessary headers are in the outgoing mail.
'''
- # Convert to EmailMessage with default policy (utf-8=false) so both
+ # Clone the default policy (utf-8=false) and map the X-Original-From
+ # header to UniqueSingleAddressHeader. Otherwise this is treated as
+ # unspecified header.
+ policy = DefaultPolicy.clone()
+ policy.header_factory.map_to_type('X-Original-From',
+ UniqueSingleAddressHeader)
+
+ # Convert to EmailMessage with the modified default policy so both
# smptlib.send_message() and the stdout dump keep the headers properly
# encoded.
parser = BytesFeedParser(policy=DefaultPolicy)
@@ -109,6 +118,10 @@ def send_mail(msg, account, mfrom, sender, listheaders, use_smtp, logger):
msg_copy_headers(msgout, msg, ['Content-Type', 'Content-Disposition',
'Content-Transfer-Encoding',
'Content-Language'])
+
+ if origfrom:
+ msgout['X-Original-From'] = origfrom
+
msgout['Envelope-To'] = get_raw_email_addr(account.addr)
# Set unixfrom with the current date/time
diff --git a/remail/maillist.py b/remail/maillist.py
index 2bd9dd8..b399ff7 100644
--- a/remail/maillist.py
+++ b/remail/maillist.py
@@ -86,11 +86,12 @@ class maillist(object):
self.gpg.encrypt(msg, account)
return msg
- def send_encrypted_mail(self, msg_plain, account, mfrom):
+ def send_encrypted_mail(self, msg_plain, account, mfrom, origfrom=None):
try:
msg_out = self.encrypt(msg_plain, account)
send_mail(msg_out, account, mfrom, self.config.listaddrs.bounce,
- self.config.listheaders, self.use_smtp, self.logger)
+ self.config.listheaders, self.use_smtp, self.logger,
+ origfrom)
except (RemailGPGException, RemailSmimeException) as ex:
'''
@@ -243,7 +244,8 @@ class maillist(object):
msgid = msg.get('Message-Id', '<No ID>')
msgto = msg.get('To')
- msgfrom = get_raw_email_addr(msg.get('From'))
+ origfrom = msg.get('From')
+ msgfrom = get_raw_email_addr(origfrom)
sinfo = sender_info(msg)
# Archive the incoming mail
@@ -272,7 +274,7 @@ class maillist(object):
for account in dest.accounts.values():
if not account.enabled:
continue
- self.send_encrypted_mail(msg_plain, account, mfrom)
+ self.send_encrypted_mail(msg_plain, account, mfrom, origfrom)
return True
def handle_log(self):