From 77b7722891e3bf3904ef05b6fdcfbda333577270 Mon Sep 17 00:00:00 2001 From: "fox.cpp" Date: Tue, 23 Jun 2020 21:31:56 +0300 Subject: [PATCH] server: Prohibit invalid commands during BDAT message transfer --- conn.go | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/conn.go b/conn.go index 87db096..462e38e 100644 --- a/conn.go +++ b/conn.go @@ -25,13 +25,14 @@ type ConnectionState struct { } type Conn struct { - conn net.Conn - text *textproto.Conn - server *Server - helo string - nbrErrors int - session Session - locker sync.Mutex + conn net.Conn + text *textproto.Conn + server *Server + helo string + nbrErrors int + session Session + locker sync.Mutex + binarymime bool bdatPipe *io.PipeWriter bdatStatus *statusCollector // used for BDAT on LMTP @@ -279,6 +280,10 @@ func (c *Conn) handleMail(arg string) { c.WriteResponse(502, EnhancedCode{2, 5, 1}, "Please introduce yourself first.") return } + if c.bdatPipe != nil { + c.WriteResponse(502, EnhancedCode{5, 5, 1}, "MAIL not allowed during message transfer") + return + } if c.Session() == nil { state := c.State() @@ -315,6 +320,7 @@ func (c *Conn) handleMail(arg string) { opts := MailOptions{} + c.binarymime = false // This is where the Conn may put BODY=8BITMIME, but we already // read the DATA as bytes, so it does not effect our processing. if len(fromArgs) > 1 { @@ -358,6 +364,7 @@ func (c *Conn) handleMail(arg string) { c.WriteResponse(504, EnhancedCode{5, 5, 4}, "BINARYMIME is not implemented") return } + c.binarymime = true case "7BIT", "8BITMIME": default: c.WriteResponse(500, EnhancedCode{5, 5, 4}, "Unknown BODY value") @@ -457,6 +464,10 @@ func (c *Conn) handleRcpt(arg string) { c.WriteResponse(502, EnhancedCode{5, 5, 1}, "Missing MAIL FROM command.") return } + if c.bdatPipe != nil { + c.WriteResponse(502, EnhancedCode{5, 5, 1}, "RCPT not allowed during message transfer") + return + } if (len(arg) < 4) || (strings.ToUpper(arg[0:3]) != "TO:") { c.WriteResponse(501, EnhancedCode{5, 5, 2}, "Was expecting RCPT arg syntax of TO:
") @@ -607,6 +618,14 @@ func (c *Conn) handleData(arg string) { c.WriteResponse(501, EnhancedCode{5, 5, 4}, "DATA command should not have any arguments") return } + if c.bdatPipe != nil { + c.WriteResponse(502, EnhancedCode{5, 5, 1}, "DATA not allowed during message transfer") + return + } + if c.binarymime { + c.WriteResponse(502, EnhancedCode{5, 5, 1}, "DATA not allowed for BINARYMIME messages") + return + } if !c.fromReceived || len(c.recipients) == 0 { c.WriteResponse(502, EnhancedCode{5, 5, 1}, "Missing RCPT TO command.")