Fix: Ignore unsupported optional SMTP 'MAIL FROM' parameters (#407)

This commit is contained in:
Ralph Slooten
2024-12-13 15:40:11 +13:00
parent b5734691e8
commit 4ad6a4553c
2 changed files with 12 additions and 6 deletions

View File

@@ -29,7 +29,9 @@ var (
Debug = false
rcptToRE = regexp.MustCompile(`[Tt][Oo]:\s?<(.+)>`)
mailFromRE = regexp.MustCompile(`[Ff][Rr][Oo][Mm]:\s?<(.*)>(\s(.*))?`) // Delivery Status Notifications are sent with "MAIL FROM:<>"
mailSizeRE = regexp.MustCompile(`[Ss][Ii][Zz][Ee]=(\d+)`)
// extract mail size from 'MAIL FROM' parameter
mailFromSizeRE = regexp.MustCompile(`(?U)(^| |,)[Ss][Ii][Zz][Ee]=(.*)($|,| )`)
)
// Handler function called upon successful receipt of an email.
@@ -411,12 +413,13 @@ loop:
} else {
// Validate the SIZE parameter if one was sent.
if len(match[2]) > 0 { // A parameter is present
sizeMatch := mailSizeRE.FindStringSubmatch(match[3])
sizeMatch := mailFromSizeRE.FindStringSubmatch(match[3])
if sizeMatch == nil {
s.writef("501 5.5.4 Syntax error in parameters or arguments (invalid SIZE parameter)")
// ignore other parameter
s.writef("250 2.1.0 Ok")
} else {
// Enforce the maximum message size if one is set.
size, err := strconv.Atoi(sizeMatch[1])
size, err := strconv.Atoi(sizeMatch[2])
if err != nil { // Bad SIZE parameter
s.writef("501 5.5.4 Syntax error in parameters or arguments (invalid SIZE parameter)")
} else if s.srv.MaxSize > 0 && size > s.srv.MaxSize { // SIZE above maximum size, if set

View File

@@ -148,11 +148,15 @@ func TestCmdMAIL(t *testing.T) {
cmdCode(t, conn, "MAIL FROM:<sender@example.com> SIZE=1000", "250")
// MAIL with bad size parameter should return 501 syntax error
cmdCode(t, conn, "MAIL FROM:<sender@example.com> SIZE", "501")
cmdCode(t, conn, "MAIL FROM:<sender@example.com> SIZE=", "501")
cmdCode(t, conn, "MAIL FROM:<sender@example.com> SIZE= ", "501")
cmdCode(t, conn, "MAIL FROM:<sender@example.com> SIZE=foo", "501")
// MAIL with options should be ignored except for SIZE
cmdCode(t, conn, "MAIL FROM:<sender@example.com> BODY=8BITMIME", "250") // ignored
cmdCode(t, conn, "MAIL FROM:<sender@example.com> BODY=8BITMIME,SIZE=1000", "250") // size detected
cmdCode(t, conn, "MAIL FROM:<sender@example.com> BODY=8BITMIME,SIZE=foo", "501") // ignored
// TODO: MAIL with valid AUTH parameter should return 250 Ok
// TODO: MAIL with invalid AUTH parameter must return 501 syntax error
@@ -170,7 +174,6 @@ func TestCmdMAILMaxSize(t *testing.T) {
cmdCode(t, conn, "MAIL FROM:<sender@example.com>", "250")
// MAIL with bad size parameter should return 501 syntax error
cmdCode(t, conn, "MAIL FROM:<sender@example.com> SIZE", "501")
cmdCode(t, conn, "MAIL FROM:<sender@example.com> SIZE=", "501")
cmdCode(t, conn, "MAIL FROM:<sender@example.com> SIZE= ", "501")
cmdCode(t, conn, "MAIL FROM:<sender@example.com> SIZE=foo", "501")