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)))