Skip to content

Commit

Permalink
Add option to convert CRLF to LF line endings for sendmail (#18075)
Browse files Browse the repository at this point in the history
It appears that several versions of sendmail require that the mail is sent to them with
LF line endings instead of CRLF endings - which of course they will then convert back
to CRLF line endings to comply with the SMTP standard.

This PR adds another setting SENDMAIL_CONVERT_CRLF which will pass the message writer
through a filter. This will filter out and convert CRLFs to LFs before writing them
out to sendmail.

Fix #18024

Signed-off-by: Andrew Thornton <art27@cantab.net>
  • Loading branch information
zeripath authored Jan 6, 2022
1 parent bf7b083 commit 1514e13
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 7 deletions.
3 changes: 3 additions & 0 deletions custom/conf/app.example.ini
Original file line number Diff line number Diff line change
Expand Up @@ -1494,6 +1494,9 @@ PATH =
;;
;; Timeout for Sendmail
;SENDMAIL_TIMEOUT = 5m
;;
;; convert \r\n to \n for Sendmail
;SENDMAIL_CONVERT_CRLF = true

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Expand Down
1 change: 1 addition & 0 deletions docs/content/doc/advanced/config-cheat-sheet.en-us.md
Original file line number Diff line number Diff line change
Expand Up @@ -667,6 +667,7 @@ Define allowed algorithms and their minimum key length (use -1 to disable a type
command or full path).
- `SENDMAIL_ARGS`: **_empty_**: Specify any extra sendmail arguments.
- `SENDMAIL_TIMEOUT`: **5m**: default timeout for sending email through sendmail
- `SENDMAIL_CONVERT_CRLF`: **true**: Most versions of sendmail prefer LF line endings rather than CRLF line endings. Set this to false if your version of sendmail requires CRLF line endings.
- `SEND_BUFFER_LEN`: **100**: Buffer length of mailing queue. **DEPRECATED** use `LENGTH` in `[queue.mailer]`

## Cache (`cache`)
Expand Down
12 changes: 7 additions & 5 deletions modules/setting/mailer.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,10 @@ type Mailer struct {
IsTLSEnabled bool

// Sendmail sender
SendmailPath string
SendmailArgs []string
SendmailTimeout time.Duration
SendmailPath string
SendmailArgs []string
SendmailTimeout time.Duration
SendmailConvertCRLF bool
}

var (
Expand Down Expand Up @@ -71,8 +72,9 @@ func newMailService() {
IsTLSEnabled: sec.Key("IS_TLS_ENABLED").MustBool(),
SubjectPrefix: sec.Key("SUBJECT_PREFIX").MustString(""),

SendmailPath: sec.Key("SENDMAIL_PATH").MustString("sendmail"),
SendmailTimeout: sec.Key("SENDMAIL_TIMEOUT").MustDuration(5 * time.Minute),
SendmailPath: sec.Key("SENDMAIL_PATH").MustString("sendmail"),
SendmailTimeout: sec.Key("SENDMAIL_TIMEOUT").MustDuration(5 * time.Minute),
SendmailConvertCRLF: sec.Key("SENDMAIL_CONVERT_CRLF").MustBool(true),
}
MailService.From = sec.Key("FROM").MustString(MailService.User)
MailService.EnvelopeFrom = sec.Key("ENVELOPE_FROM").MustString("")
Expand Down
11 changes: 9 additions & 2 deletions services/mailer/mailer.go
Original file line number Diff line number Diff line change
Expand Up @@ -290,13 +290,20 @@ func (s *sendmailSender) Send(from string, to []string, msg io.WriterTo) error {
return err
}

_, err = msg.WriteTo(pipe)
if setting.MailService.SendmailConvertCRLF {
buf := &strings.Builder{}
_, err = msg.WriteTo(buf)
if err == nil {
_, err = strings.NewReplacer("\r\n", "\n").WriteString(pipe, buf.String())
}
} else {
_, err = msg.WriteTo(pipe)
}

// we MUST close the pipe or sendmail will hang waiting for more of the message
// Also we should wait on our sendmail command even if something fails
closeError = pipe.Close()
waitError = cmd.Wait()

if err != nil {
return err
} else if closeError != nil {
Expand Down

0 comments on commit 1514e13

Please sign in to comment.