diff --git a/protocol.go b/protocol.go index d8a3297..a047f02 100644 --- a/protocol.go +++ b/protocol.go @@ -202,6 +202,11 @@ func (session *session) handleMAIL(cmd command) { return } + if session.server.Authenticator != nil && session.peer.Username == "" { + session.reply(530, "Authentication Required.") + return + } + if !session.tls && session.server.ForceTLS { session.reply(502, "Please turn on TLS by issuing a STARTTLS command.") return diff --git a/smtpd_test.go b/smtpd_test.go index 17cf0b2..dbe8d85 100644 --- a/smtpd_test.go +++ b/smtpd_test.go @@ -391,6 +391,33 @@ func TestAuthNotSupported(t *testing.T) { } +func TestAuthBypass(t *testing.T) { + + addr, closer := runsslserver(t, &smtpd.Server{ + Authenticator: func(peer smtpd.Peer, username, password string) error { + return smtpd.Error{Code: 550, Message: "Denied"} + }, + ForceTLS: true, + ProtocolLogger: log.New(os.Stdout, "log: ", log.Lshortfile), + }) + + defer closer() + + c, err := smtp.Dial(addr) + if err != nil { + t.Fatalf("Dial failed: %v", err) + } + + if err := c.StartTLS(&tls.Config{InsecureSkipVerify: true}); err != nil { + t.Fatalf("STARTTLS failed: %v", err) + } + + if err := c.Mail("sender@example.org"); err == nil { + t.Fatal("Unexpected MAIL success") + } + +} + func TestConnectionCheck(t *testing.T) { addr, closer := runserver(t, &smtpd.Server{ @@ -1270,12 +1297,8 @@ func TestErrors(t *testing.T) { t.Fatalf("AUTH didn't fail: %v", err) } - if err := c.Mail("sender@example.org"); err != nil { - t.Fatalf("MAIL failed: %v", err) - } - if err := c.Mail("sender@example.org"); err == nil { - t.Fatal("Duplicate MAIL didn't fail") + t.Fatalf("MAIL didn't fail") } if err := cmd(c.Text, 502, "STARTTLS"); err != nil { @@ -1310,6 +1333,14 @@ func TestErrors(t *testing.T) { t.Fatalf("AUTH didn't work: %v", err) } + if err := c.Mail("sender@example.org"); err != nil { + t.Fatalf("MAIL failed: %v", err) + } + + if err := c.Mail("sender@example.org"); err == nil { + t.Fatalf("Duplicate MAIL didn't fail") + } + if err := c.Quit(); err != nil { t.Fatalf("Quit failed: %v", err) }