Kai Tetzlaff <[email protected]> writes:

> Hi Michael,

Hi Kai,

> sorry - it took a while to get my emacs config working with TRAMP from
> git (savannah) in order to apply the patch [1].

No problem, I could continue to work in parallel on the patch :-)

> 1. /ssh:[email protected]|sudo::/etc/passwd
>
>    This triggers:
>
>    a) an auth-source lookup for
>
>           hostname="host.example.com", user="remoteuser", port="ssh"
>
>    b) in case a) fails, a password prompt:
>
>           `Password for /ssh:[email protected]: `
>
>    => This looks pretty good. The auth-source lookup has the proper
>       information to find a matching password. And if auth-source finds
>       a matching entry, b) (password prompt) gets skipped.
>
>       Just a minor issue: the `port="ssh"` is a bit misleading. The
>       previous `port="sudo"` seemed clearer.

Fixed. It should ask now 'Password for /sudo:[email protected]: '

> 2. /ssh:host.example.com|sudo::/etc/passwd
>
>    Which uses a host entry in ~/.ssh/config:
>
>        Host host.example.com
>            User remoteuser
>
>    This triggers:
>
>    a) an auth-source lookup for
>
>           hostname="host.example.com", user="", port="ssh"
>
>    b) a prompt for the user name:
>
>           `ssh user name for host.example.com (default kai): `
>
>       (the default seems to be the local (emacs session) username. So I
>       changed that to `remoteuser`)
>
>    c) a password prompt:
>
>           `Password for /ssh:host.example.com: `
>
>    => This one still has some issues.
>
>       The auth-source lookup happens before b) (the prompt for the user
>       name) and it is not repeated after obtaining the correct user
>       name in b). So the lookup will typically fail.
>
>       The password prompt in c)  doesn't show the user name entered in
>       b).
>
>       Is it possible to do b) (ask for the username) before a)
>       (auth-source lookup)?

This is a general problem, not introduced recently. Tramp knows only
user names which have been told, it does not check ssh config files and
alike.

But according to my recent tests, auth-source lookup is started now w/o
user (because it is nil), so it should be better now. Step b) is
skipped. To be confirmed by you.

>       An option to configure a connection specific sudo (default) user
>       would be nice (or, even better, extract the user name from the ssh
>       config).

Oh, that exists already. See tramp-default-user-alist.

The adapted patch is appended, and it works (in my environment) for
local and remote sudo, for remote doas, and for local sudoedit.

Waiting for comments :-)

> Thanks & Best Regards,
> Kai.

Best regards, Michael.

