From 641aaa12fc7ed063b036caa5d121be76e6c6a43a Mon Sep 17 00:00:00 2001 From: Andrew Thornton Date: Thu, 28 Oct 2021 21:32:34 +0100 Subject: [PATCH 1/3] Add settings to allow different SMTP envelope from address Sometimes it may be advisable to hide or alias the from address on an SMTP mail envelope. This PR adds two new options to the mailer to allow setting of an overriding from address. Fix #17477 Signed-off-by: Andrew Thornton --- custom/conf/app.example.ini | 4 ++++ .../doc/advanced/config-cheat-sheet.en-us.md | 2 ++ modules/setting/mailer.go | 18 +++++++++++------- services/mailer/mailer.go | 17 ++++++++++++++--- 4 files changed, 31 insertions(+), 10 deletions(-) diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index 1753ed233070..b1560efff1a9 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -1450,6 +1450,10 @@ PATH = ;; Mail from address, RFC 5322. This can be just an email address, or the `"Name" ` format ;FROM = ;; +;; Sometimes it is helpful to use a different address on the envelope. Set USE_DIFFERENT_ENVELOPE_FROM to true to use ENVELOPE_FROM as the from on the envelope +;USE_DIFFERENT_ENVELOPE_FROM=false +;ENVELOPE_FROM = +;; ;; Mailer user name and password ;; Please Note: Authentication is only supported when the SMTP server communication is encrypted with TLS (this can be via STARTTLS) or `HOST=localhost`. ;USER = diff --git a/docs/content/doc/advanced/config-cheat-sheet.en-us.md b/docs/content/doc/advanced/config-cheat-sheet.en-us.md index 91c62dbec34a..49df1a0a70f5 100644 --- a/docs/content/doc/advanced/config-cheat-sheet.en-us.md +++ b/docs/content/doc/advanced/config-cheat-sheet.en-us.md @@ -598,6 +598,8 @@ Define allowed algorithms and their minimum key length (use -1 to disable a type - Otherwise if `IS_TLS_ENABLED=false` and the server supports `STARTTLS` this will be used. Thus if `STARTTLS` is preferred you should set `IS_TLS_ENABLED=false`. - `FROM`: **\**: Mail from address, RFC 5322. This can be just an email address, or the "Name" \ format. +- `USE_DIFFERENT_ENVELOPE_FROM`: **false**: Set to **true** to use the value of `ENVELOPE_FROM` as the From address on the SMTP mail envelope. +- `ENVELOPE_FROM`: **\**: Address set as the From address on the SMTP mail envelope if `USE_DIFFERENT_ENVELOPE_FROM` is set to true. - `USER`: **\**: Username of mailing user (usually the sender's e-mail address). - `PASSWD`: **\**: Password of mailing user. Use \`your password\` for quoting if you use special characters in the password. - Please note: authentication is only supported when the SMTP server communication is encrypted with TLS (this can be via `STARTTLS`) or `HOST=localhost`. See [Email Setup]({{< relref "doc/usage/email-setup.en-us.md" >}}) for more information. diff --git a/modules/setting/mailer.go b/modules/setting/mailer.go index d2fac440ac08..77f62eac2d49 100644 --- a/modules/setting/mailer.go +++ b/modules/setting/mailer.go @@ -16,13 +16,15 @@ import ( // Mailer represents mail service. type Mailer struct { // Mailer - Name string - From string - FromName string - FromEmail string - SendAsPlainText bool - MailerType string - SubjectPrefix string + Name string + From string + EnvelopeFrom string + UseDifferentEnvelopeFrom bool + FromName string + FromEmail string + SendAsPlainText bool + MailerType string + SubjectPrefix string // SMTP sender Host string @@ -73,6 +75,8 @@ func newMailService() { SendmailTimeout: sec.Key("SENDMAIL_TIMEOUT").MustDuration(5 * time.Minute), } MailService.From = sec.Key("FROM").MustString(MailService.User) + MailService.UseDifferentEnvelopeFrom = sec.Key("USE_DIFFERENT_ENVELOPE_FROM").MustBool() + MailService.EnvelopeFrom = sec.Key("ENVELOPE_FROM").MustString("") if sec.HasKey("ENABLE_HTML_ALTERNATIVE") { log.Warn("ENABLE_HTML_ALTERNATIVE is deprecated, use SEND_AS_PLAIN_TEXT") diff --git a/services/mailer/mailer.go b/services/mailer/mailer.go index fae8d473e341..e73be6463625 100644 --- a/services/mailer/mailer.go +++ b/services/mailer/mailer.go @@ -210,8 +210,14 @@ func (s *smtpSender) Send(from string, to []string, msg io.WriterTo) error { } } - if err = client.Mail(from); err != nil { - return fmt.Errorf("Mail: %v", err) + if opts.UseDifferentEnvelopeFrom { + if err = client.Mail(opts.EnvelopeFrom); err != nil { + return fmt.Errorf("Mail: %v", err) + } + } else { + if err = client.Mail(from); err != nil { + return fmt.Errorf("Mail: %v", err) + } } for _, rec := range to { @@ -242,7 +248,12 @@ func (s *sendmailSender) Send(from string, to []string, msg io.WriterTo) error { var closeError error var waitError error - args := []string{"-f", from, "-i"} + envelopeFrom := from + if setting.MailService.UseDifferentEnvelopeFrom { + envelopeFrom = setting.MailService.EnvelopeFrom + } + + args := []string{"-f", envelopeFrom, "-i"} args = append(args, setting.MailService.SendmailArgs...) args = append(args, to...) log.Trace("Sending with: %s %v", setting.MailService.SendmailPath, args) From 20edfa5ce11b12b315209a02821be74ac6140714 Mon Sep 17 00:00:00 2001 From: Andrew Thornton Date: Sat, 30 Oct 2021 14:25:21 +0100 Subject: [PATCH 2/3] Remove USE_DIFFERENT_ENVELOPE_FROM option - instead determine whether to use it from the value Signed-off-by: Andrew Thornton --- custom/conf/app.example.ini | 3 +- .../doc/advanced/config-cheat-sheet.en-us.md | 3 +- modules/setting/mailer.go | 34 +++++++++++++------ services/mailer/mailer.go | 4 +-- 4 files changed, 28 insertions(+), 16 deletions(-) diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index b1560efff1a9..7f24cba350d2 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -1450,8 +1450,7 @@ PATH = ;; Mail from address, RFC 5322. This can be just an email address, or the `"Name" ` format ;FROM = ;; -;; Sometimes it is helpful to use a different address on the envelope. Set USE_DIFFERENT_ENVELOPE_FROM to true to use ENVELOPE_FROM as the from on the envelope -;USE_DIFFERENT_ENVELOPE_FROM=false +;; Sometimes it is helpful to use a different address on the envelope. Set this to use ENVELOPE_FROM as the from on the envelope. Set to `<>` to send an empty address. ;ENVELOPE_FROM = ;; ;; Mailer user name and password diff --git a/docs/content/doc/advanced/config-cheat-sheet.en-us.md b/docs/content/doc/advanced/config-cheat-sheet.en-us.md index 49df1a0a70f5..594085c3e041 100644 --- a/docs/content/doc/advanced/config-cheat-sheet.en-us.md +++ b/docs/content/doc/advanced/config-cheat-sheet.en-us.md @@ -598,8 +598,7 @@ Define allowed algorithms and their minimum key length (use -1 to disable a type - Otherwise if `IS_TLS_ENABLED=false` and the server supports `STARTTLS` this will be used. Thus if `STARTTLS` is preferred you should set `IS_TLS_ENABLED=false`. - `FROM`: **\**: Mail from address, RFC 5322. This can be just an email address, or the "Name" \ format. -- `USE_DIFFERENT_ENVELOPE_FROM`: **false**: Set to **true** to use the value of `ENVELOPE_FROM` as the From address on the SMTP mail envelope. -- `ENVELOPE_FROM`: **\**: Address set as the From address on the SMTP mail envelope if `USE_DIFFERENT_ENVELOPE_FROM` is set to true. +- `ENVELOPE_FROM`: **\**: Address set as the From address on the SMTP mail envelope. Set to `<>` to send an empty address. - `USER`: **\**: Username of mailing user (usually the sender's e-mail address). - `PASSWD`: **\**: Password of mailing user. Use \`your password\` for quoting if you use special characters in the password. - Please note: authentication is only supported when the SMTP server communication is encrypted with TLS (this can be via `STARTTLS`) or `HOST=localhost`. See [Email Setup]({{< relref "doc/usage/email-setup.en-us.md" >}}) for more information. diff --git a/modules/setting/mailer.go b/modules/setting/mailer.go index 77f62eac2d49..b51eb0514ce6 100644 --- a/modules/setting/mailer.go +++ b/modules/setting/mailer.go @@ -16,15 +16,15 @@ import ( // Mailer represents mail service. type Mailer struct { // Mailer - Name string - From string - EnvelopeFrom string - UseDifferentEnvelopeFrom bool - FromName string - FromEmail string - SendAsPlainText bool - MailerType string - SubjectPrefix string + Name string + From string + EnvelopeFrom string + OverrideEnvelopeFrom bool `ini:"-"` + FromName string + FromEmail string + SendAsPlainText bool + MailerType string + SubjectPrefix string // SMTP sender Host string @@ -75,7 +75,6 @@ func newMailService() { SendmailTimeout: sec.Key("SENDMAIL_TIMEOUT").MustDuration(5 * time.Minute), } MailService.From = sec.Key("FROM").MustString(MailService.User) - MailService.UseDifferentEnvelopeFrom = sec.Key("USE_DIFFERENT_ENVELOPE_FROM").MustBool() MailService.EnvelopeFrom = sec.Key("ENVELOPE_FROM").MustString("") if sec.HasKey("ENABLE_HTML_ALTERNATIVE") { @@ -97,6 +96,21 @@ func newMailService() { MailService.FromName = parsed.Name MailService.FromEmail = parsed.Address + switch MailService.EnvelopeFrom { + case "": + MailService.OverrideEnvelopeFrom = false + case "<>": + MailService.EnvelopeFrom = "" + MailService.OverrideEnvelopeFrom = true + default: + parsed, err = mail.ParseAddress(MailService.EnvelopeFrom) + if err != nil { + log.Fatal("Invalid mailer.ENVELOPE_FROM (%s): %v", MailService.EnvelopeFrom, err) + } + MailService.OverrideEnvelopeFrom = true + MailService.EnvelopeFrom = parsed.String() + } + if MailService.MailerType == "" { MailService.MailerType = "smtp" } diff --git a/services/mailer/mailer.go b/services/mailer/mailer.go index e73be6463625..0c0c6266276a 100644 --- a/services/mailer/mailer.go +++ b/services/mailer/mailer.go @@ -210,7 +210,7 @@ func (s *smtpSender) Send(from string, to []string, msg io.WriterTo) error { } } - if opts.UseDifferentEnvelopeFrom { + if opts.OverrideEnvelopeFrom { if err = client.Mail(opts.EnvelopeFrom); err != nil { return fmt.Errorf("Mail: %v", err) } @@ -249,7 +249,7 @@ func (s *sendmailSender) Send(from string, to []string, msg io.WriterTo) error { var waitError error envelopeFrom := from - if setting.MailService.UseDifferentEnvelopeFrom { + if setting.MailService.OverrideEnvelopeFrom { envelopeFrom = setting.MailService.EnvelopeFrom } From 59636ec43066f6670c9378638caa494cf2cb4793 Mon Sep 17 00:00:00 2001 From: Andrew Thornton Date: Tue, 16 Nov 2021 20:03:23 +0000 Subject: [PATCH 3/3] As per review Signed-off-by: Andrew Thornton --- modules/setting/mailer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/setting/mailer.go b/modules/setting/mailer.go index b51eb0514ce6..1bcd63a914bd 100644 --- a/modules/setting/mailer.go +++ b/modules/setting/mailer.go @@ -108,7 +108,7 @@ func newMailService() { log.Fatal("Invalid mailer.ENVELOPE_FROM (%s): %v", MailService.EnvelopeFrom, err) } MailService.OverrideEnvelopeFrom = true - MailService.EnvelopeFrom = parsed.String() + MailService.EnvelopeFrom = parsed.Address } if MailService.MailerType == "" {