Michael Albinus <[email protected]> writes:
Hi Kai,
>>> I see. It is not a problem of multi-hop per se, but a general problem of
>>> su(do) password prompts in Tramp. Will see what I could do.
>>
>> Ok, yes - but it's only a problem of the `sudo` method. For `su` the
>> current behaviour is correct.
>
> And perhaps 'doas' on *BSD? Don't know.
Finally, I believe we must support Tramp methods 'sudo', 'sudoedit' and
'doas'. I've prepared a patch (appended), could you pls check? The main
idea is, that for these methods the password of the previous hop is
reused. In case there is no "previous" hop, Tramp assumes a virtual one,
in order not to mix with the root password.
The patch is not polished yet, but I'd like to know whether it works in
general outside my laptop.
>> BR, Kai
Thanks, and best regards, Michael.
diff --git a/lisp/tramp-sh.el b/lisp/tramp-sh.el
index 40ddf106..a4e05294 100644
--- a/lisp/tramp-sh.el
+++ b/lisp/tramp-sh.el
@@ -5005,8 +5005,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 +5090,11 @@ 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 (string-match-p "sudo\\|sudoedit\\|doas" l-method)
+ previous-hop
+ (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.el b/lisp/tramp.el
index 0fa0e5fa..bbe82f54 100644
--- a/lisp/tramp.el
+++ b/lisp/tramp.el
@@ -395,6 +395,11 @@ See `tramp-methods' for possibilities.
Also see `tramp-default-method-alist'."
:type 'string)
+(defconst tramp-local-method "local"
+ "Method name for virtual hop prior the first one.")
+
+(add-to-list 'tramp-methods `(,tramp-local-method))
+
(defcustom tramp-default-method-alist nil
;; FIXME: This is not an "alist", because its elements are not of
;; the form (KEY . VAL) but (KEY1 KEY2 VAL).
@@ -1427,6 +1432,12 @@ 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
+ :method tramp-local-method :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))
@@ -5788,7 +5799,9 @@ Consults the auth-source package."
(tramp-check-for-regexp proc tramp-password-prompt-regexp)
(if (string-match-p "passphrase" (match-string 1))
(match-string 0)
- (format "%s for %s " (capitalize (match-string 1)) key)))))
+ (format "%s for %s " (capitalize (match-string 1))
+ (replace-regexp-in-string
+ (concat "^/" tramp-local-method ":") "" key))))))
(auth-source-creation-prompts `((secret . ,pw-prompt)))
;; Use connection-local value.
(auth-sources (buffer-local-value 'auth-sources (process-buffer proc)))
@@ -5970,8 +5983,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)))