From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Olivier Certner Newsgroups: gmane.emacs.bugs Subject: bug#46777: 28.0.50; ERC: NickServ identification: Prompt for password after other sources, overall simplifications Date: Thu, 25 Feb 2021 19:22:04 +0100 Message-ID: <2033905.uJW0cDvVUg@ravel> References: <5495728.XOh7uYVVfo@ravel> <2068265.RhTPgMbj8J@ravel> <87im6ghwek.fsf@tcd.ie> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="nextPart1896953.EnoYUHA41c" Content-Transfer-Encoding: 7Bit Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="16941"; mail-complaints-to="usenet@ciao.gmane.io" Cc: 46777@debbugs.gnu.org To: "Basil L. Contovounesios" Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Thu Feb 25 19:23:11 2021 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1lFLI6-0004GH-Lu for geb-bug-gnu-emacs@m.gmane-mx.org; Thu, 25 Feb 2021 19:23:10 +0100 Original-Received: from localhost ([::1]:52030 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lFLI5-0000YB-OV for geb-bug-gnu-emacs@m.gmane-mx.org; Thu, 25 Feb 2021 13:23:09 -0500 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:36596) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lFLHy-0000WZ-4F for bug-gnu-emacs@gnu.org; Thu, 25 Feb 2021 13:23:02 -0500 Original-Received: from debbugs.gnu.org ([209.51.188.43]:55914) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lFLHx-0001Ss-TL for bug-gnu-emacs@gnu.org; Thu, 25 Feb 2021 13:23:01 -0500 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1lFLHx-00074Y-Pg for bug-gnu-emacs@gnu.org; Thu, 25 Feb 2021 13:23:01 -0500 X-Loop: help-debbugs@gnu.org Resent-From: Olivier Certner Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Thu, 25 Feb 2021 18:23:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 46777 X-GNU-PR-Package: emacs Original-Received: via spool by 46777-submit@debbugs.gnu.org id=B46777.161427733627121 (code B ref 46777); Thu, 25 Feb 2021 18:23:01 +0000 Original-Received: (at 46777) by debbugs.gnu.org; 25 Feb 2021 18:22:16 +0000 Original-Received: from localhost ([127.0.0.1]:39227 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lFLHE-00073M-72 for submit@debbugs.gnu.org; Thu, 25 Feb 2021 13:22:16 -0500 Original-Received: from smtp6-g21.free.fr ([212.27.42.6]:14964) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lFLH7-000738-Hd for 46777@debbugs.gnu.org; Thu, 25 Feb 2021 13:22:15 -0500 Original-Received: from ravel.localnet (unknown [90.118.181.206]) (Authenticated sender: ocert.dev@free.fr) by smtp6-g21.free.fr (Postfix) with ESMTPSA id BACFF7802B2; Thu, 25 Feb 2021 19:22:04 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=free.fr; s=smtp-20201208; t=1614277328; bh=zEvhJ6aoTbtVSx2wuQVumZMkSvkBxlkblZwABxRTuDg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=bF/zBqQVPxdDLMJpQ6WKQ2U3NXveqj2hoFk42xjK0l+3KJ6u02pKhqfHJuePA4JmX c31RimO3kPpng3xnxix4hziKp5lGixidi/4LJ9WPjAStOlUtoEOWaHS3I0ufhDrJxP +HTHSEkwzo0Imf1tMEwusi8I/6WBj0RGvl5myARo71b5HP8LbvFuy+Kp/zvg1oEN0F zL0fuiVw/rLoMKiBl8FTzQGrbewKMAM2SVFPqz469F06Uw/DOPK1iuTSyL7i4d1hKs zTJQwY9NJ7/UVGUi1krWE2NyjQkyfvjMzILF73zLeYpZgLICRo1UEAPmGLdz7G6jT+ ekf0Ztgy84QGw== In-Reply-To: <87im6ghwek.fsf@tcd.ie> X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.io gmane.emacs.bugs:200807 Archived-At: This is a multi-part message in MIME format. --nextPart1896953.EnoYUHA41c Content-Transfer-Encoding: 7Bit Content-Type: text/plain; charset="UTF-8" Sure. Attached. -- Olivier Certner --nextPart1896953.EnoYUHA41c Content-Disposition: attachment; filename="0001-NickServ-identification-Prompt-for-password-last-ove.patch" Content-Transfer-Encoding: 7Bit Content-Type: text/x-patch; charset="UTF-8"; name="0001-NickServ-identification-Prompt-for-password-last-ove.patch" >From 0b3d0c7a53f4a9d14db8301a8e499bf62cab619a Mon Sep 17 00:00:00 2001 From: Olivier Certner Date: Fri, 5 Feb 2021 15:34:50 +0100 Subject: [PATCH] NickServ identification: Prompt for password last, overall simplifications When `erc-prompt-for-nickserv-password' is true, don't ignore the other forms of identification. Instead, process them first, and prompt for the password last. Separate concerns (determination of the nick to use, of the password to use, and actual message sending). Note that the user can be interactively prompted for a password on reception of a Nickserv request, as before (on `erc-prompt-for-nickserv-password'). * lisp/erc/erc-services.el (erc-nickserv-identify): Don't take the password anymore as an argument (and don't prompt for it interactively). On the contrary, now take the nick to use for identification (interactively, ask for it, defaulting to the current one). Move actual message sending into the new `erc-nickserv-send-identify', and password prompting into `erc-nickserv-get-password'. (erc-nickserv-send-identify): New function containing the sending code, given the nick and password. (erc-nickserv-get-password): Try each password source in turn, in this order: `erc-nickserv-passwords', auth-source (if `erc-use-auth-source-for-nickserv-password' is true), and in the end prompt the user interactively (if `erc-prompt-for-nickserv-password' is true). If one source returns a string, the function returns it, or nil if the string is empty. (erc-nickserv-call-identify-function): Remove. It was necessary as a cumbersome workaround for the fact that the code for password prompting was in the `interactive' form of function `erc-nickserv-identify' before this change. (erc-nickserv-identify-autodetect, erc-nickserv-identify-on-connect) (erc-nickserv-identify-on-nick-change): Call `erc-nickserv-identify' directly (`erc-nickserv-call-identify-function' was removed). For the last two functions, remove the redundant checks on the Nickserv identification flags (additionally, it is doubtful they have any measurable impact on performance). --- etc/NEWS | 14 +++- lisp/erc/erc-services.el | 157 ++++++++++++++++++++++----------------- 2 files changed, 99 insertions(+), 72 deletions(-) diff --git a/etc/NEWS b/etc/NEWS index caa366aaef..3fbf7c6b29 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1528,14 +1528,20 @@ https://www.w3.org/TR/xml/#charsets). Now it rejects such strings. ** erc ---- -*** erc-services.el now supports NickServ passwords from auth-source. +*** NickServ passwords can now be retrieved from auth-source The 'erc-use-auth-source-for-nickserv-password' user option enables querying auth-source for NickServ passwords. To enable this, add the following to your init file: - (setq erc-prompt-for-nickserv-password nil - erc-use-auth-source-for-nickserv-password t) + (setq erc-use-auth-source-for-nickserv-password t) + +*** NickServ identification now prompts for password last +When 'erc-prompt-for-nickserv-password' is true, the user used to be +unconditionally prompted interactively for a password, regardless of +the content of `erc-nickserv-passwords', which was effectively ignored +(same for the new 'erc-use-auth-source-for-nickserv-password'). This +limitation is now removed, and the user is interactively prompted +last, after the other identification methods have run. --- *** The '/ignore' command will now ask for a timeout to stop ignoring the user. diff --git a/lisp/erc/erc-services.el b/lisp/erc/erc-services.el index 9ef8b7f46a..3740e54672 100644 --- a/lisp/erc/erc-services.el +++ b/lisp/erc/erc-services.el @@ -170,9 +170,8 @@ You can also use \\[erc-nickserv-identify-mode] to change modes." (defcustom erc-use-auth-source-for-nickserv-password nil "Query auth-source for a password when identifiying to NickServ. -This option has an no effect if `erc-prompt-for-nickserv-password' -is non-nil, and passwords from `erc-nickserv-passwords' take -precedence." +Passwords from `erc-nickserv-passwords' take precedence. See +function `erc-nickserv-get-password'." :version "28.1" :group 'erc-services :type 'boolean) @@ -400,85 +399,107 @@ password for this nickname, otherwise try to send it automatically." identify-regex (string-match identify-regex msg)) (erc-log "NickServ IDENTIFY request detected") - (erc-nickserv-call-identify-function nick) + (erc-nickserv-identify nick) nil)))) (defun erc-nickserv-identify-on-connect (_server nick) "Identify to Nickserv after the connection to the server is established." - (unless (or (and (null erc-nickserv-passwords) - (null erc-prompt-for-nickserv-password) - (null erc-use-auth-source-for-nickserv-password)) - (and (eq erc-nickserv-identify-mode 'both) - (erc-nickserv-alist-regexp (erc-network)))) - (erc-nickserv-call-identify-function nick))) + (unless (and (eq erc-nickserv-identify-mode 'both) + (erc-nickserv-alist-regexp (erc-network))) + (erc-nickserv-identify nick))) (defun erc-nickserv-identify-on-nick-change (nick _old-nick) "Identify to Nickserv whenever your nick changes." - (unless (or (and (null erc-nickserv-passwords) - (null erc-prompt-for-nickserv-password) - (null erc-use-auth-source-for-nickserv-password)) - (and (eq erc-nickserv-identify-mode 'both) - (erc-nickserv-alist-regexp (erc-network)))) - (erc-nickserv-call-identify-function nick))) + (unless (and (eq erc-nickserv-identify-mode 'both) + (erc-nickserv-alist-regexp (erc-network))) + (erc-nickserv-identify nick))) -(defun erc-nickserv-get-password (nickname) - "Return the password for NICKNAME from configured sources. +(defun erc-nickserv-get-password (nick) + "Return the password for NICK from configured sources. +First, a password for NICK is looked up in +`erc-nickserv-passwords'. Then, it is looked up in auth-source +if `erc-use-auth-source-for-nickserv-password' is not nil. +Finally, interactively prompt the user, if +`erc-prompt-for-nickserv-password' is true. -It uses `erc-nickserv-passwords' and additionally auth-source -when `erc-use-auth-source-for-nickserv-password' is not nil." - (or - (when erc-nickserv-passwords - (cdr (assoc nickname - (nth 1 (assoc (erc-network) - erc-nickserv-passwords))))) - (when erc-use-auth-source-for-nickserv-password - (let* ((secret (nth 0 (auth-source-search - :max 1 :require '(:secret) - :host (erc-with-server-buffer erc-session-server) - :port (format ; ensure we have a string - "%s" (erc-with-server-buffer erc-session-port)) - :user nickname)))) - (when secret - (let ((passwd (plist-get secret :secret))) - (if (functionp passwd) (funcall passwd) passwd))))))) - -(defun erc-nickserv-call-identify-function (nickname) - "Call `erc-nickserv-identify'. -Either call it interactively or run it with NICKNAME's password, -depending on the value of `erc-prompt-for-nickserv-password'." - (if erc-prompt-for-nickserv-password - (call-interactively 'erc-nickserv-identify) - (erc-nickserv-identify (erc-nickserv-get-password nickname)))) +As soon as some source returns a password, the sequence of +lookups stops and this function returns it (or returns nil if it +is empty). Otherwise, no corresponding password was found, and +it returns nil." + (let (network server port) + ;; Fill in local vars, switching to the server buffer once only + (erc-with-server-buffer + (setq network erc-network + server erc-session-server + port erc-session-port)) + (let ((ret + (or + (when erc-nickserv-passwords + (cdr (assoc nick + (cl-second (assoc network + erc-nickserv-passwords))))) + (when erc-use-auth-source-for-nickserv-password + (let ((secret (cl-first (auth-source-search + :max 1 :require '(:secret) + :host server + ;; Ensure a string for :port + :port (format "%s" port) + :user nick)))) + (when secret + (let ((passwd (plist-get secret :secret))) + (if (functionp passwd) (funcall passwd) passwd))))) + (when erc-prompt-for-nickserv-password + (read-passwd + (format "NickServ password for %s on %s (RET to cancel): " + nick network)))))) + (when (and ret (not (string= ret ""))) + ret)))) (defvar erc-auto-discard-away) -;;;###autoload -(defun erc-nickserv-identify (password) +(defun erc-nickserv-send-identify (nick password) "Send an \"identify \" message to NickServ. -When called interactively, read the password using `read-passwd'." +Returns t if the message could be sent, nil otherwise." + (let* ((erc-auto-discard-away nil) + (network (erc-network)) + (nickserv-info (assoc network erc-nickserv-alist)) + (nickserv (or (erc-nickserv-alist-nickserv nil nickserv-info) + "NickServ")) + (identify-word (or (erc-nickserv-alist-ident-keyword + nil nickserv-info) + "IDENTIFY")) + (nick (if (erc-nickserv-alist-use-nick-p nil nickserv-info) + (concat nick " ") + "")) + (msgtype (or (erc-nickserv-alist-ident-command nil nickserv-info) + "PRIVMSG"))) + (erc-message msgtype + (concat nickserv " " identify-word " " nick password)))) + +;;;###autoload +(defun erc-nickserv-identify (&optional nick) + "Identify to NickServ immediately. +Identification will either use NICK or the current nick if not +provided, and some password obtained through +`erc-nickserv-get-password' (which see). If no password can be +found, an error is reported trough `erc-error'. + +Interactively, the user will be prompted for NICK, an empty +string meaning to default to the current nick. + +Returns t if the identify message could be sent, nil otherwise." (interactive - (list (read-passwd - (format "NickServ password for %s on %s (RET to cancel): " - (erc-current-nick) - (or (and (erc-network) - (symbol-name (erc-network))) - "Unknown network"))))) - (when (and password (not (string= "" password))) - (let* ((erc-auto-discard-away nil) - (network (erc-network)) - (nickserv-info (assoc network erc-nickserv-alist)) - (nickserv (or (erc-nickserv-alist-nickserv nil nickserv-info) - "NickServ")) - (identify-word (or (erc-nickserv-alist-ident-keyword - nil nickserv-info) - "IDENTIFY")) - (nick (if (erc-nickserv-alist-use-nick-p nil nickserv-info) - (concat (erc-current-nick) " ") - "")) - (msgtype (or (erc-nickserv-alist-ident-command nil nickserv-info) - "PRIVMSG"))) - (erc-message msgtype - (concat nickserv " " identify-word " " nick password))))) + (list + (read-from-minibuffer "Nickname: " nil nil nil + 'erc-nick-history-list (erc-current-nick)))) + (unless (and nick (not (string= nick ""))) + (setq nick (erc-current-nick))) + (let ((password (erc-nickserv-get-password nick))) + (if password + (erc-nickserv-send-identify nick password) + (erc-error "Cannot find a password for nickname %s" + nick) + nil))) (provide 'erc-services) -- 2.30.0 --nextPart1896953.EnoYUHA41c--