Skip to content

Commit

Permalink
Fix auth type auto-discovery and add test cases
Browse files Browse the repository at this point in the history
Refactor the auth type initialization to prevent incorrect assignments and handle empty supported lists. Added comprehensive test cases to verify auto-discovery selection of the strongest authentication method and ensure robustness against empty or invalid input.
  • Loading branch information
wneessen committed Nov 16, 2024
1 parent ac9117d commit 6d3640a
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 1 deletion.
5 changes: 4 additions & 1 deletion client.go
Original file line number Diff line number Diff line change
Expand Up @@ -1100,7 +1100,7 @@ func (c *Client) auth() error {
return fmt.Errorf("server does not support SMTP AUTH")
}

authType := c.smtpAuthType
var authType SMTPAuthType
if c.smtpAuthType == SMTPAuthAutoDiscover {
discoveredType, err := c.authTypeAutoDiscover(smtpAuthType)
if err != nil {
Expand Down Expand Up @@ -1182,6 +1182,9 @@ func (c *Client) auth() error {
}

func (c *Client) authTypeAutoDiscover(supported string) (SMTPAuthType, error) {
if supported == "" {
return "", ErrNoSupportedAuthDiscovered
}
preferList := []SMTPAuthType{SMTPAuthSCRAMSHA256PLUS, SMTPAuthSCRAMSHA256, SMTPAuthSCRAMSHA1PLUS, SMTPAuthSCRAMSHA1,
SMTPAuthXOAUTH2, SMTPAuthCramMD5, SMTPAuthPlain, SMTPAuthLogin}
if !c.isEncrypted {
Expand Down
36 changes: 36 additions & 0 deletions client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2514,6 +2514,42 @@ func TestClient_auth(t *testing.T) {
})
}

func TestClient_authTypeAutoDiscover(t *testing.T) {
tests := []struct {
supported string
tls bool
expect SMTPAuthType
shouldFail bool
}{
{"LOGIN SCRAM-SHA-256 SCRAM-SHA-1 SCRAM-SHA-256-PLUS SCRAM-SHA-1-PLUS", true, SMTPAuthSCRAMSHA256PLUS, false},
{"LOGIN SCRAM-SHA-256 SCRAM-SHA-1 SCRAM-SHA-256-PLUS SCRAM-SHA-1-PLUS", false, SMTPAuthSCRAMSHA256, false},
{"LOGIN PLAIN SCRAM-SHA-1 SCRAM-SHA-1-PLUS", true, SMTPAuthSCRAMSHA1PLUS, false},
{"LOGIN PLAIN SCRAM-SHA-1 SCRAM-SHA-1-PLUS", false, SMTPAuthSCRAMSHA1, false},
{"LOGIN XOAUTH2 SCRAM-SHA-1-PLUS", false, SMTPAuthXOAUTH2, false},
{"PLAIN LOGIN CRAM-MD5", false, SMTPAuthCramMD5, false},
{"CRAM-MD5", false, SMTPAuthCramMD5, false},
{"PLAIN", true, SMTPAuthPlain, false},
{"LOGIN PLAIN", true, SMTPAuthPlain, false},
{"LOGIN PLAIN", false, "no secure mechanism", true},
{"", false, "supported list empty", true},
}
for _, tt := range tests {
t.Run("AutoDiscover selects the strongest auth type: "+string(tt.expect), func(t *testing.T) {
client := &Client{smtpAuthType: SMTPAuthAutoDiscover, isEncrypted: tt.tls}
authType, err := client.authTypeAutoDiscover(tt.supported)
if err != nil && !tt.shouldFail {
t.Fatalf("failed to auto discover auth type: %s", err)
}
if tt.shouldFail && err == nil {
t.Fatal("expected auto discover to fail")
}
if !tt.shouldFail && authType != tt.expect {
t.Errorf("expected strongest auth type: %s, got: %s", tt.expect, authType)
}
})
}
}

func TestClient_Send(t *testing.T) {
message := testMessage(t)
t.Run("connect and send email", func(t *testing.T) {
Expand Down

0 comments on commit 6d3640a

Please sign in to comment.