* lisp/password-cache.el (password-data): Use a hash-table

* lisp/auth-source.el (auth-source-magic): Remove.
(auth-source-forget+, auth-source-forget-all-cached): Adjust to new
format of password-data.
(auth-source-format-cache-entry): Just use a cons.

(password-cache-remove, password-cache-add, password-reset)
(password-read-from-cache, password-in-cache-p): Adjust accordingly.

Fixes: bug#26699
This commit is contained in:
Stefan Monnier 2017-07-28 12:27:00 -04:00
parent bfb8d33fd1
commit d66dcde46a
4 changed files with 34 additions and 37 deletions

View file

@ -1084,6 +1084,9 @@ fontification, and commenting for embedded JavaScript and CSS.
* Incompatible Lisp Changes in Emacs 26.1
*** password-data is now a hash-table
so that `password-read' can use any object for the `key' argument.
+++
*** Command 'dired-mark-extension' now automatically prepends a '.' to the
extension when not present. The new command 'dired-mark-suffix' behaves

View file

@ -200,8 +200,6 @@ Note that if EPA/EPG is not available, this should NOT be used."
(const :tag "Save GPG-encrypted password tokens" gpg)
(const :tag "Don't encrypt tokens" never))))))
(defvar auth-source-magic "auth-source-magic ")
(defcustom auth-source-do-cache t
"Whether auth-source should cache information with `password-cache'."
:group 'auth-source
@ -782,16 +780,16 @@ Returns the deleted entries."
(defun auth-source-forget-all-cached ()
"Forget all cached auth-source data."
(interactive)
(cl-do-symbols (sym password-data)
;; when the symbol name starts with auth-source-magic
(when (string-match (concat "^" auth-source-magic) (symbol-name sym))
;; remove that key
(password-cache-remove (symbol-name sym))))
(maphash (lambda (key _password)
(when (eq 'auth-source (car-safe key))
;; remove that key
(password-cache-remove key)))
password-data)
(setq auth-source-netrc-cache nil))
(defun auth-source-format-cache-entry (spec)
"Format SPEC entry to put it in the password cache."
(concat auth-source-magic (format "%S" spec)))
`(auth-source . ,spec))
(defun auth-source-remember (spec found)
"Remember FOUND search results for SPEC."
@ -822,18 +820,16 @@ This is not a full `auth-source-search' spec but works similarly.
For instance, \(:host \"myhost\" \"yourhost\") would find all the
cached data that was found with a search for those two hosts,
while \(:host t) would find all host entries."
(let ((count 0)
sname)
(cl-do-symbols (sym password-data)
;; when the symbol name matches with auth-source-magic
(when (and (setq sname (symbol-name sym))
(string-match (concat "^" auth-source-magic "\\(.+\\)")
sname)
;; and the spec matches what was stored in the cache
(auth-source-specmatchp spec (read (match-string 1 sname))))
;; remove that key
(password-cache-remove sname)
(cl-incf count)))
(let ((count 0))
(maphash
(lambda (key _password)
(when (and (eq 'auth-source (car-safe key))
;; and the spec matches what was stored in the cache
(auth-source-specmatchp spec (cdr key)))
;; remove that key
(password-cache-remove key)
(cl-incf count)))
password-data)
count))
(defun auth-source-specmatchp (spec stored)

View file

@ -66,7 +66,7 @@ Whether passwords are cached at all is controlled by `password-cache'."
:type '(choice (const :tag "Never" nil)
(integer :tag "Seconds")))
(defvar password-data (make-vector 7 0))
(defvar password-data (make-hash-table :test #'equal))
(defun password-read-from-cache (key)
"Obtain passphrase for KEY from time-limited passphrase cache.
@ -74,20 +74,20 @@ Custom variables `password-cache' and `password-cache-expiry'
regulate cache behavior."
(and password-cache
key
(symbol-value (intern-soft key password-data))))
(gethash key password-data)))
;;;###autoload
(defun password-in-cache-p (key)
"Check if KEY is in the cache."
(and password-cache
key
(intern-soft key password-data)))
(gethash key password-data)))
(defun password-read (prompt &optional key)
"Read password, for use with KEY, from user, or from cache if wanted.
KEY indicate the purpose of the password, so the cache can
separate passwords. The cache is not used if KEY is nil. It is
typically a string.
separate passwords. The cache is not used if KEY is nil.
KEY is typically a string but can be anything (compared via `equal').
The variable `password-cache' control whether the cache is used."
(or (password-read-from-cache key)
(read-passwd prompt)))
@ -115,29 +115,27 @@ but can be invoked at any time to forcefully remove passwords
from the cache. This may be useful when it has been detected
that a password is invalid, so that `password-read' query the
user again."
(let ((sym (intern-soft key password-data)))
(when sym
(let ((password (symbol-value sym)))
(when (stringp password)
(if (fboundp 'clear-string)
(clear-string password)
(fillarray password ?_)))
(unintern key password-data)))))
(let ((password (gethash key password-data)))
(when (stringp password)
(if (fboundp 'clear-string)
(clear-string password)
(fillarray password ?_)))
(remhash key password-data)))
(defun password-cache-add (key password)
"Add password to cache.
The password is removed by a timer after `password-cache-expiry' seconds."
(when (and password-cache-expiry (null (intern-soft key password-data)))
(when (and password-cache-expiry (null (gethash key password-data)))
(run-at-time password-cache-expiry nil
#'password-cache-remove
key))
(set (intern key password-data) password)
(puthash key password password-data)
nil)
(defun password-reset ()
"Clear the password cache."
(interactive)
(fillarray password-data 0))
(clrhash password-data))
(provide 'password-cache)

View file

@ -215,7 +215,7 @@
(ert-deftest auth-source-test-remembrances-of-things-past ()
(let ((password-cache t)
(password-data (make-vector 7 0)))
(password-data (copy-hash-table password-data)))
(auth-source-remember '(:host "wedd") '(4 5 6))
(should (auth-source-remembered-p '(:host "wedd")))
(should-not (auth-source-remembered-p '(:host "xedd")))