From 871f70151cc345407634236d6052b873409c0058 Mon Sep 17 00:00:00 2001 From: Mechiel Lukkien Date: Mon, 13 Jan 2025 21:34:59 +0100 Subject: [PATCH] smtpserver: allow using an "message from" address from an allowed alias as smtp mail from during submission mail clients will use these message from addresses also for smtp mail from, so sending over smtp would fail for these cases. for the webmail and webapi they already succeeded since we just took the "message from" address as "smtp mail from" address. for issue #266 by Robby-, thanks for reporting! --- smtpserver/alias_test.go | 42 ++++++++++++++++++++++++++++++++++++++++ smtpserver/server.go | 7 +++++-- 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/smtpserver/alias_test.go b/smtpserver/alias_test.go index b32374b..166394b 100644 --- a/smtpserver/alias_test.go +++ b/smtpserver/alias_test.go @@ -40,6 +40,16 @@ test email ts.smtpErr(err, nil) }) + ts.run(func(err error, client *smtpclient.Client) { + t.Helper() + mailFrom := "public@mox.example" // List address as smtp mail from. + rcptTo := "public@mox.example" + if err == nil { + err = client.Deliver(ctxbg, mailFrom, rcptTo, int64(len(msg)), strings.NewReader(msg), false, false, false) + } + ts.smtpErr(err, nil) + }) + msg = strings.ReplaceAll(`From: To: Subject: test @@ -56,6 +66,16 @@ test email } ts.smtpErr(err, &smtpclient.Error{Permanent: true, Code: smtp.C550MailboxUnavail, Secode: smtp.SePol7DeliveryUnauth1}) }) + + ts.run(func(err error, client *smtpclient.Client) { + t.Helper() + mailFrom := "private@mox.example" // List address as smtp mail from. + rcptTo := "private@mox.example" + if err == nil { + err = client.Deliver(ctxbg, mailFrom, rcptTo, int64(len(msg)), strings.NewReader(msg), false, false, false) + } + ts.smtpErr(err, &smtpclient.Error{Permanent: true, Code: smtp.C550MailboxUnavail, Secode: smtp.SePol7DeliveryUnauth1}) + }) } // Non-member cannot submit as alias that allows it for members. @@ -97,6 +117,16 @@ test email } ts.smtpErr(err, &smtpclient.Error{Permanent: true, Code: smtp.C550MailboxUnavail, Secode: smtp.SePol7DeliveryUnauth1}) }) + + ts.run(func(err error, client *smtpclient.Client) { + t.Helper() + mailFrom := "public@mox.example" // List address as message from. + rcptTo := "public@mox.example" + if err == nil { + err = client.Deliver(ctxbg, mailFrom, rcptTo, int64(len(msg)), strings.NewReader(msg), true, true, false) + } + ts.smtpErr(err, &smtpclient.Error{Permanent: true, Code: smtp.C550MailboxUnavail, Secode: smtp.SePol7DeliveryUnauth1}) + }) } // Non-member can deliver to public list, not to private list. @@ -162,6 +192,18 @@ test email ts.checkCount("Inbox", 2) // Receiving for both mjl@ and móx@. }) + + ts.run(func(err error, client *smtpclient.Client) { + t.Helper() + mailFrom := "public@example.org" // List address as message from. + rcptTo := "public@mox.example" + if err == nil { + err = client.Deliver(ctxbg, mailFrom, rcptTo, int64(len(msg)), strings.NewReader(msg), false, false, false) + } + ts.smtpErr(err, nil) + + ts.checkCount("Inbox", 4) // Receiving for both mjl@ and móx@. + }) } // Member can deliver to private list, but still not with alias address as message diff --git a/smtpserver/server.go b/smtpserver/server.go index f17ff6a..01698ec 100644 --- a/smtpserver/server.go +++ b/smtpserver/server.go @@ -1756,13 +1756,16 @@ func (c *conn) cmdMail(p *parser) { // For submission, check if reverse path is allowed. I.e. authenticated account // must have the rpath configured. We do a check again on rfc5322.from during DATA. + // Mail clients may use the alias address as smtp mail from address, so we allow it + // for such aliases. rpathAllowed := func() bool { // ../rfc/6409:349 if rpath.IsZero() { return true } - accName, _, _, _, err := mox.LookupAddress(rpath.Localpart, rpath.IPDomain.Domain, false, false) - return err == nil && accName == c.account.Name + + from := smtp.NewAddress(rpath.Localpart, rpath.IPDomain.Domain) + return mox.AllowMsgFrom(c.account.Name, from) } if !c.submission && !rpath.IPDomain.Domain.IsZero() {