Compare commits

..

3 Commits

Author SHA1 Message Date
missytake
f26d2da23b Try without gcc 2025-01-27 11:37:07 +01:00
link2xt
3b32387bf8 Install python3-dev 2025-01-26 20:10:12 +00:00
link2xt
a651fba8b6 Install gcc 2025-01-26 19:58:48 +00:00
20 changed files with 145 additions and 214 deletions

View File

@@ -38,8 +38,8 @@ jobs:
if [ -f dkimkeys-ipv4/dkimkeys/opendkim.private ]; then rsync -avz -e "ssh -o StrictHostKeyChecking=accept-new" dkimkeys-ipv4 root@ns.testrun.org:/tmp/ || true; fi if [ -f dkimkeys-ipv4/dkimkeys/opendkim.private ]; then rsync -avz -e "ssh -o StrictHostKeyChecking=accept-new" dkimkeys-ipv4 root@ns.testrun.org:/tmp/ || true; fi
if [ "$(ls -A acme-ipv4/acme/certs)" ]; then rsync -avz -e "ssh -o StrictHostKeyChecking=accept-new" acme-ipv4 root@ns.testrun.org:/tmp/ || true; fi if [ "$(ls -A acme-ipv4/acme/certs)" ]; then rsync -avz -e "ssh -o StrictHostKeyChecking=accept-new" acme-ipv4 root@ns.testrun.org:/tmp/ || true; fi
# make sure CAA record isn't set # make sure CAA record isn't set
scp -o StrictHostKeyChecking=accept-new .github/workflows/staging-ipv4.testrun.org-default.zone root@ns.testrun.org:/etc/nsd/staging-ipv4.testrun.org.zone scp .github/workflows/staging-ipv4.testrun.org-default.zone root@ns.testrun.org:/etc/nsd/staging-ipv4.testrun.org.zone
ssh root@ns.testrun.org sed -i '/CAA/d' /etc/nsd/staging-ipv4.testrun.org.zone ssh -o StrictHostKeyChecking=accept-new root@ns.testrun.org sed -i '/CAA/d' /etc/nsd/staging-ipv4.testrun.org.zone
ssh root@ns.testrun.org nsd-checkzone staging-ipv4.testrun.org /etc/nsd/staging-ipv4.testrun.org.zone ssh root@ns.testrun.org nsd-checkzone staging-ipv4.testrun.org /etc/nsd/staging-ipv4.testrun.org.zone
ssh root@ns.testrun.org systemctl reload nsd ssh root@ns.testrun.org systemctl reload nsd
@@ -49,7 +49,7 @@ jobs:
-H "Authorization: Bearer ${{ secrets.HETZNER_API_TOKEN }}" \ -H "Authorization: Bearer ${{ secrets.HETZNER_API_TOKEN }}" \
-H "Content-Type: application/json" \ -H "Content-Type: application/json" \
-d '{"image":"debian-12"}' \ -d '{"image":"debian-12"}' \
"https://api.hetzner.cloud/v1/servers/${{ secrets.STAGING_IPV4_SERVER_ID }}/actions/rebuild" "https://api.hetzner.cloud/v1/servers/${{ secrets.STAGING_SERVER_ID }}/actions/rebuild"
- run: scripts/initenv.sh - run: scripts/initenv.sh
@@ -63,11 +63,11 @@ jobs:
while ! ssh -o ConnectTimeout=180 -o StrictHostKeyChecking=accept-new -v root@staging-ipv4.testrun.org id -u ; do sleep 1 ; done while ! ssh -o ConnectTimeout=180 -o StrictHostKeyChecking=accept-new -v root@staging-ipv4.testrun.org id -u ; do sleep 1 ; done
ssh -o StrictHostKeyChecking=accept-new -v root@staging-ipv4.testrun.org id -u ssh -o StrictHostKeyChecking=accept-new -v root@staging-ipv4.testrun.org id -u
# download acme & dkim state from ns.testrun.org # download acme & dkim state from ns.testrun.org
rsync -e "ssh -o StrictHostKeyChecking=accept-new" -avz root@ns.testrun.org:/tmp/acme-ipv4/acme acme-restore || true rsync -e "ssh -o StrictHostKeyChecking=accept-new" -avz root@ns.testrun.org:/tmp/acme-ipv4 acme-restore || true
rsync -avz root@ns.testrun.org:/tmp/dkimkeys-ipv4/dkimkeys dkimkeys-restore || true rsync -avz root@ns.testrun.org:/tmp/dkimkeys-ipv4 dkimkeys-restore || true
# restore acme & dkim state to staging2.testrun.org # restore acme & dkim state to staging2.testrun.org
rsync -avz acme-restore/acme root@staging-ipv4.testrun.org:/var/lib/ || true rsync -avz acme-restore/acme-ipv4/acme root@staging-ipv4.testrun.org:/var/lib/ || true
rsync -avz dkimkeys-restore/dkimkeys root@staging-ipv4.testrun.org:/etc/ || true rsync -avz dkimkeys-restore/dkimkeys-ipv4/dkimkeys root@staging-ipv4.testrun.org:/etc/ || true
ssh -o StrictHostKeyChecking=accept-new -v root@staging-ipv4.testrun.org chown root:root -R /var/lib/acme || true ssh -o StrictHostKeyChecking=accept-new -v root@staging-ipv4.testrun.org chown root:root -R /var/lib/acme || true
- name: run formatting checks - name: run formatting checks

