mirror of
https://github.com/chatmail/relay.git
synced 2026-06-10 13:41:08 +00:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 48a64cc5c9 |
@@ -10,6 +10,7 @@ dependencies = [
|
|||||||
"filelock",
|
"filelock",
|
||||||
"requests",
|
"requests",
|
||||||
"crypt-r >= 3.13.1 ; python_version >= '3.11'",
|
"crypt-r >= 3.13.1 ; python_version >= '3.11'",
|
||||||
|
"domain-validator",
|
||||||
]
|
]
|
||||||
|
|
||||||
[tool.setuptools]
|
[tool.setuptools]
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import ipaddress
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
import iniconfig
|
import iniconfig
|
||||||
|
from domain_validator import DomainValidator
|
||||||
|
|
||||||
from chatmaild.user import User
|
from chatmaild.user import User
|
||||||
|
|
||||||
@@ -24,6 +25,7 @@ class Config:
|
|||||||
self.mail_domain = f"[{raw_domain}]"
|
self.mail_domain = f"[{raw_domain}]"
|
||||||
self.postfix_myhostname = ipaddress.IPv4Address(raw_domain).reverse_pointer
|
self.postfix_myhostname = ipaddress.IPv4Address(raw_domain).reverse_pointer
|
||||||
else:
|
else:
|
||||||
|
DomainValidator().validate_domain_re(raw_domain)
|
||||||
self.ipv4_relay = None
|
self.ipv4_relay = None
|
||||||
self.mail_domain = raw_domain
|
self.mail_domain = raw_domain
|
||||||
self.postfix_myhostname = raw_domain
|
self.postfix_myhostname = raw_domain
|
||||||
|
|||||||
@@ -125,6 +125,8 @@ class MetadataDictProxy(DictProxy):
|
|||||||
case "maxsmtprecipients":
|
case "maxsmtprecipients":
|
||||||
# postfix default (see "postconf smtpd_recipient_limit")
|
# postfix default (see "postconf smtpd_recipient_limit")
|
||||||
return "O1000\n"
|
return "O1000\n"
|
||||||
|
case "unixtimestamp":
|
||||||
|
return f"O{int(time.time())}\n"
|
||||||
|
|
||||||
logging.warning(f"lookup ignored: {parts!r}")
|
logging.warning(f"lookup ignored: {parts!r}")
|
||||||
return "N\n"
|
return "N\n"
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
"acme-enter-email": "{{ email }}"
|
"acme-enter-email": "{{ email }}"
|
||||||
"acme-agreement:https://letsencrypt.org/documents/LE-SA-v1.7-June-04-2026.pdf": true
|
"acme-agreement:https://letsencrypt.org/documents/LE-SA-v1.6-August-18-2025.pdf": true
|
||||||
|
|||||||
@@ -166,7 +166,7 @@ class Deployer:
|
|||||||
return self.put_template(src, dest, **kwargs)
|
return self.put_template(src, dest, **kwargs)
|
||||||
return self.put_file(src, dest)
|
return self.put_file(src, dest)
|
||||||
|
|
||||||
def put_file(self, src, dest, mode="644", **kwargs):
|
def put_file(self, src, dest, mode="644"):
|
||||||
if isinstance(src, str):
|
if isinstance(src, str):
|
||||||
src = get_resource(src)
|
src = get_resource(src)
|
||||||
res = files.put(
|
res = files.put(
|
||||||
@@ -176,7 +176,6 @@ class Deployer:
|
|||||||
user="root",
|
user="root",
|
||||||
group="root",
|
group="root",
|
||||||
mode=mode,
|
mode=mode,
|
||||||
**kwargs,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
return self._update_restart_signals(dest, res)
|
return self._update_restart_signals(dest, res)
|
||||||
|
|||||||
@@ -164,7 +164,6 @@ class UnboundDeployer(Deployer):
|
|||||||
self.put_file(
|
self.put_file(
|
||||||
src=BytesIO(b"nameserver 127.0.0.1\nnameserver 9.9.9.9\n"),
|
src=BytesIO(b"nameserver 127.0.0.1\nnameserver 9.9.9.9\n"),
|
||||||
dest="/etc/resolv.conf",
|
dest="/etc/resolv.conf",
|
||||||
force=True,
|
|
||||||
)
|
)
|
||||||
server.shell(
|
server.shell(
|
||||||
name="Generate root keys for validating DNSSEC",
|
name="Generate root keys for validating DNSSEC",
|
||||||
|
|||||||
@@ -1,3 +1,23 @@
|
|||||||
/^DKIM-Signature:/ IGNORE
|
# List of headers for incoming messages
|
||||||
/^Authentication-Results:/ IGNORE
|
# that must be retained for functionality and compatibility reasons
|
||||||
/^Received:/ IGNORE
|
/^From:/ DUNNO
|
||||||
|
/^Message-Id:/ DUNNO
|
||||||
|
/^Chat-/ DUNNO
|
||||||
|
/^Content-Type:/ DUNNO
|
||||||
|
|
||||||
|
# For receiving clear-text messages (still supported in May 2026)
|
||||||
|
/^Subject:/ DUNNO
|
||||||
|
/^Date:/ DUNNO
|
||||||
|
/^To:/ DUNNO
|
||||||
|
/^CC:/ DUNNO
|
||||||
|
/^References:/ DUNNO
|
||||||
|
/^In-Reply-To:/ DUNNO
|
||||||
|
|
||||||
|
# Senders might support Autocrypt 1 but not RFC9788 (Header Protection)
|
||||||
|
/^Autocrypt:/ DUNNO
|
||||||
|
|
||||||
|
# SecureJoin V2 protocol headers (for backward compatibility)
|
||||||
|
/^Secure-Join/ DUNNO
|
||||||
|
|
||||||
|
# Ignore all other headers
|
||||||
|
/.*/ IGNORE
|
||||||
|
|||||||
@@ -10,11 +10,13 @@ from pathlib import Path
|
|||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from chatmaild.config import is_valid_ipv4, read_config
|
from chatmaild.config import is_valid_ipv4, read_config
|
||||||
|
from domain_validator import DomainValidator
|
||||||
|
|
||||||
|
|
||||||
def format_mail_domain(raw_domain: str) -> str:
|
def format_mail_domain(raw_domain: str) -> str:
|
||||||
if is_valid_ipv4(raw_domain):
|
if is_valid_ipv4(raw_domain):
|
||||||
return f"[{raw_domain}]"
|
return f"[{raw_domain}]"
|
||||||
|
DomainValidator().validate_domain_re(raw_domain)
|
||||||
return raw_domain
|
return raw_domain
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user