@value{tramp} sets a similar default value for both prompts.
@item @code{tramp-password-prompt-regexp}
+@item @code{tramp-otp-password-prompt-regexp}
@item @code{tramp-wrong-passwd-regexp}
@vindex tramp-password-prompt-regexp
+@vindex tramp-otp-password-prompt-regexp
@vindex tramp-wrong-passwd-regexp
@value{tramp} uses @code{tramp-password-prompt-regexp} to
is usually more convenient to add new passphrases to that 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
prompts, for which @value{tramp} uses @code{tramp-wrong-passwd-regexp}.
(defconst tramp-actions-before-shell
'((tramp-login-prompt-regexp tramp-action-login)
(tramp-password-prompt-regexp tramp-action-password)
+ (tramp-otp-password-prompt-regexp tramp-action-otp-password)
(tramp-wrong-passwd-regexp tramp-action-permission-denied)
(shell-prompt-pattern tramp-action-succeed)
(tramp-shell-prompt-pattern tramp-action-succeed)
(defconst tramp-actions-copy-out-of-band
'((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-copy-failed-regexp tramp-action-permission-denied)
(tramp-security-key-confirm-regexp tramp-action-show-and-confirm-message)
:version "29.1"
: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
(rx bol (* nonl)
(| "Permission denied"
(narrow-to-region (point-max) (point-max))))
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)
"Signal success in finding shell prompt."
(throw 'tramp-action 'ok))