From 701fa1c5ed8df2cde01487729c0e29c924e08050 Mon Sep 17 00:00:00 2001 From: Johnny Luo Date: Fri, 24 Nov 2017 21:21:44 +1100 Subject: [PATCH] net/smtp: return error from SendMail when required AUTH not available Return an error if an Auth is passed to SendMail but the server does not support authentication. Fixes #22145 Change-Id: I49a37259c47bbe5145e30fa8a2d05444e60cb378 Reviewed-on: https://go-review.googlesource.com/79776 Reviewed-by: Brad Fitzpatrick --- src/net/smtp/smtp.go | 9 ++++--- src/net/smtp/smtp_test.go | 52 ++++++++++++++++++++++++++++++++++----- 2 files changed, 51 insertions(+), 10 deletions(-) diff --git a/src/net/smtp/smtp.go b/src/net/smtp/smtp.go index cf699e6be8..e4e12ae5ee 100644 --- a/src/net/smtp/smtp.go +++ b/src/net/smtp/smtp.go @@ -343,10 +343,11 @@ func SendMail(addr string, a Auth, from string, to []string, msg []byte) error { } } if a != nil && c.ext != nil { - if _, ok := c.ext["AUTH"]; ok { - if err = c.Auth(a); err != nil { - return err - } + if _, ok := c.ext["AUTH"]; !ok { + return errors.New("smtp: server doesn't support AUTH") + } + if err = c.Auth(a); err != nil { + return err } } if err = c.Mail(from); err != nil { diff --git a/src/net/smtp/smtp_test.go b/src/net/smtp/smtp_test.go index d489922597..e97aaa4486 100644 --- a/src/net/smtp/smtp_test.go +++ b/src/net/smtp/smtp_test.go @@ -15,6 +15,7 @@ import ( "net/textproto" "runtime" "strings" + "sync" "testing" "time" ) @@ -635,6 +636,50 @@ SendMail is working for me. QUIT ` +func TestSendMailWithAuth(t *testing.T) { + l, err := net.Listen("tcp", "127.0.0.1:0") + if err != nil { + t.Fatalf("Unable to to create listener: %v", err) + } + defer l.Close() + wg := sync.WaitGroup{} + var done = make(chan struct{}) + go func() { + defer wg.Done() + conn, err := l.Accept() + if err != nil { + t.Errorf("Accept error: %v", err) + return + } + defer conn.Close() + + tc := textproto.NewConn(conn) + tc.PrintfLine("220 hello world") + msg, err := tc.ReadLine() + if msg == "EHLO localhost" { + tc.PrintfLine("250 mx.google.com at your service") + } + // for this test case, there should have no more traffic + <-done + }() + wg.Add(1) + + err = SendMail(l.Addr().String(), PlainAuth("", "user", "pass", "smtp.google.com"), "test@example.com", []string{"other@example.com"}, []byte(strings.Replace(`From: test@example.com +To: other@example.com +Subject: SendMail test + +SendMail is working for me. +`, "\n", "\r\n", -1))) + if err == nil { + t.Error("SendMail: Server doesn't support AUTH, expected to get an error, but got none ") + } + if err.Error() != "smtp: server doesn't support AUTH" { + t.Errorf("Expected: smtp: server doesn't support AUTH, got: %s", err) + } + close(done) + wg.Wait() +} + func TestAuthFailed(t *testing.T) { server := strings.Join(strings.Split(authFailedServer, "\n"), "\r\n") client := strings.Join(strings.Split(authFailedClient, "\n"), "\r\n") @@ -830,14 +875,9 @@ func init() { } func sendMail(hostPort string) error { - host, _, err := net.SplitHostPort(hostPort) - if err != nil { - return err - } - auth := PlainAuth("", "", "", host) from := "joe1@example.com" to := []string{"joe2@example.com"} - return SendMail(hostPort, auth, from, to, []byte("Subject: test\n\nhowdy!")) + return SendMail(hostPort, nil, from, to, []byte("Subject: test\n\nhowdy!")) } // (copied from net/http/httptest)