The MTA's Sovite.SMTP.Server.Handler: relay control, restrictions,
authentication, recipient checks and expansion, and durable spooling.
Recipients are checked at RCPT time:
<Postmaster>, andpostmaster@andabuse@any hosted domain, are always accepted (RFC 5321 §4.5.1, RFC 2142). A bare<Postmaster>is queued aspostmaster@<server.hostname>.- Domains this server handles (local, aliased, hosted, and relay; see
Sovite.Core.Routing): the recipient is expanded (Sovite.Core.Recipients.expand/2); one that no alias matched must be a known user (Sovite.Core.Recipients.check/2), otherwise550 5.1.1. - Any other destination, including address literals: accepted only from
smtp.trusted_networksor afterAUTH, otherwise554 5.7.1 Relay access denied. The default config trusts no one, so it is never an open relay.
Domains are compared case-insensitively. Address tricks such as
user%remote@local or source routes do not relay: only the domain of
the parsed mailbox counts.
The restriction chains (Sovite.Core.Restrictions) run at connect,
EHLO, MAIL, RCPT, DATA, and at the end of the data, after the
built-in checks of each stage; they can reject, but never permit what
relay control or recipient validation refuses.
Rewriting
The sender is rewritten at MAIL (Sovite.Core.Rewrite.sender/2) and
each recipient at RCPT, before expansion. routing.always_bcc and
the BCC maps add recipients at DATA. Mail from trusted networks and
authenticated clients also gets its header addresses rewritten.
Authentication
AUTH runs against the configured backend (auth.backend), see
Sovite.SASL.Server and Sovite.SASL.Dovecot. Failed logins are
counted per client address (per /64 for IPv6) in a
Sovite.Abuse.Penalty; a banned address gets 454 4.7.0 to AUTH, and
is turned away at connect on listeners that require authentication.
Each failure is answered after auth.failure_delay, to slow down
guessing.
An authenticated client may only use the sender addresses its login
maps to, see Sovite.Core.SenderCheck.
Submission fixes
Messages from authenticated clients are fixed up as RFC 6409 §8 allows:
a missing Date: or Message-ID: is added, and the header fields in
submission.strip_headers are removed.
Loops
A message with more than smtp.max_hops Received: fields is refused
at the end of the data with 554 5.4.6 (RFC 5321 §6.3): it is most
likely going round in circles.
Queueing
The message is accepted with 250 only after Sovite.Queue.Spool
has made it durable. A Received: header is added at the top. The
queue manager given as :queue_manager is then told about it. A
message a restriction put on hold goes to the hold queue instead; one
it discarded is accepted and dropped.
Telemetry
[:sovite, :smtp, :message, :discarded]and[:sovite, :smtp, :message, :held]-%{},%{session_id, queue_id, reason}[:sovite, :routing, :expansion_error]-%{},%{session_id, recipient, reason}
Summary
Functions
Handler options from the running configuration.
Functions
@spec opts(Sovite.Core.Config.t(), GenServer.server() | nil, keyword()) :: map()
Handler options from the running configuration.
queue_manager- theSovite.Core.QueueManagerto notify about new messages, if any.runtime-:repo(aSovite.Core.Reporeference),:penalty(the name of theSovite.Abuse.Penaltyfor failed logins),:require_auth(the listener requires authentication), and:resolver(for restrictions that look up domains).