| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292 | 
							- // integration / smokeless
 
- // =======================
 
- // Tests are in a different package so we can test as a consumer of the guerrilla package
 
- // The following are integration / smokeless, that test the overall server.
 
- // (Please put unit tests to go in a different file)
 
- // How it works:
 
- // Server's log output is redirected to the testlog file which is then used by the tests to look for
 
- // expected behaviour.
 
- //
 
- // (self signed certs are also generated on each run)
 
- // server's responses from a connection are also used to check for expected behaviour
 
- // to run:
 
- // $ go test
 
- package test
 
- import (
 
- 	"encoding/json"
 
- 	"github.com/flashmob/go-guerrilla/mail/rfc5321"
 
- 	"testing"
 
- 	"time"
 
- 	"github.com/flashmob/go-guerrilla"
 
- 	"github.com/flashmob/go-guerrilla/backends"
 
- 	"github.com/flashmob/go-guerrilla/log"
 
- 	"bufio"
 
- 	"crypto/tls"
 
- 	"errors"
 
- 	"fmt"
 
- 	"io/ioutil"
 
- 	"net"
 
- 	"strings"
 
- 	"os"
 
- 	"github.com/flashmob/go-guerrilla/tests/testcert"
 
- )
 
- type TestConfig struct {
 
- 	guerrilla.AppConfig
 
- 	BackendConfig map[string]interface{} `json:"backend_config"`
 
- }
 
- var (
 
- 	// app config loaded here
 
- 	config *TestConfig
 
- 	app guerrilla.Guerrilla
 
- 	initErr error
 
- 	logger log.Logger
 
- )
 
- func init() {
 
- 	config = &TestConfig{}
 
- 	if err := json.Unmarshal([]byte(configJson), config); err != nil {
 
- 		initErr = errors.New("Could not Unmarshal config," + err.Error())
 
- 	} else {
 
- 		logger, _ = log.GetLogger(config.LogFile, "debug")
 
- 		initErr = setupCerts(config)
 
- 		if initErr != nil {
 
- 			return
 
- 		}
 
- 		backend, _ := getBackend(config.BackendConfig, logger)
 
- 		app, initErr = guerrilla.New(&config.AppConfig, backend, logger)
 
- 	}
 
- }
 
- // a configuration file with a dummy backend
 
- var configJson = `
 
- {
 
-     "log_file" : "./testlog",
 
-     "log_level" : "debug",
 
-     "pid_file" : "go-guerrilla.pid",
 
-     "allowed_hosts": ["spam4.me","grr.la"],
 
-     "backend_config" :
 
-         {
 
-             "log_received_mails" : true
 
-         },
 
-     "servers" : [
 
-         {
 
-             "is_enabled" : true,
 
-             "host_name":"mail.guerrillamail.com",
 
-             "max_size": 100017,
 
-             "timeout":160,
 
-             "listen_interface":"127.0.0.1:2526", 
 
-             "max_clients": 2,
 
-             "log_file" : "",
 
- 			"tls" : {
 
- 				"private_key_file":"/this/will/be/ignored/guerrillamail.com.key.pem",
 
-             	"public_key_file":"/this/will/be/ignored//guerrillamail.com.crt",
 
- 				"start_tls_on":true,
 
-             	"tls_always_on":false
 
- 			}
 
-         },
 
-         {
 
-             "is_enabled" : true,
 
-             "host_name":"mail.guerrillamail.com",
 
-             "max_size":1000001,
 
-             "timeout":180,
 
-             "listen_interface":"127.0.0.1:4654",
 
-             "max_clients":1,
 
-             "log_file" : "",
 
- 			"tls" : {
 
- 				"private_key_file":"/this/will/be/ignored/guerrillamail.com.key.pem",
 
-             	"public_key_file":"/this/will/be/ignored/guerrillamail.com.crt",
 
- 				"start_tls_on":false,
 
-             	"tls_always_on":true
 
- 			}
 
-         }
 
-     ]
 
- }
 
- `
 
- func getBackend(backendConfig map[string]interface{}, l log.Logger) (backends.Backend, error) {
 
- 	b, err := backends.New(backendConfig, l)
 
- 	if err != nil {
 
- 		fmt.Println("backend init error", err)
 
- 		os.Exit(1)
 
- 	}
 
- 	return b, err
 
- }
 
- func setupCerts(c *TestConfig) error {
 
- 	for i := range c.Servers {
 
- 		err := testcert.GenerateCert(c.Servers[i].Hostname, "", 365*24*time.Hour, false, 2048, "P256", "./")
 
- 		if err != nil {
 
- 			return err
 
- 		}
 
- 		c.Servers[i].TLS.PrivateKeyFile = c.Servers[i].Hostname + ".key.pem"
 
- 		c.Servers[i].TLS.PublicKeyFile = c.Servers[i].Hostname + ".cert.pem"
 
- 	}
 
- 	return nil
 
- }
 
- func truncateIfExists(filename string) error {
 
- 	if _, err := os.Stat(filename); !os.IsNotExist(err) {
 
- 		return os.Truncate(filename, 0)
 
- 	}
 
- 	return nil
 
- }
 
- func deleteIfExists(filename string) error {
 
- 	if _, err := os.Stat(filename); !os.IsNotExist(err) {
 
- 		return os.Remove(filename)
 
- 	}
 
- 	return nil
 
- }
 
- func cleanTestArtifacts(t *testing.T) {
 
- 	if err := truncateIfExists("./testlog"); err != nil {
 
- 		t.Error("could not clean tests/testlog:", err)
 
- 	}
 
- 	letters := []byte{'A', 'B', 'C', 'D', 'E'}
 
- 	for _, l := range letters {
 
- 		if err := deleteIfExists("configJson" + string(l) + ".json"); err != nil {
 
- 			t.Error("could not delete configJson"+string(l)+".json:", err)
 
- 		}
 
- 	}
 
- 	if err := deleteIfExists("./go-guerrilla.pid"); err != nil {
 
- 		t.Error("could not delete ./guerrilla", err)
 
- 	}
 
- 	if err := deleteIfExists("./go-guerrilla2.pid"); err != nil {
 
- 		t.Error("could not delete ./go-guerrilla2.pid", err)
 
- 	}
 
- 	if err := deleteIfExists("./mail.guerrillamail.com.cert.pem"); err != nil {
 
- 		t.Error("could not delete ./mail.guerrillamail.com.cert.pem", err)
 
- 	}
 
- 	if err := deleteIfExists("./mail.guerrillamail.com.key.pem"); err != nil {
 
- 		t.Error("could not delete ./mail.guerrillamail.com.key.pem", err)
 
- 	}
 
- }
 
- // Testing start and stop of server
 
- func TestStart(t *testing.T) {
 
- 	if initErr != nil {
 
- 		t.Error(initErr)
 
- 		t.FailNow()
 
- 	}
 
- 	defer cleanTestArtifacts(t)
 
- 	if startErrors := app.Start(); startErrors != nil {
 
- 		t.Error(startErrors)
 
- 		t.FailNow()
 
- 	}
 
- 	time.Sleep(time.Second)
 
- 	app.Shutdown()
 
- 	if read, err := ioutil.ReadFile("./testlog"); err == nil {
 
- 		logOutput := string(read)
 
- 		if i := strings.Index(logOutput, "Listening on TCP 127.0.0.1:4654"); i < 0 {
 
- 			t.Error("Server did not listen on 127.0.0.1:4654")
 
- 		}
 
- 		if i := strings.Index(logOutput, "Listening on TCP 127.0.0.1:2526"); i < 0 {
 
- 			t.Error("Server did not listen on 127.0.0.1:2526")
 
- 		}
 
- 		if i := strings.Index(logOutput, "[127.0.0.1:4654] Waiting for a new client"); i < 0 {
 
- 			t.Error("Server did not wait on 127.0.0.1:4654")
 
- 		}
 
- 		if i := strings.Index(logOutput, "[127.0.0.1:2526] Waiting for a new client"); i < 0 {
 
- 			t.Error("Server did not wait on 127.0.0.1:2526")
 
- 		}
 
- 		if i := strings.Index(logOutput, "Server [127.0.0.1:4654] has stopped accepting new clients"); i < 0 {
 
- 			t.Error("Server did not stop on 127.0.0.1:4654")
 
- 		}
 
- 		if i := strings.Index(logOutput, "Server [127.0.0.1:2526] has stopped accepting new clients"); i < 0 {
 
- 			t.Error("Server did not stop on 127.0.0.1:2526")
 
- 		}
 
- 		if i := strings.Index(logOutput, "shutdown completed for [127.0.0.1:4654]"); i < 0 {
 
- 			t.Error("Server did not complete shutdown on 127.0.0.1:4654")
 
- 		}
 
- 		if i := strings.Index(logOutput, "shutdown completed for [127.0.0.1:2526]"); i < 0 {
 
- 			t.Error("Server did not complete shutdown on 127.0.0.1:2526")
 
- 		}
 
- 		if i := strings.Index(logOutput, "shutting down pool [127.0.0.1:4654]"); i < 0 {
 
- 			t.Error("Server did not shutdown pool on 127.0.0.1:4654")
 
- 		}
 
- 		if i := strings.Index(logOutput, "shutting down pool [127.0.0.1:2526]"); i < 0 {
 
- 			t.Error("Server did not shutdown pool on 127.0.0.1:2526")
 
- 		}
 
- 		if i := strings.Index(logOutput, "Backend shutdown completed"); i < 0 {
 
- 			t.Error("Backend didn't shut down")
 
- 		}
 
- 	}
 
- }
 
- // Simple smoke-test to see if the server can listen & issues a greeting on connect
 
- func TestGreeting(t *testing.T) {
 
- 	if initErr != nil {
 
- 		t.Error(initErr)
 
- 		t.FailNow()
 
- 	}
 
- 	defer cleanTestArtifacts(t)
 
- 	if startErrors := app.Start(); startErrors == nil {
 
- 		// 1. plaintext connection
 
- 		conn, err := net.Dial("tcp", config.Servers[0].ListenInterface)
 
- 		if err != nil {
 
- 			// handle error
 
- 			t.Error("Cannot dial server", config.Servers[0].ListenInterface)
 
- 		}
 
- 		if err := conn.SetReadDeadline(time.Now().Add(time.Millisecond * 500)); err != nil {
 
- 			t.Error(err)
 
- 		}
 
- 		greeting, err := bufio.NewReader(conn).ReadString('\n')
 
- 		if err != nil {
 
- 			t.Error(err)
 
- 			t.FailNow()
 
- 		} else {
 
- 			expected := "220 mail.guerrillamail.com SMTP Guerrilla"
 
- 			if strings.Index(greeting, expected) != 0 {
 
- 				t.Error("Server[1] did not have the expected greeting prefix", expected)
 
- 			}
 
- 		}
 
- 		_ = conn.Close()
 
- 		// 2. tls connection
 
- 		//	roots, err := x509.SystemCertPool()
 
- 		conn, err = tls.Dial("tcp", config.Servers[1].ListenInterface, &tls.Config{
 
- 			InsecureSkipVerify: true,
 
- 			ServerName:         "127.0.0.1",
 
- 		})
 
- 		if err != nil {
 
- 			// handle error
 
- 			t.Error(err, "Cannot dial server (TLS)", config.Servers[1].ListenInterface)
 
- 			t.FailNow()
 
- 		}
 
- 		if err := conn.SetReadDeadline(time.Now().Add(time.Millisecond * 500)); err != nil {
 
- 			t.Error(err)
 
- 		}
 
- 		greeting, err = bufio.NewReader(conn).ReadString('\n')
 
- 		if err != nil {
 
- 			t.Error(err)
 
- 			t.FailNow()
 
- 		} else {
 
- 			expected := "220 mail.guerrillamail.com SMTP Guerrilla"
 
- 			if strings.Index(greeting, expected) != 0 {
 
- 				t.Error("Server[2] (TLS) did not have the expected greeting prefix", expected)
 
- 			}
 
- 		}
 
- 		_ = conn.Close()
 
- 	} else {
 
- 		fmt.Println("Nope", startErrors)
 
- 		if startErrors := app.Start(); startErrors != nil {
 
- 			t.Error(startErrors)
 
- 			t.FailNow()
 
- 		}
 
- 	}
 
- 	app.Shutdown()
 
- 	if read, err := ioutil.ReadFile("./testlog"); err == nil {
 
- 		logOutput := string(read)
 
- 		if i := strings.Index(logOutput, "Handle client [127.0.0.1"); i < 0 {
 
- 			t.Error("Server did not handle any clients")
 
- 		}
 
- 	}
 
- }
 
- // start up a server, connect a client, greet, then shutdown, then client sends a command
 
- // expecting: 421 Server is shutting down. Please try again later. Sayonara!
 
- // server should close connection after that
 
- func TestShutDown(t *testing.T) {
 
- 	if initErr != nil {
 
- 		t.Error(initErr)
 
- 		t.FailNow()
 
- 	}
 
- 	defer cleanTestArtifacts(t)
 
- 	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())
 
- 			}
 
- 			// do a shutdown while the client is connected & in client state
 
- 			go app.Shutdown()
 
- 			time.Sleep(time.Millisecond * 150) // let server to Shutdown
 
- 			// issue a command while shutting down
 
- 			response, err := Command(conn, bufin, "HELP")
 
- 			if err != nil {
 
- 				t.Error("Help command failed", err.Error())
 
- 			}
 
- 			expected := "421 4.3.0 Server is shutting down. Please try again later. Sayonara!"
 
- 			if strings.Index(response, expected) != 0 {
 
- 				t.Error("Server did not shut down with", expected, ", it said:"+response)
 
- 			}
 
- 			time.Sleep(time.Millisecond * 250) // let server to close
 
- 		}
 
- 		_ = conn.Close()
 
- 	} else {
 
- 		if startErrors := app.Start(); startErrors != nil {
 
- 			t.Error(startErrors)
 
- 			app.Shutdown()
 
- 			t.FailNow()
 
- 		}
 
- 	}
 
