From e55d4d9859a942415994cbbb506006f674012345 Mon Sep 17 00:00:00 2001 From: Robert Sesek Date: Wed, 14 Dec 2016 00:52:14 -0500 Subject: [PATCH] Handle case-insensitivity properly for SMTP commands. --- smtp/conn.go | 31 ++++++++++++++++++++++--------- smtp/conn_test.go | 24 ++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 9 deletions(-) diff --git a/smtp/conn.go b/smtp/conn.go index c379484..3485894 100644 --- a/smtp/conn.go +++ b/smtp/conn.go @@ -5,6 +5,7 @@ import ( "net" "net/mail" "net/textproto" + "strings" ) type state int @@ -56,7 +57,7 @@ func AcceptConnection(netConn net.Conn, server Server) error { continue } - switch cmd { + switch strings.ToUpper(cmd) { case "QUIT": conn.writeReply(221, "Goodbye") conn.tp.Close() @@ -101,6 +102,19 @@ func (conn *connection) writeReply(code int, msg string) { } } +// parsePath parses out either a forward-, reverse-, or return-path from the +// current connection line. Returns a (valid-path, ReplyOK) if it was +// successfully parsed. +func (conn *connection) parsePath(command string) (string, ReplyLine) { + if len(conn.line) < len(command) { + return "", ReplyBadSyntax + } + if strings.ToUpper(command) != strings.ToUpper(conn.line[:len(command)]) { + return "", ReplyLine{500, "unrecognized command"} + } + return conn.line[len(command):], ReplyOK +} + func (conn *connection) doEHLO() { conn.resetBuffers() @@ -130,13 +144,13 @@ func (conn *connection) doMAIL() { return } - var mailFrom string - _, err := fmt.Sscanf(conn.line, "MAIL FROM:%s", &mailFrom) - if err != nil { - conn.reply(ReplyBadSyntax) + mailFrom, reply := conn.parsePath("MAIL FROM:") + if reply != ReplyOK { + conn.reply(reply) return } + var err error conn.mailFrom, err = mail.ParseAddress(mailFrom) if err != nil { conn.reply(ReplyBadSyntax) @@ -153,10 +167,9 @@ func (conn *connection) doRCPT() { return } - var rcptTo string - _, err := fmt.Sscanf(conn.line, "RCPT TO:%s", &rcptTo) - if err != nil { - conn.reply(ReplyBadSyntax) + rcptTo, reply := conn.parsePath("RCPT TO:") + if reply != ReplyOK { + conn.reply(reply) return } diff --git a/smtp/conn_test.go b/smtp/conn_test.go index 5aa5234..32ca484 100644 --- a/smtp/conn_test.go +++ b/smtp/conn_test.go @@ -164,3 +164,27 @@ func TestVerifyAddress(t *testing.T) { {"QUIT", 221, nil}, }) } + +func TestCaseSensitivty(t *testing.T) { + s := &testServer{} + l := runServer(t, s) + defer l.Close() + + conn := createClient(t, l.Addr()) + readCodeLine(t, conn, 220) + + runTableTest(t, conn, []requestResponse{ + {"nOoP", 250, nil}, + {"ehLO test.TEST", 0, func(t testing.TB, conn *textproto.Conn) { conn.ReadResponse(250) }}, + {"mail FROM:", 250, nil}, + {"RcPT tO:", 250, nil}, + {"DATa", 0, func(t testing.TB, conn *textproto.Conn) { + readCodeLine(t, conn, 354) + + ok(t, conn.PrintfLine(".")) + readCodeLine(t, conn, 250) + }}, + {"MAIL FR:", 501, nil}, + {"QUiT", 221, nil}, + }) +} -- 2.22.5