Support one-time passwords in Tramp

* doc/misc/tramp.texi (Remote shell setup):
Describe tramp-otp-password-prompt-regexp.

* lisp/net/tramp-sh.el (tramp-actions-before-shell)
(tramp-actions-copy-out-of-band):
Use `tramp-otp-password-prompt-regexp'.

* lisp/net/tramp.el (tramp-otp-password-prompt-regexp): New defcustom.
(tramp-action-otp-password): New defun.
This commit is contained in:
Michael Albinus 2023-09-16 09:59:31 +02:00
parent f880b94e64
commit 825be05b37
3 changed files with 37 additions and 0 deletions

View file

@ -2417,8 +2417,10 @@ which may not be the same as the local login shell prompt,
@value{tramp} sets a similar default value for both prompts. @value{tramp} sets a similar default value for both prompts.
@item @code{tramp-password-prompt-regexp} @item @code{tramp-password-prompt-regexp}
@item @code{tramp-otp-password-prompt-regexp}
@item @code{tramp-wrong-passwd-regexp} @item @code{tramp-wrong-passwd-regexp}
@vindex tramp-password-prompt-regexp @vindex tramp-password-prompt-regexp
@vindex tramp-otp-password-prompt-regexp
@vindex tramp-wrong-passwd-regexp @vindex tramp-wrong-passwd-regexp
@value{tramp} uses @code{tramp-password-prompt-regexp} to @value{tramp} uses @code{tramp-password-prompt-regexp} to
@ -2452,6 +2454,10 @@ This user option is, by default, initialized from
is usually more convenient to add new passphrases to that user option is usually more convenient to add new passphrases to that user option
instead of altering this user option. instead of altering this user option.
The user option @code{tramp-otp-password-prompt-regexp} has a similar
purpose, but for one-time passwords. Those passwords are not cached
by @value{tramp} for reuse.
Similar localization may be necessary for handling wrong password Similar localization may be necessary for handling wrong password
prompts, for which @value{tramp} uses @code{tramp-wrong-passwd-regexp}. prompts, for which @value{tramp} uses @code{tramp-wrong-passwd-regexp}.

View file

@ -535,6 +535,7 @@ shell from reading its init file."
(defconst tramp-actions-before-shell (defconst tramp-actions-before-shell
'((tramp-login-prompt-regexp tramp-action-login) '((tramp-login-prompt-regexp tramp-action-login)
(tramp-password-prompt-regexp tramp-action-password) (tramp-password-prompt-regexp tramp-action-password)
(tramp-otp-password-prompt-regexp tramp-action-otp-password)
(tramp-wrong-passwd-regexp tramp-action-permission-denied) (tramp-wrong-passwd-regexp tramp-action-permission-denied)
(shell-prompt-pattern tramp-action-succeed) (shell-prompt-pattern tramp-action-succeed)
(tramp-shell-prompt-pattern tramp-action-succeed) (tramp-shell-prompt-pattern tramp-action-succeed)
@ -558,6 +559,7 @@ corresponding PATTERN matches, the ACTION function is called.")
(defconst tramp-actions-copy-out-of-band (defconst tramp-actions-copy-out-of-band
'((tramp-password-prompt-regexp tramp-action-password) '((tramp-password-prompt-regexp tramp-action-password)
(tramp-otp-password-prompt-regexp tramp-action-otp-password)
(tramp-wrong-passwd-regexp tramp-action-permission-denied) (tramp-wrong-passwd-regexp tramp-action-permission-denied)
(tramp-copy-failed-regexp tramp-action-permission-denied) (tramp-copy-failed-regexp tramp-action-permission-denied)
(tramp-security-key-confirm-regexp tramp-action-show-and-confirm-message) (tramp-security-key-confirm-regexp tramp-action-show-and-confirm-message)

View file

@ -679,6 +679,16 @@ The `sudo' program appears to insert a `^@' character into the prompt."
:version "29.1" :version "29.1"
:type 'regexp) :type 'regexp)
(defcustom tramp-otp-password-prompt-regexp
(rx bol (* nonl)
;; JumpCloud.
(group (| "Verification code"))
(* nonl) (any "::៖") (* blank))
"Regexp matching one-time password prompts.
The regexp should match at end of buffer."
:version "29.2"
:type 'regexp)
(defcustom tramp-wrong-passwd-regexp (defcustom tramp-wrong-passwd-regexp
(rx bol (* nonl) (rx bol (* nonl)
(| "Permission denied" (| "Permission denied"
@ -5538,6 +5548,25 @@ of."
(narrow-to-region (point-max) (point-max)))) (narrow-to-region (point-max) (point-max))))
t) t)
(defun tramp-action-otp-password (proc vec)
"Query the user for a one-time password."
(with-current-buffer (process-buffer proc)
(let ((case-fold-search t)
prompt)
(goto-char (point-min))
(tramp-check-for-regexp proc tramp-process-action-regexp)
(setq prompt (concat (match-string 1) " "))
(tramp-message vec 3 "Sending %s" (match-string 1))
;; We don't call `tramp-send-string' in order to hide the
;; password from the debug buffer and the traces.
(process-send-string
proc
(concat
(tramp-read-passwd-without-cache proc prompt) tramp-local-end-of-line))
;; Hide password prompt.
(narrow-to-region (point-max) (point-max))))
t)
(defun tramp-action-succeed (_proc _vec) (defun tramp-action-succeed (_proc _vec)
"Signal success in finding shell prompt." "Signal success in finding shell prompt."
(throw 'tramp-action 'ok)) (throw 'tramp-action 'ok))