- 	// assuming server has shutdown by now
 
- 	if read, err := ioutil.ReadFile("./testlog"); err == nil {
 
- 		logOutput := string(read)
 
- 		//	fmt.Println(logOutput)
 
- 		if i := strings.Index(logOutput, "Handle client [127.0.0.1"); i < 0 {
 
- 			t.Error("Server did not handle any clients")
 
- 		}
 
- 	}
 
- }
 
- // add more than 100 recipients, it should fail at 101
 
- func TestRFC2821LimitRecipients(t *testing.T) {
 
- 	if initErr != nil {
 
- 		t.Error(initErr)
 
- 		t.FailNow()
 
- 	}
 
- 	defer cleanTestArtifacts(t)
 
- 	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())
 
- 			}
 
- 			for i := 0; i < 101; i++ {
 
- 				//fmt.Println(fmt.Sprintf("RCPT TO:test%[email protected]", i))
 
- 				if _, err := Command(conn, bufin, fmt.Sprintf("RCPT TO:<test%[email protected]>", i)); err != nil {
 
- 					t.Error("RCPT TO", err.Error())
 
- 					break
 
- 				}
 
- 			}
 
- 			response, err := Command(conn, bufin, "RCPT TO:<[email protected]>")
 
- 			if err != nil {
 
- 				t.Error("rcpt command failed", err.Error())
 
- 			}
 
- 			expected := "452 4.5.3 Too many recipients"
 
- 			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()
 
- 		}
 
- 	}
 
- }
 
- // RCPT TO & MAIL FROM with 64 chars in local part, it should fail at 65
 
- func TestRFC2832LimitLocalPart(t *testing.T) {
 
- 	if initErr != nil {
 
- 		t.Error(initErr)
 
- 		t.FailNow()
 
- 	}
 
- 	defer cleanTestArtifacts(t)
 
- 	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())
 
- 			}
 
- 			// repeat > 64 characters in local part
 
- 			response, err := Command(conn, bufin, fmt.Sprintf("RCPT TO:<%[email protected]>", strings.Repeat("a", rfc5321.LimitLocalPart+1)))
 
- 			if err != nil {
 
- 				t.Error("rcpt command failed", err.Error())
 
- 			}
 
- 			expected := "550 5.5.4 Local part too long"
 
- 			if strings.Index(response, expected) != 0 {
 
- 				t.Error("Server did not respond with", expected, ", it said:"+response)
 
- 			}
 
- 			// what about if it's exactly 64?
 
- 			// repeat > 64 characters in local part
 
- 			response, err = Command(conn, bufin, fmt.Sprintf("RCPT TO:<%[email protected]>", strings.Repeat("a", rfc5321.LimitLocalPart-1)))
 
- 			if err != nil {
 
- 				t.Error("rcpt command failed", err.Error())
 
- 			}
 
- 			expected = "250 2.1.5 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()
 
- 		}
 
- 	}
 
- }
 
- //RFC2821LimitPath fail if path > 256 but different error if below
 
- func TestRFC2821LimitPath(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())
 
- 			}
 
- 			// repeat > 256 characters in local part
 
- 			response, err := Command(conn, bufin, fmt.Sprintf("RCPT TO:<%[email protected]>", strings.Repeat("a", 257-7)))
 
- 			if err != nil {
 
- 				t.Error("rcpt command failed", err.Error())
 
- 			}
 
- 			expected := "550 5.5.4 Path too long"
 
- 			if strings.Index(response, expected) != 0 {
 
- 				t.Error("Server did not respond with", expected, ", it said:"+response)
 
- 			}
 
- 			// what about if it's exactly 256?
 
- 			response, err = Command(conn, bufin,
 
- 				fmt.Sprintf("RCPT TO:<%s@%s.la>", strings.Repeat("a", 64), strings.Repeat("b", 186)))
 
- 			if err != nil {
 
- 				t.Error("rcpt command failed", err.Error())
 
- 			}
 
- 			expected = "454 4.1.1 Error: Relay access denied"
 
- 			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()
 
- 		}
 
- 	}
 
- }
 
- // RFC2821LimitDomain 501 Domain cannot exceed 255 characters
 
- func TestRFC2821LimitDomain(t *testing.T) {
 
- 	if initErr != nil {
 
- 		t.Error(initErr)
 
- 		t.FailNow()
 
- 	}
 
- 	defer cleanTestArtifacts(t)
 
- 	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())
 
- 			}
 
- 			// repeat > 64 characters in local part
 
- 			response, err := Command(conn, bufin, fmt.Sprintf("RCPT TO:<a@%s.l>", strings.Repeat("a", 255-2)))
 
