guerrilla_test.go 36 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253
  1. // integration / smokeless
  2. // =======================
  3. // Tests are in a different package so we can test as a consumer of the guerrilla package
  4. // The following are integration / smokeless, that test the overall server.
  5. // (Please put unit tests to go in a different file)
  6. // How it works:
  7. // Server's log output is redirected to the testlog file which is then used by the tests to look for
  8. // expected behaviour.
  9. //
  10. // (self signed certs are also generated on each run)
  11. // server's responses from a connection are also used to check for expected behaviour
  12. // to run:
  13. // $ go test
  14. package test
  15. import (
  16. "encoding/json"
  17. "testing"
  18. "time"
  19. "github.com/flashmob/go-guerrilla"
  20. "github.com/flashmob/go-guerrilla/backends"
  21. "github.com/flashmob/go-guerrilla/log"
  22. "bufio"
  23. "crypto/tls"
  24. "errors"
  25. "fmt"
  26. "io/ioutil"
  27. "net"
  28. "strings"
  29. "github.com/flashmob/go-guerrilla/tests/testcert"
  30. "os"
  31. )
  32. type TestConfig struct {
  33. guerrilla.AppConfig
  34. BackendName string `json:"backend_name"`
  35. BackendConfig map[string]interface{} `json:"backend_config"`
  36. }
  37. var (
  38. // app config loaded here
  39. config *TestConfig
  40. app guerrilla.Guerrilla
  41. initErr error
  42. logger log.Logger
  43. )
  44. func init() {
  45. config = &TestConfig{}
  46. if err := json.Unmarshal([]byte(configJson), config); err != nil {
  47. initErr = errors.New("Could not Unmarshal config," + err.Error())
  48. } else {
  49. setupCerts(config)
  50. logger, _ = log.GetLogger(config.LogFile, "debug")
  51. backend, _ := getBackend(config.BackendConfig, logger)
  52. app, _ = guerrilla.New(&config.AppConfig, backend, logger)
  53. }
  54. }
  55. // a configuration file with a dummy backend
  56. var configJson = `
  57. {
  58. "log_file" : "./testlog",
  59. "log_level" : "debug",
  60. "pid_file" : "go-guerrilla.pid",
  61. "allowed_hosts": ["spam4.me","grr.la"],
  62. "backend_config" :
  63. {
  64. "log_received_mails" : true
  65. },
  66. "servers" : [
  67. {
  68. "is_enabled" : true,
  69. "host_name":"mail.guerrillamail.com",
  70. "max_size": 100017,
  71. "private_key_file":"/vagrant/projects/htdocs/guerrilla/config/ssl/guerrillamail.com.key",
  72. "public_key_file":"/vagrant/projects/htdocs/guerrilla/config/ssl/guerrillamail.com.crt",
  73. "timeout":160,
  74. "listen_interface":"127.0.0.1:2526",
  75. "start_tls_on":true,
  76. "tls_always_on":false,
  77. "max_clients": 2,
  78. "log_file" : ""
  79. },
  80. {
  81. "is_enabled" : true,
  82. "host_name":"mail.guerrillamail.com",
  83. "max_size":1000001,
  84. "private_key_file":"/vagrant/projects/htdocs/guerrilla/config/ssl/guerrillamail.com.key",
  85. "public_key_file":"/vagrant/projects/htdocs/guerrilla/config/ssl/guerrillamail.com.crt",
  86. "timeout":180,
  87. "listen_interface":"127.0.0.1:4654",
  88. "start_tls_on":false,
  89. "tls_always_on":true,
  90. "max_clients":1,
  91. "log_file" : ""
  92. }
  93. ]
  94. }
  95. `
  96. func getBackend(backendConfig map[string]interface{}, l log.Logger) (backends.Backend, error) {
  97. b, err := backends.New(backendConfig, l)
  98. if err != nil {
  99. fmt.Println("backend init error", err)
  100. os.Exit(1)
  101. }
  102. return b, err
  103. }
  104. func setupCerts(c *TestConfig) {
  105. for i := range c.Servers {
  106. testcert.GenerateCert(c.Servers[i].Hostname, "", 365*24*time.Hour, false, 2048, "P256", "./")
  107. c.Servers[i].PrivateKeyFile = c.Servers[i].Hostname + ".key.pem"
  108. c.Servers[i].PublicKeyFile = c.Servers[i].Hostname + ".cert.pem"
  109. }
  110. }
  111. // Testing start and stop of server
  112. func TestStart(t *testing.T) {
  113. if initErr != nil {
  114. t.Error(initErr)
  115. t.FailNow()
  116. }
  117. if startErrors := app.Start(); startErrors != nil {
  118. t.Error(startErrors)
  119. t.FailNow()
  120. }
  121. time.Sleep(time.Second)
  122. app.Shutdown()
  123. if read, err := ioutil.ReadFile("./testlog"); err == nil {
  124. logOutput := string(read)
  125. //fmt.Println(logOutput)
  126. if i := strings.Index(logOutput, "Listening on TCP 127.0.0.1:4654"); i < 0 {
  127. t.Error("Server did not listen on 127.0.0.1:4654")
  128. }
  129. if i := strings.Index(logOutput, "Listening on TCP 127.0.0.1:2526"); i < 0 {
  130. t.Error("Server did not listen on 127.0.0.1:2526")
  131. }
  132. if i := strings.Index(logOutput, "[127.0.0.1:4654] Waiting for a new client"); i < 0 {
  133. t.Error("Server did not wait on 127.0.0.1:4654")
  134. }
  135. if i := strings.Index(logOutput, "[127.0.0.1:2526] Waiting for a new client"); i < 0 {
  136. t.Error("Server did not wait on 127.0.0.1:2526")
  137. }
  138. if i := strings.Index(logOutput, "Server [127.0.0.1:4654] has stopped accepting new clients"); i < 0 {
  139. t.Error("Server did not stop on 127.0.0.1:4654")
  140. }
  141. if i := strings.Index(logOutput, "Server [127.0.0.1:2526] has stopped accepting new clients"); i < 0 {
  142. t.Error("Server did not stop on 127.0.0.1:2526")
  143. }
  144. if i := strings.Index(logOutput, "shutdown completed for [127.0.0.1:4654]"); i < 0 {
  145. t.Error("Server did not complete shutdown on 127.0.0.1:4654")
  146. }
  147. if i := strings.Index(logOutput, "shutdown completed for [127.0.0.1:2526]"); i < 0 {
  148. t.Error("Server did not complete shutdown on 127.0.0.1:2526")
  149. }
  150. if i := strings.Index(logOutput, "shutting down pool [127.0.0.1:4654]"); i < 0 {
  151. t.Error("Server did not shutdown pool on 127.0.0.1:4654")
  152. }
  153. if i := strings.Index(logOutput, "shutting down pool [127.0.0.1:2526]"); i < 0 {
  154. t.Error("Server did not shutdown pool on 127.0.0.1:2526")
  155. }
  156. if i := strings.Index(logOutput, "Backend shutdown completed"); i < 0 {
  157. t.Error("Backend didn't shut down")
  158. }
  159. }
  160. // don't forget to reset
  161. os.Truncate("./testlog", 0)
  162. }
  163. // Simple smoke-test to see if the server can listen & issues a greeting on connect
  164. func TestGreeting(t *testing.T) {
  165. //log.SetOutput(os.Stdout)
  166. if initErr != nil {
  167. t.Error(initErr)
  168. t.FailNow()
  169. }
  170. if startErrors := app.Start(); startErrors == nil {
  171. // 1. plaintext connection
  172. conn, err := net.Dial("tcp", config.Servers[0].ListenInterface)
  173. if err != nil {
  174. // handle error
  175. t.Error("Cannot dial server", config.Servers[0].ListenInterface)
  176. }
  177. conn.SetReadDeadline(time.Now().Add(time.Duration(time.Millisecond * 500)))
  178. greeting, err := bufio.NewReader(conn).ReadString('\n')
  179. //fmt.Println(greeting)
  180. if err != nil {
  181. t.Error(err)
  182. t.FailNow()
  183. } else {
  184. expected := "220 mail.guerrillamail.com SMTP Guerrilla"
  185. if strings.Index(greeting, expected) != 0 {
  186. t.Error("Server[1] did not have the expected greeting prefix", expected)
  187. }
  188. }
  189. conn.Close()
  190. // 2. tls connection
  191. // roots, err := x509.SystemCertPool()
  192. conn, err = tls.Dial("tcp", config.Servers[1].ListenInterface, &tls.Config{
  193. InsecureSkipVerify: true,
  194. ServerName: "127.0.0.1",
  195. })
  196. if err != nil {
  197. // handle error
  198. t.Error(err, "Cannot dial server (TLS)", config.Servers[1].ListenInterface)
  199. t.FailNow()
  200. }
  201. conn.SetReadDeadline(time.Now().Add(time.Duration(time.Millisecond * 500)))
  202. greeting, err = bufio.NewReader(conn).ReadString('\n')
  203. //fmt.Println(greeting)
  204. if err != nil {
  205. t.Error(err)
  206. t.FailNow()
  207. } else {
  208. expected := "220 mail.guerrillamail.com SMTP Guerrilla"
  209. if strings.Index(greeting, expected) != 0 {
  210. t.Error("Server[2] (TLS) did not have the expected greeting prefix", expected)
  211. }
  212. }
  213. conn.Close()
  214. } else {
  215. fmt.Println("Nope", startErrors)
  216. if startErrors := app.Start(); startErrors != nil {
  217. t.Error(startErrors)
  218. t.FailNow()
  219. }
  220. }
  221. app.Shutdown()
  222. if read, err := ioutil.ReadFile("./testlog"); err == nil {
  223. logOutput := string(read)
  224. //fmt.Println(logOutput)
  225. if i := strings.Index(logOutput, "Handle client [127.0.0.1"); i < 0 {
  226. t.Error("Server did not handle any clients")
  227. }
  228. }
  229. // don't forget to reset
  230. os.Truncate("./testlog", 0)
  231. }
  232. // start up a server, connect a client, greet, then shutdown, then client sends a command
  233. // expecting: 421 Server is shutting down. Please try again later. Sayonara!
  234. // server should close connection after that
  235. func TestShutDown(t *testing.T) {
  236. if initErr != nil {
  237. t.Error(initErr)
  238. t.FailNow()
  239. }
  240. if startErrors := app.Start(); startErrors == nil {
  241. conn, bufin, err := Connect(config.Servers[0], 20)
  242. if err != nil {
  243. // handle error
  244. t.Error(err.Error(), config.Servers[0].ListenInterface)
  245. t.FailNow()
  246. } else {
  247. // client goes into command state
  248. if _, err := Command(conn, bufin, "HELO localtester"); err != nil {
  249. t.Error("Hello command failed", err.Error())
  250. }
  251. // do a shutdown while the client is connected & in client state
  252. go app.Shutdown()
  253. time.Sleep(time.Millisecond * 150) // let server to Shutdown
  254. // issue a command while shutting down
  255. response, err := Command(conn, bufin, "HELP")
  256. if err != nil {
  257. t.Error("Help command failed", err.Error())
  258. }
  259. expected := "421 4.3.0 Server is shutting down. Please try again later. Sayonara!"
  260. if strings.Index(response, expected) != 0 {
  261. t.Error("Server did not shut down with", expected, ", it said:"+response)
  262. }
  263. time.Sleep(time.Millisecond * 250) // let server to close
  264. }
  265. conn.Close()
  266. } else {
  267. if startErrors := app.Start(); startErrors != nil {
  268. t.Error(startErrors)
  269. app.Shutdown()
  270. t.FailNow()
  271. }
  272. }
  273. // assuming server has shutdown by now
  274. if read, err := ioutil.ReadFile("./testlog"); err == nil {
  275. logOutput := string(read)
  276. // fmt.Println(logOutput)
  277. if i := strings.Index(logOutput, "Handle client [127.0.0.1"); i < 0 {
  278. t.Error("Server did not handle any clients")
  279. }
  280. }
  281. // don't forget to reset
  282. os.Truncate("./testlog", 0)
  283. }
  284. // add more than 100 recipients, it should fail at 101
  285. func TestRFC2821LimitRecipients(t *testing.T) {
  286. if initErr != nil {
  287. t.Error(initErr)
  288. t.FailNow()
  289. }
  290. if startErrors := app.Start(); startErrors == nil {
  291. conn, bufin, err := Connect(config.Servers[0], 20)
  292. if err != nil {
  293. // handle error
  294. t.Error(err.Error(), config.Servers[0].ListenInterface)
  295. t.FailNow()
  296. } else {
  297. // client goes into command state
  298. if _, err := Command(conn, bufin, "HELO localtester"); err != nil {
  299. t.Error("Hello command failed", err.Error())
  300. }
  301. for i := 0; i < 101; i++ {
  302. //fmt.Println(fmt.Sprintf("RCPT TO:test%[email protected]", i))
  303. if _, err := Command(conn, bufin, fmt.Sprintf("RCPT TO:test%[email protected]", i)); err != nil {
  304. t.Error("RCPT TO", err.Error())
  305. break
  306. }
  307. }
  308. response, err := Command(conn, bufin, "RCPT TO:[email protected]")
  309. if err != nil {
  310. t.Error("rcpt command failed", err.Error())
  311. }
  312. expected := "452 4.5.3 Too many recipients"
  313. if strings.Index(response, expected) != 0 {
  314. t.Error("Server did not respond with", expected, ", it said:"+response)
  315. }
  316. }
  317. conn.Close()
  318. app.Shutdown()
  319. } else {
  320. if startErrors := app.Start(); startErrors != nil {
  321. t.Error(startErrors)
  322. app.Shutdown()
  323. t.FailNow()
  324. }
  325. }
  326. // don't forget to reset
  327. os.Truncate("./testlog", 0)
  328. }
  329. // RCPT TO & MAIL FROM with 64 chars in local part, it should fail at 65
  330. func TestRFC2832LimitLocalPart(t *testing.T) {
  331. if initErr != nil {
  332. t.Error(initErr)
  333. t.FailNow()
  334. }
  335. if startErrors := app.Start(); startErrors == nil {
  336. conn, bufin, err := Connect(config.Servers[0], 20)
  337. if err != nil {
  338. // handle error
  339. t.Error(err.Error(), config.Servers[0].ListenInterface)
  340. t.FailNow()
  341. } else {
  342. // client goes into command state
  343. if _, err := Command(conn, bufin, "HELO localtester"); err != nil {
  344. t.Error("Hello command failed", err.Error())
  345. }
  346. // repeat > 64 characters in local part
  347. response, err := Command(conn, bufin, fmt.Sprintf("RCPT TO:%[email protected]", strings.Repeat("a", 65)))
  348. if err != nil {
  349. t.Error("rcpt command failed", err.Error())
  350. }
  351. expected := "550 5.5.4 Local part too long"
  352. if strings.Index(response, expected) != 0 {
  353. t.Error("Server did not respond with", expected, ", it said:"+response)
  354. }
  355. // what about if it's exactly 64?
  356. // repeat > 64 characters in local part
  357. response, err = Command(conn, bufin, fmt.Sprintf("RCPT TO:%[email protected]", strings.Repeat("a", 64)))
  358. if err != nil {
  359. t.Error("rcpt command failed", err.Error())
  360. }
  361. expected = "250 2.1.5 OK"
  362. if strings.Index(response, expected) != 0 {
  363. t.Error("Server did not respond with", expected, ", it said:"+response)
  364. }
  365. }
  366. conn.Close()
  367. app.Shutdown()
  368. } else {
  369. if startErrors := app.Start(); startErrors != nil {
  370. t.Error(startErrors)
  371. app.Shutdown()
  372. t.FailNow()
  373. }
  374. }
  375. // don't forget to reset
  376. os.Truncate("./testlog", 0)
  377. }
  378. //RFC2821LimitPath fail if path > 256 but different error if below
  379. func TestRFC2821LimitPath(t *testing.T) {
  380. if initErr != nil {
  381. t.Error(initErr)
  382. t.FailNow()
  383. }
  384. if startErrors := app.Start(); startErrors == nil {
  385. conn, bufin, err := Connect(config.Servers[0], 20)
  386. if err != nil {
  387. // handle error
  388. t.Error(err.Error(), config.Servers[0].ListenInterface)
  389. t.FailNow()
  390. } else {
  391. // client goes into command state
  392. if _, err := Command(conn, bufin, "HELO localtester"); err != nil {
  393. t.Error("Hello command failed", err.Error())
  394. }
  395. // repeat > 256 characters in local part
  396. response, err := Command(conn, bufin, fmt.Sprintf("RCPT TO:%[email protected]", strings.Repeat("a", 257-7)))
  397. if err != nil {
  398. t.Error("rcpt command failed", err.Error())
  399. }
  400. expected := "550 5.5.4 Path too long"
  401. if strings.Index(response, expected) != 0 {
  402. t.Error("Server did not respond with", expected, ", it said:"+response)
  403. }
  404. // what about if it's exactly 256?
  405. response, err = Command(conn, bufin,
  406. fmt.Sprintf("RCPT TO:%s@%s.la", strings.Repeat("a", 64), strings.Repeat("b", 257-5-64)))
  407. if err != nil {
  408. t.Error("rcpt command failed", err.Error())
  409. }
  410. expected = "454 4.1.1 Error: Relay access denied"
  411. if strings.Index(response, expected) != 0 {
  412. t.Error("Server did not respond with", expected, ", it said:"+response)
  413. }
  414. }
  415. conn.Close()
  416. app.Shutdown()
  417. } else {
  418. if startErrors := app.Start(); startErrors != nil {
  419. t.Error(startErrors)
  420. app.Shutdown()
  421. t.FailNow()
  422. }
  423. }
  424. // don't forget to reset
  425. os.Truncate("./testlog", 0)
  426. }
  427. // RFC2821LimitDomain 501 Domain cannot exceed 255 characters
  428. func TestRFC2821LimitDomain(t *testing.T) {
  429. if initErr != nil {
  430. t.Error(initErr)
  431. t.FailNow()
  432. }
  433. if startErrors := app.Start(); startErrors == nil {
  434. conn, bufin, err := Connect(config.Servers[0], 20)
  435. if err != nil {
  436. // handle error
  437. t.Error(err.Error(), config.Servers[0].ListenInterface)
  438. t.FailNow()
  439. } else {
  440. // client goes into command state
  441. if _, err := Command(conn, bufin, "HELO localtester"); err != nil {
  442. t.Error("Hello command failed", err.Error())
  443. }
  444. // repeat > 64 characters in local part
  445. response, err := Command(conn, bufin, fmt.Sprintf("RCPT TO:a@%s.l", strings.Repeat("a", 255-2)))
  446. if err != nil {
  447. t.Error("command failed", err.Error())
  448. }
  449. expected := "550 5.5.4 Path too long"
  450. if strings.Index(response, expected) != 0 {
  451. t.Error("Server did not respond with", expected, ", it said:"+response)
  452. }
  453. // what about if it's exactly 255?
  454. response, err = Command(conn, bufin,
  455. fmt.Sprintf("RCPT TO:a@%s.la", strings.Repeat("b", 255-4)))
  456. if err != nil {
  457. t.Error("command failed", err.Error())
  458. }
  459. expected = "454 4.1.1 Error: Relay access denied"
  460. if strings.Index(response, expected) != 0 {
  461. t.Error("Server did not respond with", expected, ", it said:"+response)
  462. }
  463. }
  464. conn.Close()
  465. app.Shutdown()
  466. } else {
  467. if startErrors := app.Start(); startErrors != nil {
  468. t.Error(startErrors)
  469. app.Shutdown()
  470. t.FailNow()
  471. }
  472. }
  473. // don't forget to reset
  474. os.Truncate("./testlog", 0)
  475. }
  476. // Test several different inputs to MAIL FROM command
  477. func TestMailFromCmd(t *testing.T) {
  478. if initErr != nil {
  479. t.Error(initErr)
  480. t.FailNow()
  481. }
  482. if startErrors := app.Start(); startErrors == nil {
  483. conn, bufin, err := Connect(config.Servers[0], 20)
  484. if err != nil {
  485. // handle error
  486. t.Error(err.Error(), config.Servers[0].ListenInterface)
  487. t.FailNow()
  488. } else {
  489. // client goes into command state
  490. if _, err := Command(conn, bufin, "HELO localtester"); err != nil {
  491. t.Error("Hello command failed", err.Error())
  492. }
  493. // Basic valid address
  494. response, err := Command(conn, bufin, "MAIL FROM:[email protected]")
  495. if err != nil {
  496. t.Error("command failed", err.Error())
  497. }
  498. expected := "250 2.1.0 OK"
  499. if strings.Index(response, expected) != 0 {
  500. t.Error("Server did not respond with", expected, ", it said:"+response)
  501. }
  502. // Reset
  503. response, err = Command(conn, bufin, "RSET")
  504. if err != nil {
  505. t.Error("command failed", err.Error())
  506. }
  507. expected = "250 2.1.0 OK"
  508. if strings.Index(response, expected) != 0 {
  509. t.Error("Server did not respond with", expected, ", it said:"+response)
  510. }
  511. // Basic valid address (RfC)
  512. response, err = Command(conn, bufin, "MAIL FROM:<[email protected]>")
  513. if err != nil {
  514. t.Error("command failed", err.Error())
  515. }
  516. expected = "250 2.1.0 OK"
  517. if strings.Index(response, expected) != 0 {
  518. t.Error("Server did not respond with", expected, ", it said:"+response)
  519. }
  520. // Reset
  521. response, err = Command(conn, bufin, "RSET")
  522. if err != nil {
  523. t.Error("command failed", err.Error())
  524. }
  525. expected = "250 2.1.0 OK"
  526. if strings.Index(response, expected) != 0 {
  527. t.Error("Server did not respond with", expected, ", it said:"+response)
  528. }
  529. // Bounce
  530. response, err = Command(conn, bufin, "MAIL FROM:<>")
  531. if err != nil {
  532. t.Error("command failed", err.Error())
  533. }
  534. expected = "250 2.1.0 OK"
  535. if strings.Index(response, expected) != 0 {
  536. t.Error("Server did not respond with", expected, ", it said:"+response)
  537. }
  538. // Reset
  539. response, err = Command(conn, bufin, "RSET")
  540. if err != nil {
  541. t.Error("command failed", err.Error())
  542. }
  543. expected = "250 2.1.0 OK"
  544. if strings.Index(response, expected) != 0 {
  545. t.Error("Server did not respond with", expected, ", it said:"+response)
  546. }
  547. // No mail from content
  548. response, err = Command(conn, bufin, "MAIL FROM:")
  549. if err != nil {
  550. t.Error("command failed", err.Error())
  551. }
  552. expected = "501 5.5.4 Invalid address"
  553. if strings.Index(response, expected) != 0 {
  554. t.Error("Server did not respond with", expected, ", it said:"+response)
  555. }
  556. // Reset
  557. response, err = Command(conn, bufin, "RSET")
  558. if err != nil {
  559. t.Error("command failed", err.Error())
  560. }
  561. expected = "250 2.1.0 OK"
  562. if strings.Index(response, expected) != 0 {
  563. t.Error("Server did not respond with", expected, ", it said:"+response)
  564. }
  565. // Short mail from content
  566. response, err = Command(conn, bufin, "MAIL FROM:<")
  567. if err != nil {
  568. t.Error("command failed", err.Error())
  569. }
  570. expected = "501 5.5.4 Invalid address"
  571. if strings.Index(response, expected) != 0 {
  572. t.Error("Server did not respond with", expected, ", it said:"+response)
  573. }
  574. // Reset
  575. response, err = Command(conn, bufin, "RSET")
  576. if err != nil {
  577. t.Error("command failed", err.Error())
  578. }
  579. expected = "250 2.1.0 OK"
  580. if strings.Index(response, expected) != 0 {
  581. t.Error("Server did not respond with", expected, ", it said:"+response)
  582. }
  583. // Short mail from content 2
  584. response, err = Command(conn, bufin, "MAIL FROM:x")
  585. if err != nil {
  586. t.Error("command failed", err.Error())
  587. }
  588. expected = "501 5.5.4 Invalid address"
  589. if strings.Index(response, expected) != 0 {
  590. t.Error("Server did not respond with", expected, ", it said:"+response)
  591. }
  592. // Reset
  593. response, err = Command(conn, bufin, "RSET")
  594. if err != nil {
  595. t.Error("command failed", err.Error())
  596. }
  597. expected = "250 2.1.0 OK"
  598. if strings.Index(response, expected) != 0 {
  599. t.Error("Server did not respond with", expected, ", it said:"+response)
  600. }
  601. // What?
  602. response, err = Command(conn, bufin, "MAIL FROM:<<>>")
  603. if err != nil {
  604. t.Error("command failed", err.Error())
  605. }
  606. expected = "501 5.5.4 Invalid address"
  607. if strings.Index(response, expected) != 0 {
  608. t.Error("Server did not respond with", expected, ", it said:"+response)
  609. }
  610. // Reset
  611. response, err = Command(conn, bufin, "RSET")
  612. if err != nil {
  613. t.Error("command failed", err.Error())
  614. }
  615. expected = "250 2.1.0 OK"
  616. if strings.Index(response, expected) != 0 {
  617. t.Error("Server did not respond with", expected, ", it said:"+response)
  618. }
  619. // Invalid address?
  620. response, err = Command(conn, bufin, "MAIL FROM:<justatest>")
  621. if err != nil {
  622. t.Error("command failed", err.Error())
  623. }
  624. expected = "501 5.5.4 Invalid address"
  625. if strings.Index(response, expected) != 0 {
  626. t.Error("Server did not respond with", expected, ", it said:"+response)
  627. }
  628. // Reset
  629. response, err = Command(conn, bufin, "RSET")
  630. if err != nil {
  631. t.Error("command failed", err.Error())
  632. }
  633. expected = "250 2.1.0 OK"
  634. if strings.Index(response, expected) != 0 {
  635. t.Error("Server did not respond with", expected, ", it said:"+response)
  636. }
  637. // SMTPUTF8 not implemented for now, currently still accepted
  638. response, err = Command(conn, bufin, "MAIL FROM:<anö[email protected]>")
  639. if err != nil {
  640. t.Error("command failed", err.Error())
  641. }
  642. expected = "250 2.1.0 OK"
  643. if strings.Index(response, expected) != 0 {
  644. t.Error("Server did not respond with", expected, ", it said:"+response)
  645. }
  646. // Reset
  647. response, err = Command(conn, bufin, "RSET")
  648. if err != nil {
  649. t.Error("command failed", err.Error())
  650. }
  651. expected = "250 2.1.0 OK"
  652. if strings.Index(response, expected) != 0 {
  653. t.Error("Server did not respond with", expected, ", it said:"+response)
  654. }
  655. // 8BITMIME (RfC 6152)
  656. response, err = Command(conn, bufin, "MAIL FROM:<[email protected]> BODY=8BITMIME")
  657. if err != nil {
  658. t.Error("command failed", err.Error())
  659. }
  660. expected = "250 2.1.0 OK"
  661. if strings.Index(response, expected) != 0 {
  662. t.Error("Server did not respond with", expected, ", it said:"+response)
  663. }
  664. // Reset
  665. response, err = Command(conn, bufin, "RSET")
  666. if err != nil {
  667. t.Error("command failed", err.Error())
  668. }
  669. expected = "250 2.1.0 OK"
  670. if strings.Index(response, expected) != 0 {
  671. t.Error("Server did not respond with", expected, ", it said:"+response)
  672. }
  673. // 8BITMIME (RfC 6152) Bounce
  674. response, err = Command(conn, bufin, "MAIL FROM:<> BODY=8BITMIME")
  675. if err != nil {
  676. t.Error("command failed", err.Error())
  677. }
  678. expected = "250 2.1.0 OK"
  679. if strings.Index(response, expected) != 0 {
  680. t.Error("Server did not respond with", expected, ", it said:"+response)
  681. }
  682. // Reset
  683. response, err = Command(conn, bufin, "RSET")
  684. if err != nil {
  685. t.Error("command failed", err.Error())
  686. }
  687. expected = "250 2.1.0 OK"
  688. if strings.Index(response, expected) != 0 {
  689. t.Error("Server did not respond with", expected, ", it said:"+response)
  690. }
  691. }
  692. conn.Close()
  693. app.Shutdown()
  694. } else {
  695. if startErrors := app.Start(); startErrors != nil {
  696. t.Error(startErrors)
  697. app.Shutdown()
  698. t.FailNow()
  699. }
  700. }
  701. }
  702. // Test several different inputs to MAIL FROM command
  703. func TestHeloEhlo(t *testing.T) {
  704. if initErr != nil {
  705. t.Error(initErr)
  706. t.FailNow()
  707. }
  708. if startErrors := app.Start(); startErrors == nil {
  709. conn, bufin, err := Connect(config.Servers[0], 20)
  710. hostname := config.Servers[0].Hostname
  711. if err != nil {
  712. // handle error
  713. t.Error(err.Error(), config.Servers[0].ListenInterface)
  714. t.FailNow()
  715. } else {
  716. // Test HELO
  717. response, err := Command(conn, bufin, "HELO localtester")
  718. if err != nil {
  719. t.Error("command failed", err.Error())
  720. }
  721. expected := fmt.Sprintf("250 %s Hello", hostname)
  722. if strings.Index(response, expected) != 0 {
  723. t.Error("Server did not respond with", expected, ", it said:"+response)
  724. }
  725. // Reset
  726. response, err = Command(conn, bufin, "RSET")
  727. if err != nil {
  728. t.Error("command failed", err.Error())
  729. }
  730. expected = "250 2.1.0 OK"
  731. if strings.Index(response, expected) != 0 {
  732. t.Error("Server did not respond with", expected, ", it said:"+response)
  733. }
  734. // Test EHLO
  735. // This is tricky as it is a multiline response
  736. var fullresp string
  737. response, err = Command(conn, bufin, "EHLO localtester")
  738. fullresp = fullresp + response
  739. if err != nil {
  740. t.Error("command failed", err.Error())
  741. }
  742. for err == nil {
  743. response, err = bufin.ReadString('\n')
  744. fullresp = fullresp + response
  745. if strings.HasPrefix(response, "250 ") { // Last response has a whitespace and no "-"
  746. break // bail
  747. }
  748. }
  749. 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)
  750. if fullresp != expected {
  751. t.Error("Server did not respond with [" + expected + "], it said [" + fullresp + "]")
  752. }
  753. // be kind, QUIT. And we are sure that bufin does not contain fragments from the EHLO command.
  754. response, err = Command(conn, bufin, "QUIT")
  755. if err != nil {
  756. t.Error("command failed", err.Error())
  757. }
  758. expected = "221 2.0.0 Bye"
  759. if strings.Index(response, expected) != 0 {
  760. t.Error("Server did not respond with", expected, ", it said:"+response)
  761. }
  762. }
  763. conn.Close()
  764. app.Shutdown()
  765. } else {
  766. if startErrors := app.Start(); startErrors != nil {
  767. t.Error(startErrors)
  768. app.Shutdown()
  769. t.FailNow()
  770. }
  771. }
  772. }
  773. // It should error when MAIL FROM was given twice
  774. func TestNestedMailCmd(t *testing.T) {
  775. if initErr != nil {
  776. t.Error(initErr)
  777. t.FailNow()
  778. }
  779. if startErrors := app.Start(); startErrors == nil {
  780. conn, bufin, err := Connect(config.Servers[0], 20)
  781. if err != nil {
  782. // handle error
  783. t.Error(err.Error(), config.Servers[0].ListenInterface)
  784. t.FailNow()
  785. } else {
  786. // client goes into command state
  787. if _, err := Command(conn, bufin, "HELO localtester"); err != nil {
  788. t.Error("Hello command failed", err.Error())
  789. }
  790. // repeat > 64 characters in local part
  791. response, err := Command(conn, bufin, "MAIL FROM:[email protected]")
  792. if err != nil {
  793. t.Error("command failed", err.Error())
  794. }
  795. response, err = Command(conn, bufin, "MAIL FROM:[email protected]")
  796. if err != nil {
  797. t.Error("command failed", err.Error())
  798. }
  799. expected := "503 5.5.1 Error: nested MAIL command"
  800. if strings.Index(response, expected) != 0 {
  801. t.Error("Server did not respond with", expected, ", it said:"+response)
  802. }
  803. // Plot twist: if you EHLO , it should allow MAIL FROM again
  804. if _, err := Command(conn, bufin, "HELO localtester"); err != nil {
  805. t.Error("Hello command failed", err.Error())
  806. }
  807. response, err = Command(conn, bufin, "MAIL FROM:[email protected]")
  808. if err != nil {
  809. t.Error("command failed", err.Error())
  810. }
  811. expected = "250 2.1.0 OK"
  812. if strings.Index(response, expected) != 0 {
  813. t.Error("Server did not respond with", expected, ", it said:"+response)
  814. }
  815. // Plot twist: if you RSET , it should allow MAIL FROM again
  816. response, err = Command(conn, bufin, "RSET")
  817. if err != nil {
  818. t.Error("command failed", err.Error())
  819. }
  820. expected = "250 2.1.0 OK"
  821. if strings.Index(response, expected) != 0 {
  822. t.Error("Server did not respond with", expected, ", it said:"+response)
  823. }
  824. response, err = Command(conn, bufin, "MAIL FROM:[email protected]")
  825. if err != nil {
  826. t.Error("command failed", err.Error())
  827. }
  828. expected = "250 2.1.0 OK"
  829. if strings.Index(response, expected) != 0 {
  830. t.Error("Server did not respond with", expected, ", it said:"+response)
  831. }
  832. }
  833. conn.Close()
  834. app.Shutdown()
  835. } else {
  836. if startErrors := app.Start(); startErrors != nil {
  837. t.Error(startErrors)
  838. app.Shutdown()
  839. t.FailNow()
  840. }
  841. }
  842. // don't forget to reset
  843. os.Truncate("./testlog", 0)
  844. }
  845. // It should error on a very long command line, exceeding CommandLineMaxLength 1024
  846. func TestCommandLineMaxLength(t *testing.T) {
  847. if initErr != nil {
  848. t.Error(initErr)
  849. t.FailNow()
  850. }
  851. if startErrors := app.Start(); startErrors == nil {
  852. conn, bufin, err := Connect(config.Servers[0], 20)
  853. if err != nil {
  854. // handle error
  855. t.Error(err.Error(), config.Servers[0].ListenInterface)
  856. t.FailNow()
  857. } else {
  858. // client goes into command state
  859. if _, err := Command(conn, bufin, "HELO localtester"); err != nil {
  860. t.Error("Hello command failed", err.Error())
  861. }
  862. // repeat > 1024 characters
  863. response, err := Command(conn, bufin, strings.Repeat("s", guerrilla.CommandLineMaxLength+1))
  864. if err != nil {
  865. t.Error("command failed", err.Error())
  866. }
  867. expected := "554 5.5.1 Line too long"
  868. if strings.Index(response, expected) != 0 {
  869. t.Error("Server did not respond with", expected, ", it said:"+response)
  870. }
  871. }
  872. conn.Close()
  873. app.Shutdown()
  874. } else {
  875. if startErrors := app.Start(); startErrors != nil {
  876. t.Error(startErrors)
  877. app.Shutdown()
  878. t.FailNow()
  879. }
  880. }
  881. // don't forget to reset
  882. os.Truncate("./testlog", 0)
  883. }
  884. // It should error on a very long message, exceeding servers config value
  885. func TestDataMaxLength(t *testing.T) {
  886. if initErr != nil {
  887. t.Error(initErr)
  888. t.FailNow()
  889. }
  890. if startErrors := app.Start(); startErrors == nil {
  891. conn, bufin, err := Connect(config.Servers[0], 20)
  892. if err != nil {
  893. // handle error
  894. t.Error(err.Error(), config.Servers[0].ListenInterface)
  895. t.FailNow()
  896. } else {
  897. // client goes into command state
  898. if _, err := Command(conn, bufin, "HELO localtester"); err != nil {
  899. t.Error("Hello command failed", err.Error())
  900. }
  901. response, err := Command(conn, bufin, "MAIL FROM:[email protected]")
  902. if err != nil {
  903. t.Error("command failed", err.Error())
  904. }
  905. //fmt.Println(response)
  906. response, err = Command(conn, bufin, "RCPT TO:[email protected]")
  907. if err != nil {
  908. t.Error("command failed", err.Error())
  909. }
  910. //fmt.Println(response)
  911. response, err = Command(conn, bufin, "DATA")
  912. if err != nil {
  913. t.Error("command failed", err.Error())
  914. }
  915. response, err = Command(
  916. conn,
  917. bufin,
  918. fmt.Sprintf("Subject:test\r\n\r\nHello %s\r\n.\r\n",
  919. strings.Repeat("n", int(config.Servers[0].MaxSize-20))))
  920. //expected := "500 Line too long"
  921. expected := "451 4.3.0 Error: Maximum DATA size exceeded"
  922. if strings.Index(response, expected) != 0 {
  923. t.Error("Server did not respond with", expected, ", it said:"+response, err)
  924. }
  925. }
  926. conn.Close()
  927. app.Shutdown()
  928. } else {
  929. if startErrors := app.Start(); startErrors != nil {
  930. t.Error(startErrors)
  931. app.Shutdown()
  932. t.FailNow()
  933. }
  934. }
  935. // don't forget to reset
  936. os.Truncate("./testlog", 0)
  937. }
  938. func TestDataCommand(t *testing.T) {
  939. if initErr != nil {
  940. t.Error(initErr)
  941. t.FailNow()
  942. }
  943. testHeader :=
  944. "Subject: =?Shift_JIS?B?W4NYg06DRYNGg0GBRYNHg2qDYoNOg1ggg0GDSoNFg5ODZ12DQYNKg0WDk4Nn?=\r\n" +
  945. "\t=?Shift_JIS?B?k2+YXoqul7mCzIKokm2C54K5?=\r\n"
  946. email :=
  947. "Delivered-To: [email protected]\r\n" +
  948. "\tReceived: from mail.guerrillamail.com (mail.guerrillamail.com [104.218.55.28:44246])\r\n" +
  949. "\tby grr.la with SMTP id [email protected];\r\n" +
  950. "\tWed, 18 Jan 2017 15:43:29 +0000\r\n" +
  951. "Received: by 192.99.19.220 with HTTP; Wed, 18 Jan 2017 15:43:29 +0000\r\n" +
  952. "MIME-Version: 1.0\r\n" +
  953. "Message-ID: <[email protected]>\r\n" +
  954. "Date: Wed, 18 Jan 2017 15:43:29 +0000\r\n" +
  955. "To: \"[email protected]\" <[email protected]>\r\n" +
  956. "From: <[email protected]>\r\n" +
  957. "Subject: test\r\n" +
  958. "X-Originating-IP: [60.241.160.150]\r\n" +
  959. "Content-Type: text/plain; charset=\"utf-8\"\r\n" +
  960. "Content-Transfer-Encoding: quoted-printable\r\n" +
  961. "X-Domain-Signer: PHP mailDomainSigner 0.2-20110415 <http://code.google.com/p/php-mail-domain-signer/>\r\n" +
  962. "DKIM-Signature: v=1; a=rsa-sha256; s=highgrade; d=guerrillamail.com; l=182;\r\n" +
  963. "\tt=1484754209; c=relaxed/relaxed; h=to:from:subject;\r\n" +
  964. "\tbh=GHSgjHpBp5QjNn9tzfug681+RcWMOUgpwAuTzppM5wY=;\r\n" +
  965. "\tb=R7FxWgACnT+pKXqEg15qgzH4ywMFRx5pDlIFCnSt1BfwmLvZPZK7oOLrbiRoGGR2OJnSfyCxeASH\r\n" +
  966. "\t019LNeLB/B8o+fMRX87m/tBpqIZ2vgXdT9rUCIbSDJnYoCHXakGcF+zGtTE3SEksMbeJQ76aGj6M\r\n" +
  967. "\tG80p76IT2Xu3iDJLYYWxcAeX+7z4M/bbYNeqxMQcXYZp1wNYlSlHahL6RDUYdcqikDqKoXmzMNVd\r\n" +
  968. "\tDr0EbH9iiu1DQtfUDzVE5LLus1yn36WU/2KJvEak45gJvm9s9J+Xrcb882CaYkxlAbgQDz1KeQLf\r\n" +
  969. "\teUyNspyAabkh2yTg7kOvNZSOJtbMSQS6/GMxsg==\r\n" +
  970. "\r\n" +
  971. "test=0A.mooo=0A..mooo=0Atest=0A.=0A=0A=0A=0A=0A=0A----=0ASent using Guerril=\r\n" +
  972. "lamail.com=0ABlock or report abuse: https://www.guerrillamail.com//abuse/?a=\r\n" +
  973. "=3DVURnES0HUaZbhA8%3D=0A\r\n.\r\n"
  974. if startErrors := app.Start(); startErrors == nil {
  975. conn, bufin, err := Connect(config.Servers[0], 20)
  976. if err != nil {
  977. // handle error
  978. t.Error(err.Error(), config.Servers[0].ListenInterface)
  979. t.FailNow()
  980. } else {
  981. // client goes into command state
  982. if _, err := Command(conn, bufin, "HELO localtester"); err != nil {
  983. t.Error("Hello command failed", err.Error())
  984. }
  985. response, err := Command(conn, bufin, "MAIL FROM:[email protected]")
  986. if err != nil {
  987. t.Error("command failed", err.Error())
  988. }
  989. //fmt.Println(response)
  990. response, err = Command(conn, bufin, "RCPT TO:[email protected]")
  991. if err != nil {
  992. t.Error("command failed", err.Error())
  993. }
  994. //fmt.Println(response)
  995. response, err = Command(conn, bufin, "DATA")
  996. if err != nil {
  997. t.Error("command failed", err.Error())
  998. }
  999. /*
  1000. response, err = Command(
  1001. conn,
  1002. bufin,
  1003. testHeader+"\r\nHello World\r\n.\r\n")
  1004. */
  1005. _ = testHeader
  1006. response, err = Command(
  1007. conn,
  1008. bufin,
  1009. email+"\r\n.\r\n")
  1010. //expected := "500 Line too long"
  1011. expected := "250 2.0.0 OK : queued as "
  1012. if strings.Index(response, expected) != 0 {
  1013. t.Error("Server did not respond with", expected, ", it said:"+response, err)
  1014. }
  1015. }
  1016. conn.Close()
  1017. app.Shutdown()
  1018. } else {
  1019. if startErrors := app.Start(); startErrors != nil {
  1020. t.Error(startErrors)
  1021. app.Shutdown()
  1022. t.FailNow()
  1023. }
  1024. }
  1025. // don't forget to reset
  1026. os.Truncate("./testlog", 0)
  1027. }
  1028. // Fuzzer crashed the server by submitting "DATA\r\n" as the first command
  1029. func TestFuzz86f25b86b09897aed8f6c2aa5b5ee1557358a6de(t *testing.T) {
  1030. if initErr != nil {
  1031. t.Error(initErr)
  1032. t.FailNow()
  1033. }
  1034. if startErrors := app.Start(); startErrors == nil {
  1035. conn, bufin, err := Connect(config.Servers[0], 20)
  1036. if err != nil {
  1037. // handle error
  1038. t.Error(err.Error(), config.Servers[0].ListenInterface)
  1039. t.FailNow()
  1040. } else {
  1041. response, err := Command(
  1042. conn,
  1043. bufin,
  1044. "DATA\r\n")
  1045. expected := "503 5.5.1 Error: No sender"
  1046. if strings.Index(response, expected) != 0 {
  1047. t.Error("Server did not respond with", expected, ", it said:"+response, err)
  1048. }
  1049. }
  1050. conn.Close()
  1051. app.Shutdown()
  1052. } else {
  1053. if startErrors := app.Start(); startErrors != nil {
  1054. t.Error(startErrors)
  1055. app.Shutdown()
  1056. t.FailNow()
  1057. }
  1058. }
  1059. // don't forget to reset
  1060. os.Truncate("./testlog", 0)
  1061. }
  1062. // Appears to hang the fuzz test, but not server.
  1063. func TestFuzz21c56f89989d19c3bbbd81b288b2dae9e6dd2150(t *testing.T) {
  1064. if initErr != nil {
  1065. t.Error(initErr)
  1066. t.FailNow()
  1067. }
  1068. str := "X_\r\nMAIL FROM:<u\xfd\xfdrU" +
  1069. "\x10c22695140\xfd727235530" +
  1070. " Walter Sobchak\x1a\tDon" +
  1071. "ny, x_6_, Donnyre " +
  1072. "\t\t outof89 !om>\r\nMAI" +
  1073. "L\t\t \t\tFROM:<C4o\xfd\xfdr@e" +
  1074. "xample.c22695140\xfd727" +
  1075. "235530 Walter Sobcha" +
  1076. "k: Donny, you>re out" +
  1077. " of your element!om>" +
  1078. "\r\nMAIL RCPT TO:t@IRS" +
  1079. "ETRCPTIRSETRCP:<\x00\xfd\xfdr" +
  1080. "@example 7A924_F__4_" +
  1081. "c22695140\xfd-061.0x30C" +
  1082. "8bC87fE4d3 Walter MA" +
  1083. "IL Donny, youiq__n_l" +
  1084. "wR8qs_0RBcw_0hIY_pS_" +
  1085. "___x9_E0___sL598_G82" +
  1086. "_6 out your elemen" +
  1087. "t!>\r\nX _9KB___X_p:<o" +
  1088. "ut\xfd\xfdr@example9gTnr2N" +
  1089. "__Vl_T7U_AqfU_dPfJ_0" +
  1090. "HIqKK0037f6W_KGM_y_Z" +
  1091. "_9_96_w_815Q572py2_9" +
  1092. "F\xfd727235530Walter\tSo" +
  1093. "bchakRSET MAIL from:" +
  1094. " : cows eat\t\t grass" +
  1095. " , _S___46_PbG03_iW'" +
  1096. "__v5L2_2L_J61u_38J55" +
  1097. "_PpwQ_Fs_7L_3p7S_t__" +
  1098. "g9XP48T_9HY_EDl_c_C3" +
  1099. "3_3b708EreT_OR out 9" +
  1100. "9_pUY4 \t\t\t \x05om>\r" +
  1101. "\n FROM<u\xfd\xfdr@example." +
  1102. "<\xfd-05110602 Walter S" +
  1103. "obchak: Donny, \t\t w" +
  1104. "50TI__m_5EsC___n_l_d" +
  1105. "__57GP9G02_32n_FR_xw" +
  1106. "_2_103___rnED5PGIKN7" +
  1107. "BBs3VIuNV_514qDBp_Gs" +
  1108. "_qj4\tre out all cows" +
  1109. " eatof your element\x03" +
  1110. "om>\r\n_2 FROM:<u\x10\xfdr@e" +
  1111. "xample.oQ_VLq909_E_5" +
  1112. "AQ7_4_\xfd1935012674150" +
  1113. "6773818422493001838." +
  1114. "-010\tWalter\tSobchak:" +
  1115. " Donny, youyouteIz2y" +
  1116. "__Z2q5_qoA're Q6MP2_" +
  1117. "CT_z70____0c0nU7_83d" +
  1118. "4jn_eFD7h_9MbPjr_s_L" +
  1119. "9_X23G_7 of _kU_L9Yz" +
  1120. "_K52345QVa902H1__Hj_" +
  1121. "Nl_PP2tW2ODi0_V80F15" +
  1122. "_i65i_V5uSQdiG eleme" +
  1123. "nt!om>\r\n"
  1124. if startErrors := app.Start(); startErrors == nil {
  1125. conn, bufin, err := Connect(config.Servers[0], 20)
  1126. if err != nil {
  1127. // handle error
  1128. t.Error(err.Error(), config.Servers[0].ListenInterface)
  1129. t.FailNow()
  1130. } else {
  1131. response, err := Command(
  1132. conn,
  1133. bufin,
  1134. str)
  1135. expected := "554 5.5.1 Unrecognized command"
  1136. if strings.Index(response, expected) != 0 {
  1137. t.Error("Server did not respond with", expected, ", it said:"+response, err)
  1138. }
  1139. }
  1140. conn.Close()
  1141. app.Shutdown()
  1142. } else {
  1143. if startErrors := app.Start(); startErrors != nil {
  1144. t.Error(startErrors)
  1145. app.Shutdown()
  1146. t.FailNow()
  1147. }
  1148. }
  1149. // don't forget to reset
  1150. os.Truncate("./testlog", 0)
  1151. }