From fb2eb3771c2494a4eb50b263658063410828d8fd Mon Sep 17 00:00:00 2001 From: Sean van Osnabrugge <18647660+osnabrugge@users.noreply.github.com> Date: Thu, 16 Apr 2026 18:24:10 -0400 Subject: [PATCH] smtp: add LOGIN SASL auth directive --- internal/target/smtp/sasl.go | 10 ++++++++-- internal/target/smtp/sasl_test.go | 17 +++++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/internal/target/smtp/sasl.go b/internal/target/smtp/sasl.go index 75f5d4e5..96861721 100644 --- a/internal/target/smtp/sasl.go +++ b/internal/target/smtp/sasl.go @@ -57,12 +57,18 @@ func saslAuthDirective(_ *config.Map, node config.Node) (interface{}, error) { } return sasl.NewPlainClient("", msgMeta.Conn.AuthUser, msgMeta.Conn.AuthPassword), nil }, nil - case "plain": + case "plain", "login": if len(node.Args) != 3 { return nil, config.NodeErr(node, "two additional arguments are required (username, password)") } return func(*module.MsgMetadata) (sasl.Client, error) { - return sasl.NewPlainClient("", node.Args[1], node.Args[2]), nil + if node.Args[0] == "plain" { + return sasl.NewPlainClient("", node.Args[1], node.Args[2]), nil + } + if node.Args[0] == "login" { + return sasl.NewLoginClient(node.Args[1], node.Args[2]), nil + } + return nil, config.NodeErr(node, "unknown authentication mechanism: %s", node.Args[0]) }, nil case "external": if len(node.Args) > 1 { diff --git a/internal/target/smtp/sasl_test.go b/internal/target/smtp/sasl_test.go index a1054845..c28ec7e4 100644 --- a/internal/target/smtp/sasl_test.go +++ b/internal/target/smtp/sasl_test.go @@ -101,6 +101,23 @@ func TestSASL_Plain_AuthFail(t *testing.T) { } } +func TestSASL_Login_Directive(t *testing.T) { + factory := testSaslFactory(t, "login", "test", "testpass") + client, err := factory(nil) + if err != nil { + t.Fatal(err) + } + + mech, _, err := client.Start() + if err != nil { + t.Fatal(err) + } + + if mech != "LOGIN" { + t.Fatalf("expected LOGIN mechanism, got %q", mech) + } +} + func TestSASL_Forward(t *testing.T) { be, srv := testutils.SMTPServer(t, "127.0.0.1:"+testPort) defer func() {