mirror of
https://blitiri.com.ar/repos/chasquid
synced 2025-12-18 14:47:03 +00:00
chasquid: Make "MAIL FROM" ignore extra parameters
MAIL FROM commands usually come in the form of:
MAIL FROM:<from@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("<from> 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.
This commit is contained in:
18
chasquid.go
18
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) {
|
func (c *Conn) MAIL(params string) (code int, msg string) {
|
||||||
// params should be: "FROM:<name@host>"
|
// params should be: "FROM:<name@host>", and possibly followed by
|
||||||
// First, get rid of the "FROM:" part (but check it, it's mandatory).
|
// "BODY=8BITMIME" (which we ignore).
|
||||||
sp := strings.SplitN(strings.ToLower(params), ":", 2)
|
// Check that it begins with "FROM:" first, otherwise it's pointless.
|
||||||
if len(sp) != 2 || sp[0] != "from" {
|
if !strings.HasPrefix(strings.ToLower(params), "from:") {
|
||||||
return 500, "unknown command"
|
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
|
// Special case a null reverse-path, which is explicitly allowed and used
|
||||||
// for notification messages.
|
// for notification messages.
|
||||||
// It should be written "<>", we check for that and remove spaces just to
|
// It should be written "<>", we check for that and remove spaces just to
|
||||||
// be more flexible.
|
// be more flexible.
|
||||||
e := &mail.Address{}
|
e := &mail.Address{}
|
||||||
if strings.Replace(sp[1], " ", "", -1) == "<>" {
|
if strings.Replace(addr, " ", "", -1) == "<>" {
|
||||||
e.Address = "<>"
|
e.Address = "<>"
|
||||||
} else {
|
} else {
|
||||||
var err error
|
var err error
|
||||||
e, err = mail.ParseAddress(sp[1])
|
e, err = mail.ParseAddress(addr)
|
||||||
if err != nil || e.Address == "" {
|
if err != nil || e.Address == "" {
|
||||||
return 501, "malformed address"
|
return 501, "malformed address"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -135,7 +135,7 @@ func TestWrongMailParsing(t *testing.T) {
|
|||||||
c := mustDial(t, false)
|
c := mustDial(t, false)
|
||||||
defer c.Close()
|
defer c.Close()
|
||||||
|
|
||||||
addrs := []string{"", "from", "a b c", "a @ b", "<x>", "<x y>", "><"}
|
addrs := []string{"from", "a b c", "a @ b", "<x>", "<x y>", "><"}
|
||||||
|
|
||||||
for _, addr := range addrs {
|
for _, addr := range addrs {
|
||||||
if err := c.Mail(addr); err == nil {
|
if err := c.Mail(addr); err == nil {
|
||||||
@@ -158,7 +158,7 @@ func TestNullMailFrom(t *testing.T) {
|
|||||||
c := mustDial(t, false)
|
c := mustDial(t, false)
|
||||||
defer c.Close()
|
defer c.Close()
|
||||||
|
|
||||||
addrs := []string{"<>", " <>", " < > "}
|
addrs := []string{"", "<>", " <>", " < > "}
|
||||||
for _, addr := range addrs {
|
for _, addr := range addrs {
|
||||||
if err := c.Text.PrintfLine(addr); err != nil {
|
if err := c.Text.PrintfLine(addr); err != nil {
|
||||||
t.Fatalf("MAIL FROM failed with addr %q: %v", addr, err)
|
t.Fatalf("MAIL FROM failed with addr %q: %v", addr, err)
|
||||||
|
|||||||
Reference in New Issue
Block a user