Skip to content

Commit

Permalink
Replace subject with [...] for outgoing mail
Browse files Browse the repository at this point in the history
`authclean` cleanup server is used by
reinjecting smtpd running on localhost:10025 by default.
It runs after filtermail
and currently removes `Received` header
to avoid leaking IP address.
Can as well be used to replace `Subject` lines
with `Subject: [...]`.
If there are multiple `Subject` lines,
all of them should be replaced.

This allows us to avoid dealing with
localized subjects, including SecureJoin
messages `vc-request` and `vg-request`
which can have Subject lines like
Subject: =?utf-8?q?Nachricht_von_nrn178fi4=40nine=2Etestrun=2Eorg?=
  • Loading branch information
link2xt committed Feb 16, 2025
1 parent 5633582 commit 268eda8
Show file tree
Hide file tree
Showing 7 changed files with 33 additions and 76 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
- remove MTA-STS daemon
([#488](https://github.com/deltachat/chatmail/pull/488))

- replace `Subject` with `[...]` for all outgoing mails.
([#481](https://github.com/deltachat/chatmail/pull/481))

## 1.5.0 2024-12-20

- cmdeploy dns: always show recommended DNS records
Expand Down
59 changes: 0 additions & 59 deletions chatmaild/src/chatmaild/common_encrypted_subjects.py

This file was deleted.

3 changes: 0 additions & 3 deletions chatmaild/src/chatmaild/filtermail.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@

from aiosmtpd.controller import Controller

from .common_encrypted_subjects import common_encrypted_subjects
from .config import read_config


Expand Down Expand Up @@ -128,8 +127,6 @@ def check_encrypted(message):
"""
if not message.is_multipart():
return False
if message.get("subject") not in common_encrypted_subjects:
return False
if message.get_content_type() != "multipart/encrypted":
return False
parts_count = 0
Expand Down
2 changes: 1 addition & 1 deletion chatmaild/src/chatmaild/tests/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ def maildata(request):

assert datadir.exists(), datadir

def maildata(name, from_addr, to_addr, subject="..."):
def maildata(name, from_addr, to_addr, subject="[...]"):
# Using `.read_bytes().decode()` instead of `.read_text()` to preserve newlines.
data = datadir.joinpath(name).read_bytes().decode()

Expand Down
20 changes: 7 additions & 13 deletions chatmaild/src/chatmaild/tests/test_filtermail.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
SendRateLimiter,
check_armored_payload,
check_encrypted,
common_encrypted_subjects,
is_securejoin,
)

Expand Down Expand Up @@ -71,18 +70,13 @@ def test_filtermail_securejoin_detection(maildata):


def test_filtermail_encryption_detection(maildata):
for subject in common_encrypted_subjects:
msg = maildata(
"encrypted.eml",
from_addr="1@example.org",
to_addr="2@example.org",
subject=subject,
)
assert check_encrypted(msg)

# if the subject is not a known encrypted subject value, it is not considered ac-encrypted
msg.replace_header("Subject", "Click this link")
assert not check_encrypted(msg)
msg = maildata(
"encrypted.eml",
from_addr="1@example.org",
to_addr="2@example.org",
subject="Subject does not matter, will be replaced anyway",
)
assert check_encrypted(msg)


def test_filtermail_no_literal_packets(maildata):
Expand Down
1 change: 1 addition & 0 deletions cmdeploy/src/cmdeploy/postfix/submission_header_cleanup
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
/^X-Originating-IP:/ IGNORE
/^X-Mailer:/ IGNORE
/^User-Agent:/ IGNORE
/^Subject:/ REPLACE Subject: [...]
21 changes: 21 additions & 0 deletions cmdeploy/src/cmdeploy/tests/online/test_1_basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,27 @@ def test_reject_missing_dkim(cmsetup, maildata, from_addr):
s.sendmail(from_addr=from_addr, to_addrs=recipient.addr, msg=msg)


def test_rewrite_subject(cmsetup, maildata):
"""Test that subject gets replaced with [...]."""
user1, user2 = cmsetup.gen_users(2)

sent_msg = maildata(
"encrypted.eml",
from_addr=user1.addr,
to_addr=user2.addr,
subject="Unencrypted subject",
).as_string()
user1.smtp.sendmail(from_addr=user1.addr, to_addrs=[user2.addr], msg=sent_msg)

messages = user2.imap.fetch_all_messages()
assert len(messages) == 1
rcvd_msg = messages[0]
assert "Subject: [...]" not in sent_msg
assert "Subject: [...]" in rcvd_msg
assert "Subject: Unencrypted subject" in sent_msg
assert "Subject: Unencrypted subject" not in rcvd_msg


@pytest.mark.slow
def test_exceed_rate_limit(cmsetup, gencreds, maildata, chatmail_config):
"""Test that the per-account send-mail limit is exceeded."""
Expand Down

0 comments on commit 268eda8

Please # to comment.