Subject: 27.1; smtpmail does not attempt alternative auth methods when primary (cram-md5) fails

From: klu <[email-masked]>
Date: Fri, 21 May 2021 06:24:26 +0000

For some reason the SMTP server I talk to (mx.sdf.org) fails the CRAM-MD5
authetication, and the bug is, when this happens, smtpmail didn't know to try
the rest of the supported auth methods (namely, 'plain, and 'login), and
therefore, fails to send the mail.

The SMTP info is:

  (setq smtpmail-smtp-server "mx.sdf.org")
  (setq smtpmail-smtp-service 587)
  (setq mtpmail-stream-type 'starttls)

And here is smtpmail's trace on the failure - notice how it stopped after
CRAM-MD5 failure and didn't try the rest:

  220 mx.sdf.org ESMTP Sendmail 8.15.2/8.14.5; Thu, 20 May 2021 23:55:20 GMT
  250-mx.sdf.org Hello xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx [xx.xxx.xxx.xx],
                 pleased to meet you
  250-ENHANCEDSTATUSCODES
  250-PIPELINING
  250-EXPN
  250-VERB
  250-8BITMIME
  250-SIZE 2147483648
  250-AUTH DIGEST-MD5 CRAM-MD5 PLAIN
  250-STARTTLS
  250-DELIVERBY
  250 HELP
  220 2.0.0 Ready to start TLS
  250-mx.sdf.org Hello xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 
                 pleased to meet you
  250-ENHANCEDSTATUSCODES
  250-PIPELINING
  250-EXPN
  250-VERB
  250-8BITMIME
  250-SIZE 2147483648
  250-AUTH DIGEST-MD5 CRAM-MD5 PLAIN
  250-DELIVERBY
  250 HELP
  AUTH CRAM-MD5
  334 PDM1O___________________________________Zz4=
  a2___________________________________________TAx
  535 5.7.0 authentication failed
  QUIT
  221 2.0.0 mx.sdf.org closing connection
  Process smtpmail connection broken by remote peer

This is clearly Emacs problem. Because I can send mail using other clients, including
iOS mail app, mac mail app, Alpine, and, below as an example, hand-made Python code:

The code:

  >>> import smtplib as s
  >>> with s.SMTP("mx.sdf.org", 587) as smtp:
  ...     smtp.set_debuglevel(2)
  ...     smtp.login('foobar', '___________')
  ...     smtp.sendmail(
  ...         "From: [email-masked]",
  ...         "To: [email-masked]",
  ...         "hello"
  ...     )
  ... 

The log (notice how Python also fails CRAM-MD5, but proceeds wit PLAIN which
succeeded):

  05:04:16.672784 send: 'ehlo [127.0.0.1]\r\n'
  05:04:16.689710 reply: b'250-mx.sdf.org Hello xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx [xx.xxx.xxx.xx], pleased to meet you\r\n'
  05:04:16.689792 reply: b'250-ENHANCEDSTATUSCODES\r\n'
  05:04:16.689840 reply: b'250-PIPELINING\r\n'
  05:04:16.689877 reply: b'250-EXPN\r\n'
  05:04:16.689914 reply: b'250-VERB\r\n'
  05:04:16.689951 reply: b'250-8BITMIME\r\n'
  05:04:16.689987 reply: b'250-SIZE 2147483648\r\n'
  05:04:16.690023 reply: b'250-AUTH DIGEST-MD5 CRAM-MD5 PLAIN\r\n'
  05:04:16.690060 reply: b'250-STARTTLS\r\n'
  05:04:16.690096 reply: b'250-DELIVERBY\r\n'
  05:04:16.690132 reply: b'250 HELP\r\n'
  05:04:16.690178 reply: retcode (250); Msg: b'mx.sdf.org Hello c-73-109-252-21.hsd1.wa.comcast.net [73.109.252.
  21], pleased to meet you\nENHANCEDSTATUSCODES\nPIPELINING\nEXPN\nVERB\n8BITMIME\nSIZE 2147483648\nAUTH DIGEST-
  MD5 CRAM-MD5 PLAIN\nSTARTTLS\nDELIVERBY\nHELP'
  05:04:16.690386 send: 'AUTH CRAM-MD5\r\n'
  05:04:16.701705 reply: b'334 PDM3NTM_____________________________Lm9yZz4=\r\n'
  05:04:16.701776 reply: retcode (334); Msg: b'PDM3NT______________________________Lm9yZz4='
  05:04:16.701936 send: 'a2x1IDM3__________________________________c2ZjNk\r\n'
  05:04:16.713173 reply: b'535 5.7.0 authentication failed\r\n'
  05:04:16.713247 reply: retcode (535); Msg: b'5.7.0 authentication failed'
  05:04:16.713339 send: 'AUTH PLAIN ____\r\n'
  05:04:16.790840 reply: b'235 2.0.0 OK Authenticated\r\n'
  05:04:16.790938 reply: retcode (235); Msg: b'2.0.0 OK Authenticated'
  (235, b'2.0.0 OK Authenticated')
  05:04:16.791612 send: 'mail FROM:<[email-masked]> size=5\r\n'
  05:04:16.810506 reply: b'250 2.1.0 <[email-masked]>... Sender ok\r\n'
  05:04:16.810579 reply: retcode (250); Msg: b'2.1.0 <[email-masked]>... Sender ok'
  05:04:16.810767 send: 'rcpt TO:<[email-masked]>\r\n'
  05:04:16.821945 reply: b'250 2.1.5 <[email-masked]>... Recipient ok\r\n'
  05:04:16.822010 reply: retcode (250); Msg: b'2.1.5 <[email-masked]>... Recipient ok'
  05:04:16.822059 send: 'data\r\n'
  05:04:16.838365 reply: b'354 Enter mail, end with "." on a line by itself\r\n'
  05:04:16.838434 reply: retcode (354); Msg: b'Enter mail, end with "." on a line by itself'
  05:04:16.838474 data: (354, b'Enter mail, end with "." on a line by itself')
  05:04:16.838698 send: b'hello\r\n.\r\n'
  05:04:16.857556 reply: b'250 2.0.0 xxxxxxxxxxxxxx Message accepted for delivery\r\n'
  05:04:16.857629 reply: retcode (250); Msg: b'2.0.0 xxxxxxxxxxxxxx Message accepted for delivery'
  05:04:16.857669 data: (250, b'2.0.0 xxxxxxxxxxxxxx Message accepted for delivery')
  {}
  05:04:16.857730 send: 'QUIT\r\n'
  05:04:16.868917 reply: b'221 2.0.0 mx.sdf.org closing connection\r\n'
  05:04:16.868990 reply: retcode (221); Msg: b'2.0.0 mx.sdf.org closing connection'

