Function: tramp-read-passwd

tramp-read-passwd is a byte-compiled function defined in tramp.el.gz.

Signature

(tramp-read-passwd PROC &optional PROMPT)

Documentation

Read a password from user (compat function).

Consults the auth-source package.

Source Code

;; Defined in /usr/src/emacs/lisp/net/tramp.el.gz
;; When calling "emacs -Q", `auth-source-search' won't be called.  If
;; you want to debug exactly this case, call "emacs -Q --eval '(setq
;; tramp-cache-read-persistent-data t)'" instead.
(defun tramp-read-passwd (proc &optional prompt)
  "Read a password from user (compat function).
Consults the auth-source package."
  (let* (;; If `auth-sources' contains "~/.authinfo.gpg", and
	 ;; `exec-path' contains a relative file name like ".", it
	 ;; could happen that the "gpg" command is not found.  So we
	 ;; adapt `default-directory'.  (Bug#39389, Bug#39489)
	 (default-directory tramp-compat-temporary-file-directory)
	 (case-fold-search t)
	 ;; In tramp-sh.el, we must use "password-vector" due to
	 ;; multi-hop.
	 (vec (tramp-get-connection-property
	       proc "password-vector" (process-get proc 'tramp-vector)))
	 (key (tramp-make-tramp-file-name vec 'noloc))
	 (method (tramp-file-name-method vec))
	 (user (or (tramp-file-name-user-domain vec)
		   (tramp-get-connection-property key "login-as")))
	 (host (tramp-file-name-host-port vec))
	 (pw-prompt
	  (string-trim-left
	   (or prompt
	       (with-current-buffer (process-buffer proc)
		 (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))))))
	 (auth-source-creation-prompts `((secret . ,pw-prompt)))
	 ;; Use connection-local value.
	 (auth-sources (buffer-local-value 'auth-sources (process-buffer proc)))
	 ;; We suspend the timers while reading the password.
         (stimers (with-timeout-suspend))
	 auth-info auth-passwd)

    (unwind-protect
	;; We cannot use `with-parsed-tramp-file-name', because it
	;; expands the file name.
	(or
	 (setq tramp-password-save-function nil)
	 ;; See if auth-sources contains something useful.
	 (ignore-errors
	   (and (tramp-get-connection-property vec "first-password-request")
		;; Try with Tramp's current method.  If there is no
		;; user name, `:create' triggers to ask for.  We
		;; suppress it.
		(setq auth-info
		      (car
		       (auth-source-search
			:max 1 :user user :host host :port method
			:require (cons :secret (and user '(:user)))
			:create (and user t)))
		      tramp-password-save-function
		      (plist-get auth-info :save-function)
		      auth-passwd
		      (tramp-compat-auth-info-password auth-info))))

	 ;; Try the password cache.
	 (progn
	   (setq auth-passwd (password-read pw-prompt key)
		 tramp-password-save-function
		 (lambda () (password-cache-add key auth-passwd)))
	   auth-passwd))

      ;; Workaround.  Prior Emacs 28.1, auth-source has saved empty
      ;; passwords.  See discussion in Bug#50399.
      (when (tramp-string-empty-or-nil-p auth-passwd)
	(setq tramp-password-save-function nil))
      (tramp-set-connection-property vec "first-password-request" nil)

      ;; Reenable the timers.
      (with-timeout-unsuspend stimers))))