bug#59858: 29.0.60; Preserve a nil erc-session-password when reconnecting

"J.P." <[email protected]>
Newsgroups gmane.emacs.erc.general
Message-ID <[email protected]>
Hi people,

When reconnecting, `erc-determine-parameters' prefers reusing existing
session parameters, mainly by way of the various "compute" functions,
like `erc-compute-server'. But this isn't true if a parameter is nil.
The "danger" here is that, once exposed to new details, like the network
name, a custom auth-source-search function, for example, could reach a
different conclusion than it did initially, which could then lead to the
unwanted transmission of a non-server password via the PASS command.

One solution would be to just bypass `erc-determine-parameters' when
reconnecting and instead copy over all session vars verbatim while
leaving them unset in target buffers. However, there may be third-party
code expecting these vars to be recomputed whenever `erc-open' runs. So,
for the sake of compatibility, it's probably prudent to just focus on
`erc-session-password' for now because it's the likeliest offender (and
because passwords).

For this, we're mainly concerned with `erc-auth-source-server-function',
which always runs when reconnecting if the existing session password is
nil (and the opt itself is non-nil). One way to partially address this
might be to hide an existing "derived" `erc-network--id' from
`erc-auth-source-server-function' when reconnecting or opening a target
buffer. But this assumes a lot. Alternatively, we could just inhibit
`erc-auth-source-server-function' from running whenever
`erc--server-reconnecting' is non-nil and `erc-open' was called with a
nil session password, which is what this patch does.

(Better ideas welcome, as always.)

Thanks,
J.P.


In GNU Emacs 29.0.60 (build 2, x86_64-pc-linux-gnu, GTK+ Version
 3.24.35, cairo version 1.17.6) of 2022-12-04 built on localhost
Repository revision: 4bcdb1cc65bf779b6479f99a7aa767ab83b3bae1
Repository branch: emacs-29
Windowing system distributor 'The X.Org Foundation', version 11.0.12014000
System Description: Fedora Linux 36 (Workstation Edition)

Configured using:
 'configure --enable-check-lisp-object-type --enable-checking=yes,glyphs
 'CFLAGS=-O0 -g3'
 PKG_CONFIG_PATH=:/usr/lib64/pkgconfig:/usr/share/pkgconfig'

Configured features:
ACL CAIRO DBUS FREETYPE GIF GLIB GMP GNUTLS GPM GSETTINGS HARFBUZZ JPEG
JSON LCMS2 LIBOTF LIBSELINUX LIBSYSTEMD LIBXML2 M17N_FLT MODULES NOTIFY
INOTIFY PDUMPER PNG RSVG SECCOMP SOUND SQLITE3 THREADS TIFF
TOOLKIT_SCROLL_BARS WEBP X11 XDBE XIM XINPUT2 XPM GTK3 ZLIB

Important settings:
  value of $LANG: en_US.UTF-8
  value of $XMODIFIERS: @im=ibus
  locale-coding-system: utf-8-unix

Major mode: Lisp Interaction

Minor modes in effect:
  tooltip-mode: t
  global-eldoc-mode: t
  eldoc-mode: t
  show-paren-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
  blink-cursor-mode: t
  line-number-mode: t
  indent-tabs-mode: t
  transient-mark-mode: t
  auto-composition-mode: t
  auto-encryption-mode: t
  auto-compression-mode: t

Load-path shadows:
None found.