diff --git a/lisp/tramp-sh.el b/lisp/tramp-sh.el
index 40ddf106..3c284635 100644
--- a/lisp/tramp-sh.el
+++ b/lisp/tramp-sh.el
@@ -301,7 +301,8 @@ The string is used in `tramp-methods'.")
                 (tramp-remote-shell-login   ("-l"))
                 (tramp-remote-shell-args    ("-c"))
                 (tramp-connection-timeout   10)
-                (tramp-session-timeout      300)))
+                (tramp-session-timeout      300)
+		(tramp-password-previous-hop t)))
  (add-to-list 'tramp-methods
               `("doas"
                 (tramp-login-program        "doas")
@@ -309,7 +310,8 @@ The string is used in `tramp-methods'.")
                 (tramp-remote-shell         ,tramp-default-remote-shell)
                 (tramp-remote-shell-args    ("-c"))
                 (tramp-connection-timeout   10)
-                (tramp-session-timeout      300)))
+                (tramp-session-timeout      300)
+		(tramp-password-previous-hop t)))
  (add-to-list 'tramp-methods
               `("ksu"
                 (tramp-login-program        "ksu")
@@ -5005,8 +5007,7 @@ connection if a previous connection has died for some reason."
                 (tramp-error vec 'file-error "`tramp-encoding-shell' not set"))
 	      (let* ((current-host tramp-system-name)
 		     (target-alist (tramp-compute-multi-hops vec))
-		     ;; Needed for `tramp-get-remote-null-device'.
-		     (previous-hop nil)
+		     (previous-hop tramp-null-hop)
 		     ;; We will apply `tramp-ssh-controlmaster-options'
 		     ;; only for the first hop.
 		     (options (tramp-ssh-controlmaster-options vec))
@@ -5091,9 +5092,14 @@ connection if a previous connection has died for some reason."
 		    ;; Set password prompt vector.
 		    (tramp-set-connection-property
 		     p "password-vector"
-		     (make-tramp-file-name
-		      :method l-method :user l-user :domain l-domain
-		      :host l-host :port l-port))
+		     (if (tramp-get-method-parameter
+			  hop 'tramp-password-previous-hop)
+			 (let ((pv (copy-tramp-file-name previous-hop)))
+			   (setf (tramp-file-name-method pv) l-method)
+			   pv)
+		       (make-tramp-file-name
+			:method l-method :user l-user :domain l-domain
+			:host l-host :port l-port)))

 		    ;; Set session timeout.
 		    (when (tramp-get-method-parameter
diff --git a/lisp/tramp-sudoedit.el b/lisp/tramp-sudoedit.el
index 797804df..a35f9391 100644
--- a/lisp/tramp-sudoedit.el
+++ b/lisp/tramp-sudoedit.el
@@ -45,7 +45,8 @@
  (add-to-list 'tramp-methods
               `(,tramp-sudoedit-method
                 (tramp-sudo-login (("sudo") ("-u" "%u") ("-S") ("-H")
-			           ("-p" "Password:") ("--")))))
+			           ("-p" "Password:") ("--")))
+		(tramp-password-previous-hop t)))

  (add-to-list 'tramp-default-user-alist '("\\`sudoedit\\'" nil "root"))

@@ -168,6 +169,12 @@ arguments to pass to the OPERATION."
  (tramp-register-foreign-file-name-handler
   #'tramp-sudoedit-file-name-p #'tramp-sudoedit-file-name-handler))

+;; Needed for `tramp-read-passwd'.
+(defconst tramp-sudoedit-null-hop
+  (make-tramp-file-name
+   :method tramp-sudoedit-method :user (user-login-name) :host tramp-system-name)
+"Connection hop which identifies the virtual hop before the first one.")
+
 
 ;; File name primitives.

@@ -825,6 +832,7 @@ in case of error, t otherwise."
       (process-put p 'vector vec)
       (process-put p 'adjust-window-size-function #'ignore)
       (set-process-query-on-exit-flag p nil)
+      (tramp-set-connection-property p "password-vector" tramp-sudoedit-null-hop)
       (tramp-process-actions p vec nil tramp-sudoedit-sudo-actions)
       (tramp-message vec 6 "%s\n%s" (process-exit-status p) (buffer-string))
       (prog1
diff --git a/lisp/tramp.el b/lisp/tramp.el
index 0fa0e5fa..b483d764 100644
--- a/lisp/tramp.el
+++ b/lisp/tramp.el
@@ -315,14 +315,20 @@ pair of the form (KEY VALUE).  The following KEYs are defined:
   * `tramp-connection-timeout'
     This is the maximum time to be spent for establishing a connection.
     In general, the global default value shall be used, but for
-    some methods, like \"su\" or \"sudo\", a shorter timeout
-    might be desirable.
+    some methods, like \"doas\", \"su\" or \"sudo\", a shorter
+    timeout might be desirable.

   * `tramp-session-timeout'
     How long a Tramp connection keeps open before being disconnected.
-    This is useful for methods like \"su\" or \"sudo\", which
+    This is useful for methods like \"doas\" or \"sudo\", which
     shouldn't run an open connection in the background forever.

+  * `tramp-password-previous-hop'
+    The password for this connection is the same like the
+    password for the previous hop.  If there is no previous hop,
+    the password of the local user is applied.  This is needed
+    for methods like \"doas\", \"sudo\" or \"sudoedit\".
+
   * `tramp-case-insensitive'
     Whether the remote file system handles file names case insensitive.
     Only a non-nil value counts, the default value nil means to
@@ -1427,6 +1433,11 @@ calling HANDLER.")
 (put #'tramp-file-name-localname 'tramp-suppress-trace t)
 (put #'tramp-file-name-hop 'tramp-suppress-trace t)

+;; Needed for `tramp-read-passwd' and `tramp-get-remote-null-device'.
+(defconst tramp-null-hop
+  (make-tramp-file-name :user (user-login-name) :host tramp-system-name)
+"Connection hop which identifies the virtual hop before the first one.")
+
 (defun tramp-file-name-user-domain (vec)
   "Return user and domain components of VEC."
   (when (or (tramp-file-name-user vec) (tramp-file-name-domain vec))
@@ -5970,8 +5981,8 @@ name of a process or buffer, or nil to default to the current buffer."

 (defun tramp-get-remote-null-device (vec)
   "Return null device on the remote host identified by VEC.
-If VEC is nil, return local null device."
-  (if (null vec)
+If VEC is nil or `tramp-null-hop', return local null device."
+  (if (or (null vec) (equal vec tramp-null-hop))
       null-device
     (with-tramp-connection-property vec "null-device"
       (let ((default-directory (tramp-make-tramp-file-name vec)))

Reply via email to