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. Invokes password-read if available, read-passwd else.

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.
Invokes `password-read' if available, `read-passwd' else."
  (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)
	 (key (tramp-make-tramp-file-name
	       ;; In tramp-sh.el, we must use "password-vector" due to
	       ;; multi-hop.
	       (tramp-get-connection-property
		proc "password-vector" (process-get proc 'vector))
	       'noloc 'nohop))
	 (pw-prompt
	  (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 (with-current-buffer (process-buffer proc) auth-sources))
	 ;; We suspend the timers while reading the password.
         (stimers (with-timeout-suspend))
	 auth-info auth-passwd)

    (unwind-protect
	(with-parsed-tramp-file-name key nil
	  (setq tramp-password-save-function nil
		user
		(or user (tramp-get-connection-property key "login-as" nil)))
	  (prog1
	      (or
	       ;; See if auth-sources contains something useful.
	       (ignore-errors
		 (and (tramp-get-connection-property
		       v "first-password-request" nil)
		      ;; Try with Tramp's current method.
		      (setq auth-info
			    (car
			     (auth-source-search
			      :max 1
			      (and user :user)
			      (if domain
				  (concat
				   user tramp-prefix-domain-format domain)
				user)
			      :host
			      (if port
				  (concat
				   host tramp-prefix-port-format port)
				host)
			      :port method
			      :require (cons :secret (and user '(:user)))
			      :create t))
			    tramp-password-save-function
			    (plist-get auth-info :save-function)
			    auth-passwd (plist-get auth-info :secret)))
		 (while (functionp auth-passwd)
		   (setq auth-passwd (funcall auth-passwd)))
		 auth-passwd)

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

	       ;; Else, get the password interactively w/o cache.
	       (read-passwd pw-prompt))

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

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