mirror of
https://github.com/jhillyerd/inbucket.git
synced 2025-12-17 17:47:03 +00:00
Now adds a Recieved: header to raw message
This commit is contained in:
@@ -24,6 +24,8 @@ const (
|
|||||||
QUIT // Close session
|
QUIT // Close session
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const STAMP_FMT = "Mon, 02 Jan 2006 15:04:05 -0700 (MST)"
|
||||||
|
|
||||||
func (s State) String() string {
|
func (s State) String() string {
|
||||||
switch s {
|
switch s {
|
||||||
case GREET:
|
case GREET:
|
||||||
@@ -59,15 +61,16 @@ var commands = map[string]bool{
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Session struct {
|
type Session struct {
|
||||||
server *Server
|
server *Server
|
||||||
id int
|
id int
|
||||||
conn net.Conn
|
conn net.Conn
|
||||||
remoteHost string
|
remoteDomain string
|
||||||
sendError error
|
remoteHost string
|
||||||
state State
|
sendError error
|
||||||
reader *bufio.Reader
|
state State
|
||||||
from string
|
reader *bufio.Reader
|
||||||
recipients *list.List
|
from string
|
||||||
|
recipients *list.List
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSession(server *Server, id int, conn net.Conn) *Session {
|
func NewSession(server *Server, id int, conn net.Conn) *Session {
|
||||||
@@ -196,9 +199,21 @@ func (s *Server) startSession(id int, conn net.Conn) {
|
|||||||
func (ss *Session) greetHandler(cmd string, arg string) {
|
func (ss *Session) greetHandler(cmd string, arg string) {
|
||||||
switch cmd {
|
switch cmd {
|
||||||
case "HELO":
|
case "HELO":
|
||||||
|
domain, err := parseHelloArgument(arg)
|
||||||
|
if err != nil {
|
||||||
|
ss.send("501 Domain/address argument required for HELO")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ss.remoteDomain = domain
|
||||||
ss.send("250 Great, let's get this show on the road")
|
ss.send("250 Great, let's get this show on the road")
|
||||||
ss.enterState(READY)
|
ss.enterState(READY)
|
||||||
case "EHLO":
|
case "EHLO":
|
||||||
|
domain, err := parseHelloArgument(arg)
|
||||||
|
if err != nil {
|
||||||
|
ss.send("501 Domain/address argument required for EHLO")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ss.remoteDomain = domain
|
||||||
ss.send("250-Great, let's get this show on the road")
|
ss.send("250-Great, let's get this show on the road")
|
||||||
ss.send("250-8BITMIME")
|
ss.send("250-8BITMIME")
|
||||||
ss.send(fmt.Sprintf("250 SIZE %v", ss.server.maxMessageBytes))
|
ss.send(fmt.Sprintf("250 SIZE %v", ss.server.maxMessageBytes))
|
||||||
@@ -208,6 +223,17 @@ func (ss *Session) greetHandler(cmd string, arg string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func parseHelloArgument(arg string) (string, error) {
|
||||||
|
domain := arg
|
||||||
|
if idx := strings.IndexRune(arg, ' '); idx >= 0 {
|
||||||
|
domain = arg[:idx]
|
||||||
|
}
|
||||||
|
if domain == "" {
|
||||||
|
return "", fmt.Errorf("Invalid domain")
|
||||||
|
}
|
||||||
|
return domain, nil
|
||||||
|
}
|
||||||
|
|
||||||
// READY state -> waiting for MAIL
|
// READY state -> waiting for MAIL
|
||||||
func (ss *Session) readyHandler(cmd string, arg string) {
|
func (ss *Session) readyHandler(cmd string, arg string) {
|
||||||
if cmd == "MAIL" {
|
if cmd == "MAIL" {
|
||||||
@@ -305,11 +331,12 @@ func (ss *Session) mailHandler(cmd string, arg string) {
|
|||||||
|
|
||||||
// DATA
|
// DATA
|
||||||
func (ss *Session) dataHandler() {
|
func (ss *Session) dataHandler() {
|
||||||
msgSize := 0
|
// Timestamp for Received header
|
||||||
|
stamp := time.Now().Format(STAMP_FMT)
|
||||||
// Get a Mailbox and a new Message for each recipient
|
// Get a Mailbox and a new Message for each recipient
|
||||||
mailboxes := make([]Mailbox, ss.recipients.Len())
|
mailboxes := make([]Mailbox, ss.recipients.Len())
|
||||||
messages := make([]Message, ss.recipients.Len())
|
messages := make([]Message, ss.recipients.Len())
|
||||||
|
msgSize := 0
|
||||||
if ss.server.storeMessages {
|
if ss.server.storeMessages {
|
||||||
i := 0
|
i := 0
|
||||||
for e := ss.recipients.Front(); e != nil; e = e.Next() {
|
for e := ss.recipients.Front(); e != nil; e = e.Next() {
|
||||||
@@ -332,6 +359,11 @@ func (ss *Session) dataHandler() {
|
|||||||
}
|
}
|
||||||
mailboxes[i] = mb
|
mailboxes[i] = mb
|
||||||
messages[i] = mb.NewMessage()
|
messages[i] = mb.NewMessage()
|
||||||
|
|
||||||
|
// Generate Received header
|
||||||
|
recd := fmt.Sprintf("Received: from %s ([%s]) by %s\r\n for <%s>; %s\r\n",
|
||||||
|
ss.remoteDomain, ss.remoteHost, ss.server.domain, recip, stamp)
|
||||||
|
messages[i].Append([]byte(recd))
|
||||||
} else {
|
} else {
|
||||||
log.LogTrace("Not storing message for %q", recip)
|
log.LogTrace("Not storing message for %q", recip)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,6 +33,8 @@ func TestGreetState(t *testing.T) {
|
|||||||
|
|
||||||
// Test out some mangled HELOs
|
// Test out some mangled HELOs
|
||||||
script = []scriptStep{
|
script = []scriptStep{
|
||||||
|
{"HELO", 501},
|
||||||
|
{"EHLO", 501},
|
||||||
{"HELLO", 500},
|
{"HELLO", 500},
|
||||||
{"HELL", 500},
|
{"HELL", 500},
|
||||||
{"hello", 500},
|
{"hello", 500},
|
||||||
@@ -43,9 +45,6 @@ func TestGreetState(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Valid HELOs
|
// Valid HELOs
|
||||||
if err := playSession(t, server, []scriptStep{{"HELO", 250}}); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
if err := playSession(t, server, []scriptStep{{"HELO mydomain", 250}}); err != nil {
|
if err := playSession(t, server, []scriptStep{{"HELO mydomain", 250}}); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
@@ -55,6 +54,23 @@ func TestGreetState(t *testing.T) {
|
|||||||
if err := playSession(t, server, []scriptStep{{"HelO mydom.com", 250}}); err != nil {
|
if err := playSession(t, server, []scriptStep{{"HelO mydom.com", 250}}); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
|
if err := playSession(t, server, []scriptStep{{"helo 127.0.0.1", 250}}); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Valid EHLOs
|
||||||
|
if err := playSession(t, server, []scriptStep{{"EHLO mydomain", 250}}); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
if err := playSession(t, server, []scriptStep{{"EHLO mydom.com", 250}}); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
if err := playSession(t, server, []scriptStep{{"EhlO mydom.com", 250}}); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
if err := playSession(t, server, []scriptStep{{"ehlo 127.0.0.1", 250}}); err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
if t.Failed() {
|
if t.Failed() {
|
||||||
// Wait for handler to finish logging
|
// Wait for handler to finish logging
|
||||||
@@ -317,7 +333,7 @@ func playScriptAgainst(t *testing.T, c *textproto.Conn, script []scriptStep) err
|
|||||||
}
|
}
|
||||||
|
|
||||||
c.StartResponse(id)
|
c.StartResponse(id)
|
||||||
code, msg, err := c.ReadCodeLine(step.expect)
|
code, msg, err := c.ReadResponse(step.expect)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = fmt.Errorf("Step %d, sent %q, expected %v, got %v: %q",
|
err = fmt.Errorf("Step %d, sent %q, expected %v, got %v: %q",
|
||||||
i, step.send, step.expect, code, msg)
|
i, step.send, step.expect, code, msg)
|
||||||
|
|||||||
Reference in New Issue
Block a user