Added `comint-password-function' hook
* etc/NEWS: * lisp/comint.el (comint-password-function): New variable. (comint-send-invisible): Use it. * test/lisp/comint-tests.el (comint-test-no-password-function, comint-test-password-function-with-value, comint-test-password-function-with-nil): Test new variable.
This commit is contained in:
parent
eea05713be
commit
3df7d06d41
3 changed files with 95 additions and 2 deletions
13
etc/NEWS
13
etc/NEWS
|
@ -1131,6 +1131,19 @@ end.
|
|||
*** 'comint-run' can now accept a list of switches to pass to the program.
|
||||
'C-u M-x comint-run' will prompt for the switches interactively.
|
||||
|
||||
*** Abnormal hook `comint-password-function' has been added.
|
||||
This hook permits a derived mode to supply a password for the
|
||||
underlying command interpreter without prompting the user. For
|
||||
example, in sql-mode, the password for connecting to the database may
|
||||
be stored in the connection wallet and may be passed on the command
|
||||
line to start the SQL interpreter. This is a potential security flaw
|
||||
that could expose user's database passwords on the command line
|
||||
through the use of a process list (Bug#8427). With this hook, it is
|
||||
possible to not pass the password on the command line and wait for the
|
||||
program to prompt for the password. When it does so, the password cam
|
||||
be supplied to the SQL interpreter without involving the user just as
|
||||
if it had been supplied on the command line.
|
||||
|
||||
** SQL
|
||||
|
||||
*** SQL Indent Minor Mode
|
||||
|
|
|
@ -2356,6 +2356,13 @@ a buffer local variable."
|
|||
;; saved -- typically passwords to ftp, telnet, or somesuch.
|
||||
;; Just enter m-x comint-send-invisible and type in your line.
|
||||
|
||||
(defvar comint-password-function nil
|
||||
"Abnormal hook run when prompted for a password.
|
||||
This function gets one argument, a string containing the prompt.
|
||||
It may return a string containing the password, or nil if normal
|
||||
password prompting should occur.")
|
||||
(make-variable-buffer-local 'comint-password-function)
|
||||
|
||||
(defun comint-send-invisible (&optional prompt)
|
||||
"Read a string without echoing.
|
||||
Then send it to the process running in the current buffer.
|
||||
|
@ -2370,8 +2377,13 @@ Security bug: your string can still be temporarily recovered with
|
|||
(format "(In buffer %s) "
|
||||
(current-buffer)))))
|
||||
(if proc
|
||||
(let ((str (read-passwd (concat prefix
|
||||
(or prompt "Non-echoed text: ")))))
|
||||
(let ((prefix-prompt (concat prefix
|
||||
(or prompt "Non-echoed text: ")))
|
||||
str)
|
||||
(when comint-password-function
|
||||
(setq str (funcall comint-password-function prefix-prompt)))
|
||||
(unless str
|
||||
(setq str (read-passwd prefix-prompt)))
|
||||
(if (stringp str)
|
||||
(progn
|
||||
(comint-snapshot-last-prompt)
|
||||
|
|
|
@ -52,6 +52,74 @@
|
|||
(dolist (str comint-testsuite-password-strings)
|
||||
(should (string-match comint-password-prompt-regexp str))))
|
||||
|
||||
(ert-deftest comint-test-no-password-function ()
|
||||
"Test that `comint-password-function' not being set does not
|
||||
alter normal password flow."
|
||||
(cl-letf
|
||||
(((symbol-function 'read-passwd)
|
||||
(lambda (_prompt &optional _confirm _default)
|
||||
"PaSsWoRd123")))
|
||||
(let ((cat (executable-find "cat")))
|
||||
(when cat
|
||||
(with-temp-buffer
|
||||
(make-comint-in-buffer "test-comint-password" (current-buffer) cat)
|
||||
(let ((proc (get-buffer-process (current-buffer))))
|
||||
(comint-send-string proc "Password: ")
|
||||
(accept-process-output proc 0 1 t)
|
||||
(comint-send-eof)
|
||||
(accept-process-output proc 0 1 t)
|
||||
(should (string-equal (buffer-substring-no-properties (point-min) (point-max))
|
||||
"Password: PaSsWoRd123\n"))
|
||||
(when (process-live-p proc)
|
||||
(kill-process proc))
|
||||
(accept-process-output proc 0 1 t)))))))
|
||||
|
||||
(ert-deftest comint-test-password-function-with-value ()
|
||||
"Test that `comint-password-function' alters normal password
|
||||
flow. Hook function returns alternative password."
|
||||
(cl-letf
|
||||
(((symbol-function 'read-passwd)
|
||||
(lambda (_prompt &optional _confirm _default)
|
||||
"PaSsWoRd123")))
|
||||
(let ((cat (executable-find "cat"))
|
||||
(comint-password-function (lambda (_prompt) "MaGiC-PaSsWoRd789")))
|
||||
(when cat
|
||||
(with-temp-buffer
|
||||
(make-comint-in-buffer "test-comint-password" (current-buffer) cat)
|
||||
(let ((proc (get-buffer-process (current-buffer))))
|
||||
(comint-send-string proc "Password: ")
|
||||
(accept-process-output proc 0 1 t)
|
||||
(comint-send-eof)
|
||||
(accept-process-output proc 0 1 t)
|
||||
(should (string-equal (buffer-substring-no-properties (point-min) (point-max))
|
||||
"Password: MaGiC-PaSsWoRd789\n"))
|
||||
(when (process-live-p proc)
|
||||
(kill-process proc))
|
||||
(accept-process-output proc 0 1 t)))))))
|
||||
|
||||
(ert-deftest comint-test-password-function-with-nil ()
|
||||
"Test that `comint-password-function' does not alter the normal
|
||||
password flow if it returns a nil value."
|
||||
(cl-letf
|
||||
(((symbol-function 'read-passwd)
|
||||
(lambda (_prompt &optional _confirm _default)
|
||||
"PaSsWoRd456")))
|
||||
(let ((cat (executable-find "cat"))
|
||||
(comint-password-function (lambda (_prompt) nil)))
|
||||
(when cat
|
||||
(with-temp-buffer
|
||||
(make-comint-in-buffer "test-comint-password" (current-buffer) cat)
|
||||
(let ((proc (get-buffer-process (current-buffer))))
|
||||
(comint-send-string proc "Password: ")
|
||||
(accept-process-output proc 0 1 t)
|
||||
(comint-send-eof)
|
||||
(accept-process-output proc 0 1 t)
|
||||
(should (string-equal (buffer-substring-no-properties (point-min) (point-max))
|
||||
"Password: PaSsWoRd456\n"))
|
||||
(when (process-live-p proc)
|
||||
(kill-process proc))
|
||||
(accept-process-output proc 0 1 t)))))))
|
||||
|
||||
;; Local Variables:
|
||||
;; no-byte-compile: t
|
||||
;; End:
|
||||
|
|
Loading…
Add table
Reference in a new issue