Finally, as a work around, I manually set `smtpmail-auth-supported` to only
PLAIN. And this works.

  (setq smtpmail-auth-supported '(plain))

Below are Emacs Bug Report generated info:
-----------------------------------------

In GNU Emacs 27.1 (build 1, amd64-portbld-freebsd11.4)
System Description: 11.4-RELEASE-p6

Recent messages:
Checking new news...
Reading active file via nnnil...done
Reading active file from archive via nnfolder...done
Reading active file via nndraft...done
Checking new news...done
Saving file /home/klu/News/drafts/drafts/3...
Wrote /home/klu/News/drafts/drafts/3
Deleting article /home/klu/News/drafts/drafts/1 in drafts...
current-kill: Kill ring is empty [4 times]
C-c k is undefined

Configured using:
 'configure --disable-build-details --localstatedir=/var --with-x
 --enable-acl --without-cairo --with-dbus --without-gconf --without-gif
 --with-gnutls --with-gsettings --with-harfbuzz --without-jpeg
 --with-json --with-file-notification=kqueue --with-lcms2
 --with-m17n-flt --without-imagemagick --with-mailutils --with-modules
 --without-libotf --without-png --without-toolkit-scroll-bars
 --without-rsvg --with-threads --without-tiff --with-xft --without-xim
 --with-xml2 --without-xpm --without-xwidgets --with-x-toolkit=no
 --x-libraries=/usr/local/lib --x-includes=/usr/local/include
 --prefix=/usr/local --mandir=/usr/local/man --disable-silent-rules
 --infodir=/usr/local/share/emacs/info/
 --build=amd64-portbld-freebsd11.4 'CFLAGS=-O2 -pipe
 -fstack-protector-strong -isystem /usr/local/include
 -fno-strict-aliasing ' 'CPPFLAGS=-isystem /usr/local/include' 'LDFLAGS=
 -fstack-protector-strong -L/usr/local/lib ''

Configured features:
SOUND DBUS GSETTINGS GLIB NOTIFY KQUEUE ACL GNUTLS LIBXML2 FREETYPE
HARFBUZZ XFT ZLIB OLDXMENU X11 XDBE XIM MODULES THREADS JSON PDUMPER
LCMS2 GMP

Important settings:
  value of $LC_ALL: en_US.UTF-8
  locale-coding-system: utf-8-unix

Major mode: Group

Minor modes in effect:
  cursor-sensor-mode: t
  gnus-undo-mode: t
  global-display-line-numbers-mode: t
  display-line-numbers-mode: t
  xterm-mouse-mode: t
  better-jumper-mode: t
  better-jumper-local-mode: t
  evil-mode: t
  evil-local-mode: t
  helm-mode: t
  shell-dirtrack-mode: t
  async-bytecomp-package-mode: t
  straight-use-package-mode: t
  straight-package-neutering-mode: t
  tooltip-mode: t
  global-eldoc-mode: t
  electric-indent-mode: t
  mouse-wheel-mode: t
  tool-bar-mode: t
  menu-bar-mode: t
  file-name-shadow-mode: t
  global-font-lock-mode: t
  font-lock-mode: t
  auto-composition-mode: t
  auto-encryption-mode: t
  auto-compression-mode: t
  buffer-read-only: t
  line-number-mode: t
  transient-mark-mode: t

Load-path shadows:
None found.

Features:
(shadow sort emacsbug sendmail winner tramp-archive tramp-gvfs dbus
gnus-bcklg gnus-cite mail-extr nnir gnus-draft gnus-ml disp-table
cursor-sensor nndraft nnmh utf-7 gnutls network-stream nsm nnfolder
nnnil gnus-agent gnus-srvr gnus-score score-mode nnvirtual gnus-msg
gnus-art mm-uu mml2015 mm-view mml-smime smime dig nntp gnus-cache
gnus-sum url url-proxy url-privacy url-expand url-methods url-history
mailcap shr url-cookie url-domsuf url-util url-parse url-vars svg xml
dom browse-url gnus-group gnus-undo gnus-start gnus-cloud nnimap nnmail
mail-source utf7 netrc nnoo gnus-spec gnus-int gnus-range message rmc
puny dired dired-loaddefs rfc822 mml mml-sec epa derived epg epg-config
mm-decode mm-bodies mm-encode mail-parse rfc2231 mailabbrev gmm-utils
mailheader gnus-win gnus nnheader gnus-util rmail rmail-loaddefs rfc2047
rfc2045 ietf-drums text-property-search mail-utils mm-util mail-prsvr
wid-edit term/screen term/xterm xterm display-line-numbers xt-mouse
better-jumper evil evil-keybindings evil-integration evil-maps
evil-commands reveal flyspell ispell evil-jumps evil-command-window
evil-types evil-search evil-ex evil-macros evil-repeat evil-states
evil-core advice evil-common windmove calc calc-loaddefs calc-macs
thingatpt rect evil-digraphs evil-vars helm-mode helm-files filenotify
tramp tramp-loaddefs trampver tramp-integration files-x tramp-compat
shell pcomplete comint ansi-color ring parse-time iso8601 time-date
ls-lisp auth-source password-cache json map helm-buffers helm-occur
helm-tags helm-locate helm-grep helm-regexp format-spec helm-utils
helm-help helm-types helm easy-mmode async-bytecomp helm-global-bindings
helm-easymenu helm-source eieio eieio-core eieio-loaddefs
helm-multi-match helm-lib async edmacro kmacro better-jumper-autoloads
evil-autoloads finder-inf goto-chg-autoloads helm-autoloads
helm-core-autoloads popup-autoloads async-autoloads straight-autoloads
info cl-seq cl-extra help-mode easymenu seq byte-opt straight subr-x
cl-macs gv cl-loaddefs cl-lib bytecomp byte-compile cconv tooltip eldoc
electric uniquify ediff-hook vc-hooks lisp-float-type mwheel term/x-win
x-win term/common-win x-dnd tool-bar dnd fontset image regexp-opt fringe
tabulated-list replace newcomment text-mode elisp-mode lisp-mode
prog-mode register page tab-bar menu-bar rfn-eshadow isearch timer
select scroll-bar mouse jit-lock font-lock syntax facemenu font-core
term/tty-colors frame minibuffer cl-generic cham georgian utf-8-lang
misc-lang vietnamese tibetan thai tai-viet lao korean japanese eucjp-ms
cp51932 hebrew greek romanian slovak czech european ethiopic indian
cyrillic chinese composite charscript charprop case-table epa-hook
jka-cmpr-hook help simple abbrev obarray cl-preloaded nadvice loaddefs
button faces cus-face macroexp files text-properties overlay sha1 md5
base64 format env code-pages mule custom widget hashtable-print-readable
backquote threads dbusbind kqueue lcms2 dynamic-setting
system-font-setting font-render-setting x multi-tty make-network-process
emacs)

Memory information:
((conses 16 219173 19146)
 (symbols 48 23877 2)
 (strings 32 69897 3387)
 (string-bytes 1 2641629)
 (vectors 16 34835)
 (vector-slots 8 411664 18272)
 (floats 8 271 499)
 (intervals 56 455 0)
 (buffers 1000 25))