summaryrefslogtreecommitdiff
path: root/lisp/gnus/auth-source.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/gnus/auth-source.el')
-rw-r--r--lisp/gnus/auth-source.el164
1 files changed, 91 insertions, 73 deletions
diff --git a/lisp/gnus/auth-source.el b/lisp/gnus/auth-source.el
index 34fe5afe7af..47359500dc4 100644
--- a/lisp/gnus/auth-source.el
+++ b/lisp/gnus/auth-source.el
@@ -42,7 +42,6 @@
(require 'password-cache)
(require 'mm-util)
(require 'gnus-util)
-(require 'assoc)
(eval-when-compile (require 'cl))
(require 'eieio)
@@ -92,9 +91,9 @@ let-binding."
(const :tag "30 Minutes" 1800)
(integer :tag "Seconds")))
-;;; The slots below correspond with the `auth-source-search' spec,
-;;; so a backend with :host set, for instance, would match only
-;;; searches for that host. Normally they are nil.
+;; The slots below correspond with the `auth-source-search' spec,
+;; so a backend with :host set, for instance, would match only
+;; searches for that host. Normally they are nil.
(defclass auth-source-backend ()
((type :initarg :type
:initform 'netrc
@@ -149,8 +148,8 @@ let-binding."
(repeat :tag "Names"
(string :tag "Name")))))
-;;; generate all the protocols in a format Customize can use
-;;; TODO: generate on the fly from auth-source-protocols
+;; Generate all the protocols in a format Customize can use.
+;; TODO: generate on the fly from auth-source-protocols
(defconst auth-source-protocols-customize
(mapcar (lambda (a)
(let ((p (car-safe a)))
@@ -339,7 +338,7 @@ If the value is not a list, symmetric encryption will be used."
msg))
-;;; (auth-source-read-char-choice "enter choice? " '(?a ?b ?q))
+;; (auth-source-read-char-choice "enter choice? " '(?a ?b ?q))
(defun auth-source-read-char-choice (prompt choices)
"Read one of CHOICES by `read-char-choice', or `read-char'.
`dropdown-list' support is disabled because it doesn't work reliably.
@@ -711,10 +710,10 @@ must call it to obtain the actual value."
(setq matches (append matches bmatches))))))
matches))
-;;; (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 :host "nonesuch" :type 'secrets)
+;; (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 :host "nonesuch" :type 'secrets)
(defun* auth-source-delete (&rest spec
&key delete
@@ -776,16 +775,16 @@ This is the same SPEC you passed to `auth-source-search'.
Returns t or nil for forgotten or not found."
(password-cache-remove (auth-source-format-cache-entry spec)))
-;;; (loop for sym being the symbols of password-data when (string-match (concat "^" auth-source-magic) (symbol-name sym)) collect (symbol-name sym))
+;; (loop for sym being the symbols of password-data when (string-match (concat "^" auth-source-magic) (symbol-name sym)) collect (symbol-name sym))
-;;; (auth-source-remember '(:host "wedd") '(4 5 6))
-;;; (auth-source-remembered-p '(:host "wedd"))
-;;; (auth-source-remember '(:host "xedd") '(1 2 3))
-;;; (auth-source-remembered-p '(:host "xedd"))
-;;; (auth-source-remembered-p '(:host "zedd"))
-;;; (auth-source-recall '(:host "xedd"))
-;;; (auth-source-recall '(:host t))
-;;; (auth-source-forget+ :host t)
+;; (auth-source-remember '(:host "wedd") '(4 5 6))
+;; (auth-source-remembered-p '(:host "wedd"))
+;; (auth-source-remember '(:host "xedd") '(1 2 3))
+;; (auth-source-remembered-p '(:host "xedd"))
+;; (auth-source-remembered-p '(:host "zedd"))
+;; (auth-source-recall '(:host "xedd"))
+;; (auth-source-recall '(:host t))
+;; (auth-source-forget+ :host t)
(defun* auth-source-forget+ (&rest spec &allow-other-keys)
"Forget any cached data matching SPEC. Returns forgotten count.
@@ -819,8 +818,8 @@ while \(:host t) would find all host entries."
(return 'no)))
'no))))
-;;; (auth-source-pick-first-password :host "z.lifelogs.com")
-;;; (auth-source-pick-first-password :port "imap")
+;; (auth-source-pick-first-password :host "z.lifelogs.com")
+;; (auth-source-pick-first-password :port "imap")
(defun auth-source-pick-first-password (&rest spec)
"Pick the first secret found from applying SPEC to `auth-source-search'."
(let* ((result (nth 0 (apply 'auth-source-search (plist-put spec :max 1))))
@@ -853,7 +852,22 @@ while \(:host t) would find all host entries."
;;; Backend specific parsing: netrc/authinfo backend
-;;; (auth-source-netrc-parse "~/.authinfo.gpg")
+(defun auth-source--aput-1 (alist key val)
+ (let ((seen ())
+ (rest alist))
+ (while (and (consp rest) (not (equal key (caar rest))))
+ (push (pop rest) seen))
+ (cons (cons key val)
+ (if (null rest) alist
+ (nconc (nreverse seen)
+ (if (equal key (caar rest)) (cdr rest) rest))))))
+(defmacro auth-source--aput (var key val)
+ `(setq ,var (auth-source--aput-1 ,var ,key ,val)))
+
+(defun auth-source--aget (alist key)
+ (cdr (assoc key alist)))
+
+;; (auth-source-netrc-parse "~/.authinfo.gpg")
(defun* auth-source-netrc-parse (&rest
spec
&key file max host user port delete require
@@ -888,10 +902,11 @@ Note that the MAX parameter is used so we can exit the parse early."
;; cache all netrc files (used to be just .gpg files)
;; Store the contents of the file heavily encrypted in memory.
;; (note for the irony-impaired: they are just obfuscated)
- (aput 'auth-source-netrc-cache file
- (list :mtime (nth 5 (file-attributes file))
- :secret (lexical-let ((v (mapcar '1+ (buffer-string))))
- (lambda () (apply 'string (mapcar '1- v)))))))
+ (auth-source--aput
+ auth-source-netrc-cache file
+ (list :mtime (nth 5 (file-attributes file))
+ :secret (lexical-let ((v (mapcar '1+ (buffer-string))))
+ (lambda () (apply 'string (mapcar '1- v)))))))
(goto-char (point-min))
;; Go through the file, line by line.
(while (and (not (eobp))
@@ -937,21 +952,21 @@ Note that the MAX parameter is used so we can exit the parse early."
(auth-source-search-collection
host
(or
- (aget alist "machine")
- (aget alist "host")
+ (auth-source--aget alist "machine")
+ (auth-source--aget alist "host")
t))
(auth-source-search-collection
user
(or
- (aget alist "login")
- (aget alist "account")
- (aget alist "user")
+ (auth-source--aget alist "login")
+ (auth-source--aget alist "account")
+ (auth-source--aget alist "user")
t))
(auth-source-search-collection
port
(or
- (aget alist "port")
- (aget alist "protocol")
+ (auth-source--aget alist "port")
+ (auth-source--aget alist "protocol")
t))
(or
;; the required list of keys is nil, or
@@ -1086,8 +1101,8 @@ FILE is the file from which we obtained this token."
ret))
alist))
-;;; (setq secret (plist-get (nth 0 (auth-source-search :host t :type 'netrc :K 1 :max 1)) :secret))
-;;; (funcall secret)
+;; (setq secret (plist-get (nth 0 (auth-source-search :host t :type 'netrc :K 1 :max 1)) :secret))
+;; (funcall secret)
(defun* auth-source-netrc-search (&rest
spec
@@ -1133,8 +1148,8 @@ See `auth-source-search' for details on SPEC."
(nth 0 v)
v))
-;;; (auth-source-search :host "nonesuch" :type 'netrc :max 1 :create t)
-;;; (auth-source-search :host "nonesuch" :type 'netrc :max 1 :create t :create-extra-keys '((A "default A") (B)))
+;; (auth-source-search :host "nonesuch" :type 'netrc :max 1 :create t)
+;; (auth-source-search :host "nonesuch" :type 'netrc :max 1 :create t :create-extra-keys '((A "default A") (B)))
(defun* auth-source-netrc-create (&rest spec
&key backend
@@ -1166,7 +1181,7 @@ See `auth-source-search' for details on SPEC."
;; just the value otherwise
(t (symbol-value br)))))
(when br-choice
- (aput 'valist br br-choice)))))
+ (auth-source--aput valist br br-choice)))))
;; for extra required elements, see if the spec includes a value for them
(dolist (er create-extra)
@@ -1175,17 +1190,18 @@ See `auth-source-search' for details on SPEC."
collect (nth i spec))))
(dolist (k keys)
(when (equal (symbol-name k) name)
- (aput 'valist er (plist-get spec k))))))
+ (auth-source--aput valist er (plist-get spec k))))))
;; for each required element
(dolist (r required)
- (let* ((data (aget valist r))
+ (let* ((data (auth-source--aget valist r))
;; take the first element if the data is a list
(data (or (auth-source-netrc-element-or-first data)
(plist-get current-data
(intern (format ":%s" r) obarray))))
;; this is the default to be offered
- (given-default (aget auth-source-creation-defaults r))
+ (given-default (auth-source--aget
+ auth-source-creation-defaults r))
;; the default supplementals are simple:
;; for the user, try `given-default' and then (user-login-name);
;; otherwise take `given-default'
@@ -1197,22 +1213,22 @@ See `auth-source-search' for details on SPEC."
(cons 'user
(or
(auth-source-netrc-element-or-first
- (aget valist 'user))
+ (auth-source--aget valist 'user))
(plist-get artificial :user)
"[any user]"))
(cons 'host
(or
(auth-source-netrc-element-or-first
- (aget valist 'host))
+ (auth-source--aget valist 'host))
(plist-get artificial :host)
"[any host]"))
(cons 'port
(or
(auth-source-netrc-element-or-first
- (aget valist 'port))
+ (auth-source--aget valist 'port))
(plist-get artificial :port)
"[any port]"))))
- (prompt (or (aget auth-source-creation-prompts r)
+ (prompt (or (auth-source--aget auth-source-creation-prompts r)
(case r
(secret "%p password for %u@%h: ")
(user "%p user name for %h: ")
@@ -1221,9 +1237,9 @@ See `auth-source-search' for details on SPEC."
(format "Enter %s (%%u@%%h:%%p): " r)))
(prompt (auth-source-format-prompt
prompt
- `((?u ,(aget printable-defaults 'user))
- (?h ,(aget printable-defaults 'host))
- (?p ,(aget printable-defaults 'port))))))
+ `((?u ,(auth-source--aget printable-defaults 'user))
+ (?h ,(auth-source--aget printable-defaults 'host))
+ (?p ,(auth-source--aget printable-defaults 'port))))))
;; Store the data, prompting for the password if needed.
(setq data (or data
@@ -1384,16 +1400,16 @@ Respects `auth-source-save-behavior'. Uses
file)
(message "Saved new authentication information to %s" file)
nil))))
- (aput 'auth-source-netrc-cache key "ran"))))
+ (auth-source--aput auth-source-netrc-cache key "ran"))))
;;; Backend specific parsing: Secrets API backend
-;;; (let ((auth-sources '(default))) (auth-source-search :max 1 :create t))
-;;; (let ((auth-sources '(default))) (auth-source-search :max 1 :delete t))
-;;; (let ((auth-sources '(default))) (auth-source-search :max 1))
-;;; (let ((auth-sources '(default))) (auth-source-search))
-;;; (let ((auth-sources '("secrets:Login"))) (auth-source-search :max 1))
-;;; (let ((auth-sources '("secrets:Login"))) (auth-source-search :max 1 :signon_realm "https://git.gnus.org/Git"))
+;; (let ((auth-sources '(default))) (auth-source-search :max 1 :create t))
+;; (let ((auth-sources '(default))) (auth-source-search :max 1 :delete t))
+;; (let ((auth-sources '(default))) (auth-source-search :max 1))
+;; (let ((auth-sources '(default))) (auth-source-search))
+;; (let ((auth-sources '("secrets:Login"))) (auth-source-search :max 1))
+;; (let ((auth-sources '("secrets:Login"))) (auth-source-search :max 1 :signon_realm "https://git.gnus.org/Git"))
(defun* auth-source-secrets-search (&rest
spec
@@ -1609,7 +1625,7 @@ authentication tokens:
;; just the value otherwise
(t (symbol-value br)))))
(when br-choice
- (aput 'valist br br-choice)))))
+ (auth-source--aput valist br br-choice)))))
;; for extra required elements, see if the spec includes a value for them
(dolist (er create-extra)
@@ -1618,17 +1634,18 @@ authentication tokens:
collect (nth i spec))))
(dolist (k keys)
(when (equal (symbol-name k) name)
- (aput 'valist er (plist-get spec k))))))
+ (auth-source--aput valist er (plist-get spec k))))))
;; for each required element
(dolist (r required)
- (let* ((data (aget valist r))
+ (let* ((data (auth-source--aget valist r))
;; take the first element if the data is a list
(data (or (auth-source-netrc-element-or-first data)
(plist-get current-data
(intern (format ":%s" r) obarray))))
;; this is the default to be offered
- (given-default (aget auth-source-creation-defaults r))
+ (given-default (auth-source--aget
+ auth-source-creation-defaults r))
;; the default supplementals are simple:
;; for the user, try `given-default' and then (user-login-name);
;; otherwise take `given-default'
@@ -1640,22 +1657,22 @@ authentication tokens:
(cons 'user
(or
(auth-source-netrc-element-or-first
- (aget valist 'user))
+ (auth-source--aget valist 'user))
(plist-get artificial :user)
"[any user]"))
(cons 'host
(or
(auth-source-netrc-element-or-first
- (aget valist 'host))
+ (auth-source--aget valist 'host))
(plist-get artificial :host)
"[any host]"))
(cons 'port
(or
(auth-source-netrc-element-or-first
- (aget valist 'port))
+ (auth-source--aget valist 'port))
(plist-get artificial :port)
"[any port]"))))
- (prompt (or (aget auth-source-creation-prompts r)
+ (prompt (or (auth-source--aget auth-source-creation-prompts r)
(case r
(secret "%p password for %u@%h: ")
(user "%p user name for %h: ")
@@ -1664,20 +1681,21 @@ authentication tokens:
(format "Enter %s (%%u@%%h:%%p): " r)))
(prompt (auth-source-format-prompt
prompt
- `((?u ,(aget printable-defaults 'user))
- (?h ,(aget printable-defaults 'host))
- (?p ,(aget printable-defaults 'port))))))
+ `((?u ,(auth-source--aget printable-defaults 'user))
+ (?h ,(auth-source--aget printable-defaults 'host))
+ (?p ,(auth-source--aget printable-defaults 'port))))))
;; Store the data, prompting for the password if needed.
(setq data (or data
(if (eq r 'secret)
(or (eval default) (read-passwd prompt))
(if (stringp default)
- (read-string (if (string-match ": *\\'" prompt)
- (concat (substring prompt 0 (match-beginning 0))
- " (default " default "): ")
- (concat prompt "(default " default ") "))
- nil nil default)
+ (read-string
+ (if (string-match ": *\\'" prompt)
+ (concat (substring prompt 0 (match-beginning 0))
+ " (default " default "): ")
+ (concat prompt "(default " default ") "))
+ nil nil default)
(eval default)))))
(when data
@@ -1701,7 +1719,7 @@ authentication tokens:
;;; older API
-;;; (auth-source-user-or-password '("login" "password") "imap.myhost.com" t "tzz")
+;; (auth-source-user-or-password '("login" "password") "imap.myhost.com" t "tzz")
;; deprecate the old interface
(make-obsolete 'auth-source-user-or-password