# General config
compatibility_level=3.6

inet_interfaces = all
inet_protocols = ipv4

# Accept mail for any recipient. We'll filter later
mydestination = pcre:/etc/postfix/localmap
local_recipient_maps =
virtual_alias_maps =
virtual_mailbox_maps =

# Use milter for synchronous delivery during SMTP session (before queue)
smtpd_milters = unix:/var/spool/postfix/milter/delivery.sock
milter_default_action = tempfail
milter_protocol = 6

# Since milter handles delivery, use simple local delivery to discard
local_transport = discard

# Rate limiting, disabled for now
smtpd_client_event_limit_exceptions = static:all

# Logging
maillog_file = /dev/stdout

smtpd_recipient_limit = 100
smtpd_hard_error_limit = 50
bounce_queue_lifetime = 0

# Disable any conflicting delivery settings
home_mailbox =

# Proxy support
postscreen_client_connection_count_limit = 1000

# Security
disable_vrfy_command = yes

# SMTP smuggling defense (CVE-2023-51764 family + USENIX'25 variants).
# Postfix 3.9+ defaults to ``normalize`` but we pin explicitly so a
# distro / image change can't silently re-introduce the vector.
#
# NOTE: this is **defense in depth, not sufficient on its own**.
# The Python backend parser must defend the same threat model
# independently because many ingest paths (EML upload, mbox / PST /
# IMAP import, drafts, forwards) bypass this MTA-in layer entirely.
# A future migration to a Python-native MTA-in (suitenumerique/messages
# PR #692) makes these settings transitional. See
# the ``jmap-email`` library's ``parse_email`` for the canonical hardening.
#
#  - ``normalize`` rewrites every bare-LF in DATA to CRLF before the
#    cleanup queue, defeating the <LF>.<CR><LF> end-of-DATA confusion.
#  - The empty exclusions list prevents bypass by clients on
#    ``$mynetworks`` — we set ``mynetworks`` tight below.
#  - ``smtpd_forbid_unauth_pipelining = yes`` blocks the pre-greeting /
#    pre-banner pipeline attacks.
smtpd_forbid_bare_newline = normalize
smtpd_forbid_bare_newline_exclusions =
smtpd_forbid_unauth_pipelining = yes
mynetworks = 127.0.0.0/8 [::1]/128

# Done through postconf in entrypoint.sh:
# - message_size_limit

# Extended debug
# debug_peer_level = 10
# debug_peer_list = 127.0.0.1,192.168.0.3,192.168.0.2,172.30.0.1

# TODO
# local_destination_concurrency_limit
# local_destination_recipient_limit / smtpd_recipient_limit
# mailbox_size_limit