Features:
(shadow sort mail-extr emacsbug message mailcap yank-media puny dired
dired-loaddefs rfc822 mml mml-sec epa derived epg rfc6068 epg-config
gnus-util text-property-search mm-decode mm-bodies mm-encode mail-parse
rfc2231 mailabbrev gmm-utils mailheader sendmail rfc2047 rfc2045
ietf-drums mm-util mail-prsvr mail-utils erc iso8601 time-date
auth-source cl-seq eieio eieio-core cl-macs password-cache json subr-x
map thingatpt pp format-spec cl-loaddefs cl-lib erc-backend erc-goodies
erc-networks byte-opt gv bytecomp byte-compile erc-common erc-compat
erc-loaddefs rmc iso-transl tooltip cconv eldoc paren electric uniquify
ediff-hook vc-hooks lisp-float-type elisp-mode 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 lisp-mode prog-mode register
page tab-bar menu-bar rfn-eshadow isearch easymenu timer select
scroll-bar mouse jit-lock font-lock syntax font-core term/tty-colors
frame minibuffer nadvice seq simple cl-generic indonesian philippine
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 emoji-zwj charscript
charprop case-table epa-hook jka-cmpr-hook help abbrev obarray oclosure
cl-preloaded button loaddefs theme-loaddefs faces cus-face macroexp
files window text-properties overlay sha1 md5 base64 format env
code-pages mule custom widget keymap hashtable-print-readable backquote
threads dbusbind inotify lcms2 dynamic-setting system-font-setting
font-render-setting cairo move-toolbar gtk x-toolkit xinput2 x multi-tty
make-network-process emacs)

Memory information:
((conses 16 64335 6194)
 (symbols 48 8606 0)
 (strings 32 23623 2014)
 (string-bytes 1 683188)
 (vectors 16 15217)
 (vector-slots 8 208663 8804)
 (floats 8 24 28)
 (intervals 56 227 0)
 (buffers 984 11))
0001-Respect-a-nil-erc-session-password-when-reconnecting.patch (text/x-patch, 8.6 KB)
From 1275701490424d70a7bf568ee4e0e54d3f87ef23 Mon Sep 17 00:00:00 2001
From: "F. Jason Park" <[email protected]>
Date: Fri, 2 Dec 2022 23:11:24 -0800
Subject: [PATCH] Respect a nil erc-session-password when reconnecting

* lisp/erc/erc.el (erc-open): Simplify `old-vars' expression.
(erc--compute-server-password): Only compute a server password when
first connecting.  For compatibility, this respects third-party code
that expects session passwords in target buffers when initially
non-nil.
* test/lisp/erc/erc-scenarios-services-misc.el
(erc-scenarios-services-auth-source-reconnect): Add new test.
* test/lisp/erc/resources/services/auth-source/recon.eld: Add new test
data file.
---
 lisp/erc/erc.el                               |  4 +-
 test/lisp/erc/erc-scenarios-services-misc.el  | 59 +++++++++++++++++++
 .../resources/services/auth-source/recon.eld  | 48 +++++++++++++++
 3 files changed, 110 insertions(+), 1 deletion(-)
 create mode 100644 test/lisp/erc/resources/services/auth-source/recon.eld

diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el
index 268d83dc44..e3733ccb96 100644
--- a/lisp/erc/erc.el
+++ b/lisp/erc/erc.el
@@ -1970,7 +1970,7 @@ erc-open
   (let* ((target (and channel (erc--target-from-string channel)))
          (buffer (erc-get-buffer-create server port nil target id))
          (old-buffer (current-buffer))
-         (old-vars (and (not connect) (buffer-local-variables)))
+         (old-vars (and target (buffer-local-variables)))
          (old-recon-count erc-server-reconnect-count)
          (old-point nil)
          (delayed-modules nil)
@@ -6452,6 +6452,8 @@ erc--compute-server-password
 When `erc-auth-source-server-function' is non-nil, call it with NICK for
 the user field and use whatever it returns as the server password."
   (or password (and erc-auth-source-server-function
+                    (not erc--server-reconnecting)
+                    (not erc--target)
                     (funcall erc-auth-source-server-function :user nick))))
 
 (defun erc-compute-full-name (&optional full-name)
diff --git a/test/lisp/erc/erc-scenarios-services-misc.el b/test/lisp/erc/erc-scenarios-services-misc.el
index cb1aa6ff32..176e7b7ed3 100644
--- a/test/lisp/erc/erc-scenarios-services-misc.el
+++ b/test/lisp/erc/erc-scenarios-services-misc.el
@@ -83,4 +83,63 @@ erc-scenarios-services-prompt
 
     (should-not (memq 'services erc-modules))))
 
+;; A user with `services' enabled connects, quits, and reconnects.  An
+;; entry in their netrc matches the network ID, which isn't known when
+;; `erc-auth-source-server-function' runs -- initially *or* on
+;; reconnect.  It's only seen by `erc-auth-source-services-function'.
+
+(ert-deftest erc-scenarios-services-auth-source-reconnect ()
+  :tags '(:expensive-test)
+  (erc-scenarios-common-with-cleanup
+      ((erc-scenarios-common-dialog "services/auth-source")
+       (erc-server-flood-penalty 0.1)
+       (dumb-server (erc-d-run "localhost" t 'recon 'recon))
+       (port (process-contact dumb-server :service))
+       (netrc-file (make-temp-file
+                    "auth-source-test" nil nil
+                    "machine FooNet login tester password changeme\n"))
+       (auth-sources (list netrc-file))
+       (auth-source-do-cache nil)
+       (erc-modules (cons 'services erc-modules))
+       (erc-use-auth-source-for-nickserv-password t) ; do consult
+       (erc-prompt-for-nickserv-password nil) ; don't prompt
+       (erc-nickserv-alist
+        (cons '(FooNet
+                "[email protected]"
+                "This nickname is registered. Please choose"
+                "NickServ" "IDENTIFY" nil nil "You are now identified for ")
+              erc-nickserv-alist))
+       (expect (erc-d-t-make-expecter))
+       (erc-scenarios-common-extra-teardown (lambda ()
+                                              (delete-file netrc-file))))
+
+    (ert-info ("Server password omitted from initial connection")
+      (with-current-buffer (erc :server "127.0.0.1"
+                                :port port
+                                :nick "tester"
+                                :user "tester"
+                                :full-name "tester")
+        (should (string= (buffer-name) (format "127.0.0.1:%d" port)))
+        (ert-info ("Services module authenticates")
+          (funcall expect 10 "This nickname is registered.")
+          (funcall expect 3 "You are now identified"))
+        (erc-cmd-JOIN "#chan")
+        (with-current-buffer (erc-d-t-wait-for 10 (get-buffer "#chan"))
+          (funcall expect 10 "the gallants desire it"))
+        (erc-cmd-QUIT "")
+        (funcall expect 3 "finished")))
+
+    (ert-info ("Server password withheld on reconnect")
+      (with-current-buffer "#chan"
+        (erc-cmd-RECONNECT))
+      (with-current-buffer "FooNet"
+        (funcall expect 10 "This nickname is registered.")
+        (funcall expect 3 "You are now identified")
+        (with-current-buffer "#chan" ; autojoined
+          (funcall expect 10 "the gallants desire it"))
+        (erc-cmd-QUIT "")
+        (funcall expect 3 "finished")))
+
+    (erc-services-mode -1)))
+
 ;;; erc-scenarios-services-misc.el ends here
diff --git a/test/lisp/erc/resources/services/auth-source/recon.eld b/test/lisp/erc/resources/services/auth-source/recon.eld
new file mode 100644
index 0000000000..40ea3c9157
--- /dev/null
+++ b/test/lisp/erc/resources/services/auth-source/recon.eld
@@ -0,0 +1,48 @@
+;; -*- mode: lisp-data; -*-
+((nick 10 "NICK tester"))
+((user 5 "USER tester 0 * :tester")
+ (0.00 ":irc.foonet.net NOTICE * :*** Looking up your hostname...")
+ (0.04 ":irc.foonet.net NOTICE tester :*** Could not resolve your hostname: Domain not found; using your IP address (10.0.2.100) instead.")
+ (0.06 ":irc.foonet.net 001 tester :Welcome to the FooNet IRC Network [email protected]")
+ (0.01 ":irc.foonet.net 002 tester :Your host is irc.foonet.net, running version InspIRCd-3")
+ (0.01 ":irc.foonet.net 003 tester :This server was created 08:32:24 Dec 05 2022")
+ (0.01 ":irc.foonet.net 004 tester irc.foonet.net InspIRCd-3 BIRcgikorsw ACHIKMORTXabcefghijklmnopqrstvz :HIXabefghjkloqv")
+ (0.01 ":irc.foonet.net 005 tester ACCEPT=30 AWAYLEN=200 BOT=B CALLERID=g CASEMAPPING=ascii CHANLIMIT=#:20 CHANMODES=IXbeg,k,Hfjl,ACKMORTcimnprstz CHANNELLEN=64 CHANTYPES=# ELIST=CMNTU ESILENCE=CcdiNnPpTtx EXCEPTS=e :are supported by this server")
+ (0.01 ":irc.foonet.net 005 tester EXTBAN=,ACORTUacjrwz HOSTLEN=64 INVEX=I KEYLEN=32 KICKLEN=255 LINELEN=512 MAXLIST=I:100,X:100,b:100,e:100,g:100 MAXTARGETS=20 MODES=20 MONITOR=30 NAMELEN=128 NAMESX NETWORK=FooNet :are supported by this server")
+ (0.01 ":irc.foonet.net 005 tester NICKLEN=30 PREFIX=(qaohv)~&@%+ SAFELIST SILENCE=32 STATUSMSG=~&@%+ TOPICLEN=307 UHNAMES USERIP USERLEN=10 USERMODES=,,s,BIRcgikorw WHOX :are supported by this server")
+ (0.01 ":irc.foonet.net 251 tester :There are 2 users and 0 invisible on 2 servers")
+ (0.00 ":irc.foonet.net 253 tester 1 :unknown connections")
+ (0.00 ":irc.foonet.net 254 tester 1 :channels formed")
+ (0.00 ":irc.foonet.net 255 tester :I have 2 clients and 1 servers")
+ (0.00 ":irc.foonet.net 265 tester :Current local users: 2  Max: 3")
+ (0.00 ":irc.foonet.net 266 tester :Current global users: 2  Max: 3")
+ (0.00 ":irc.foonet.net 375 tester :irc.foonet.net message of the day")
+ (0.00 ":irc.foonet.net 372 tester :Have fun!")
+ (0.00 ":irc.foonet.net 376 tester :End of message of the day."))
+
+((mode-a 10 "MODE tester +i")
+ (0.00 ":irc.foonet.net 501 tester x :is not a recognised user mode.")
+ (0.04 ":[email protected] MODE tester :+i")
+ (0.00 ":[email protected] NOTICE tester :This nickname is registered. Please choose a different nickname, or identify via \2/msg NickServ identify <password>\2."))
+
+((~privmsg 10 "PRIVMSG NickServ :IDENTIFY changeme")
+ (0.00 ":[email protected] NOTICE tester :You are now identified for \2tester\2.")
+ (0.01 ":irc.foonet.net 900 tester [email protected] tester :You are now logged in as tester"))
+
+((~join 10 "JOIN #chan")
+ (0.00 ":[email protected] JOIN :#chan")
+ (0.04 ":irc.foonet.net 353 tester = #chan :@alice bob tester")
+ (0.00 ":irc.foonet.net 366 tester #chan :End of /NAMES list."))
+
+((mode-b 10 "MODE #chan")
+ (0.03 ":irc.foonet.net 324 tester #chan :+nt")
+ (0.01 ":irc.foonet.net 329 tester #chan :1670229160")
+ (0.00 ":alice!alice@0::1 PRIVMSG #chan :tester, welcome!")
+ (0.00 ":bob!bob@0::1 PRIVMSG #chan :tester, welcome!")
+ (0.05 ":alice!alice@0::1 PRIVMSG #chan :bob: Thou art the cap of all the fools alive.")
+ (0.06 ":bob!bob@0::1 PRIVMSG #chan :alice: What, man! 'tis a night of revels; the gallants desire it."))
+
+((quit 10 "QUIT :\2ERC\2")
+ (0.1 ":[email protected] QUIT :Client Quit"))
+
+((drop 1 DROP))
-- 
2.38.1
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.