From ae1c246bde804a26bd60f66be47ad8eaf1bd01ef Mon Sep 17 00:00:00 2001 From: Alberto Bertogli Date: Wed, 20 Jul 2016 00:47:45 +0100 Subject: [PATCH] chasquid: Make "MAIL FROM" ignore extra parameters MAIL FROM commands usually come in the form of: MAIL FROM: BODY=8BITMIME Note that there's extra parameters after the address, which for now we want to ignore. The current parser doesn't ignore them, and relies on mail.ParseAddress doing so (that is, on mail.ParseAddress(" BODY=8BITMIME") working). However, in go 1.7, the parser will get more strict and start to fail these cases. To fix this, we change the way we parse the line to use fmt.Sprintf, which is much nicer than splitting by hand, and is more readable as well. --- chasquid.go | 18 ++++++++++++------ chasquid_test.go | 4 ++-- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/chasquid.go b/chasquid.go index 2779290..ba1065e 100644 --- a/chasquid.go +++ b/chasquid.go @@ -474,23 +474,29 @@ func (c *Conn) NOOP(params string) (code int, msg string) { } func (c *Conn) MAIL(params string) (code int, msg string) { - // params should be: "FROM:" - // First, get rid of the "FROM:" part (but check it, it's mandatory). - sp := strings.SplitN(strings.ToLower(params), ":", 2) - if len(sp) != 2 || sp[0] != "from" { + // params should be: "FROM:", and possibly followed by + // "BODY=8BITMIME" (which we ignore). + // Check that it begins with "FROM:" first, otherwise it's pointless. + if !strings.HasPrefix(strings.ToLower(params), "from:") { return 500, "unknown command" } + addr := "" + _, err := fmt.Sscanf(params[5:], "%s ", &addr) + if err != nil { + return 500, "malformed command - " + err.Error() + } + // Special case a null reverse-path, which is explicitly allowed and used // for notification messages. // It should be written "<>", we check for that and remove spaces just to // be more flexible. e := &mail.Address{} - if strings.Replace(sp[1], " ", "", -1) == "<>" { + if strings.Replace(addr, " ", "", -1) == "<>" { e.Address = "<>" } else { var err error - e, err = mail.ParseAddress(sp[1]) + e, err = mail.ParseAddress(addr) if err != nil || e.Address == "" { return 501, "malformed address" } diff --git a/chasquid_test.go b/chasquid_test.go index da54706..e306dbc 100644 --- a/chasquid_test.go +++ b/chasquid_test.go @@ -135,7 +135,7 @@ func TestWrongMailParsing(t *testing.T) { c := mustDial(t, false) defer c.Close() - addrs := []string{"", "from", "a b c", "a @ b", "", "", "><"} + addrs := []string{"from", "a b c", "a @ b", "", "", "><"} for _, addr := range addrs { if err := c.Mail(addr); err == nil { @@ -158,7 +158,7 @@ func TestNullMailFrom(t *testing.T) { c := mustDial(t, false) defer c.Close() - addrs := []string{"<>", " <>", " < > "} + addrs := []string{"", "<>", " <>", " < > "} for _, addr := range addrs { if err := c.Text.PrintfLine(addr); err != nil { t.Fatalf("MAIL FROM failed with addr %q: %v", addr, err)