- 			if err != nil {
 
- 				t.Error("command failed", err.Error())
 
- 			}
 
- 			expected := "550 5.5.4 Path too long"
 
- 			if strings.Index(response, expected) != 0 {
 
- 				t.Error("Server did not respond with", expected, ", it said:"+response)
 
- 			}
 
- 			// what about if it's exactly 255?
 
- 			response, err = Command(conn, bufin,
 
- 				fmt.Sprintf("RCPT TO:<a@%s.la>", strings.Repeat("b", 255-6)))
 
- 			if err != nil {
 
- 				t.Error("command failed", err.Error())
 
- 			}
 
- 			expected = "454 4.1.1 Error: Relay access denied"
 
- 			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()
 
- 		}
 
- 	}
 
- }
 
- // Test several different inputs to MAIL FROM command
 
- func TestMailFromCmd(t *testing.T) {
 
- 	if initErr != nil {
 
- 		t.Error(initErr)
 
- 		t.FailNow()
 
- 	}
 
- 	defer cleanTestArtifacts(t)
 
- 	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)
 
- 			}
 
- 			// No mail from content
 
- 			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)
 
- 			}
 
- 			// Short mail from content
 
- 			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)
 
- 			}
 
- 			// Short mail from content 2
 
- 			response, err = Command(conn, bufin, "MAIL FROM:x")
 
- 			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)
 
- 			}
 
- 			// 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)
 
- 			}
 
