By default Halon supports two SASL AUTH mechanism (LOGIN and PLAIN), both of which are simple username/password based methods, which requires not complex state transitions or server based reply in order to obtain a username and password (which then can be easily authenticated in the AUTH script). However other SASL mechanism exist and most of them do not have a simple username/password scheme, some rely on a server generated challenge or multiple steps (responses/replies) in order to authenticate the user (e.g. OAUTHBEARER, OTP and CRAM-MD5). In order to enable you to build custom authentication we've given you direct access to the client response data (as defined by rfc4954), and also the ability to send custom reply (response) while holding an state in the AUTH script.
The initial client response will be available in the first execution of the AUTH script (in the $saslresponse) variable. The $saslstate will be zero.
AUTH mechanism [initial-response]
You may then choose any of the four functions
- Accept - Accept the request (you should also set the username by argument).
- Defer - Deny the authentication request with a temporary error.
- Reject - Deny the authentication request with a permanent error.
- Reply - Send a reply, which will cause the next user-input to execute the authentication script again.
If we expect the actions of Accept, Defer and Reject to be straight forward regardless of the state we're in, we focus on you sending a Reply. The Reply function send a 334 reply to the client with the response you provided base64 encoded. The next user input will execute the AUTH script once again with $saslstate incremented by one (in this example it's gonna be one).
334 [reply]
[client-response]
This chat scheme will move on until you call either Accept, Defer or Reject. In order to save state between each AUTH script execution, you can store data in the $context variable, based on the current $saslstate.
In order to announce and support (run the AUTH script for that mechanism) custom SASL mechanism you will need to add them to the SMTP servers list of supported mechanisms. That is done on the Configuration -> Email engine -> Settings page per SMTP server configuration.
CRAM-MD5
In this section we will implement the CRAM-MD5 mechanism to our AUTH script. We start by announcing support for it to the SMTP server on the Configuration -> Email engine -> Settings page, add CRAM-MD5 to the Mechanisms input field with the other mechanisms (e.g. LOGIN,PLAIN). Then add the following to your AUTH script.
if ($saslmechanism == "CRAM-MD5")
{
if ($saslstate == 0)
{
if ($saslresponse != none)
Reject("Bad syntax");
$context["saslchallenge"] = "<" . uuid() . "@" . gethostname() . ">";
Reply($context["saslchallenge"]);
}
if ($saslstate == 1)
{
[$username, $password] = explode(" ", $saslresponse);
if ($username == "john.doe" and $password == hmac_md5("secret", $context["saslchallenge"]))
Accept(["username" => $username]);
Reject("Sorry");
}
}
Comments
0 comments
Article is closed for comments.