diff options
| author | Michael Albinus | 2010-06-08 15:05:11 +0200 |
|---|---|---|
| committer | Michael Albinus | 2010-06-08 15:05:11 +0200 |
| commit | 0e4966fb65bb4374d334d127ad1de1f55f5c86c8 (patch) | |
| tree | 30e5a39e556d7c521cc3b87dad912a7f11a15fc8 /lisp | |
| parent | d7c5d87df66ddde23546e919ca4078f00be4d20b (diff) | |
| download | emacs-0e4966fb65bb4374d334d127ad1de1f55f5c86c8.tar.gz emacs-0e4966fb65bb4374d334d127ad1de1f55f5c86c8.zip | |
* auth-source.el (top): Autoload `secrets-list-collections',
`secrets-create-item', `secrets-delete-item'.
(auth-sources): Fix tag string.
(auth-get-source, auth-source-retrieve, auth-source-create)
(auth-source-delete): New defuns.
(auth-source-pick): Rewrite in order to avoid 2 passes.
(auth-source-forget-user-or-password): New parameter USERNAME.
(auth-source-user-or-password): New parameters CREATE-MISSING and
DELETE-EXISTING. Retrieve password interactively, if needed.
Diffstat (limited to 'lisp')
| -rw-r--r-- | lisp/gnus/ChangeLog | 12 | ||||
| -rw-r--r-- | lisp/gnus/auth-source.el | 345 |
2 files changed, 218 insertions, 139 deletions
diff --git a/lisp/gnus/ChangeLog b/lisp/gnus/ChangeLog index 3ab4ed98aca..5be038b5519 100644 --- a/lisp/gnus/ChangeLog +++ b/lisp/gnus/ChangeLog | |||
| @@ -1,3 +1,15 @@ | |||
| 1 | 2010-06-08 Michael Albinus <michael.albinus@gmx.de> | ||
| 2 | |||
| 3 | * auth-source.el (top): Autoload `secrets-list-collections', | ||
| 4 | `secrets-create-item', `secrets-delete-item'. | ||
| 5 | (auth-sources): Fix tag string. | ||
| 6 | (auth-get-source, auth-source-retrieve, auth-source-create) | ||
| 7 | (auth-source-delete): New defuns. | ||
| 8 | (auth-source-pick): Rewrite in order to avoid 2 passes. | ||
| 9 | (auth-source-forget-user-or-password): New parameter USERNAME. | ||
| 10 | (auth-source-user-or-password): New parameters CREATE-MISSING and | ||
| 11 | DELETE-EXISTING. Retrieve password interactively, if needed. | ||
| 12 | |||
| 1 | 2010-06-07 Teemu Likonen <tlikonen@iki.fi> (tiny change) | 13 | 2010-06-07 Teemu Likonen <tlikonen@iki.fi> (tiny change) |
| 2 | 14 | ||
| 3 | * gnus-agent.el (gnus-agent-expire-unagentized-dirs): Don't ask about | 15 | * gnus-agent.el (gnus-agent-expire-unagentized-dirs): Don't ask about |
diff --git a/lisp/gnus/auth-source.el b/lisp/gnus/auth-source.el index a5e323c0395..89b2ef3d11d 100644 --- a/lisp/gnus/auth-source.el +++ b/lisp/gnus/auth-source.el | |||
| @@ -35,10 +35,13 @@ | |||
| 35 | 35 | ||
| 36 | (eval-when-compile (require 'cl)) | 36 | (eval-when-compile (require 'cl)) |
| 37 | (autoload 'netrc-machine-user-or-password "netrc") | 37 | (autoload 'netrc-machine-user-or-password "netrc") |
| 38 | (autoload 'secrets-search-items "secrets") | 38 | (autoload 'secrets-create-item "secrets") |
| 39 | (autoload 'secrets-delete-item "secrets") | ||
| 39 | (autoload 'secrets-get-alias "secrets") | 40 | (autoload 'secrets-get-alias "secrets") |
| 40 | (autoload 'secrets-get-attribute "secrets") | 41 | (autoload 'secrets-get-attribute "secrets") |
| 41 | (autoload 'secrets-get-secret "secrets") | 42 | (autoload 'secrets-get-secret "secrets") |
| 43 | (autoload 'secrets-list-collections "secrets") | ||
| 44 | (autoload 'secrets-search-items "secrets") | ||
| 42 | 45 | ||
| 43 | (defgroup auth-source nil | 46 | (defgroup auth-source nil |
| 44 | "Authentication sources." | 47 | "Authentication sources." |
| @@ -122,7 +125,7 @@ can get pretty complex." | |||
| 122 | (const :format "" :value :source) | 125 | (const :format "" :value :source) |
| 123 | (choice :tag "Authentication backend choice" | 126 | (choice :tag "Authentication backend choice" |
| 124 | (string :tag "Authentication Source (file)") | 127 | (string :tag "Authentication Source (file)") |
| 125 | (list :tag "secrets.el (Secret Service API/KWallet/GNOME KeyRing)" | 128 | (list :tag "secrets.el (Secret Service API/KWallet/GNOME Keyring)" |
| 126 | (const :format "" :value :secrets) | 129 | (const :format "" :value :secrets) |
| 127 | (choice :tag "Collection to use" | 130 | (choice :tag "Collection to use" |
| 128 | (string :tag "Collection name") | 131 | (string :tag "Collection name") |
| @@ -178,123 +181,182 @@ can get pretty complex." | |||
| 178 | 181 | ||
| 179 | ;; (auth-source-pick nil :host "any" :protocol 'imap :user "joe") | 182 | ;; (auth-source-pick nil :host "any" :protocol 'imap :user "joe") |
| 180 | ;; (auth-source-pick t :host "any" :protocol 'imap :user "joe") | 183 | ;; (auth-source-pick t :host "any" :protocol 'imap :user "joe") |
| 181 | ;; (setq auth-sources '((:source (:secrets default) :host t :protocol t :user "joe") | 184 | ;; (setq auth-sources '((:source (:secrets default) :host t :protocol t :user "joe") |
| 182 | ;; (:source (:secrets "session") :host t :protocol t :user "joe") | 185 | ;; (:source (:secrets "session") :host t :protocol t :user "joe") |
| 183 | ;; (:source (:secrets "login") :host t :protocol t) | 186 | ;; (:source (:secrets "login") :host t :protocol t) |
| 184 | ;; (:source "~/.authinfo.gpg" :host t :protocol t))) | 187 | ;; (:source "~/.authinfo.gpg" :host t :protocol t))) |
| 185 | 188 | ||
| 186 | ;; (setq auth-sources '((:source (:secrets default) :host t :protocol t :user "joe") | 189 | ;; (setq auth-sources '((:source (:secrets default) :host t :protocol t :user "joe") |
| 187 | ;; (:source (:secrets "session") :host t :protocol t :user "joe") | 190 | ;; (:source (:secrets "session") :host t :protocol t :user "joe") |
| 188 | ;; (:source (:secrets "login") :host t :protocol t) | 191 | ;; (:source (:secrets "login") :host t :protocol t) |
| 189 | ;; )) | 192 | ;; )) |
| 190 | 193 | ||
| 191 | ;; (setq auth-sources '((:source "~/.authinfo.gpg" :host t :protocol t))) | 194 | ;; (setq auth-sources '((:source "~/.authinfo.gpg" :host t :protocol t))) |
| 192 | 195 | ||
| 196 | (defun auth-get-source (entry) | ||
| 197 | "Return the source string of ENTRY, which is one entry in `auth-sources'. | ||
| 198 | If it is a Secret Service API, return the collection name, otherwise | ||
| 199 | the file name." | ||
| 200 | (let ((source (plist-get entry :source))) | ||
| 201 | (if (stringp source) | ||
| 202 | source | ||
| 203 | ;; Secret Service API. | ||
| 204 | (setq source (plist-get source :secrets)) | ||
| 205 | (when (eq source 'default) | ||
| 206 | (setq source (or (secrets-get-alias "default") "login"))) | ||
| 207 | (or source "session")))) | ||
| 208 | |||
| 193 | (defun auth-source-pick (&rest spec) | 209 | (defun auth-source-pick (&rest spec) |
| 194 | "Parse `auth-sources' for matches of the SPEC plist. | 210 | "Parse `auth-sources' for matches of the SPEC plist. |
| 195 | 211 | ||
| 196 | Common keys are :host, :protocol, and :user. A value of t in | 212 | Common keys are :host, :protocol, and :user. A value of t in |
| 197 | SPEC means to always succeed in the match. A string value is | 213 | SPEC means to always succeed in the match. A string value is |
| 198 | matched as a regex. | 214 | matched as a regex." |
| 199 | 215 | (let ((keys (loop for i below (length spec) by 2 collect (nth i spec))) | |
| 200 | The first pass skips fallback choices. If no choices are found | 216 | choices) |
| 201 | on the first pass, a second pass is made including the fallback | 217 | (dolist (choice (copy-tree auth-sources) choices) |
| 202 | choices. | 218 | (let ((source (plist-get choice :source)) |
| 203 | 219 | (match t)) | |
| 204 | For string (filename) sources, fallback choices are those where | 220 | (when |
| 205 | PROTOCOL or HOST are nil. | 221 | (and |
| 206 | 222 | ;; Check existence of source. | |
| 207 | For secrets.el collections, the :host and :protocol keys are not | 223 | (if (consp source) |
| 208 | checked for fallback choices." | 224 | ;; Secret Service API. |
| 209 | (let (choices) | 225 | (member (auth-get-source choice) (secrets-list-collections)) |
| 210 | (dolist (fallback '(nil t)) | 226 | ;; authinfo file. |
| 211 | (let ((keys (loop for i below (length spec) by 2 | 227 | (file-exists-p source)) |
| 212 | collect (nth i spec))) | 228 | |
| 213 | (default-session-fallback "login")) | 229 | ;; Check keywords. |
| 214 | (dolist (choice auth-sources) | 230 | (dolist (k keys match) |
| 215 | (let* ((s (plist-get choice :source)) | 231 | (let* ((v (plist-get spec k)) |
| 216 | ;; this is only set for Secret Service API specs (see secrets.el) | 232 | (choicev (plist-get choice k))) |
| 217 | (coll (and (consp s) (plist-get s :secrets))) | 233 | (setq match |
| 218 | (score 0)) | 234 | (and match |
| 219 | (cond | 235 | (or |
| 220 | (coll ; use secrets.el here | 236 | ;; source always matches spec key |
| 221 | (when (eq coll 'default) | 237 | (eq t choicev) |
| 222 | (setq coll (secrets-get-alias "default")) | 238 | ;; source key gives regex to match against spec |
| 223 | (unless coll | 239 | (and (stringp choicev) (string-match choicev v)) |
| 224 | (auth-source-do-debug | 240 | ;; source key gives symbol to match against spec |
| 225 | "No 'default' alias. Trying collection '%s'." | 241 | (and (symbolp choicev) (eq choicev v)))))))) |
| 226 | default-session-fallback) | 242 | |
| 227 | (setq coll default-session-fallback))) | 243 | (add-to-list 'choices choice 'append)))))) |
| 228 | (let* ((coll-search (cond | 244 | |
| 229 | ((stringp coll) coll) | 245 | (defun auth-source-retrieve (mode entry &rest spec) |
| 230 | 246 | "Retrieve MODE credentials according to SPEC from ENTRY." | |
| 231 | ;; when the collection is nil: | 247 | (catch 'no-password |
| 232 | ;; in fallback mode, accept it as any | 248 | (let ((host (plist-get spec :host)) |
| 233 | ;; otherwise, hope to fail | 249 | (user (plist-get spec :user)) |
| 234 | ((null coll) (if fallback | 250 | (prot (plist-get spec :protocol)) |
| 235 | nil | 251 | (source (plist-get entry :source)) |
| 236 | " *fallback-fail*")))) | 252 | result) |
| 237 | ;; assemble a search query for secrets-search-items | 253 | (cond |
| 238 | ;; in fallback mode, host and protocol are not checked | 254 | ;; Secret Service API. |
| 239 | (other-search (loop for k | 255 | ((consp source) |
| 240 | in (if fallback | 256 | (let ((coll (auth-get-source entry)) |
| 241 | (remove :host | 257 | item) |
| 242 | (remove :protocol keys)) | 258 | ;; Loop over candidates with a matching host attribute. |
| 243 | keys) | 259 | (dolist (elt (secrets-search-items coll :host host) item) |
| 244 | append (list | 260 | (when (and (or (not user) |
| 245 | k | 261 | (string-equal |
| 246 | ;; convert symbols to a string | 262 | user (secrets-get-attribute coll elt :user))) |
| 247 | (let ((v (plist-get spec k))) | 263 | (or (not prot) |
| 248 | (if (stringp v) | 264 | (string-equal |
| 249 | v | 265 | prot (secrets-get-attribute coll elt :protocol)))) |
| 250 | (prin1-to-string v)))))) | 266 | (setq item elt) |
| 251 | ;; the score is based on how exact the search was, | 267 | (return elt))) |
| 252 | ;; plus base score = 1 for any match | 268 | ;; Compose result. |
| 253 | (score (1+ (length other-search))) | 269 | (when item |
| 254 | (results (apply 'secrets-search-items | 270 | (setq result |
| 255 | coll-search | 271 | (mapcar (lambda (m) |
| 256 | other-search))) | 272 | (if (string-equal "password" m) |
| 257 | (auth-source-do-debug | 273 | (or (secrets-get-secret coll item) |
| 258 | "auth-source-pick: got items %s in collection '%s' + %s" | 274 | ;; When we do not find a password, |
| 259 | results coll-search other-search) | 275 | ;; we return nil anyway. |
| 260 | ;; put the results in the choices variable | 276 | (throw 'no-password nil)) |
| 261 | (dolist (result results) | 277 | (or (secrets-get-attribute coll item :user) |
| 262 | (setq choices (cons (list score | 278 | user))) |
| 263 | `(:source secrets | 279 | (if (consp mode) mode (list mode))))) |
| 264 | :item ,result | 280 | (if (consp mode) result (car result)))) |
| 265 | :collection ,coll | 281 | ;; Anything else is netrc. |
| 266 | :search ,coll-search | 282 | (t |
| 267 | ,@other-search)) | 283 | (let ((search (list source (list host) (list (format "%s" prot)) |
| 268 | choices))))) | 284 | (auth-source-protocol-defaults prot)))) |
| 269 | ;; this is any non-secrets spec (currently means a string filename) | 285 | (setq result |
| 270 | (t | 286 | (mapcar (lambda (m) |
| 271 | (let ((match t)) | 287 | (if (string-equal "password" m) |
| 272 | (dolist (k keys) | 288 | (or (apply |
| 273 | (let* ((v (plist-get spec k)) | 289 | 'netrc-machine-user-or-password m search) |
| 274 | (choicev (plist-get choice k))) | 290 | ;; When we do not find a password, we |
| 275 | (setq match | 291 | ;; return nil anyway. |
| 276 | (and match | 292 | (throw 'no-password nil)) |
| 277 | (or (eq t choicev) ; source always matches spec key | 293 | (or (apply |
| 278 | ;; source key gives regex to match against spec | 294 | 'netrc-machine-user-or-password m search) |
| 279 | (and (stringp choicev) (string-match choicev v)) | 295 | user))) |
| 280 | ;; source key gives symbol to match against spec | 296 | (if (consp mode) mode (list mode))))) |
| 281 | (and (symbolp choicev) (eq choicev v)) | 297 | (if (consp mode) result (car result))))))) |
| 282 | ;; in fallback mode, missing source key is OK | 298 | |
| 283 | fallback))) | 299 | (defun auth-source-create (mode entry &rest spec) |
| 284 | (when match (incf score)))) ; increment the score for each match | 300 | "Create interactively credentials according to SPEC in ENTRY. |
| 285 | 301 | Return structure as specified by MODE." | |
| 286 | ;; now if the whole iteration resulted in a match: | 302 | (let* ((host (plist-get spec :host)) |
| 287 | (when match | 303 | (user (plist-get spec :user)) |
| 288 | (setq choices (cons (list score choice) choices)))))))) | 304 | (prot (plist-get spec :protocol)) |
| 289 | ;; when there were matches, skip the second pass | 305 | (source (plist-get entry :source)) |
| 290 | (when choices (return choices)))) | 306 | (name (concat (if user (format "%s@" user)) |
| 291 | 307 | host | |
| 292 | ;; return the results sorted by score | 308 | (if prot (format ":%s" prot)))) |
| 293 | (mapcar 'cadr (sort choices (lambda (x y) (> (car x) (car y))))))) | 309 | result) |
| 294 | 310 | (setq result | |
| 295 | (defun auth-source-forget-user-or-password (mode host protocol) | 311 | (mapcar |
| 312 | (lambda (m) | ||
| 313 | (if (equal "password" m) | ||
| 314 | (let ((passwd (read-passwd "Password: "))) | ||
| 315 | (cond | ||
| 316 | ;; Secret Service API. | ||
| 317 | ((consp source) | ||
| 318 | (apply | ||
| 319 | 'secrets-create-item | ||
| 320 | (auth-get-source entry) name passwd spec)) | ||
| 321 | (t)) ;; netrc not implemented yes. | ||
| 322 | passwd) | ||
| 323 | (or | ||
| 324 | ;; the originally requested :user | ||
| 325 | user | ||
| 326 | "unknown-user"))) | ||
| 327 | (if (consp mode) mode (list mode)))) | ||
| 328 | (if (consp mode) result (car result)))) | ||
| 329 | |||
| 330 | (defun auth-source-delete (entry &rest spec) | ||
| 331 | "Delete credentials according to SPEC in ENTRY." | ||
| 332 | (let ((host (plist-get spec :host)) | ||
| 333 | (user (plist-get spec :user)) | ||
| 334 | (prot (plist-get spec :protocol)) | ||
| 335 | (source (plist-get entry :source))) | ||
| 336 | (cond | ||
| 337 | ;; Secret Service API. | ||
| 338 | ((consp source) | ||
| 339 | (let ((coll (auth-get-source entry))) | ||
| 340 | ;; Loop over candidates with a matching host attribute. | ||
| 341 | (dolist (elt (secrets-search-items coll :host host)) | ||
| 342 | (when (and (or (not user) | ||
| 343 | (string-equal | ||
| 344 | user (secrets-get-attribute coll elt :user))) | ||
| 345 | (or (not prot) | ||
| 346 | (string-equal | ||
| 347 | prot (secrets-get-attribute coll elt :protocol)))) | ||
| 348 | (secrets-delete-item coll elt))))) | ||
| 349 | (t)))) ;; netrc not implemented yes. | ||
| 350 | |||
| 351 | (defun auth-source-forget-user-or-password | ||
| 352 | (mode host protocol &optional username) | ||
| 353 | "Remove cached authentication token." | ||
| 296 | (interactive "slogin/password: \nsHost: \nsProtocol: \n") ;for testing | 354 | (interactive "slogin/password: \nsHost: \nsProtocol: \n") ;for testing |
| 297 | (remhash (format "%s %s:%s" mode host protocol) auth-source-cache)) | 355 | (remhash |
| 356 | (if username | ||
| 357 | (format "%s %s:%s %s" mode host protocol username) | ||
| 358 | (format "%s %s:%s" mode host protocol)) | ||
| 359 | auth-source-cache)) | ||
| 298 | 360 | ||
| 299 | (defun auth-source-forget-all-cached () | 361 | (defun auth-source-forget-all-cached () |
| 300 | "Forget all cached auth-source authentication tokens." | 362 | "Forget all cached auth-source authentication tokens." |
| @@ -308,7 +370,8 @@ checked for fallback choices." | |||
| 308 | ;; (auth-source-user-or-password '("login" "password") "imap.myhost.com" "other" "tzz") | 370 | ;; (auth-source-user-or-password '("login" "password") "imap.myhost.com" "other" "tzz") |
| 309 | ;; (auth-source-user-or-password '("login" "password") "imap.myhost.com" "other" "joe"))) | 371 | ;; (auth-source-user-or-password '("login" "password") "imap.myhost.com" "other" "joe"))) |
| 310 | 372 | ||
| 311 | (defun auth-source-user-or-password (mode host protocol &optional username) | 373 | (defun auth-source-user-or-password |
| 374 | (mode host protocol &optional username create-missing delete-existing) | ||
| 312 | "Find MODE (string or list of strings) matching HOST and PROTOCOL. | 375 | "Find MODE (string or list of strings) matching HOST and PROTOCOL. |
| 313 | 376 | ||
| 314 | USERNAME is optional and will be used as \"login\" in a search | 377 | USERNAME is optional and will be used as \"login\" in a search |
| @@ -317,17 +380,31 @@ items don't have a username. This means that if you search for | |||
| 317 | username \"joe\" and it matches an item but the item doesn't have | 380 | username \"joe\" and it matches an item but the item doesn't have |
| 318 | a :user attribute, the username \"joe\" will be returned. | 381 | a :user attribute, the username \"joe\" will be returned. |
| 319 | 382 | ||
| 320 | MODE can be \"login\" or \"password\" for example." | 383 | A non nil DELETE-EXISTING means deleting any matching password |
| 384 | entry in the respective sources. This is useful only when | ||
| 385 | CREATE-MISSING is non nil as well; the intended use case is to | ||
| 386 | remove wrong password entries. | ||
| 387 | |||
| 388 | If no matching entry is found, and CREATE-MISSING is non nil, | ||
| 389 | the password will be retrieved interactively, and it will be | ||
| 390 | stored in the password database which matches best (see | ||
| 391 | `auth-sources'). | ||
| 392 | |||
| 393 | MODE can be \"login\" or \"password\"." | ||
| 321 | (auth-source-do-debug | 394 | (auth-source-do-debug |
| 322 | "auth-source-user-or-password: get %s for %s (%s) + user=%s" | 395 | "auth-source-user-or-password: get %s for %s (%s) + user=%s" |
| 323 | mode host protocol username) | 396 | mode host protocol username) |
| 324 | (let* ((listy (listp mode)) | 397 | (let* ((listy (listp mode)) |
| 325 | (mode (if listy mode (list mode))) | 398 | (mode (if listy mode (list mode))) |
| 326 | (extras (when username `(:user ,username))) | 399 | (cname (if username |
| 327 | (cname (format "%s %s:%s %s" mode host protocol extras)) | 400 | (format "%s %s:%s %s" mode host protocol username) |
| 401 | (format "%s %s:%s" mode host protocol))) | ||
| 328 | (search (list :host host :protocol protocol)) | 402 | (search (list :host host :protocol protocol)) |
| 329 | (search (if username (append search (list :user username)) search)) | 403 | (search (if username (append search (list :user username)) search)) |
| 330 | (found (gethash cname auth-source-cache))) | 404 | (found (if (not delete-existing) |
| 405 | (gethash cname auth-source-cache) | ||
| 406 | (remhash cname auth-source-cache) | ||
| 407 | nil))) | ||
| 331 | (if found | 408 | (if found |
| 332 | (progn | 409 | (progn |
| 333 | (auth-source-do-debug | 410 | (auth-source-do-debug |
| @@ -337,45 +414,35 @@ MODE can be \"login\" or \"password\" for example." | |||
| 337 | (if (and (member "password" mode) auth-source-hide-passwords) | 414 | (if (and (member "password" mode) auth-source-hide-passwords) |
| 338 | "SECRET" | 415 | "SECRET" |
| 339 | found) | 416 | found) |
| 340 | host protocol extras) | 417 | host protocol username) |
| 341 | found) ; return the found data | 418 | found) ; return the found data |
| 342 | ;; else, if not found | 419 | ;; else, if not found |
| 343 | (dolist (choice (apply 'auth-source-pick search)) | 420 | (let ((choices (apply 'auth-source-pick search))) |
| 344 | (setq found (cond | 421 | (dolist (choice choices) |
| 345 | ;; the secrets.el spec | 422 | (if delete-existing |
| 346 | ((eq (plist-get choice :source) 'secrets) | 423 | (apply 'auth-source-delete choice search) |
| 347 | (let ((coll (plist-get choice :search)) | 424 | (setq found (apply 'auth-source-retrieve mode choice search))) |
| 348 | (item (plist-get choice :item))) | 425 | (and found (return found))) |
| 349 | (mapcar (lambda (m) | 426 | |
| 350 | (if (equal "password" m) | 427 | ;; We haven't found something, so we will create it interactively. |
| 351 | (secrets-get-secret coll item) | 428 | (when (and (not found) choices create-missing) |
| 352 | ;; the user name is either | 429 | (setq found (apply 'auth-source-create mode (car choices) search))) |
| 353 | (or | 430 | |
| 354 | ;; the secret's attribute :user, or | 431 | ;; Cache the result. |
| 355 | (secrets-get-attribute coll item :user) | ||
| 356 | ;; the originally requested :user | ||
| 357 | username | ||
| 358 | "unknown-user"))) | ||
| 359 | mode))) | ||
| 360 | (t ; anything else is netrc | ||
| 361 | (netrc-machine-user-or-password | ||
| 362 | mode | ||
| 363 | (plist-get choice :source) | ||
| 364 | (list host) | ||
| 365 | (list (format "%s" protocol)) | ||
| 366 | (auth-source-protocol-defaults protocol))))) | ||
| 367 | (when found | 432 | (when found |
| 368 | (auth-source-do-debug | 433 | (auth-source-do-debug |
| 369 | "auth-source-user-or-password: found %s=%s for %s (%s) + %s" | 434 | "auth-source-user-or-password: found %s=%s for %s (%s) + %s" |
| 370 | mode | 435 | mode |
| 371 | ;; don't show the password | 436 | ;; don't show the password |
| 372 | (if (and (member "password" mode) auth-source-hide-passwords) "SECRET" found) | 437 | (if (and (member "password" mode) auth-source-hide-passwords) |
| 373 | host protocol extras) | 438 | "SECRET" found) |
| 439 | host protocol username) | ||
| 374 | (setq found (if listy found (car-safe found))) | 440 | (setq found (if listy found (car-safe found))) |
| 375 | (when auth-source-do-cache | 441 | (when auth-source-do-cache |
| 376 | (puthash cname found auth-source-cache))) | 442 | (puthash cname found auth-source-cache))) |
| 377 | (return found))))) | 443 | |
| 378 | 444 | found)))) | |
| 445 | |||
| 379 | (defun auth-source-protocol-defaults (protocol) | 446 | (defun auth-source-protocol-defaults (protocol) |
| 380 | "Return a list of default ports and names for PROTOCOL." | 447 | "Return a list of default ports and names for PROTOCOL." |
| 381 | (cdr-safe (assoc protocol auth-source-protocols))) | 448 | (cdr-safe (assoc protocol auth-source-protocols))) |