marlam / msmtp

SMTP client with sendmail compatible interface
https://marlam.de/msmtp
GNU General Public License v3.0
176 stars 36 forks source link

[feature request] Compatibility with postfix' `pipe` transport. #166

Closed shamefulCake1 closed 1 month ago

shamefulCake1 commented 1 month ago

Hello, and thank you for a wonderful tool!

I am using it as a replacement for the postfix' smtp transport, and while my setup works, I think that a slight modification to msmtp could save me one (and everyone) one wrapper script, which I thought might come in handy?

So, I am calling msmtp from master.cf like this:

coolscript unix -    n    n    -    50    pipe
    flags=R user=nobody argv=/etc/bin/email-using-msmtp.bash --sender=${sender} --user=${user} --extension=${extension} --recipient=${recipient}

The message with all headers is passed to msmtp as-is, and the envelope parameters are passed via command-line arguments.

The wrapper script does option parsing, which is not strictly necessary, because msmtp supports the required arguments from the command line.

But what is incompatible with postfix is the output. Msmtp passes the SMTP error message, as expected, however it prepends its own prefix:

msmtp: server message:  ....

This is very user-friendly, but postfix does not like this prefixes, and cannot parse them on its own, so I have to filter them out in the wrapper:

OUT=$(msmtp --host='fixed' --port=587 --tls-starttls=on --from="$sender" "$recipient" 2>&1)                                                           
rc=$?                                                                                                                                                         

MESSAGE=$(printf '%s' "$OUT" | sed -E --quiet '/server message/s/msmtp: server message: (.*)/\1/gp')
printf '%s' "$MESSAGE"
exit $rc

Would it be possible to add a switch to produce a "terse error output", which would be compatible with postfix?

Thank you!

marlam commented 1 month ago

Is there a documentation on what postfix would expect? Is multi-line ok or does everything have to be on a single line?

shamefulCake1 commented 1 month ago

I used the man page to connect the pipe transport with msmtp as described above: https://www.postfix.org/pipe.8.html

Command exit status codes are expected to follow the conventions defined in . Exit status 0 means normal successful comple- tion.

  In the case of a non-zero exit status, a limited amount of command out-
  put  is  logged,  and reported in a delivery status notification.  When
  the output begins with a 4.X.X or 5.X.X enhanced status code, the  sta-
  tus  code  takes precedence over the non-zero exit status (Postfix ver-
  sion 2.3 and later).

  After successful delivery (zero exit status) a limited amount  of  com-
  mand  output is logged, and reported in "success" delivery status noti-
  fications (Postfix 3.0 and later).  This command output is not examined
  for the presence of an enhanced status code.

I am not a postfix guru, unfortunately, but in my case, the only thing I had to do to hook into the system was to ensure that

output begins with a 4.X.X or 5.X.X enhanced status code

I had it report output as is, and it seemed to just chomp the line breaks, and fail at recognizing the exit status.

So, I would just add a switch to "only output SMTP Error", call it --postfix, and see if anybody else catches the bait of using this switch and comes back with an error report.

marlam commented 1 month ago

Hm, I don't see anything in this documentation that says that the current msmtp output cannot be digested by postfix. It's just that enhanced status codes (if they are reported by the remote server at all!) do not override the exit code given by msmtp. But that exit code is already correct according to sysexits.h conventions, as required by postfix, so it does not need to be overridden.

Am I missing something?

shamefulCake1 commented 1 month ago

I have re-checked once again, and it seems that you are right, and I am wrong.

It seemed to me that the TEMPFAIL exit status was interpreted as fatal, but now I retried, and it seems to work fine.

Perhaps it is my mistake.