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() {