Переглянути джерело

Emptymailfrom (#59)

* Fix for issue #53.
* We now accept Bounce mails (MAIL FROM:<>)
* Some tests for MAIL FROM
Philipp Resch 8 роки тому
батько
коміт
94b7ac9deb
2 змінених файлів з 202 додано та 1 видалено
  1. 9 1
      server.go
  2. 193 0
      tests/guerrilla_test.go

+ 9 - 1
server.go

@@ -17,6 +17,7 @@ import (
 	"sync/atomic"
 
 	"github.com/flashmob/go-guerrilla/backends"
+	"github.com/flashmob/go-guerrilla/envelope"
 	"github.com/flashmob/go-guerrilla/response"
 )
 
@@ -346,7 +347,14 @@ func (server *server) handleClient(client *client) {
 					client.responseAdd(response.CustomString(response.InvalidCommand, 503, response.ClassPermanentFailure, "Error: nested MAIL command"))
 					break
 				}
-				from, err := extractEmail(input[10:])
+				// Fix for issue #53 - MAIL FROM may only be <> if it is a bounce
+				mail := input[10:]
+				from := &envelope.EmailAddress{}
+				if mail[0:2] != "<>" {
+					// Not Bounce, extract mail.
+					from, err = extractEmail(mail)
+				}
+
 				if err != nil {
 					client.responseAdd(err.Error())
 				} else {

+ 193 - 0
tests/guerrilla_test.go

@@ -535,6 +535,199 @@ func TestRFC2821LimitDomain(t *testing.T) {
 	logIn.Reset(&logBuffer)
 }
 
+// Test several different inputs to MAIL FROM command
+func TestMailFromCmd(t *testing.T) {
+	if initErr != nil {
+		t.Error(initErr)
+		t.FailNow()
+	}
+	if startErrors := app.Start(); startErrors == nil {
+		conn, bufin, err := Connect(config.Servers[0], 20)
+		if err != nil {
+			// handle error
+			t.Error(err.Error(), config.Servers[0].ListenInterface)
+			t.FailNow()
+		} else {
+			// client goes into command state
+			if _, err := Command(conn, bufin, "HELO localtester"); err != nil {
+				t.Error("Hello command failed", err.Error())
+			}
+			// Basic valid address
+			response, err := Command(conn, bufin, "MAIL FROM:[email protected]")
+			if err != nil {
+				t.Error("command failed", err.Error())
+			}
+			expected := "250 2.1.0 OK"
+			if strings.Index(response, expected) != 0 {
+				t.Error("Server did not respond with", expected, ", it said:"+response)
+			}
+
+			// Reset
+			response, err = Command(conn, bufin, "RSET")
+			if err != nil {
+				t.Error("command failed", err.Error())
+			}
+			expected = "250 2.1.0 OK"
+			if strings.Index(response, expected) != 0 {
+				t.Error("Server did not respond with", expected, ", it said:"+response)
+			}
+
+			// Basic valid address (RfC)
+			response, err = Command(conn, bufin, "MAIL FROM:<[email protected]>")
+			if err != nil {
+				t.Error("command failed", err.Error())
+			}
+			expected = "250 2.1.0 OK"
+			if strings.Index(response, expected) != 0 {
+				t.Error("Server did not respond with", expected, ", it said:"+response)
+			}
+
+			// Reset
+			response, err = Command(conn, bufin, "RSET")
+			if err != nil {
+				t.Error("command failed", err.Error())
+			}
+			expected = "250 2.1.0 OK"
+			if strings.Index(response, expected) != 0 {
+				t.Error("Server did not respond with", expected, ", it said:"+response)
+			}
+
+			// Bounce
+			response, err = Command(conn, bufin, "MAIL FROM:<>")
+			if err != nil {
+				t.Error("command failed", err.Error())
+			}
+			expected = "250 2.1.0 OK"
+			if strings.Index(response, expected) != 0 {
+				t.Error("Server did not respond with", expected, ", it said:"+response)
+			}
+
+			// Reset
+			response, err = Command(conn, bufin, "RSET")
+			if err != nil {
+				t.Error("command failed", err.Error())
+			}
+			expected = "250 2.1.0 OK"
+			if strings.Index(response, expected) != 0 {
+				t.Error("Server did not respond with", expected, ", it said:"+response)
+			}
+
+			// What?
+			response, err = Command(conn, bufin, "MAIL FROM:<<>>")
+			if err != nil {
+				t.Error("command failed", err.Error())
+			}
+			expected = "501 5.5.4 Invalid address"
+			if strings.Index(response, expected) != 0 {
+				t.Error("Server did not respond with", expected, ", it said:"+response)
+			}
+
+			// Reset
+			response, err = Command(conn, bufin, "RSET")
+			if err != nil {
+				t.Error("command failed", err.Error())
+			}
+			expected = "250 2.1.0 OK"
+			if strings.Index(response, expected) != 0 {
+				t.Error("Server did not respond with", expected, ", it said:"+response)
+			}
+
+			// Invalid address?
+			response, err = Command(conn, bufin, "MAIL FROM:<justatest>")
+			if err != nil {
+				t.Error("command failed", err.Error())
+			}
+			expected = "501 5.5.4 Invalid address"
+			if strings.Index(response, expected) != 0 {
+				t.Error("Server did not respond with", expected, ", it said:"+response)
+			}
+
+			// Reset
+			response, err = Command(conn, bufin, "RSET")
+			if err != nil {
+				t.Error("command failed", err.Error())
+			}
+			expected = "250 2.1.0 OK"
+			if strings.Index(response, expected) != 0 {
+				t.Error("Server did not respond with", expected, ", it said:"+response)
+			}
+
+			// SMTPUTF8 not implemented for now, currently still accepted
+			response, err = Command(conn, bufin, "MAIL FROM:<anö[email protected]>")
+			if err != nil {
+				t.Error("command failed", err.Error())
+			}
+			expected = "250 2.1.0 OK"
+			if strings.Index(response, expected) != 0 {
+				t.Error("Server did not respond with", expected, ", it said:"+response)
+			}
+
+			// Reset
+			response, err = Command(conn, bufin, "RSET")
+			if err != nil {
+				t.Error("command failed", err.Error())
+			}
+			expected = "250 2.1.0 OK"
+			if strings.Index(response, expected) != 0 {
+				t.Error("Server did not respond with", expected, ", it said:"+response)
+			}
+
+			// 8BITMIME (RfC 6152)
+			response, err = Command(conn, bufin, "MAIL FROM:<[email protected]> BODY=8BITMIME")
+			if err != nil {
+				t.Error("command failed", err.Error())
+			}
+			expected = "250 2.1.0 OK"
+			if strings.Index(response, expected) != 0 {
+				t.Error("Server did not respond with", expected, ", it said:"+response)
+			}
+
+			// Reset
+			response, err = Command(conn, bufin, "RSET")
+			if err != nil {
+				t.Error("command failed", err.Error())
+			}
+			expected = "250 2.1.0 OK"
+			if strings.Index(response, expected) != 0 {
+				t.Error("Server did not respond with", expected, ", it said:"+response)
+			}
+
+			// 8BITMIME (RfC 6152) Bounce
+			response, err = Command(conn, bufin, "MAIL FROM:<> BODY=8BITMIME")
+			if err != nil {
+				t.Error("command failed", err.Error())
+			}
+			expected = "250 2.1.0 OK"
+			if strings.Index(response, expected) != 0 {
+				t.Error("Server did not respond with", expected, ", it said:"+response)
+			}
+
+			// Reset
+			response, err = Command(conn, bufin, "RSET")
+			if err != nil {
+				t.Error("command failed", err.Error())
+			}
+			expected = "250 2.1.0 OK"
+			if strings.Index(response, expected) != 0 {
+				t.Error("Server did not respond with", expected, ", it said:"+response)
+			}
+
+		}
+		conn.Close()
+		app.Shutdown()
+	} else {
+		if startErrors := app.Start(); startErrors != nil {
+			t.Error(startErrors)
+			app.Shutdown()
+			t.FailNow()
+		}
+	}
+	logOut.Flush()
+	// don't forget to reset
+	logBuffer.Reset()
+	logIn.Reset(&logBuffer)
+}
+
 // It should error when MAIL FROM was given twice
 func TestNestedMailCmd(t *testing.T) {
 	if initErr != nil {