- 			/*
 
- 				// todo SMTPUTF8 not implemented for now,
 
- 				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()
 
- 		}
 
- 	}
 
- }
 
- // Test several different inputs to MAIL FROM command
 
- func TestHeloEhlo(t *testing.T) {
 
- 	if initErr != nil {
 
- 		t.Error(initErr)
 
- 		t.FailNow()
 
- 	}
 
- 	defer cleanTestArtifacts(t)
 
- 	if startErrors := app.Start(); startErrors == nil {
 
- 		conn, bufin, err := Connect(config.Servers[0], 20)
 
- 		hostname := config.Servers[0].Hostname
 
- 		if err != nil {
 
- 			// handle error
 
- 			t.Error(err.Error(), config.Servers[0].ListenInterface)
 
- 			t.FailNow()
 
- 		} else {
 
- 			// Test HELO
 
- 			response, err := Command(conn, bufin, "HELO localtester")
 
- 			if err != nil {
 
- 				t.Error("command failed", err.Error())
 
- 			}
 
- 			expected := fmt.Sprintf("250 %s Hello", hostname)
 
- 			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)
 
- 			}
 
- 			// Test EHLO
 
- 			// This is tricky as it is a multiline response
 
- 			var fullresp string
 
- 			response, err = Command(conn, bufin, "EHLO localtester")
 
- 			fullresp = fullresp + response
 
- 			if err != nil {
 
- 				t.Error("command failed", err.Error())
 
- 			}
 
- 			for err == nil {
 
- 				response, err = bufin.ReadString('\n')
 
- 				fullresp = fullresp + response
 
- 				if strings.HasPrefix(response, "250 ") { // Last response has a whitespace and no "-"
 
- 					break // bail
 
- 				}
 
- 			}
 
- 			expected = fmt.Sprintf("250-%s Hello\r\n250-SIZE 100017\r\n250-PIPELINING\r\n250-STARTTLS\r\n250-ENHANCEDSTATUSCODES\r\n250 HELP\r\n", hostname)
 
- 			if fullresp != expected {
 
- 				t.Error("Server did not respond with [" + expected + "], it said [" + fullresp + "]")
 
- 			}
 
- 			// be kind, QUIT. And we are sure that bufin does not contain fragments from the EHLO command.
 
- 			response, err = Command(conn, bufin, "QUIT")
 
- 			if err != nil {
 
- 				t.Error("command failed", err.Error())
 
- 			}
 
- 			expected = "221 2.0.0 Bye"
 
- 			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()
 
- 		}
 
- 	}
 
- }
 
- // It should error when MAIL FROM was given twice
 
- func TestNestedMailCmd(t *testing.T) {
 
- 	if initErr != nil {
 
- 		t.Error(initErr)
 
- 		t.FailNow()
 
- 	}
 
- 	defer cleanTestArtifacts(t)
 
- 	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())
 
- 			}
 
- 			// repeat > 64 characters in local part
 
- 			response, err := Command(conn, bufin, "MAIL FROM:<[email protected]>")
 
- 			if err != nil {
 
- 				t.Error("command failed", err.Error())
 
- 			}
 
- 			response, err = Command(conn, bufin, "MAIL FROM:<[email protected]>")
 
- 			if err != nil {
 
- 				t.Error("command failed", err.Error())
 
- 			}
 
- 			expected := "503 5.5.1 Error: nested MAIL command"
 
- 			if strings.Index(response, expected) != 0 {
 
- 				t.Error("Server did not respond with", expected, ", it said:"+response)
 
- 			}
 
- 			// Plot twist: if you EHLO , it should allow MAIL FROM again
 
- 			if _, err := Command(conn, bufin, "HELO localtester"); err != nil {
 
- 				t.Error("Hello command failed", err.Error())
 
- 			}
 
- 			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)
 
- 			}
 
- 			// Plot twist: if you RSET , it should allow MAIL FROM again
 
- 			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)
 
- 			}
 
- 			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)
 
- 			}
 
- 		}
 
- 		_ = conn.Close()
 
- 		app.Shutdown()
 
- 	} else {
 
- 		if startErrors := app.Start(); startErrors != nil {
 
- 			t.Error(startErrors)
 
- 			app.Shutdown()
 
- 			t.FailNow()
 
- 		}
 
- 	}
 
- }
 
- // It should error on a very long command line, exceeding CommandLineMaxLength 1024
 
- func TestCommandLineMaxLength(t *testing.T) {
 
- 	if initErr != nil {
 
- 		t.Error(initErr)
 
- 		t.FailNow()
 
- 	}
 
- 	defer cleanTestArtifacts(t)
 
- 	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())
 
- 			}
 
- 			// repeat > 1024 characters
 
- 			response, err := Command(conn, bufin, strings.Repeat("s", guerrilla.CommandLineMaxLength+1))
 
- 			if err != nil {
 
- 				t.Error("command failed", err.Error())
 
- 			}
 
- 			expected := "554 5.5.1 Line too long"
 
- 			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()
 
- 		}
 
- 	}
 
- }
 
- // It should error on a very long message, exceeding servers config value
 
- func TestDataMaxLength(t *testing.T) {
 
- 	if initErr != nil {
 
- 		t.Error(initErr)
 
- 		t.FailNow()
 
- 	}
 
- 	defer cleanTestArtifacts(t)
 
- 	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())
 
- 			}
 
- 			response, err := Command(conn, bufin, "MAIL FROM:[email protected]")
 
- 			if err != nil {
 
- 				t.Error("command failed", err.Error())
 
- 			}
 
- 			//fmt.Println(response)
 
- 			response, err = Command(conn, bufin, "RCPT TO:<[email protected]>")
 
- 			if err != nil {
 
- 				t.Error("command failed", err.Error())
 
- 			}
 
- 			//fmt.Println(response)
 
- 			response, err = Command(conn, bufin, "DATA")
 
- 			if err != nil {
 
- 				t.Error("command failed", err.Error())
 
- 			}
 
- 			response, err = Command(
 
- 				conn,
 
- 				bufin,
 
- 				fmt.Sprintf("Subject:test\r\n\r\nHello %s\r\n.\r\n",
 
- 					strings.Repeat("n", int(config.Servers[0].MaxSize-20))))
 
- 			//expected := "500 Line too long"
 
- 			expected := "451 4.3.0 Error: maximum DATA size exceeded"
 
- 			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()
 
- 		}
 
- 	}
 
- }
 
- func TestDataCommand(t *testing.T) {
 
- 	if initErr != nil {
 
- 		t.Error(initErr)
 
- 		t.FailNow()
 
- 	}
 
- 	defer cleanTestArtifacts(t)
 
- 	testHeader :=
 
- 		"Subject: =?Shift_JIS?B?W4NYg06DRYNGg0GBRYNHg2qDYoNOg1ggg0GDSoNFg5ODZ12DQYNKg0WDk4Nn?=\r\n" +
 
- 			"\t=?Shift_JIS?B?k2+YXoqul7mCzIKokm2C54K5?=\r\n"
 
- 	email :=
 
- 		"Delivered-To: [email protected]\r\n" +
 
- 			"\tReceived: from mail.guerrillamail.com (mail.guerrillamail.com  [104.218.55.28:44246])\r\n" +
 
- 			"\tby grr.la with SMTP id [email protected];\r\n" +
 
- 			"\tWed, 18 Jan 2017 15:43:29 +0000\r\n" +
 
- 			"Received: by 192.99.19.220 with HTTP; Wed, 18 Jan 2017 15:43:29 +0000\r\n" +
 
- 			"MIME-Version: 1.0\r\n" +
 
- 			"Message-ID: <[email protected]>\r\n" +
 
- 			"Date: Wed, 18 Jan 2017 15:43:29 +0000\r\n" +
 
- 			"To: \"[email protected]\" <[email protected]>\r\n" +
 
- 			"From: <[email protected]>\r\n" +
 
- 			"Subject: test\r\n" +
 
- 			"X-Originating-IP: [60.241.160.150]\r\n" +
 
- 			"Content-Type: text/plain; charset=\"utf-8\"\r\n" +
 
- 			"Content-Transfer-Encoding: quoted-printable\r\n" +
 
- 			"X-Domain-Signer: PHP mailDomainSigner 0.2-20110415 <http://code.google.com/p/php-mail-domain-signer/>\r\n" +
 
- 			"DKIM-Signature: v=1; a=rsa-sha256; s=highgrade; d=guerrillamail.com; l=182;\r\n" +
 
- 			"\tt=1484754209; c=relaxed/relaxed; h=to:from:subject;\r\n" +
 
- 			"\tbh=GHSgjHpBp5QjNn9tzfug681+RcWMOUgpwAuTzppM5wY=;\r\n" +
 
- 			"\tb=R7FxWgACnT+pKXqEg15qgzH4ywMFRx5pDlIFCnSt1BfwmLvZPZK7oOLrbiRoGGR2OJnSfyCxeASH\r\n" +
 
- 			"\t019LNeLB/B8o+fMRX87m/tBpqIZ2vgXdT9rUCIbSDJnYoCHXakGcF+zGtTE3SEksMbeJQ76aGj6M\r\n" +
 
- 			"\tG80p76IT2Xu3iDJLYYWxcAeX+7z4M/bbYNeqxMQcXYZp1wNYlSlHahL6RDUYdcqikDqKoXmzMNVd\r\n" +
 
- 			"\tDr0EbH9iiu1DQtfUDzVE5LLus1yn36WU/2KJvEak45gJvm9s9J+Xrcb882CaYkxlAbgQDz1KeQLf\r\n" +
 
- 			"\teUyNspyAabkh2yTg7kOvNZSOJtbMSQS6/GMxsg==\r\n" +
 
- 			"\r\n" +
 
- 			"test=0A.mooo=0A..mooo=0Atest=0A.=0A=0A=0A=0A=0A=0A----=0ASent using Guerril=\r\n" +
 
- 			"lamail.com=0ABlock or report abuse: https://www.guerrillamail.com//abuse/?a=\r\n" +
 
- 			"=3DVURnES0HUaZbhA8%3D=0A\r\n.\r\n"
 
- 	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())
 
- 			}
 
- 			response, err := Command(conn, bufin, "MAIL FROM:<[email protected]>")
 
- 			if err != nil {
 
- 				t.Error("command failed", err.Error())
 
- 			}
 
- 			//fmt.Println(response)
 
- 			response, err = Command(conn, bufin, "RCPT TO:<[email protected]>")
 
- 			if err != nil {
 
- 				t.Error("command failed", err.Error())
 
- 			}
 
- 			//fmt.Println(response)
 
- 			response, err = Command(conn, bufin, "DATA")
 
- 			if err != nil {
 
- 				t.Error("command failed", err.Error())
 
- 			}
 
- 			/*
 
- 				response, err = Command(
 
- 					conn,
 
- 					bufin,
 
- 					testHeader+"\r\nHello World\r\n.\r\n")
 
- 			*/
 