View File

@@ -2,39 +2,12 @@
## untagged ## untagged
- filtermail: don't require exactly 2 lines after openPGP payload
([#497](https://github.com/chatmail/chatmail/pull/497))
- cmdeploy dns: offer alternative DKIM record format for some web interfaces - cmdeploy dns: offer alternative DKIM record format for some web interfaces
([#470](https://github.com/deltachat/chatmail/pull/470)) ([#470](https://github.com/deltachat/chatmail/pull/470))
- journald: remove old logs from disk
([#490](https://github.com/deltachat/chatmail/pull/490))
- opendkim: restart once every day to mend RAM leaks
([#498](https://github.com/chatmail/chatmail/pull/498)
- migration guide: let opendkim own the DKIM keys directory - migration guide: let opendkim own the DKIM keys directory
([#468](https://github.com/deltachat/chatmail/pull/468)) ([#468](https://github.com/deltachat/chatmail/pull/468))
- improve secure-join message detection
([#473](https://github.com/deltachat/chatmail/pull/473))
- use old crypt lib in python < 3.11
([#483](https://github.com/deltachat/chatmail/pull/483))
- chatmaild: set umask to 0700 for doveauth + metadata
([#490](https://github.com/deltachat/chatmail/pull/492))
- 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))
- opendkim: use su instead of sudo
([#491](https://github.com/deltachat/chatmail/pull/491))
## 1.5.0 2024-12-20 ## 1.5.0 2024-12-20
- cmdeploy dns: always show recommended DNS records - cmdeploy dns: always show recommended DNS records

View File

@@ -12,7 +12,7 @@ dependencies = [
"deltachat-rpc-client", "deltachat-rpc-client",
"filelock", "filelock",
"requests", "requests",
"crypt-r >= 3.13.1 ; python_version >= '3.11'", "crypt-r",
] ]
[tool.setuptools] [tool.setuptools]

View File

@@ -0,0 +1,59 @@
"""Generated from deltachat, draft-ietf-lamps-header-protection, and
encrypted_subject localizations in
https://github.com/thunderbird/thunderbird-android/
"""
common_encrypted_subjects = {
"...",
"[...]",
"암호화된 메시지",
"Ĉifrita mesaĝo",
"Courriel chiffré",
"Dulrituð skilaboð",
"Encrypted Message",
"Fersifere berjocht",
"Kemennadenn enrineget",
"Krüptitud kiri",
"Krypterat meddelande",
"Krypteret besked",
"Kryptert melding",
"Mensagem criptografada",
"Mensagem encriptada",
"Mensaje cifrado",
"Mensaxe cifrada",
"Mesaj Criptat",
"Mesazh i Fshehtëzuar",
"Messaggio criptato",
"Messaghju cifratu",
"Missatge encriptat",
"Neges wedi'i Hamgryptio",
"Pesan terenkripsi",
"Salattu viesti",
"Şifreli İleti",
"Šifrēta ziņa",
"Šifrirana poruka",
"Šifrirano sporočilo",
"Šifruotas laiškas",
"Tin nhắn được mã hóa",
"Titkosított üzenet",
"Verschlüsselte Nachricht",
"Versleuteld bericht",
"Zašifrovaná zpráva",
"Zaszyfrowana wiadomość",
"Zifratu mezua",
"Κρυπτογραφημένο μήνυμα",
"Зашифроване повідомлення",
"Зашифрованное сообщение",
"Зашыфраваны ліст",
"Криптирано съобщение",
"Шифрована порука",
"დაშიფრული წერილი",
"הודעה מוצפנת",
"پیام رمزنگاری‌شده",
"رسالة مشفّرة",
"എൻക്രിപ്റ്റുചെയ്‌ത സന്ദേശം",
"加密邮件",
"已加密的訊息",
"暗号化されたメッセージ",
}

View File

@@ -3,10 +3,7 @@ import logging
import os import os
import sys import sys
try: import crypt_r
import crypt_r
except ImportError:
import crypt as crypt_r
from .config import Config, read_config from .config import Config, read_config
from .dictproxy import DictProxy from .dictproxy import DictProxy

View File

@@ -12,6 +12,7 @@ from smtplib import SMTP as SMTPClient
from aiosmtpd.controller import Controller from aiosmtpd.controller import Controller
from .common_encrypted_subjects import common_encrypted_subjects
from .config import read_config from .config import read_config
@@ -80,9 +81,7 @@ def check_armored_payload(payload: str):
return False return False
payload = payload.removeprefix(prefix) payload = payload.removeprefix(prefix)
while payload.endswith("\r\n"): suffix = "-----END PGP MESSAGE-----\r\n\r\n"
payload = payload.removesuffix("\r\n")
suffix = "-----END PGP MESSAGE-----"
if not payload.endswith(suffix): if not payload.endswith(suffix):
return False return False
payload = payload.removesuffix(suffix) payload = payload.removesuffix(suffix)
@@ -101,27 +100,6 @@ def check_armored_payload(payload: str):
return False return False
def is_securejoin(message):
if message.get("secure-join") not in ["vc-request", "vg-request"]:
return False
if not message.is_multipart():
return False
parts_count = 0
for part in message.iter_parts():
parts_count += 1
if parts_count > 1:
return False
if part.is_multipart():
return False
if part.get_content_type() != "text/plain":
return False
payload = part.get_payload().strip().lower()
if payload not in ("secure-join: vc-request", "secure-join: vg-request"):
return False
return True
def check_encrypted(message): def check_encrypted(message):
"""Check that the message is an OpenPGP-encrypted message. """Check that the message is an OpenPGP-encrypted message.
@@ -129,6 +107,8 @@ def check_encrypted(message):
""" """
if not message.is_multipart(): if not message.is_multipart():
return False return False
if message.get("subject") not in common_encrypted_subjects:
return False
if message.get_content_type() != "multipart/encrypted": if message.get_content_type() != "multipart/encrypted":
return False return False
parts_count = 0 parts_count = 0
@@ -223,7 +203,11 @@ class BeforeQueueHandler:
passthrough_recipients = self.config.passthrough_recipients passthrough_recipients = self.config.passthrough_recipients
if mail_encrypted or is_securejoin(message): is_securejoin = message.get("secure-join") in [
"vc-request",
"vg-request",
]
if is_securejoin:
return return
for recipient in envelope.rcpt_tos: for recipient in envelope.rcpt_tos:
@@ -238,7 +222,7 @@ class BeforeQueueHandler:
_recipient_addr, recipient_domain = res _recipient_addr, recipient_domain = res
is_outgoing = recipient_domain != envelope_from_domain is_outgoing = recipient_domain != envelope_from_domain
if is_outgoing: if is_outgoing and not mail_encrypted:
print("Rejected unencrypted mail.", file=sys.stderr) print("Rejected unencrypted mail.", file=sys.stderr)
return f"500 Invalid unencrypted mail to <{recipient}>" return f"500 Invalid unencrypted mail to <{recipient}>"

View File

@@ -1,21 +0,0 @@
Subject: Message from {from_addr}
From: <{from_addr}>
To: <{to_addr}>
Date: Sun, 15 Oct 2023 16:43:25 +0000
Message-ID: <Mr.78MWtlV7RAi.goCFzBhCYfy@c2.testrun.org>
Chat-Version: 1.0
Secure-Join: vc-request
Secure-Join-Invitenumber: RANDOM-TOKEN
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="Gl92xgZjOShJ5PGHntqYkoo2OK2Dvi"
--Gl92xgZjOShJ5PGHntqYkoo2OK2Dvi
Content-Type: text/plain; charset=utf-8
Buy viagra!
--Gl92xgZjOShJ5PGHntqYkoo2OK2Dvi--

View File

@@ -1,21 +0,0 @@
Subject: Message from {from_addr}
From: <{from_addr}>
To: <{to_addr}>
Date: Sun, 15 Oct 2023 16:43:25 +0000
Message-ID: <Mr.78MWtlV7RAi.goCFzBhCYfy@c2.testrun.org>
Chat-Version: 1.0
Secure-Join: vc-request
Secure-Join-Invitenumber: RANDOM-TOKEN
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="Gl92xgZjOShJ5PGHntqYkoo2OK2Dvi"
--Gl92xgZjOShJ5PGHntqYkoo2OK2Dvi
Content-Type: text/plain; charset=utf-8
Secure-Join: vc-request
--Gl92xgZjOShJ5PGHntqYkoo2OK2Dvi--

View File

@@ -69,7 +69,7 @@ def maildata(request):
assert datadir.exists(), datadir 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. # Using `.read_bytes().decode()` instead of `.read_text()` to preserve newlines.
data = datadir.joinpath(name).read_bytes().decode() data = datadir.joinpath(name).read_bytes().decode()

View File

@@ -5,7 +5,7 @@ from chatmaild.filtermail import (
SendRateLimiter, SendRateLimiter,
check_armored_payload, check_armored_payload,
check_encrypted, check_encrypted,
is_securejoin, common_encrypted_subjects,
) )
@@ -55,28 +55,19 @@ def test_filtermail_no_encryption_detection(maildata):
assert not check_encrypted(msg) assert not check_encrypted(msg)
def test_filtermail_securejoin_detection(maildata):
msg = maildata(
"securejoin-vc.eml", from_addr="some@example.org", to_addr="other@example.org"
)
assert is_securejoin(msg)
msg = maildata(
"securejoin-vc-fake.eml",
from_addr="some@example.org",
to_addr="other@example.org",
)
assert not is_securejoin(msg)
def test_filtermail_encryption_detection(maildata): def test_filtermail_encryption_detection(maildata):
msg = maildata( for subject in common_encrypted_subjects:
"encrypted.eml", msg = maildata(
from_addr="1@example.org", "encrypted.eml",
to_addr="2@example.org", from_addr="1@example.org",
subject="Subject does not matter, will be replaced anyway", to_addr="2@example.org",
) subject=subject,
assert check_encrypted(msg) )
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)
def test_filtermail_no_literal_packets(maildata): def test_filtermail_no_literal_packets(maildata):
@@ -205,20 +196,10 @@ UN4fiB0KR9JyG2ayUdNJVkXZSZLnHyRgiaadlpUo16LVvw==\r
=b5Kp\r =b5Kp\r
-----END PGP MESSAGE-----\r -----END PGP MESSAGE-----\r
\r \r
\r
""" """
assert check_armored_payload(payload) == True assert check_armored_payload(payload) == True
payload = payload.removesuffix("\r\n")
assert check_armored_payload(payload) == True
payload = payload.removesuffix("\r\n")
assert check_armored_payload(payload) == True
payload = payload.removesuffix("\r\n")
assert check_armored_payload(payload) == True
payload = """-----BEGIN PGP MESSAGE-----\r payload = """-----BEGIN PGP MESSAGE-----\r
\r \r
HELLOWORLD HELLOWORLD

View File

@@ -79,8 +79,8 @@ def _install_remote_venv_with_chatmaild(config) -> None:
) )
apt.packages( apt.packages(
name="install gcc and headers to build crypt_r source package", name="install python3-dev to build crypt_r source package",
packages=["gcc", "python3-dev"], packages=["python3-dev"],
) )
server.shell( server.shell(
@@ -217,36 +217,49 @@ def _configure_opendkim(domain: str, dkim_selector: str = "dkim") -> bool:
commands=[ commands=[
f"opendkim-genkey -D /etc/dkimkeys -d {domain} -s {dkim_selector}" f"opendkim-genkey -D /etc/dkimkeys -d {domain} -s {dkim_selector}"
], ],
_use_su_login=True, _sudo=True,
_su_user="opendkim", _sudo_user="opendkim",
) )
service_file = files.put(
name="Configure opendkim to restart once a day",
src=importlib.resources.files(__package__).joinpath("opendkim/systemd.conf"),
dest="/etc/systemd/system/opendkim.service.d/10-prevent-memory-leak.conf",
)
need_restart |= service_file.changed
return need_restart return need_restart
def _uninstall_mta_sts_daemon() -> None: def _install_mta_sts_daemon() -> bool:
# Remove configuration. need_restart = False
files.file("/etc/mta-sts-daemon.yml", present=False)
files.directory("/usr/local/lib/postfix-mta-sts-resolver", present=False) config = files.put(
name="upload postfix-mta-sts-resolver config",
files.file("/etc/systemd/system/mta-sts-daemon.service", present=False) src=importlib.resources.files(__package__).joinpath(
"postfix/mta-sts-daemon.yml"
systemd.service( ),
name="Stop MTA-STS daemon", dest="/etc/mta-sts-daemon.yml",
service="mta-sts-daemon.service", user="root",
daemon_reload=True, group="root",
running=False, mode="644",
enabled=False,
) )
need_restart |= config.changed
server.shell(
name="install postfix-mta-sts-resolver with pip",
commands=[
"python3 -m virtualenv /usr/local/lib/postfix-mta-sts-resolver",
"/usr/local/lib/postfix-mta-sts-resolver/bin/pip install postfix-mta-sts-resolver",
],
)
systemd_unit = files.put(
name="upload mta-sts-daemon systemd unit",
src=importlib.resources.files(__package__).joinpath(
"postfix/mta-sts-daemon.service"
),
dest="/etc/systemd/system/mta-sts-daemon.service",
user="root",
group="root",
mode="644",
)
need_restart |= systemd_unit.changed
return need_restart
def _configure_postfix(config: Config, debug: bool = False) -> bool: def _configure_postfix(config: Config, debug: bool = False) -> bool:
@@ -650,8 +663,8 @@ def deploy_chatmail(config_path: Path, disable_mail: bool) -> None:
debug = False debug = False
dovecot_need_restart = _configure_dovecot(config, debug=debug) dovecot_need_restart = _configure_dovecot(config, debug=debug)
postfix_need_restart = _configure_postfix(config, debug=debug) postfix_need_restart = _configure_postfix(config, debug=debug)
mta_sts_need_restart = _install_mta_sts_daemon()
nginx_need_restart = _configure_nginx(config) nginx_need_restart = _configure_nginx(config)
_uninstall_mta_sts_daemon()
_remove_rspamd() _remove_rspamd()
opendkim_need_restart = _configure_opendkim(mail_domain, "opendkim") opendkim_need_restart = _configure_opendkim(mail_domain, "opendkim")
@@ -661,10 +674,18 @@ def deploy_chatmail(config_path: Path, disable_mail: bool) -> None:
service="opendkim.service", service="opendkim.service",
running=True, running=True,
enabled=True, enabled=True,
daemon_reload=opendkim_need_restart,
restarted=opendkim_need_restart, restarted=opendkim_need_restart,
) )
systemd.service(
name="Start and enable MTA-STS daemon",
service="mta-sts-daemon.service",
daemon_reload=True,
running=True,
enabled=True,
restarted=mta_sts_need_restart,
)
# Dovecot should be started before Postfix # Dovecot should be started before Postfix
# because it creates authentication socket # because it creates authentication socket
# required by Postfix. # required by Postfix.
@@ -714,11 +735,6 @@ def deploy_chatmail(config_path: Path, disable_mail: bool) -> None:
enabled=True, enabled=True,
restarted=journald_conf.changed, restarted=journald_conf.changed,
) )
files.directory(
name="Ensure old logs on disk are deleted",
path="/var/log/journal/",
present=False,
)
apt.packages( apt.packages(
name="Ensure cron is installed", name="Ensure cron is installed",

View File

@@ -16,7 +16,7 @@ www.{{ mail_domain }}. CNAME {{ mail_domain }}.
; ;
; Recommended DNS entries for interoperability and security-hardening ; Recommended DNS entries for interoperability and security-hardening
; ;
{{ mail_domain }}. TXT "v=spf1 a ~all" {{ mail_domain }}. TXT "v=spf1 a:{{ mail_domain }} ~all"
_dmarc.{{ mail_domain }}. TXT "v=DMARC1;p=reject;adkim=s;aspf=s" _dmarc.{{ mail_domain }}. TXT "v=DMARC1;p=reject;adkim=s;aspf=s"
{% if acme_account_url %} {% if acme_account_url %}

View File

@@ -209,7 +209,7 @@ ssl = required
ssl_cert = </var/lib/acme/live/{{ config.mail_domain }}/fullchain ssl_cert = </var/lib/acme/live/{{ config.mail_domain }}/fullchain
ssl_key = </var/lib/acme/live/{{ config.mail_domain }}/privkey ssl_key = </var/lib/acme/live/{{ config.mail_domain }}/privkey
ssl_dh = </usr/share/dovecot/dh.pem ssl_dh = </usr/share/dovecot/dh.pem
ssl_min_protocol = TLSv1.3 ssl_min_protocol = TLSv1.2
ssl_prefer_server_ciphers = yes ssl_prefer_server_ciphers = yes

View File

@@ -1,3 +0,0 @@
[Service]
Restart=always
RuntimeMaxSec=1d

View File

@@ -20,9 +20,9 @@ smtpd_tls_key_file=/var/lib/acme/live/{{ config.mail_domain }}/privkey
smtpd_tls_security_level=may smtpd_tls_security_level=may
smtp_tls_CApath=/etc/ssl/certs smtp_tls_CApath=/etc/ssl/certs
smtp_tls_security_level=verify smtp_tls_security_level=may
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
smtp_tls_policy_maps = inline:{nauta.cu=may} smtp_tls_policy_maps = socketmap:inet:127.0.0.1:8461:postfix
smtpd_tls_protocols = >=TLSv1.2 smtpd_tls_protocols = >=TLSv1.2
# Disable anonymous cipher suites # Disable anonymous cipher suites

View File

@@ -18,7 +18,6 @@ smtp inet n - y - - smtpd
submission inet n - y - 5000 smtpd submission inet n - y - 5000 smtpd
-o syslog_name=postfix/submission -o syslog_name=postfix/submission
-o smtpd_tls_security_level=encrypt -o smtpd_tls_security_level=encrypt
-o smtpd_tls_mandatory_protocols=>=TLSv1.3
-o smtpd_sasl_auth_enable=yes -o smtpd_sasl_auth_enable=yes
-o smtpd_sasl_type=dovecot -o smtpd_sasl_type=dovecot
-o smtpd_sasl_path=private/auth -o smtpd_sasl_path=private/auth
@@ -37,7 +36,6 @@ smtps inet n - y - 5000 smtpd
-o syslog_name=postfix/smtps -o syslog_name=postfix/smtps
-o smtpd_tls_wrappermode=yes -o smtpd_tls_wrappermode=yes
-o smtpd_tls_security_level=encrypt -o smtpd_tls_security_level=encrypt
-o smtpd_tls_mandatory_protocols=>=TLSv1.3
-o smtpd_sasl_auth_enable=yes -o smtpd_sasl_auth_enable=yes
-o smtpd_sasl_type=dovecot -o smtpd_sasl_type=dovecot
-o smtpd_sasl_path=private/auth -o smtpd_sasl_path=private/auth
@@ -81,6 +79,7 @@ filter unix - n n - - lmtp
# Local SMTP server for reinjecting filered mail. # Local SMTP server for reinjecting filered mail.
localhost:{{ config.postfix_reinject_port }} inet n - n - 10 smtpd localhost:{{ config.postfix_reinject_port }} inet n - n - 10 smtpd
-o syslog_name=postfix/reinject -o syslog_name=postfix/reinject
-o smtpd_milters=unix:opendkim/opendkim.sock
-o cleanup_service_name=authclean -o cleanup_service_name=authclean
# Cleanup `Received` headers for authenticated mail # Cleanup `Received` headers for authenticated mail

View File

@@ -2,4 +2,3 @@
/^X-Originating-IP:/ IGNORE /^X-Originating-IP:/ IGNORE
/^X-Mailer:/ IGNORE /^X-Mailer:/ IGNORE
/^User-Agent:/ IGNORE /^User-Agent:/ IGNORE
/^Subject:/ REPLACE Subject: [...]

View File

@@ -7,7 +7,6 @@ Restart=always
RestartSec=30 RestartSec=30
User=vmail User=vmail
RuntimeDirectory=chatmail-metadata RuntimeDirectory=chatmail-metadata
UMask=0077
[Install] [Install]
WantedBy=multi-user.target WantedBy=multi-user.target

View File

@@ -7,7 +7,6 @@ Restart=always
RestartSec=30 RestartSec=30
User=vmail User=vmail
RuntimeDirectory=doveauth RuntimeDirectory=doveauth
UMask=0077
[Install] [Install]
WantedBy=multi-user.target WantedBy=multi-user.target

View File

@@ -1,4 +1,3 @@
import datetime
import smtplib import smtplib
import pytest import pytest
@@ -53,14 +52,6 @@ class TestSSHExecutor:
else: else:
pytest.fail("didn't raise exception") pytest.fail("didn't raise exception")
def test_opendkim_restarted(self, sshexec):
"""check that opendkim is not running for longer than a day."""
out = sshexec(call=remote.rshell.shell, kwargs=dict(command="systemctl status opendkim"))
assert type(out) == str
since_date_str = out.split("since ")[1].split(";")[0]
since_date = datetime.datetime.strptime(since_date_str, "%a %Y-%m-%d %H:%M:%S %Z")
assert (datetime.datetime.now() - since_date).total_seconds() < 60 * 60 * 24
def test_remote(remote, imap_or_smtp): def test_remote(remote, imap_or_smtp):
lineproducer = remote.iter_output(imap_or_smtp.logcmd) lineproducer = remote.iter_output(imap_or_smtp.logcmd)
@@ -124,27 +115,6 @@ def test_reject_missing_dkim(cmsetup, maildata, from_addr):
s.sendmail(from_addr=from_addr, to_addrs=recipient.addr, msg=msg) 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 @pytest.mark.slow
def test_exceed_rate_limit(cmsetup, gencreds, maildata, chatmail_config): def test_exceed_rate_limit(cmsetup, gencreds, maildata, chatmail_config):
"""Test that the per-account send-mail limit is exceeded.""" """Test that the per-account send-mail limit is exceeded."""