feat(smtp): auth login extension draft support

This adds support for the auth login extension draft.
This commit is contained in:
James Elliott 2024-01-07 13:34:33 +11:00
parent 6cb8290e13
commit a73a914fb2
No known key found for this signature in database
GPG key ID: 0F1C4A096E857E49
2 changed files with 29 additions and 9 deletions

View file

@ -16,11 +16,31 @@ type loginAuth struct {
}
const (
// ServerRespUsername represents the "Username:" response by the SMTP server
ServerRespUsername = "Username:"
// LoginXUsernameChallenge represents the Username Challenge response sent by the SMTP server per the AUTH LOGIN
// extension.
//
// See: https://learn.microsoft.com/en-us/openspecs/exchange_server_protocols/ms-xlogin/.
LoginXUsernameChallenge = "Username:"
// ServerRespPassword represents the "Password:" response by the SMTP server
ServerRespPassword = "Password:"
// LoginXPasswordChallenge represents the Password Challenge response sent by the SMTP server per the AUTH LOGIN
// extension.
//
// See: https://learn.microsoft.com/en-us/openspecs/exchange_server_protocols/ms-xlogin/.
LoginXPasswordChallenge = "Password:"
// LoginXDraftUsernameChallenge represents the Username Challenge response sent by the SMTP server per the IETF
// draft AUTH LOGIN extension. It should be noted this extension is an expired draft which was never formally
// published and was deprecated in favor of the AUTH PLAIN extension.
//
// See: https://datatracker.ietf.org/doc/html/draft-murchison-sasl-login-00.
LoginXDraftUsernameChallenge = "User Name\x00"
// LoginXDraftPasswordChallenge represents the Password Challenge response sent by the SMTP server per the IETF
// draft AUTH LOGIN extension. It should be noted this extension is an expired draft which was never formally
// published and was deprecated in favor of the AUTH PLAIN extension.
//
// See: https://datatracker.ietf.org/doc/html/draft-murchison-sasl-login-00.
LoginXDraftPasswordChallenge = "Password\x00"
)
// LoginAuth returns an Auth that implements the LOGIN authentication
@ -56,9 +76,9 @@ func (a *loginAuth) Start(server *ServerInfo) (string, []byte, error) {
func (a *loginAuth) Next(fromServer []byte, more bool) ([]byte, error) {
if more {
switch string(fromServer) {
case ServerRespUsername:
case LoginXUsernameChallenge, LoginXDraftUsernameChallenge:
return []byte(a.username), nil
case ServerRespPassword:
case LoginXPasswordChallenge, LoginXDraftPasswordChallenge:
return []byte(a.password), nil
default:
return nil, fmt.Errorf("unexpected server response: %s", string(fromServer))

View file

@ -57,10 +57,10 @@ var authTests = []authTest{
},
{
LoginAuth("user", "pass", "testserver"),
[]string{"Username:", "Password:", "Invalid:"},
[]string{"Username:", "Password:", "User Name\x00", "Password\x00", "Invalid:"},
"LOGIN",
[]string{"", "user", "pass", ""},
[]bool{false, false, true},
[]string{"", "user", "pass", "user", "pass", ""},
[]bool{false, false, false, false, true},
},
{
CRAMMD5Auth("user", "pass"),