- 			_ = testHeader
 
- 			response, err = Command(
 
- 				conn,
 
- 				bufin,
 
- 				email+"\r\n.\r\n")
 
- 			//expected := "500 Line too long"
 
- 			expected := "250 2.0.0 OK: queued as "
 
- 			if strings.Index(response, expected) != 0 {
 
- 				t.Error("Server did not respond with", expected, ", it said:"+response, err)
 
- 			}
 
- 		}
 
- 		_ = conn.Close()
 
- 		app.Shutdown()
 
- 	} else {
 
- 		if startErrors := app.Start(); startErrors != nil {
 
- 			t.Error(startErrors)
 
- 			app.Shutdown()
 
- 			t.FailNow()
 
- 		}
 
- 	}
 
- }
 
- // Fuzzer crashed the server by submitting "DATA\r\n" as the first command
 
- func TestFuzz86f25b86b09897aed8f6c2aa5b5ee1557358a6de(t *testing.T) {
 
- 	if initErr != nil {
 
- 		t.Error(initErr)
 
- 		t.FailNow()
 
- 	}
 
- 	defer cleanTestArtifacts(t)
 
- 	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 {
 
- 			response, err := Command(
 
- 				conn,
 
- 				bufin,
 
- 				"DATA\r\n")
 
- 			expected := "503 5.5.1 Error: No recipients"
 
- 			if strings.Index(response, expected) != 0 {
 
- 				t.Error("Server did not respond with", expected, ", it said:"+response, err)
 
- 			}
 
- 		}
 
- 		_ = conn.Close()
 
- 		app.Shutdown()
 
- 	} else {
 
- 		if startErrors := app.Start(); startErrors != nil {
 
- 			t.Error(startErrors)
 
- 			app.Shutdown()
 
- 			t.FailNow()
 
- 		}
 
- 	}
 
