Skip to content

Commit

Permalink
Fix: Ignore unsupported optional SMTP 'MAIL FROM' parameters (#407)
Browse files Browse the repository at this point in the history
  • Loading branch information
axllent committed Dec 13, 2024
1 parent b573469 commit 4ad6a45
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 6 deletions.
11 changes: 7 additions & 4 deletions server/smtpd/lib.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand Down
7 changes: 5 additions & 2 deletions server/smtpd/smtpd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,11 +148,15 @@ func TestCmdMAIL(t *testing.T) {
cmdCode(t, conn, "MAIL FROM:<[email protected]> SIZE=1000", "250")

// MAIL with bad size parameter should return 501 syntax error
cmdCode(t, conn, "MAIL FROM:<[email protected]> SIZE", "501")
cmdCode(t, conn, "MAIL FROM:<[email protected]> SIZE=", "501")
cmdCode(t, conn, "MAIL FROM:<[email protected]> SIZE= ", "501")
cmdCode(t, conn, "MAIL FROM:<[email protected]> SIZE=foo", "501")

// MAIL with options should be ignored except for SIZE
cmdCode(t, conn, "MAIL FROM:<[email protected]> BODY=8BITMIME", "250") // ignored
cmdCode(t, conn, "MAIL FROM:<[email protected]> BODY=8BITMIME,SIZE=1000", "250") // size detected
cmdCode(t, conn, "MAIL FROM:<[email protected]> 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
Expand All @@ -170,7 +174,6 @@ func TestCmdMAILMaxSize(t *testing.T) {
cmdCode(t, conn, "MAIL FROM:<[email protected]>", "250")

// MAIL with bad size parameter should return 501 syntax error
cmdCode(t, conn, "MAIL FROM:<[email protected]> SIZE", "501")
cmdCode(t, conn, "MAIL FROM:<[email protected]> SIZE=", "501")
cmdCode(t, conn, "MAIL FROM:<[email protected]> SIZE= ", "501")
cmdCode(t, conn, "MAIL FROM:<[email protected]> SIZE=foo", "501")
Expand Down

0 comments on commit 4ad6a45

Please sign in to comment.