-
-
Notifications
You must be signed in to change notification settings - Fork 105
Description
Version
v2.10.0 (also tested on latest)
Description
When connecting to an SMTP server that advertises only AUTH LOGIN (no STARTTLS, no AUTH PLAIN), authentication always fails with 535 Authentication Failed.
Server capabilities
250-localhost
250-AUTH LOGIN
250 HELP
No STARTTLS, no SSL — plain connection on port 587 with EncryptionNone.
Root cause
In smtp.go, the authenticate() function sends the initial response immediately alongside AUTH LOGIN:
code, msg64, err := c.cmd(0, strings.TrimSpace(fmt.Sprintf("AUTH %s %s", mech, resp64)))This sends AUTH LOGIN <base64> in one shot. However, the AUTH LOGIN protocol requires a challenge-response flow:
- Client sends:
AUTH LOGIN - Server responds:
334 VXNlcm5hbWU6(base64 of "Username:") - Client sends:
<base64 username> - Server responds:
334 UGFzc3dvcmQ6(base64 of "Password:") - Client sends:
<base64 password> - Server responds:
235 Authentication successful
By sending the initial response immediately, the library skips step 2 and confuses the server, causing 535.
Proof
The same credentials work perfectly using net/smtp with a custom LoginAuth that returns nil as the initial response:
func (a *loginAuth) Start(server *smtp.ServerInfo) (string, []byte, error) {
return "LOGIN", nil, nil // sends just "AUTH LOGIN", then waits for challenge
}
func (a *loginAuth) Next(fromServer []byte, more bool) ([]byte, error) {
if more {
switch string(fromServer) {
case "Username:":
return []byte(a.username), nil
case "Password:":
return []byte(a.password), nil
default:
return nil, fmt.Errorf("unexpected server challenge: %s", fromServer)
}
}
return nil, nil
}Expected behavior
AUTH LOGIN should send no initial response and wait for the server's 334 Username: challenge before sending credentials.
Suggested fix
In authenticate(), when the mechanism is LOGIN, the initial resp returned by a.start() should be nil, and the first cmd should send only AUTH LOGIN without appending any base64 data.
Thanks for maintaining this library — it's been really useful. I hope this report helps improve compatibility with servers that strictly follow the AUTH LOGIN challenge-response flow.