Randy Yates <ran...@as2inc.com> writes:

Hi Randy,

>     My organization has recently enabled MFA/totp over ssh on all our linux
>     systems. We are using JumpCloud and it was apparently configured by
>     JumpCloud automatically when they turned MFA on.
>
>     I am able to ssh from one linux box (ubuntu 18.04) to another using the
>     command-line ssh (openssh). The transaction looks like this:
>
>         <username>@Lubuntu-22259:/<cwd>$ ssh -YC <username>@<dest-host>
>         Password:
>         Verification code: xxxxxxxxxxxx

[...]

>     I found that when I use tramp, it prompts me for the password as usual,
>     but after entering the correct password, it prompts me again for the
>     password instead of the verification code.

[...]

>     Finally, note that before these security updates, tramp was working
>     fine. I am using emacs version
>
>         GNU Emacs 29.0.50 (build 2, x86_64-pc-linux-gnu, GTK+ Version 
> 3.22.30, cairo version 1.15.10) of 2022-06-16.
>
>     Is it possible to update tramp so that it operates correctly with this
>     configuration?

Well, my first reaction was to ask you to add the "verification code"
prompt to password-word-equivalents. This is what Tramp uses for
password prompts.

However, one-time passwords are different. So I've assembled the
appended patch, could you pls test? It is on top of the emacs-29 branch
in git, I hope it applies to your more-than-a-year-old Emacs 29
version. If not, you could install the recent Tramp 2.6.1.2 from GNU
ELPA, and apply the patch on this. Note that there is a problem in
installing Tramp from GNU ELPA with Emacs 29.1, see
<https://elpa.gnu.org/packages/tramp.html>.

>     Thanks for your help, and let me know if there is anything else you
>     need.
>
>     Randy Yates

Best regards, Michael.

diff --git a/lisp/tramp-sh.el b/lisp/tramp-sh.el
index 5a1e73aa..59d5c005 100644
--- a/lisp/tramp-sh.el
+++ b/lisp/tramp-sh.el
@@ -535,6 +535,7 @@ shell from reading its init file."
 (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)
@@ -558,6 +559,7 @@ corresponding PATTERN matches, the ACTION function is called.")
 
 (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)
diff --git a/lisp/tramp.el b/lisp/tramp.el
index d10f93b3..83610193 100644
--- a/lisp/tramp.el
+++ b/lisp/tramp.el
@@ -679,6 +679,17 @@ The `sudo' program appears to insert a `^@' character into the prompt."
   :version "29.1"
   :type 'regexp)
 
+(defcustom tramp-otp-password-prompt-regexp
+  (tramp-compat-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"
@@ -5538,6 +5549,25 @@ of."
       (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))

Reply via email to