From 6ce957154b701282217191d47764187535754529 Mon Sep 17 00:00:00 2001 From: "F. Jason Park" Date: Thu, 8 Jun 2023 23:49:23 -0700 Subject: [PATCH] Redo erc-nickname-in-use-functions as a local module * etc/ERC-NEWS: Mention new module `services-regain'. * lisp/erc/erc-backend.el: Rename option. * lisp/erc/erc-services.el (erc-services-regain-alist): Strategies for regaining a lost nickname on reconnect. This option, in addition to the rest of these changes, is a redo of `erc-nickname-in-use-functions' from commit 8c0c9826 "Add hook to regain nickname in ERC", which originally stemmed from bug#62044. (erc-services-retry-nick-on-connect, erc-services-issue-regain, erc-services-issue-ghost-and-retry-nick): New function variants for `erc-services-regain-alist. (erc-services-regain-mode, erc-services-regain-enable, erc-services-regain-disable): New local module to activate nick-regaining behavior. (erc--nickname-in-use-make-request): New method, a services-specific implementation. * lisp/erc/erc.el (erc--nickname-in-use-make-request): New generic function to request alternate nick when first choice is rejected. (erc-nickname-in-use): Call `erc--nickname-in-use-make-request' to request alternate nick. * test/lisp/erc/erc-scenarios-services-misc.el (erc-scenarios-services-misc--reconnect-retry-nick): Adopt renamed version of `erc-scenarios-base-renick-auto-regain'. (erc-scenarios-services-misc--regain-command, erc-scenarios-services-misc--ghost-and-retry-nick): New tests. * test/lisp/erc/resources/services/regain/reconnect-retry-again.eld: New test data file reusing existing blob c0529052 that once lived at resources/base/renick/regain/normal-again.eld. * test/lisp/erc/resources/services/regain/reconnect-retry.eld: New test data file reusing existing blob 9f4df70e5 that once lived at resources/base/renick/regain/normal.eld. * test/lisp/erc/resources/services/regain/taken-ghost.eld: New test data file. * test/lisp/erc/resources/services/regain/taken-regain.eld New test data file. --- etc/ERC-NEWS | 6 +- lisp/erc/erc-backend.el | 4 +- lisp/erc/erc-services.el | 121 ++++++++++++++++++ lisp/erc/erc.el | 6 +- test/lisp/erc/erc-scenarios-services-misc.el | 105 +++++++++++++++ .../services/regain/reconnect-retry-again.eld | 56 ++++++++ .../services/regain/reconnect-retry.eld | 53 ++++++++ .../resources/services/regain/taken-ghost.eld | 42 ++++++ .../services/regain/taken-regain.eld | 42 ++++++ 9 files changed, 430 insertions(+), 5 deletions(-) create mode 100644 test/lisp/erc/resources/services/regain/reconnect-retry-again.eld create mode 100644 test/lisp/erc/resources/services/regain/reconnect-retry.eld create mode 100644 test/lisp/erc/resources/services/regain/taken-ghost.eld create mode 100644 test/lisp/erc/resources/services/regain/taken-regain.eld diff --git a/etc/ERC-NEWS b/etc/ERC-NEWS index 68cf0e2d6ca..2f465e247d7 100644 --- a/etc/ERC-NEWS +++ b/etc/ERC-NEWS @@ -78,9 +78,9 @@ appearing in their saved logs. ** Smarter reconnect handling for users on the move. ERC now offers a new, experimental reconnect strategy in the function 'erc-server-delayed-check-reconnect', which tests for underlying -connectivity before attempting to reconnect in earnest. See options -'erc-server-reconnect-function' and 'erc-nickname-in-use-functions' to -get started. +connectivity before attempting to reconnect in earnest. See option +'erc-server-reconnect-function' and new local module 'services-regain' +(also experimental) to get started. ** Module 'fill' can add a bit of space between messages. On graphical displays, it's now possible to add some breathing room diff --git a/lisp/erc/erc-backend.el b/lisp/erc/erc-backend.el index b5bd96c189d..f1b51f9234a 100644 --- a/lisp/erc/erc-backend.el +++ b/lisp/erc/erc-backend.el @@ -427,7 +427,9 @@ This only has an effect if `erc-server-auto-reconnect' is non-nil." If this value is too low, servers may reject your initial nick request upon reconnecting because they haven't yet noticed that your previous connection is dead. If this happens, try setting -this value to 120 or greater." +this value to 120 or greater and/or exploring the option +`erc-regain-services-alist', which may provide a more proactive +means of handling this situation on some servers." :type 'number) (defcustom erc-server-reconnect-function 'erc-server-delayed-reconnect diff --git a/lisp/erc/erc-services.el b/lisp/erc/erc-services.el index 5408ba405db..47c59f76b5c 100644 --- a/lisp/erc/erc-services.el +++ b/lisp/erc/erc-services.el @@ -513,6 +513,127 @@ Returns t if the identify message could be sent, nil otherwise." nick) nil)) + +;;;; Regaining nicknames + +(defcustom erc-services-regain-alist nil + "Alist mapping networks to nickname-regaining functions. +This option depends on the `services-regain' module being loaded. +Keys can also be symbols for user-provided \"context IDs\" (see +Info node `Network Identifier'). Functions run once, when first +establishing a logical IRC connection. Although ERC currently +calls them with one argument, the desired but rejected nickname, +robust user implementations should leave room for later additions +by defining an &rest _ parameter, as well. + +The simplest value is `erc-services-retry-nick-on-connect', which +attempts to kill off stale connections without engaging services +at all. Others, like `erc-services-issue-regain', and +`erc-services-issue-ghost-and-retry-nick', only speak a +particular flavor of NickServ. See their respective doc strings +for details and use cases." + :package-version '(ERC . "5.6") + :group 'erc-hooks + :type '(alist :key-type (symbol :tag "Network") + :value-type + (choice :tag "Strategy function" + (function-item erc-services-retry-nick-on-connect) + (function-item erc-services-issue-regain) + (function-item erc-services-issue-ghost-and-retry-nick) + function))) + +(defun erc-services-retry-nick-on-connect (want) + "Try at most once to grab nickname WANT after reconnecting. +Expect to be used when automatically reconnecting to servers +that are slow to abandon the previous connection. + +Note that this strategy may only work under certain conditions, +such as when a user's account name matches their nick." + (erc-cmd-NICK want)) + +(defun erc-services-issue-regain (want) + "Ask NickServ to regain nickname WANT. +Assume WANT belongs to the user and that the services suite +offers a \"REGAIN\" sub-command." + (erc-cmd-MSG (concat "NickServ REGAIN " want))) + +(defun erc-services-issue-ghost-and-retry-nick (want) + "Ask NickServ to \"GHOST\" nickname WANT. +After which, attempt to grab WANT before the contending party +reconnects. Assume the ERC user owns WANT and that the server's +services suite lacks a \"REGAIN\" command. + +Note that this function will only work for a specific services +implementation and is meant primarily as an example for adapting +as needed." + ;; While heuristics based on error text may seem brittle, consider + ;; the fact that \"is not online\" has been present in Atheme's + ;; \"GHOST\" responses since at least 2005. + (letrec ((attempts 3) + (on-notice + (lambda (_proc parsed) + (when-let ((nick (erc-extract-nick + (erc-response.sender parsed))) + ((erc-nick-equal-p nick "nickserv")) + (contents (erc-response.contents parsed)) + (case-fold-search t) + ((string-match (rx (or "ghost" "is not online")) + contents))) + (setq attempts 1) + (erc-server-send (concat "NICK " want) 'force)) + (when (zerop (cl-decf attempts)) + (remove-hook 'erc-server-NOTICE-functions on-notice t)) + nil))) + (add-hook 'erc-server-NOTICE-functions on-notice nil t) + (erc-message "PRIVMSG" (concat "NickServ GHOST " want)))) + +;;;###autoload(put 'services-regain 'erc--feature 'erc-services) +(define-erc-module services-regain nil + "Reacquire a nickname from your past self or some interloper. +This module only concerns itself with initial nick rejections +that occur during connection registration in response to an +opening \"NICK\" command. More specifically, the following +conditions must be met for ERC to activate this mechanism and +consider its main option, `erc-services-regain-alist': + + - the server must reject the opening \"NICK\" request + - ERC must request a temporary nickname + - the user must successfully authenticate + +In practical terms, this means that this module, which is still +somewhat experimental, is likely only useful in conjunction with +SASL authentication rather than the traditional approach provided +by the `services' module it shares a library with (see Info +node `(erc) SASL' for more)." + nil nil 'local) + +(cl-defmethod erc--nickname-in-use-make-request + ((want string) temp &context (erc-server-connected null) + (erc-services-regain-mode (eql t)) + (erc-services-regain-alist cons)) + "Schedule possible regain attempt upon establishing connection. +Expect WANT to be the desired nickname and TEMP to be the current +one." + (letrec + ((after-connect + (lambda (_ nick) + (remove-hook 'erc-after-connect after-connect t) + (when-let* + (((equal temp nick)) + (conn (or (erc-networks--id-given erc-networks--id) + (erc-network))) + (found (alist-get conn erc-services-regain-alist))) + (funcall found want)))) + (on-900 + (lambda (_ parsed) + (remove-hook 'erc-server-900-functions on-900 t) + (unless erc-server-connected + (when (equal (car (erc-response.command-args parsed)) temp) + (add-hook 'erc-after-connect after-connect nil t))) + nil))) + (add-hook 'erc-server-900-functions on-900 nil t)) + (cl-call-next-method)) + (provide 'erc-services) diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el index 70adbb15b5f..e23185934f7 100644 --- a/lisp/erc/erc.el +++ b/lisp/erc/erc.el @@ -4930,6 +4930,10 @@ E.g. \"Read error to Nick [user@some.host]: 110\" would be shortened to (match-string 1 reason)) reason)) +(cl-defmethod erc--nickname-in-use-make-request (_nick temp) + "Request nickname TEMP in place of rejected NICK." + (erc-cmd-NICK temp)) + (defun erc-nickname-in-use (nick reason) "If NICK is unavailable, tell the user the REASON. @@ -4963,7 +4967,7 @@ See also `erc-display-error-notice'." ;; established a connection yet (- 9 (length erc-nick-uniquifier)))) erc-nick-uniquifier))) - (erc-cmd-NICK newnick) + (erc--nickname-in-use-make-request nick newnick) (erc-display-error-notice nil (format "Nickname %s is %s, trying %s" diff --git a/test/lisp/erc/erc-scenarios-services-misc.el b/test/lisp/erc/erc-scenarios-services-misc.el index a1679d302f4..1113849578f 100644 --- a/test/lisp/erc/erc-scenarios-services-misc.el +++ b/test/lisp/erc/erc-scenarios-services-misc.el @@ -143,4 +143,109 @@ (erc-services-mode -1))) +;; The server rejects your nick during registration, so ERC acquires a +;; placeholder and successfully renicks once the connection is up. +;; See also `erc-scenarios-base-renick-self-auto'. + +(ert-deftest erc-scenarios-services-misc--reconnect-retry-nick () + :tags '(:expensive-test) + (erc-scenarios-common-with-cleanup + ((erc-server-flood-penalty 0.1) + (erc-scenarios-common-dialog "services/regain") + (dumb-server (erc-d-run "localhost" t 'reconnect-retry + 'reconnect-retry-again)) + (port (process-contact dumb-server :service)) + (erc-server-auto-reconnect t) + (erc-modules `(services-regain sasl ,@erc-modules)) + (erc-services-regain-alist + '((Libera.Chat . erc-services-retry-nick-on-connect))) + (expect (erc-d-t-make-expecter))) + + ;; FIXME figure out and explain why this is so. + (should (featurep 'erc-services)) + + (ert-info ("Session succeeds but cut short") + (with-current-buffer (erc :server "127.0.0.1" + :port port + :nick "tester" + :user "tester" + :password "changeme" + :full-name "tester") + (funcall expect 10 "Last login from") + (erc-cmd-JOIN "#test"))) + + (with-current-buffer (erc-d-t-wait-for 10 (get-buffer "#test")) + (funcall expect 10 "was created on")) + + (ert-info ("Service restored") + (with-current-buffer "Libera.Chat" + (erc-d-t-wait-for 10 erc--server-reconnect-timer) + (funcall expect 10 "Connection failed!") + (funcall expect 10 "already in use") + (funcall expect 10 "changed mode for tester`") + (funcall expect 10 "Last login from") + (funcall expect 10 "Your new nickname is tester"))) + + (with-current-buffer (get-buffer "#test") + (funcall expect 10 "tester ") + (funcall expect 10 "was created on")))) + +;; This only asserts that the handler fires and issues the right +;; NickServ command, but it doesn't accurately recreate a +;; disconnection, but it probably should. +(ert-deftest erc-scenarios-services-misc--regain-command () + :tags '(:expensive-test) + (erc-scenarios-common-with-cleanup + ((erc-server-flood-penalty 0.1) + (erc-scenarios-common-dialog "services/regain") + (dumb-server (erc-d-run "localhost" t 'taken-regain)) + (port (process-contact dumb-server :service)) + (erc-server-auto-reconnect t) + (erc-modules `(services-regain sasl ,@erc-modules)) + (erc-services-regain-alist + '((ExampleNet . erc-services-issue-regain))) + (expect (erc-d-t-make-expecter))) + + (should (featurep 'erc-services)) ; see note in prior test + + (with-current-buffer (erc :server "127.0.0.1" + :port port + :nick "dummy" + :user "tester" + :password "changeme" + :full-name "tester" + :id 'ExampleNet) + (funcall expect 10 "dummy is already in use, trying dummy`") + (funcall expect 10 "You are now logged in as tester") + (funcall expect 10 "-NickServ- dummy has been regained.") + (funcall expect 10 "*** Your new nickname is dummy") + ;; Works with "given" `:id'. + (should (and (erc-network) (not (eq (erc-network) 'ExampleNet))))))) + +(ert-deftest erc-scenarios-services-misc--ghost-and-retry-nick () + :tags '(:expensive-test) + (erc-scenarios-common-with-cleanup + ((erc-server-flood-penalty 0.1) + (erc-scenarios-common-dialog "services/regain") + (dumb-server (erc-d-run "localhost" t 'taken-ghost)) + (port (process-contact dumb-server :service)) + (erc-server-auto-reconnect t) + (erc-modules `(services-regain sasl ,@erc-modules)) + (erc-services-regain-alist + '((FooNet . erc-services-issue-ghost-and-retry-nick))) + (expect (erc-d-t-make-expecter))) + + (should (featurep 'erc-services)) ; see note in prior test + + (with-current-buffer (erc :server "127.0.0.1" + :port port + :nick "dummy" + :user "tester" + :password "changeme" + :full-name "tester") + (funcall expect 10 "dummy is already in use, trying dummy`") + (funcall expect 10 "You are now logged in as tester") + (funcall expect 10 "-NickServ- dummy has been ghosted.") + (funcall expect 10 "*** Your new nickname is dummy")))) + ;;; erc-scenarios-services-misc.el ends here diff --git a/test/lisp/erc/resources/services/regain/reconnect-retry-again.eld b/test/lisp/erc/resources/services/regain/reconnect-retry-again.eld new file mode 100644 index 00000000000..c0529052c70 --- /dev/null +++ b/test/lisp/erc/resources/services/regain/reconnect-retry-again.eld @@ -0,0 +1,56 @@ +;; -*- mode: lisp-data; -*- +((cap 10 "CAP REQ :sasl")) +((nick 10 "NICK tester")) +((user 10 "USER tester 0 * :tester")) + +((authenticate 10 "AUTHENTICATE PLAIN") + (0.04 ":tantalum.libera.chat NOTICE * :*** Checking Ident") + (0.01 ":tantalum.libera.chat NOTICE * :*** Looking up your hostname...") + (0.01 ":tantalum.libera.chat NOTICE * :*** Couldn't look up your hostname") + (0.06 ":tantalum.libera.chat NOTICE * :*** No Ident response") + (0.02 ":tantalum.libera.chat CAP * ACK :sasl") + (0.03 ":tantalum.libera.chat 433 * tester :Nickname is already in use.")) + +((nick 10 "NICK tester`") + (0.03 "AUTHENTICATE +")) + +((authenticate 10 "AUTHENTICATE AHRlc3RlcgBjaGFuZ2VtZQ==") + (0.06 ":tantalum.libera.chat 900 tester` tester`!tester@127.0.0.1 tester :You are now logged in as tester") + (0.02 ":tantalum.libera.chat 903 tester` :SASL authentication successful")) + +((cap 10 "CAP END") + (0.02 ":tantalum.libera.chat 001 tester` :Welcome to the Libera.Chat Internet Relay Chat Network tester`") + (0.02 ":tantalum.libera.chat 002 tester` :Your host is tantalum.libera.chat[93.158.237.2/6697], running version solanum-1.0-dev") + (0.02 ":tantalum.libera.chat 003 tester` :This server was created Mon Feb 13 2023 at 12:05:04 UTC") + (0.01 ":tantalum.libera.chat 004 tester` tantalum.libera.chat solanum-1.0-dev DGMQRSZaghilopsuwz CFILMPQRSTbcefgijklmnopqrstuvz bkloveqjfI") + (0.01 ":tantalum.libera.chat 005 tester` WHOX MONITOR=100 SAFELIST ELIST=CMNTU ETRACE FNC CALLERID=g KNOCK CHANTYPES=# EXCEPTS INVEX CHANMODES=eIbq,k,flj,CFLMPQRSTcgimnprstuz :are supported by this server") + (0.01 ":tantalum.libera.chat 005 tester` CHANLIMIT=#:250 PREFIX=(ov)@+ MAXLIST=bqeI:100 MODES=4 NETWORK=Libera.Chat STATUSMSG=@+ CASEMAPPING=rfc1459 NICKLEN=16 MAXNICKLEN=16 CHANNELLEN=50 TOPICLEN=390 DEAF=D :are supported by this server") + (0.03 ":tantalum.libera.chat 005 tester` TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,PRIVMSG:4,NOTICE:4,ACCEPT:,MONITOR: EXTBAN=$,ajrxz :are supported by this server") + (0.01 ":tantalum.libera.chat 251 tester` :There are 70 users and 42977 invisible on 28 servers") + (0.00 ":tantalum.libera.chat 252 tester` 38 :IRC Operators online") + (0.00 ":tantalum.libera.chat 253 tester` 87 :unknown connection(s)") + (0.00 ":tantalum.libera.chat 254 tester` 22908 :channels formed") + (0.00 ":tantalum.libera.chat 255 tester` :I have 2507 clients and 1 servers") + (0.00 ":tantalum.libera.chat 265 tester` 2507 3232 :Current local users 2507, max 3232") + (0.00 ":tantalum.libera.chat 266 tester` 43047 51777 :Current global users 43047, max 51777") + (0.00 ":tantalum.libera.chat 250 tester` :Highest connection count: 3233 (3232 clients) (284887 connections received)") + (0.03 ":tantalum.libera.chat 375 tester` :- tantalum.libera.chat Message of the Day - ") + (0.00 ":tantalum.libera.chat 372 tester` :- This server provided by Hyperfilter (https://hyperfilter.com)") + (0.00 ":tantalum.libera.chat 372 tester` :- Email: support@libera.chat") + (0.02 ":tantalum.libera.chat 376 tester` :End of /MOTD command.")) + +((mode 10 "MODE tester` +i") + (0.01 ":tester` MODE tester` :+Ziw") + (0.02 ":SaslServ!SaslServ@services.libera.chat NOTICE tester` :Last login from: \2~tester@127.0.0.1\2 on Apr 07 01:36:25 2023 +0000.")) + +((nick 10 "NICK tester") + (0.02 ":tester`!~tester@127.0.0.1 NICK :tester")) + +((join 10 "JOIN #test") + (0.02 ":tester!~tester@127.0.0.1 JOIN #test") + (0.02 ":tantalum.libera.chat 353 tester = #test :tester zbyqbepbqre7 pusevgfpu Thrfg2187 zngbeb qnexNssvavgl wrebzr- rqpentt Ilehf grfg2 AvtugZbaxrl pevfgvvbna xrivap_ fnvybePng shohxv gxan arrqyr avpx16 NeanhqW_kzcc jvyyr wrnaogeq Wnarg cnefavc0 Xbentt RcvpArb flfqrs wfgbxre hafcrag__ Lbevpx_") + (0.02 ":tantalum.libera.chat 366 tester #test :End of /NAMES list.")) + +((mode 10 "MODE #test") + (0.02 ":tantalum.libera.chat 324 tester #test +nt") + (0.02 ":tantalum.libera.chat 329 tester #test 1621432263")) diff --git a/test/lisp/erc/resources/services/regain/reconnect-retry.eld b/test/lisp/erc/resources/services/regain/reconnect-retry.eld new file mode 100644 index 00000000000..9f4df70e580 --- /dev/null +++ b/test/lisp/erc/resources/services/regain/reconnect-retry.eld @@ -0,0 +1,53 @@ +;; -*- mode: lisp-data; -*- +((cap 10 "CAP REQ :sasl")) +((nick 10 "NICK tester")) +((user 10 "USER tester 0 * :tester")) + +((authenticate 10 "AUTHENTICATE PLAIN") + (0.02 ":cadmium.libera.chat NOTICE * :*** Checking Ident") + (0.01 ":cadmium.libera.chat NOTICE * :*** Looking up your hostname...") + (0.01 ":cadmium.libera.chat NOTICE * :*** Couldn't look up your hostname") + (0.06 ":cadmium.libera.chat NOTICE * :*** No Ident response") + (0.09 ":cadmium.libera.chat CAP * ACK :sasl") + (0.01 "AUTHENTICATE +")) + +((authenticate 10 "AUTHENTICATE AHRlc3RlcgBjaGFuZ2VtZQ==") + (0.03 ":cadmium.libera.chat 900 tester tester!tester@127.0.0.1 tester :You are now logged in as tester") + (0.01 ":cadmium.libera.chat 903 tester :SASL authentication successful")) + +((cap 10 "CAP END") + (0.03 ":cadmium.libera.chat 001 tester :Welcome to the Libera.Chat Internet Relay Chat Network tester") + (0.02 ":cadmium.libera.chat 002 tester :Your host is cadmium.libera.chat[103.196.37.95/6697], running version solanum-1.0-dev") + (0.01 ":cadmium.libera.chat 003 tester :This server was created Wed Jan 25 2023 at 10:22:45 UTC") + (0.01 ":cadmium.libera.chat 004 tester cadmium.libera.chat solanum-1.0-dev DGMQRSZaghilopsuwz CFILMPQRSTbcefgijklmnopqrstuvz bkloveqjfI") + (0.00 ":cadmium.libera.chat 005 tester CALLERID=g WHOX ETRACE FNC SAFELIST ELIST=CMNTU KNOCK MONITOR=100 CHANTYPES=# EXCEPTS INVEX CHANMODES=eIbq,k,flj,CFLMPQRSTcgimnprstuz :are supported by this server") + (0.01 ":cadmium.libera.chat 005 tester CHANLIMIT=#:250 PREFIX=(ov)@+ MAXLIST=bqeI:100 MODES=4 NETWORK=Libera.Chat STATUSMSG=@+ CASEMAPPING=rfc1459 NICKLEN=16 MAXNICKLEN=16 CHANNELLEN=50 TOPICLEN=390 DEAF=D :are supported by this server") + (0.01 ":cadmium.libera.chat 005 tester TARGMAX=NAMES:1,LIST:1,KICK:1,WHOIS:1,PRIVMSG:4,NOTICE:4,ACCEPT:,MONITOR: EXTBAN=$,ajrxz :are supported by this server") + (0.01 ":cadmium.libera.chat 251 tester :There are 70 users and 42996 invisible on 28 servers") + (0.02 ":cadmium.libera.chat 252 tester 38 :IRC Operators online") + (0.01 ":cadmium.libera.chat 253 tester 57 :unknown connection(s)") + (0.01 ":cadmium.libera.chat 254 tester 22912 :channels formed") + (0.01 ":cadmium.libera.chat 255 tester :I have 2499 clients and 1 servers") + (0.01 ":cadmium.libera.chat 265 tester 2499 4187 :Current local users 2499, max 4187") + (0.01 ":cadmium.libera.chat 266 tester 43066 51827 :Current global users 43066, max 51827") + (0.01 ":cadmium.libera.chat 250 tester :Highest connection count: 4188 (4187 clients) (319420 connections received)") + (0.01 ":cadmium.libera.chat 375 tester :- cadmium.libera.chat Message of the Day - ") + (0.01 ":cadmium.libera.chat 372 tester :- This server kindly provided by Mach Dilemma (www.m-d.net)") + (0.01 ":cadmium.libera.chat 372 tester :- Welcome to Libera Chat, the IRC network for") + (0.00 ":cadmium.libera.chat 372 tester :- Email: support@libera.chat") + (0.00 ":cadmium.libera.chat 376 tester :End of /MOTD command.") + (0.00 ":tester MODE tester :+Ziw") + (0.02 ":SaslServ!SaslServ@services.libera.chat NOTICE tester :Last login from: \2~tester@127.0.0.1\2 on Apr 07 01:02:11 2023 +0000.")) + +((mode 10 "MODE tester +i")) + +((join 10 "JOIN #test") + (0.09 ":tester!~tester@127.0.0.1 JOIN #test")) + +((mode 10 "MODE #test") + (0.03 ":cadmium.libera.chat 353 tester = #test :tester zbyqbepbqre7 pusevgfpu Thrfg2187 zngbeb qnexNssvavgl wrebzr- rqpentt Ilehf grfg2 AvtugZbaxrl pevfgvvbna xrivap_ fnvybePng shohxv gxan arrqyr avpx16 NeanhqW_kzcc Lbevpx_ hafcrag__ wfgbxre flfqrs RcvpArb Xbentt jvyyr cnefavc0 Wnarg wrnaogeq") + (0.02 ":cadmium.libera.chat 366 tester #test :End of /NAMES list.") + (0.00 ":cadmium.libera.chat 324 tester #test +nt") + (0.01 ":cadmium.libera.chat 329 tester #test 1621432263")) + +((drop 0 DROP)) diff --git a/test/lisp/erc/resources/services/regain/taken-ghost.eld b/test/lisp/erc/resources/services/regain/taken-ghost.eld new file mode 100644 index 00000000000..d5afd124a43 --- /dev/null +++ b/test/lisp/erc/resources/services/regain/taken-ghost.eld @@ -0,0 +1,42 @@ +;; -*- mode: lisp-data; -*- +((cap 10 "CAP REQ :sasl") + (0.00 ":irc.example.net NOTICE * :*** Looking up your hostname...") + (0.01 ":irc.example.net NOTICE * :*** Could not resolve your hostname: Domain not found; using your IP address (10.0.2.100) instead.")) +((nick 10 "NICK dummy")) +((user 10 "USER dummy 0 * :tester")) +((authenticate 10 "AUTHENTICATE PLAIN") + (0.00 ":irc.example.net CAP * ACK :sasl") + (0.03 ":irc.example.net 433 * dummy :Nickname is already in use.") + (0.04 "AUTHENTICATE :+")) +((nick 10 "NICK dummy`") + (0.00 "PING :orrMOjk^|V")) +((~pong 10 "PONG :orrMOjk^|V")) +((authenticate 10 "AUTHENTICATE AHRlc3RlcgBjaGFuZ2VtZQ==") + (0.01 ":irc.example.net 900 dummy` dummy`!dummy@10.0.2.100 tester :You are now logged in as tester") + (0.01 ":irc.example.net 903 dummy` :SASL authentication successful")) +((cap 10 "CAP END") + (0.00 ":irc.example.net 001 dummy` :Welcome to the FooNet IRC Network dummy`!dummy@10.0.2.100") + (0.03 ":irc.example.net 002 dummy` :Your host is irc.example.net, running version InspIRCd-3") + (0.01 ":irc.example.net 003 dummy` :This server was created 13:01:55 Jun 08 2023") + (0.01 ":irc.example.net 004 dummy` irc.example.net InspIRCd-3 BIRcgikorsw ACHIKMORTXabcefghijklmnopqrstvz :HIXabefghjkloqv") + (0.00 ":irc.example.net 005 dummy` 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.example.net 005 dummy` 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.example.net 005 dummy` 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.example.net 251 dummy` :There are 2 users and 1 invisible on 2 servers") + (0.01 ":irc.example.net 253 dummy` 1 :unknown connections") + (0.00 ":irc.example.net 254 dummy` 1 :channels formed") + (0.00 ":irc.example.net 255 dummy` :I have 3 clients and 1 servers") + (0.00 ":irc.example.net 265 dummy` :Current local users: 3 Max: 4") + (0.00 ":irc.example.net 266 dummy` :Current global users: 3 Max: 4") + (0.00 ":irc.example.net 375 dummy` :irc.example.net message of the day") + (0.00 ":irc.example.net 372 dummy` : Have fun with the image!") + (0.00 ":irc.example.net 376 dummy` :End of message of the day.")) + +((mode 10 "MODE dummy` +i")) +((privmsg 10 "PRIVMSG NickServ :GHOST dummy") + (0.00 ":irc.example.net 501 dummy` x :is not a recognised user mode.") + (0.00 ":irc.example.net NOTICE dummy` :*** You are connected to irc.example.net using TLS (SSL) cipher 'TLS1.3-ECDHE-RSA-AES-256-GCM-AEAD'") + (0.03 ":dummy`!dummy@10.0.2.100 MODE dummy` :+i") + (0.02 ":NickServ!NickServ@services.int NOTICE dummy` :\2dummy\2 has been ghosted.")) +((nick 10 "NICK dummy") + (0.02 ":dummy`!dummy@10.0.2.100 NICK :dummy")) diff --git a/test/lisp/erc/resources/services/regain/taken-regain.eld b/test/lisp/erc/resources/services/regain/taken-regain.eld new file mode 100644 index 00000000000..22635d4cc89 --- /dev/null +++ b/test/lisp/erc/resources/services/regain/taken-regain.eld @@ -0,0 +1,42 @@ +;; -*- mode: lisp-data; -*- +((cap 10 "CAP REQ :sasl") + (0.00 ":irc.example.net NOTICE * :*** Looking up your hostname...") + (0.01 ":irc.example.net NOTICE * :*** Could not resolve your hostname: Domain not found; using your IP address (10.0.2.100) instead.")) +((nick 10 "NICK dummy")) +((user 10 "USER dummy 0 * :tester")) +;; This also happens to a test late ACK (see ghost variant for server-sent PING) +((authenticate 10 "AUTHENTICATE PLAIN") + (0.00 ":irc.example.net CAP * ACK :sasl") + (0.09 ":irc.example.net 433 * dummy :Nickname is already in use.") + (0.04 "AUTHENTICATE :+")) +((nick 10 "NICK dummy`")) +((authenticate 10 "AUTHENTICATE AHRlc3RlcgBjaGFuZ2VtZQ==") + (0.00 ":irc.example.net 900 dummy` dummy`!dummy@10.0.2.100 tester :You are now logged in as tester") + (0.01 ":irc.example.net 903 dummy` :SASL authentication successful")) + +((cap 10 "CAP END") + (0.00 ":irc.example.net 001 dummy` :Welcome to the FooNet IRC Network dummy`!dummy@10.0.2.100") + (0.02 ":irc.example.net 002 dummy` :Your host is irc.example.net, running version InspIRCd-3") + (0.02 ":irc.example.net 003 dummy` :This server was created 08:16:52 Jun 08 2023") + (0.01 ":irc.example.net 004 dummy` irc.example.net InspIRCd-3 BIRcgikorsw ACHIKMORTXabcefghijklmnopqrstvz :HIXabefghjkloqv") + (0.00 ":irc.example.net 005 dummy` 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.example.net 005 dummy` 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.example.net 005 dummy` 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.example.net 251 dummy` :There are 2 users and 1 invisible on 2 servers") + (0.01 ":irc.example.net 253 dummy` 1 :unknown connections") + (0.00 ":irc.example.net 254 dummy` 1 :channels formed") + (0.02 ":irc.example.net 255 dummy` :I have 3 clients and 1 servers") + (0.00 ":irc.example.net 265 dummy` :Current local users: 3 Max: 4") + (0.00 ":irc.example.net 266 dummy` :Current global users: 3 Max: 4") + (0.00 ":irc.example.net 375 dummy` :irc.example.net message of the day") + (0.00 ":irc.example.net 372 dummy` : Have fun with the image!") + (0.00 ":irc.example.net 376 dummy` :End of message of the day.") + (0.00 ":irc.example.net 501 dummy` x :is not a recognised user mode.") + (0.00 ":irc.example.net NOTICE dummy` :*** You are connected to irc.example.net using TLS (SSL) cipher 'TLS1.3-ECDHE-RSA-AES-256-GCM-AEAD'")) + +((mode 10 "MODE dummy` +i")) + +((privmsg 10 "PRIVMSG NickServ :REGAIN dummy") + (0.00 ":dummy`!dummy@10.0.2.100 MODE dummy` :+i") + (0.02 ":NickServ!NickServ@services.int NOTICE dummy` :\2dummy\2 has been regained.") + (0.02 ":dummy`!dummy@10.0.2.100 NICK :dummy")) -- 2.39.2