Fix bug#5620: recalculate all markers on compilation buffer
[emacs.git] / lisp / gnus / auth-source.el
blob3b0d700a86f3a46d36cf2441bd76d9b3fb85b442
1 ;;; auth-source.el --- authentication sources for Gnus and Emacs
3 ;; Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
5 ;; Author: Ted Zlatanov <tzz@lifelogs.com>
6 ;; Keywords: news
8 ;; This file is part of GNU Emacs.
10 ;; GNU Emacs is free software: you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation, either version 3 of the License, or
13 ;; (at your option) any later version.
15 ;; GNU Emacs is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
23 ;;; Commentary:
25 ;; This is the auth-source.el package. It lets users tell Gnus how to
26 ;; authenticate in a single place. Simplicity is the goal. Instead
27 ;; of providing 5000 options, we'll stick to simple, easy to
28 ;; understand options.
30 ;; See the auth.info Info documentation for details.
32 ;;; Code:
34 (require 'gnus-util)
36 (eval-when-compile (require 'cl))
37 (autoload 'netrc-machine-user-or-password "netrc")
38 (autoload 'secrets-search-items "secrets")
39 (autoload 'secrets-get-alias "secrets")
40 (autoload 'secrets-get-attribute "secrets")
42 (defgroup auth-source nil
43 "Authentication sources."
44 :version "23.1" ;; No Gnus
45 :group 'gnus)
47 (defcustom auth-source-protocols '((imap "imap" "imaps" "143" "993")
48 (pop3 "pop3" "pop" "pop3s" "110" "995")
49 (ssh "ssh" "22")
50 (sftp "sftp" "115")
51 (smtp "smtp" "25"))
52 "List of authentication protocols and their names"
54 :group 'auth-source
55 :version "23.2" ;; No Gnus
56 :type '(repeat :tag "Authentication Protocols"
57 (cons :tag "Protocol Entry"
58 (symbol :tag "Protocol")
59 (repeat :tag "Names"
60 (string :tag "Name")))))
62 ;;; generate all the protocols in a format Customize can use
63 (defconst auth-source-protocols-customize
64 (mapcar (lambda (a)
65 (let ((p (car-safe a)))
66 (list 'const
67 :tag (upcase (symbol-name p))
68 p)))
69 auth-source-protocols))
71 (defvar auth-source-cache (make-hash-table :test 'equal)
72 "Cache for auth-source data")
74 (defcustom auth-source-do-cache t
75 "Whether auth-source should cache information."
76 :group 'auth-source
77 :version "23.2" ;; No Gnus
78 :type `boolean)
80 (defcustom auth-source-debug nil
81 "Whether auth-source should log debug messages.
82 Also see `auth-source-hide-passwords'.
84 If the value is nil, debug messages are not logged.
85 If the value is t, debug messages are logged with `message'.
86 In that case, your authentication data will be in the
87 clear (except for passwords, which are always stripped out).
88 If the value is a function, debug messages are logged by calling
89 that function using the same arguments as `message'."
90 :group 'auth-source
91 :version "23.2" ;; No Gnus
92 :type `(choice
93 :tag "auth-source debugging mode"
94 (const :tag "Log using `message' to the *Messages* buffer" t)
95 (function :tag "Function that takes arguments like `message'")
96 (const :tag "Don't log anything" nil)))
98 (defcustom auth-source-hide-passwords t
99 "Whether auth-source should hide passwords in log messages.
100 Only relevant if `auth-source-debug' is not nil."
101 :group 'auth-source
102 :version "23.2" ;; No Gnus
103 :type `boolean)
105 (defcustom auth-sources '((:source "~/.authinfo.gpg" :host t :protocol t))
106 "List of authentication sources.
108 Each entry is the authentication type with optional properties.
110 It's best to customize this with `M-x customize-variable' because the choices
111 can get pretty complex."
112 :group 'auth-source
113 :version "23.2" ;; No Gnus
114 :type `(repeat :tag "Authentication Sources"
115 (list :tag "Source definition"
116 (const :format "" :value :source)
117 (choice :tag "Authentication backend choice"
118 (string :tag "Authentication Source (file)")
119 (list :tag "secrets.el (Secret Service API/KWallet/GNOME KeyRing)"
120 (const :format "" :value :secrets)
121 (choice :tag "Collection to use"
122 (string :tag "Collection name")
123 (const :tag "Default" 'default)
124 (const :tag "Any" t)
125 (const :tag "Temporary" "session")
126 (string :tag "Specific session name")
127 (const :tag "Fallback" nil))))
128 (const :format "" :value :host)
129 (choice :tag "Host (machine) choice"
130 (const :tag "Any" t)
131 (regexp :tag "Host (machine) regular expression (TODO)")
132 (const :tag "Fallback" nil))
133 (const :format "" :value :protocol)
134 (choice :tag "Protocol"
135 (const :tag "Any" t)
136 (const :tag "Fallback" nil)
137 ,@auth-source-protocols-customize)
138 (repeat :tag "Extra Parameters" :inline t
139 (choice :tag "Extra parameter"
140 (list :tag "Preferred username" :inline t
141 (const :format "" :value :preferred-username)
142 (choice :tag "Personality or username"
143 (const :tag "Any" t)
144 (const :tag "Fallback" nil)
145 (string :tag "Specific user name"))))))))
147 ;; temp for debugging
148 ;; (unintern 'auth-source-protocols)
149 ;; (unintern 'auth-sources)
150 ;; (customize-variable 'auth-sources)
151 ;; (setq auth-sources nil)
152 ;; (format "%S" auth-sources)
153 ;; (customize-variable 'auth-source-protocols)
154 ;; (setq auth-source-protocols nil)
155 ;; (format "%S" auth-source-protocols)
156 ;; (auth-source-pick "a" 'imap)
157 ;; (auth-source-user-or-password "login" "imap.myhost.com" 'imap)
158 ;; (auth-source-user-or-password "password" "imap.myhost.com" 'imap)
159 ;; (auth-source-user-or-password-imap "login" "imap.myhost.com")
160 ;; (auth-source-user-or-password-imap "password" "imap.myhost.com")
161 ;; (auth-source-protocol-defaults 'imap)
163 ;; (let ((auth-source-debug 'debug)) (auth-source-debug "hello"))
164 ;; (let ((auth-source-debug t)) (auth-source-debug "hello"))
165 ;; (let ((auth-source-debug nil)) (auth-source-debug "hello"))
166 (defun auth-source-do-debug (&rest msg)
167 ;; set logger to either the function in auth-source-debug or 'message
168 ;; note that it will be 'message if auth-source-debug is nil, so
169 ;; we also check the value
170 (when auth-source-debug
171 (let ((logger (if (functionp auth-source-debug)
172 auth-source-debug
173 'message)))
174 (apply logger msg))))
176 (defun auth-source-pick (host protocol &optional fallback)
177 "Parse `auth-sources' for HOST, and PROTOCOL matches.
179 Returns fallback choices (where PROTOCOL or HOST are nil) with FALLBACK t."
180 (interactive "sHost: \nsProtocol: \n") ;for testing
181 (let (choices)
182 (dolist (choice auth-sources)
183 (let ((h (plist-get choice :host))
184 (p (plist-get choice :protocol)))
185 (when (and
186 (or (equal t h)
187 (and (stringp h) (string-match h host))
188 (and fallback (equal h nil)))
189 (or (equal t p)
190 (and (symbolp p) (equal p protocol))
191 (and fallback (equal p nil))))
192 (push choice choices))))
193 (if choices
194 choices
195 (unless fallback
196 (auth-source-pick host protocol t)))))
198 (defun auth-source-forget-user-or-password (mode host protocol)
199 (interactive "slogin/password: \nsHost: \nsProtocol: \n") ;for testing
200 (remhash (format "%s %s:%s" mode host protocol) auth-source-cache))
202 (defun auth-source-forget-all-cached ()
203 "Forget all cached auth-source authentication tokens."
204 (interactive)
205 (setq auth-source-cache (make-hash-table :test 'equal)))
207 (defun auth-source-user-or-password (mode host protocol)
208 "Find MODE (string or list of strings) matching HOST and PROTOCOL.
209 MODE can be \"login\" or \"password\" for example."
210 (auth-source-do-debug
211 "auth-source-user-or-password: get %s for %s (%s)"
212 mode host protocol)
213 (let* ((listy (listp mode))
214 (mode (if listy mode (list mode)))
215 (cname (format "%s %s:%s" mode host protocol))
216 (found (gethash cname auth-source-cache)))
217 (if found
218 (progn
219 (auth-source-do-debug
220 "auth-source-user-or-password: cached %s=%s for %s (%s)"
221 mode
222 ;; don't show the password
223 (if (and (member "password" mode) auth-source-hide-passwords) "SECRET" found)
224 host protocol)
225 found)
226 (dolist (choice (auth-source-pick host protocol))
227 (setq found (netrc-machine-user-or-password
228 mode
229 (plist-get choice :source)
230 (list host)
231 (list (format "%s" protocol))
232 (auth-source-protocol-defaults protocol)))
233 (when found
234 (auth-source-do-debug
235 "auth-source-user-or-password: found %s=%s for %s (%s)"
236 mode
237 ;; don't show the password
238 (if (and (member "password" mode) auth-source-hide-passwords) "SECRET" found)
239 host protocol)
240 (setq found (if listy found (car-safe found)))
241 (when auth-source-do-cache
242 (puthash cname found auth-source-cache)))
243 (return found)))))
245 (defun auth-source-protocol-defaults (protocol)
246 "Return a list of default ports and names for PROTOCOL."
247 (cdr-safe (assoc protocol auth-source-protocols)))
249 (defun auth-source-user-or-password-imap (mode host)
250 (auth-source-user-or-password mode host 'imap))
252 (defun auth-source-user-or-password-pop3 (mode host)
253 (auth-source-user-or-password mode host 'pop3))
255 (defun auth-source-user-or-password-ssh (mode host)
256 (auth-source-user-or-password mode host 'ssh))
258 (defun auth-source-user-or-password-sftp (mode host)
259 (auth-source-user-or-password mode host 'sftp))
261 (defun auth-source-user-or-password-smtp (mode host)
262 (auth-source-user-or-password mode host 'smtp))
264 (provide 'auth-source)
266 ;; arch-tag: ff1afe78-06e9-42c2-b693-e9f922cbe4ab
267 ;;; auth-source.el ends here