Fix SMTP AUTH LOGIN method for servers with uncommon success messages

This fixes #94 and basically reverts d0f0435. As James points out correctly in #94, we should not assume specific responses from the server. As long as the spec is followed and the server returns the correct SMTP code, we should not do our own magic.

I've also extended the `getTestConnection` method in client_test.go, so that we can specify more test environment options like `TEST_PORT` and `TEST_TLS_SKIP_VERIFY`. This was needed for testing with the ProtonMail Bridge which listens on a different port and has non-trusted certificates.
This commit is contained in:
Winni Neessen 2023-01-07 11:31:46 +01:00
parent 3b3c1e6e8d
commit 862749f863
Signed by: wneessen
GPG key ID: 385AC9889632126E
2 changed files with 17 additions and 10 deletions

View file

@ -9,7 +9,6 @@ import (
"errors" "errors"
"fmt" "fmt"
"net/smtp" "net/smtp"
"strings"
) )
type loginAuth struct { type loginAuth struct {
@ -23,10 +22,6 @@ const (
// ServerRespPassword represents the "Password:" response by the SMTP server // ServerRespPassword represents the "Password:" response by the SMTP server
ServerRespPassword = "Password:" ServerRespPassword = "Password:"
// ServerRespAuthSuccess represents the "Authentication successful:" response that is
// by sent by some SMTP servers
ServerRespAuthSuccess = "Authentication successful"
) )
// LoginAuth returns an Auth that implements the LOGIN authentication // LoginAuth returns an Auth that implements the LOGIN authentication
@ -70,10 +65,9 @@ func (a *loginAuth) Next(fromServer []byte, more bool) ([]byte, error) {
return []byte(a.username), nil return []byte(a.username), nil
case ServerRespPassword: case ServerRespPassword:
return []byte(a.password), nil return []byte(a.password), nil
default:
return nil, fmt.Errorf("unexpected server response: %s", string(fromServer))
} }
} }
if strings.HasSuffix(string(fromServer), ServerRespAuthSuccess) { return nil, nil
return nil, nil
}
return nil, fmt.Errorf("unexpected server response: %s", string(fromServer))
} }

View file

@ -11,6 +11,7 @@ import (
"fmt" "fmt"
"net/smtp" "net/smtp"
"os" "os"
"strconv"
"strings" "strings"
"testing" "testing"
"time" "time"
@ -1087,10 +1088,22 @@ func getTestConnection(auth bool) (*Client, error) {
if th == "" { if th == "" {
return nil, fmt.Errorf("no TEST_HOST set") return nil, fmt.Errorf("no TEST_HOST set")
} }
c, err := NewClient(th) tp := 25
if tps := os.Getenv("TEST_PORT"); tps != "" {
tpi, err := strconv.Atoi(tps)
if err == nil {
tp = tpi
}
}
sv := false
if sve := os.Getenv("TEST_TLS_SKIP_VERIFY"); sve != "" {
sv = true
}
c, err := NewClient(th, WithPort(tp))
if err != nil { if err != nil {
return c, err return c, err
} }
c.tlsconfig.InsecureSkipVerify = sv
if auth { if auth {
st := os.Getenv("TEST_SMTPAUTH_TYPE") st := os.Getenv("TEST_SMTPAUTH_TYPE")
if st != "" { if st != "" {