;;; auth-source.el --- authentication sources for Gnus and Emacs
-;; Copyright (C) 2008-2012 Free Software Foundation, Inc.
+;; Copyright (C) 2008-2015 Free Software Foundation, Inc.
;; Author: Ted Zlatanov <tzz@lifelogs.com>
;; Keywords: news
(defcustom auth-sources '("~/.authinfo" "~/.authinfo.gpg" "~/.netrc")
"List of authentication sources.
-
-The default will get login and password information from
-\"~/.authinfo.gpg\", which you should set up with the EPA/EPG
-packages to be encrypted. If that file doesn't exist, it will
-try the unencrypted version \"~/.authinfo\" and the famous
-\"~/.netrc\" file.
-
-See the auth.info manual for details.
-
Each entry is the authentication type with optional properties.
+Entries are tried in the order in which they appear.
+See Info node `(auth)Help for users' for details.
+
+If an entry names a file with the \".gpg\" extension and you have
+EPA/EPG set up, the file will be encrypted and decrypted
+automatically. See Info node `(epa)Encrypting/decrypting gpg files'
+for details.
It's best to customize this with `M-x customize-variable' because the choices
can get pretty complex."
:type `(repeat :tag "Authentication Sources"
(choice
(string :tag "Just a file")
- (const :tag "Default Secrets API Collection" 'default)
+ (const :tag "Default Secrets API Collection" default)
(const :tag "Login Secrets API Collection" "secrets:Login")
(const :tag "Temp Secrets API Collection" "secrets:session")
(const :tag "Default internet Mac OS Keychain"
- 'macos-keychain-internet)
+ macos-keychain-internet)
(const :tag "Default generic Mac OS Keychain"
- 'macos-keychain-generic)
+ macos-keychain-generic)
(list :tag "Source definition"
(const :format "" :value :source)
(const :format "" :value :secrets)
(choice :tag "Collection to use"
(string :tag "Collection name")
- (const :tag "Default" 'default)
+ (const :tag "Default" default)
(const :tag "Login" "Login")
(const
:tag "Temporary" "session")))
:value :macos-keychain-internet)
(choice :tag "Collection to use"
(string :tag "internet Keychain path")
- (const :tag "default" 'default))))
+ (const :tag "default" default)))
(list
:tag "Mac OS generic Keychain"
(const :format ""
:value :macos-keychain-generic)
(choice :tag "Collection to use"
(string :tag "generic Keychain path")
- (const :tag "default" 'default))))
+ (const :tag "default" default))))
(repeat :tag "Extra Parameters" :inline t
(choice :tag "Extra parameter"
(list
'secrets are the only ones supported right now.
:max N means to try to return at most N items (defaults to 1).
-When 0 the function will return just t or nil to indicate if any
-matches were found. More than N items may be returned, depending
-on the search and the backend.
+More than N items may be returned, depending on the search and
+the backend.
+
+When :max is 0 the function will return just t or nil to indicate
+if any matches were found.
:host (X Y Z) means to match only hosts X, Y, or Z according to
the match rules above. Defaults to t.
(when auth-source-do-cache
(auth-source-remember spec found)))
- found))
+ (if (zerop max)
+ (not (null found))
+ found)))
(defun auth-source-search-backends (backends spec max create delete require)
- (let (matches)
+ (let ((max (if (zerop max) 1 max)) ; stop with 1 match if we're asked for zero
+ matches)
(dolist (backend backends)
- (when (> max (length matches)) ; when we need more matches...
+ (when (> max (length matches)) ; if we need more matches...
(let* ((bmatches (apply
(slot-value backend 'search-function)
:backend backend
:type (slot-value backend :type)
;; note we're overriding whatever the spec
- ;; has for :require, :create, and :delete
+ ;; has for :max, :require, :create, and :delete
+ :max max
:require require
:create create
:delete delete
(setq matches (append matches bmatches))))))
matches))
+;; (auth-source-search :max 0)
;; (auth-source-search :max 1)
;; (funcall (plist-get (nth 0 (auth-source-search :max 1)) :secret))
;; (auth-source-search :host "nonesuch" :type 'netrc :K 1)
(auth-source-search (plist-put spec :delete t)))
(defun auth-source-search-collection (collection value)
- "Returns t is VALUE is t or COLLECTION is t or contains VALUE."
+ "Returns t is VALUE is t or COLLECTION is t or COLLECTION contains VALUE."
(when (and (atom collection) (not (eq t collection)))
(setq collection (list collection)))
(when (and c v)
(setq prompt (replace-regexp-in-string (format "%%%c" c)
(format "%s" v)
- prompt)))))
+ prompt nil t)))))
prompt)
(defun auth-source-ensure-strings (values)
(defun auth-source--aget (alist key)
(cdr (assoc key alist)))
-;; (auth-source-netrc-parse "~/.authinfo.gpg")
+;; (auth-source-netrc-parse :file "~/.authinfo.gpg")
(defun* auth-source-netrc-parse (&rest
spec
&key file max host user port delete require
(when (file-exists-p file)
(setq port (auth-source-ensure-strings port))
(with-temp-buffer
- (let* ((tokens '("machine" "host" "default" "login" "user"
- "password" "account" "macdef" "force"
- "port" "protocol"))
- (max (or max 5000)) ; sanity check: default to stop at 5K
+ (let* ((max (or max 5000)) ; sanity check: default to stop at 5K
(modified 0)
(cached (cdr-safe (assoc file auth-source-netrc-cache)))
(cached-mtime (plist-get cached :mtime))
(cached-secrets (plist-get cached :secret))
- alist elem result pair)
+ (check (lambda(alist)
+ (and alist
+ (auth-source-search-collection
+ host
+ (or
+ (auth-source--aget alist "machine")
+ (auth-source--aget alist "host")
+ t))
+ (auth-source-search-collection
+ user
+ (or
+ (auth-source--aget alist "login")
+ (auth-source--aget alist "account")
+ (auth-source--aget alist "user")
+ t))
+ (auth-source-search-collection
+ port
+ (or
+ (auth-source--aget alist "port")
+ (auth-source--aget alist "protocol")
+ t))
+ (or
+ ;; the required list of keys is nil, or
+ (null require)
+ ;; every element of require is in n(ormalized)
+