X-Git-Url: https://cgit.sxemacs.org/?a=blobdiff_plain;f=lisp%2Fauth-source.el;h=bfe470c9ae8709147e9106c1f56da2d7470655ff;hb=524e94faf9db4206a60cf28a34ebb564a3f410d4;hp=f37e0368845e658c41a1c33ddf7cf8b96bb94026;hpb=752ff432e022e8fb193dd3933b434fa594c0cf0e;p=gnus diff --git a/lisp/auth-source.el b/lisp/auth-source.el index f37e03688..bfe470c9a 100644 --- a/lisp/auth-source.el +++ b/lisp/auth-source.el @@ -1,26 +1,24 @@ ;;; auth-source.el --- authentication sources for Gnus and Emacs -;; Copyright (C) 2008 Free Software Foundation, Inc. +;; Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc. ;; Author: Ted Zlatanov ;; Keywords: news ;; This file is part of GNU Emacs. -;; GNU Emacs is free software; you can redistribute it and/or modify +;; GNU Emacs is free software: you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 3, or (at your option) -;; any later version. +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. ;; GNU Emacs is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;; Boston, MA 02110-1301, USA. +;; along with GNU Emacs. If not, see . ;;; Commentary: @@ -28,11 +26,20 @@ ;; authenticate in a single place. Simplicity is the goal. Instead ;; of providing 5000 options, we'll stick to simple, easy to ;; understand options. + +;; See the auth.info Info documentation for details. + ;;; Code: +(require 'gnus-util) + (eval-when-compile (require 'cl)) (eval-when-compile (require 'netrc)) +(autoload 'secrets-search-items "secrets") +(autoload 'secrets-get-alias "secrets") +(autoload 'secrets-get-attribute "secrets") + (defgroup auth-source nil "Authentication sources." :version "23.1" ;; No Gnus @@ -46,7 +53,7 @@ "List of authentication protocols and their names" :group 'auth-source - :version "23.1" ;; No Gnus + :version "23.2" ;; No Gnus :type '(repeat :tag "Authentication Protocols" (cons :tag "Protocol Entry" (symbol :tag "Protocol") @@ -57,32 +64,86 @@ (defconst auth-source-protocols-customize (mapcar (lambda (a) (let ((p (car-safe a))) - (list 'const + (list 'const :tag (upcase (symbol-name p)) p))) auth-source-protocols)) -;;; this default will be changed to ~/.authinfo.gpg -(defcustom auth-sources '((:source "~/.authinfo.enc" :host t :protocol t)) +(defvar auth-source-cache (make-hash-table :test 'equal) + "Cache for auth-source data") + +(defcustom auth-source-do-cache t + "Whether auth-source should cache information." + :group 'auth-source + :version "23.2" ;; No Gnus + :type `boolean) + +(defcustom auth-source-debug nil + "Whether auth-source should log debug messages. +Also see `auth-source-hide-passwords'. + +If the value is nil, debug messages are not logged. +If the value is t, debug messages are logged with `message'. + In that case, your authentication data will be in the + clear (except for passwords, which are always stripped out). +If the value is a function, debug messages are logged by calling + that function using the same arguments as `message'." + :group 'auth-source + :version "23.2" ;; No Gnus + :type `(choice + :tag "auth-source debugging mode" + (const :tag "Log using `message' to the *Messages* buffer" t) + (function :tag "Function that takes arguments like `message'") + (const :tag "Don't log anything" nil))) + +(defcustom auth-source-hide-passwords t + "Whether auth-source should hide passwords in log messages. +Only relevant if `auth-source-debug' is not nil." + :group 'auth-source + :version "23.2" ;; No Gnus + :type `boolean) + +(defcustom auth-sources '((:source "~/.authinfo.gpg" :host t :protocol t)) "List of authentication sources. -Each entry is the authentication type with optional properties." +Each entry is the authentication type with optional properties. + +It's best to customize this with `M-x customize-variable' because the choices +can get pretty complex." :group 'auth-source - :version "23.1" ;; No Gnus + :version "23.2" ;; No Gnus :type `(repeat :tag "Authentication Sources" (list :tag "Source definition" (const :format "" :value :source) - (string :tag "Authentication Source") + (choice :tag "Authentication backend choice" + (string :tag "Authentication Source (file)") + (list :tag "secrets.el (Secret Service API/KWallet/GNOME KeyRing)" + (const :format "" :value :secrets) + (choice :tag "Collection to use" + (string :tag "Collection name") + (const :tag "Default" 'default) + (const :tag "Any" t) + (const :tag "Temporary" "session") + (string :tag "Specific session name") + (const :tag "Fallback" nil)))) (const :format "" :value :host) - (choice :tag "Host choice" + (choice :tag "Host (machine) choice" (const :tag "Any" t) - (regexp :tag "Host regular expression (TODO)") + (regexp :tag "Host (machine) regular expression (TODO)") (const :tag "Fallback" nil)) (const :format "" :value :protocol) (choice :tag "Protocol" (const :tag "Any" t) (const :tag "Fallback" nil) - ,@auth-source-protocols-customize)))) + ,@auth-source-protocols-customize) + (repeat :tag "Extra Parameters" :inline t + (choice :tag "Extra parameter" + (list :tag "Preferred username" :inline t + (const :format "" :value :preferred-username) + (choice :tag "Personality or username" + (const :tag "Any" t) + (const :tag "Fallback" nil) + (string :tag "Specific user name")))))))) ;; temp for debugging ;; (unintern 'auth-source-protocols) @@ -100,8 +161,21 @@ Each entry is the authentication type with optional properties." ;; (auth-source-user-or-password-imap "password" "imap.myhost.com") ;; (auth-source-protocol-defaults 'imap) +;; (let ((auth-source-debug 'debug)) (auth-source-debug "hello")) +;; (let ((auth-source-debug t)) (auth-source-debug "hello")) +;; (let ((auth-source-debug nil)) (auth-source-debug "hello")) +(defun auth-source-do-debug (&rest msg) + ;; set logger to either the function in auth-source-debug or 'message + ;; note that it will be 'message if auth-source-debug is nil, so + ;; we also check the value + (when auth-source-debug + (let ((logger (if (functionp auth-source-debug) + auth-source-debug + 'message))) + (apply logger msg)))) + (defun auth-source-pick (host protocol &optional fallback) - "Parse `auth-sources' for HOST and PROTOCOL matches. + "Parse `auth-sources' for HOST, and PROTOCOL matches. Returns fallback choices (where PROTOCOL or HOST are nil) with FALLBACK t." (interactive "sHost: \nsProtocol: \n") ;for testing @@ -122,17 +196,51 @@ Returns fallback choices (where PROTOCOL or HOST are nil) with FALLBACK t." (unless fallback (auth-source-pick host protocol t))))) +(defun auth-source-forget-user-or-password (mode host protocol) + (interactive "slogin/password: \nsHost: \nsProtocol: \n") ;for testing + (remhash (format "%s %s:%s" mode host protocol) auth-source-cache)) + +(defun auth-source-forget-all-cached () + "Forget all cached auth-source authentication tokens." + (interactive) + (setq auth-source-cache (make-hash-table :test 'equal))) + (defun auth-source-user-or-password (mode host protocol) - "Find user or password (from the string MODE) matching HOST and PROTOCOL." - (let (found) - (dolist (choice (auth-source-pick host protocol)) - (setq found (netrc-machine-user-or-password - mode - (plist-get choice :source) - (list host) - (list (format "%s" protocol)) - (auth-source-protocol-defaults protocol))) - (when found + "Find MODE (string or list of strings) matching HOST and PROTOCOL. +MODE can be \"login\" or \"password\" for example." + (auth-source-do-debug + "auth-source-user-or-password: get %s for %s (%s)" + mode host protocol) + (let* ((listy (listp mode)) + (mode (if listy mode (list mode))) + (cname (format "%s %s:%s" mode host protocol)) + (found (gethash cname auth-source-cache))) + (if found + (progn + (auth-source-do-debug + "auth-source-user-or-password: cached %s=%s for %s (%s)" + mode + ;; don't show the password + (if (and (member "password" mode) auth-source-hide-passwords) "SECRET" found) + host protocol) + found) + (dolist (choice (auth-source-pick host protocol)) + (setq found (netrc-machine-user-or-password + mode + (plist-get choice :source) + (list host) + (list (format "%s" protocol)) + (auth-source-protocol-defaults protocol))) + (when found + (auth-source-do-debug + "auth-source-user-or-password: found %s=%s for %s (%s)" + mode + ;; don't show the password + (if (and (member "password" mode) auth-source-hide-passwords) "SECRET" found) + host protocol) + (setq found (if listy found (car-safe found))) + (when auth-source-do-cache + (puthash cname found auth-source-cache))) (return found))))) (defun auth-source-protocol-defaults (protocol)