- }
 
- // Appears to hang the fuzz test, but not server.
 
- func TestFuzz21c56f89989d19c3bbbd81b288b2dae9e6dd2150(t *testing.T) {
 
- 	if initErr != nil {
 
- 		t.Error(initErr)
 
- 		t.FailNow()
 
- 	}
 
- 	defer cleanTestArtifacts(t)
 
- 	str := "X_\r\nMAIL FROM:<u\xfd\xfdrU" +
 
- 		"\x10c22695140\xfd727235530" +
 
- 		" Walter Sobchak\x1a\tDon" +
 
- 		"ny, x_6_, Donnyre   " +
 
- 		"\t\t outof89 !om>\r\nMAI" +
 
- 		"L\t\t \t\tFROM:<C4o\xfd\xfdr@e" +
 
- 		"xample.c22695140\xfd727" +
 
- 		"235530 Walter Sobcha" +
 
- 		"k: Donny, you>re out" +
 
- 		" of your element!om>" +
 
- 		"\r\nMAIL RCPT TO:t@IRS" +
 
- 		"ETRCPTIRSETRCP:<\x00\xfd\xfdr" +
 
- 		"@example 7A924_F__4_" +
 
- 		"c22695140\xfd-061.0x30C" +
 
- 		"8bC87fE4d3 Walter MA" +
 
- 		"IL Donny, youiq__n_l" +
 
- 		"wR8qs_0RBcw_0hIY_pS_" +
 
- 		"___x9_E0___sL598_G82" +
 
- 		"_6 out   your elemen" +
 
- 		"t!>\r\nX _9KB___X_p:<o" +
 
- 		"ut\xfd\xfdr@example9gTnr2N" +
 
- 		"__Vl_T7U_AqfU_dPfJ_0" +
 
- 		"HIqKK0037f6W_KGM_y_Z" +
 
- 		"_9_96_w_815Q572py2_9" +
 
- 		"F\xfd727235530Walter\tSo" +
 
- 		"bchakRSET MAIL from:" +
 
- 		" : cows eat\t\t  grass" +
 
- 		" , _S___46_PbG03_iW'" +
 
- 		"__v5L2_2L_J61u_38J55" +
 
- 		"_PpwQ_Fs_7L_3p7S_t__" +
 
- 		"g9XP48T_9HY_EDl_c_C3" +
 
- 		"3_3b708EreT_OR out 9" +
 
- 		"9_pUY4 \t\t\t     \x05om>\r" +
 
- 		"\n FROM<u\xfd\xfdr@example." +
 
- 		"<\xfd-05110602 Walter S" +
 
- 		"obchak: Donny, \t\t  w" +
 
- 		"50TI__m_5EsC___n_l_d" +
 
- 		"__57GP9G02_32n_FR_xw" +
 
- 		"_2_103___rnED5PGIKN7" +
 
- 		"BBs3VIuNV_514qDBp_Gs" +
 
- 		"_qj4\tre out all cows" +
 
- 		" eatof your element\x03" +
 
- 		"om>\r\n_2 FROM:<u\x10\xfdr@e" +
 
- 		"xample.oQ_VLq909_E_5" +
 
- 		"AQ7_4_\xfd1935012674150" +
 
- 		"6773818422493001838." +
 
- 		"-010\tWalter\tSobchak:" +
 
- 		" Donny, youyouteIz2y" +
 
- 		"__Z2q5_qoA're Q6MP2_" +
 
- 		"CT_z70____0c0nU7_83d" +
 
- 		"4jn_eFD7h_9MbPjr_s_L" +
 
- 		"9_X23G_7 of _kU_L9Yz" +
 
- 		"_K52345QVa902H1__Hj_" +
 
- 		"Nl_PP2tW2ODi0_V80F15" +
 
- 		"_i65i_V5uSQdiG eleme" +
 
- 		"nt!om>\r\n"
 
- 	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 {
 
- 			response, err := Command(
 
- 				conn,
 
- 				bufin,
 
- 				str)
 
- 			expected := "554 5.5.1 Unrecognized command"
 
- 			if strings.Index(response, expected) != 0 {
 
- 				t.Error("Server did not respond with", expected, ", it said:"+response, err)
 
- 			}
 
- 		}
 
- 		_ = conn.Close()
 
- 		app.Shutdown()
 
- 	} else {
 
- 		if startErrors := app.Start(); startErrors != nil {
 
- 			t.Error(startErrors)
 
- 			app.Shutdown()
 
- 			t.FailNow()
 
- 		}
 
- 	}
 
- }
 
 
  |