aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael R. Mauger2019-12-22 23:56:05 -0500
committerMichael R. Mauger2019-12-22 23:56:05 -0500
commit3df7d06d4187d402e4df1177461862af638d96de (patch)
treeceb522ae690fec95a1ee7118293cd93edd460479
parenteea05713bef7b86ff84ca843948f944e4c856119 (diff)
downloademacs-3df7d06d4187d402e4df1177461862af638d96de.tar.gz
emacs-3df7d06d4187d402e4df1177461862af638d96de.zip
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.
-rw-r--r--etc/NEWS13
-rw-r--r--lisp/comint.el16
-rw-r--r--test/lisp/comint-tests.el68
3 files changed, 95 insertions, 2 deletions
diff --git a/etc/NEWS b/etc/NEWS
index 20288398bd3..2b0622e752f 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1131,6 +1131,19 @@ end.
1131*** 'comint-run' can now accept a list of switches to pass to the program. 1131*** 'comint-run' can now accept a list of switches to pass to the program.
1132'C-u M-x comint-run' will prompt for the switches interactively. 1132'C-u M-x comint-run' will prompt for the switches interactively.
1133 1133
1134*** Abnormal hook `comint-password-function' has been added.
1135This hook permits a derived mode to supply a password for the
1136underlying command interpreter without prompting the user. For
1137example, in sql-mode, the password for connecting to the database may
1138be stored in the connection wallet and may be passed on the command
1139line to start the SQL interpreter. This is a potential security flaw
1140that could expose user's database passwords on the command line
1141through the use of a process list (Bug#8427). With this hook, it is
1142possible to not pass the password on the command line and wait for the
1143program to prompt for the password. When it does so, the password cam
1144be supplied to the SQL interpreter without involving the user just as
1145if it had been supplied on the command line.
1146
1134** SQL 1147** SQL
1135 1148
1136*** SQL Indent Minor Mode 1149*** SQL Indent Minor Mode
diff --git a/lisp/comint.el b/lisp/comint.el
index 4bb43670354..c06a63fbd24 100644
--- a/lisp/comint.el
+++ b/lisp/comint.el
@@ -2356,6 +2356,13 @@ a buffer local variable."
2356;; saved -- typically passwords to ftp, telnet, or somesuch. 2356;; saved -- typically passwords to ftp, telnet, or somesuch.
2357;; Just enter m-x comint-send-invisible and type in your line. 2357;; Just enter m-x comint-send-invisible and type in your line.
2358 2358
2359(defvar comint-password-function nil
2360 "Abnormal hook run when prompted for a password.
2361This function gets one argument, a string containing the prompt.
2362It may return a string containing the password, or nil if normal
2363password prompting should occur.")
2364(make-variable-buffer-local 'comint-password-function)
2365
2359(defun comint-send-invisible (&optional prompt) 2366(defun comint-send-invisible (&optional prompt)
2360 "Read a string without echoing. 2367 "Read a string without echoing.
2361Then send it to the process running in the current buffer. 2368Then send it to the process running in the current buffer.
@@ -2370,8 +2377,13 @@ Security bug: your string can still be temporarily recovered with
2370 (format "(In buffer %s) " 2377 (format "(In buffer %s) "
2371 (current-buffer))))) 2378 (current-buffer)))))
2372 (if proc 2379 (if proc
2373 (let ((str (read-passwd (concat prefix 2380 (let ((prefix-prompt (concat prefix
2374 (or prompt "Non-echoed text: "))))) 2381 (or prompt "Non-echoed text: ")))
2382 str)
2383 (when comint-password-function
2384 (setq str (funcall comint-password-function prefix-prompt)))
2385 (unless str
2386 (setq str (read-passwd prefix-prompt)))
2375 (if (stringp str) 2387 (if (stringp str)
2376 (progn 2388 (progn
2377 (comint-snapshot-last-prompt) 2389 (comint-snapshot-last-prompt)
diff --git a/test/lisp/comint-tests.el b/test/lisp/comint-tests.el
index 213a5c7c9e4..c04134599f6 100644
--- a/test/lisp/comint-tests.el
+++ b/test/lisp/comint-tests.el
@@ -52,6 +52,74 @@
52 (dolist (str comint-testsuite-password-strings) 52 (dolist (str comint-testsuite-password-strings)
53 (should (string-match comint-password-prompt-regexp str)))) 53 (should (string-match comint-password-prompt-regexp str))))
54 54
55(ert-deftest comint-test-no-password-function ()
56 "Test that `comint-password-function' not being set does not
57alter normal password flow."
58 (cl-letf
59 (((symbol-function 'read-passwd)
60 (lambda (_prompt &optional _confirm _default)
61 "PaSsWoRd123")))
62 (let ((cat (executable-find "cat")))
63 (when cat
64 (with-temp-buffer
65 (make-comint-in-buffer "test-comint-password" (current-buffer) cat)
66 (let ((proc (get-buffer-process (current-buffer))))
67 (comint-send-string proc "Password: ")
68 (accept-process-output proc 0 1 t)
69 (comint-send-eof)
70 (accept-process-output proc 0 1 t)
71 (should (string-equal (buffer-substring-no-properties (point-min) (point-max))
72 "Password: PaSsWoRd123\n"))
73 (when (process-live-p proc)
74 (kill-process proc))
75 (accept-process-output proc 0 1 t)))))))
76
77(ert-deftest comint-test-password-function-with-value ()
78 "Test that `comint-password-function' alters normal password
79flow. Hook function returns alternative password."
80 (cl-letf
81 (((symbol-function 'read-passwd)
82 (lambda (_prompt &optional _confirm _default)
83 "PaSsWoRd123")))
84 (let ((cat (executable-find "cat"))
85 (comint-password-function (lambda (_prompt) "MaGiC-PaSsWoRd789")))
86 (when cat
87 (with-temp-buffer
88 (make-comint-in-buffer "test-comint-password" (current-buffer) cat)
89 (let ((proc (get-buffer-process (current-buffer))))
90 (comint-send-string proc "Password: ")
91 (accept-process-output proc 0 1 t)
92 (comint-send-eof)
93 (accept-process-output proc 0 1 t)
94 (should (string-equal (buffer-substring-no-properties (point-min) (point-max))
95 "Password: MaGiC-PaSsWoRd789\n"))
96 (when (process-live-p proc)
97 (kill-process proc))
98 (accept-process-output proc 0 1 t)))))))
99
100(ert-deftest comint-test-password-function-with-nil ()
101 "Test that `comint-password-function' does not alter the normal
102password flow if it returns a nil value."
103 (cl-letf
104 (((symbol-function 'read-passwd)
105 (lambda (_prompt &optional _confirm _default)
106 "PaSsWoRd456")))
107 (let ((cat (executable-find "cat"))
108 (comint-password-function (lambda (_prompt) nil)))
109 (when cat
110 (with-temp-buffer
111 (make-comint-in-buffer "test-comint-password" (current-buffer) cat)
112 (let ((proc (get-buffer-process (current-buffer))))
113 (comint-send-string proc "Password: ")
114 (accept-process-output proc 0 1 t)
115 (comint-send-eof)
116 (accept-process-output proc 0 1 t)
117 (should (string-equal (buffer-substring-no-properties (point-min) (point-max))
118 "Password: PaSsWoRd456\n"))
119 (when (process-live-p proc)
120 (kill-process proc))
121 (accept-process-output proc 0 1 t)))))))
122
55;; Local Variables: 123;; Local Variables:
56;; no-byte-compile: t 124;; no-byte-compile: t
57;; End: 125;; End: