Authentication System
aiosmtpd provides a framework for SMTP Authentication that fully complies with RFC 4954.
Activating Authentication
aiosmtpd authentication is always activated,
but attempts to authenticate will always be rejected
unless the authenticator parameter of SMTP
is set to a valid & working Authenticator Callback.
AUTH API
The aiosmtpd Authentication Framework comprises several components,
who are collectivelly called the “AUTH API”.
AUTH Handler Hook
- async handle_AUTH(server: SMTP, session: Session, envelope: Envelope, args)
Called to handle
AUTHcommand, if you need custom AUTH behavior.Most of the time, you will NOT need to implement this hook; AUTH Mechanism Hooks are provided to override/implement selective SMTP AUTH mechanisms (see below).
If you do implement this hook:
You MUST comply with RFC 4954.
argswill contain the list of words following theAUTHcommand.You will have to leverage the
SMTP.push()andSMTP.challenge_auth()methods to interact with the clients.You will need to modify the
session.auth_dataandsession.authenticatedattributes.You may ignore the
envelope.
AUTH Mechanism Hooks
Separately from AUTH Handler Hook,
aiosmtpd also implement support for “AUTH Mechanism Hooks”.
These async hooks will implement the logic for SMTP Authentication Mechanisms.
Every AUTH Mechanism Hook is named auth_MECHANISM
where MECHANISM is the all-uppercase name of the mechanism
that the hook will implement.
(Mechanism is the word following the AUTH command sent by client.)
Important
If MECHANISM has a dash within its name,
use double-underscore to represent the dash.
For example, to implement a MECH-WITH-DASHES mechanism,
name the AUTH hook as auth_MECH__WITH__DASHES.
Single underscores will not be modified.
So a hook named auth_MECH_WITH_UNDERSCORE
will implement the MECH_WITH_UNDERSCORE mechanism.
(If in the future a SASL mechanism with double underscores in its name gets defined, this name-mangling mechanism will be revisited. That is very unlikely to happen, though.)
Alternatively, you can also use the auth_mechanism() decorator,
which you can import from the aiosmtpd.smtp module.
The SMTP class provides built-in AUTH hooks for the LOGIN and PLAIN
mechanisms, named auth_LOGIN and auth_PLAIN, respectively.
If the handler class implements auth_LOGIN and/or auth_PLAIN, then
the methods of the handler instance will override the built-in methods.
- async auth_MECHANISM(server: SMTP, args: List[str]) aiosmtpd.smtp.AuthResult
- Parameters:
server – The instance of the
SMTPclass invoking the AUTH Mechanism hookargs – A list of string split from the characters following the
AUTHcommand.args[0]is usually equal toMECHANISM(unless theauth_mechanism()decorator has been used).
The AUTH hook MUST perform the actual validation of AUTH credentials.
In the built-in AUTH hooks, this is done by invoking the function specified by the
authenticatorinitialization argument.AUTH Mechanism Hooks in handlers are NOT required to do the same, and MAY implement their own authenticator system.
The AUTH Mechanism Hook MUST return an instance of
AuthResultcontaining the result of the Authentication process.
Important
Defining additional AUTH hooks in your handler
will NOT disable the built-in LOGIN and PLAIN hooks;
if you do not want to offer the LOGIN and PLAIN mechanisms,
specify them in the auth_exclude_mechanism parameter
of the SMTP class.
Authenticator Callback
- Authenticator(server, session, envelope, mechanism, auth_data) AuthResult
- Parameters:
server – The
SMTPinstance that invoked the authenticatorsession – A
Sessioninstance containing session data so farenvelope – An
Envelopeinstance containing transaction data so farmechanism (str) – name of the AUTH Mechanism chosen by the client
auth_data – A data structure containing authentication data gathered by the AUTH Mechanism
- Returns:
Result of authentication
- Return type:
This function would be invoked during or at the end of an Authentication Process by AUTH Mechanisms. Based on
mechanismandauth_data, this function should return a decision on whether Authentication has been successful or not.This function SHOULD NOT modify the attributes of
sessionandenvelope.The type and contents of the
auth_dataparameter is wholly at the discretion of the calling AUTH Mechanism. For the built-inLOGINandPLAINMechanisms, the type of data will beaiosmtpd.smtp.LoginPasswordAdded in version 1.3.
AuthResult API
- class AuthResult(*, success, handled, message, auth_data)
- success: bool
This attribute indicates whether Authentication is successful or not.
- handled: bool = True
This attribute indicates whether Authenticator Decision process (e.g., sending of status codes) have been carried out by Authenticator or not.
If set to
True,smtp_AUTH()will not perform additional processing and will simply exits.Applicable only if
success=False
- message: str | None = None
The message to send back to client, regardless of success status.
This message will be sent as-is; as such, it MUST be prefixed with the correct SMTP Status Code and optionally, SMTP Extended Status Code.
If not given (set/kept to
None),smtp_AUTH()will use standard SMTP Status Code & Message.
- auth_data: Any = None
Optional free-form authentication data. This will be saved by
smtp_AUTH()into thesession.auth_dataattribute.If
auth_datahas the attributelogin, thensmtp_AUTH()will saveauth_data.loginintosession.login_dataas well. This is to cater for possible backward-compatibility requirements, where legacy handlers might be looking forsession.login_datafor some reasons.
Security Considerations
We have taken steps to prevent leakage of sensitive information (i.e., password) through logging
by overriding the __repr__ and __str__ methods of the AuthResult and
LoginPassword classes.
However, we have no control on the (logging) output of your custom hooks. Please be very careful emitting/recording AUTH information to prevent leakage.
Example
An example is provided in examples/authenticated_relayer.