* mail-source.el: Load auth-source.el.
[gnus] / lisp / auth-source.el
1 ;;; auth-source.el --- authentication sources for Gnus and Emacs
2
3 ;; Copyright (C) 2008 Free Software Foundation, Inc.
4
5 ;; Author: Ted Zlatanov <tzz@lifelogs.com>
6 ;; Keywords: news
7
8 ;; This file is part of GNU Emacs.
9
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, or (at your option)
13 ;; any later version.
14
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.
19
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GNU Emacs; see the file COPYING.  If not, write to the
22 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02110-1301, USA.
24
25 ;;; Commentary:
26
27 ;; This is the auth-source.el package.  It lets users tell Gnus how to
28 ;; authenticate in a single place.  Simplicity is the goal.  Instead
29 ;; of providing 5000 options, we'll stick to simple, easy to
30 ;; understand options.
31
32 ;; Easy setup:
33 ;; (require 'auth-source)
34 ;; (customize-variable 'auth-sources) ;; optional
35
36 ;; now, whatever sources you've defined for password have to be available
37
38 ;; if you want encrypted sources, which is strongly recommended, do
39 ;; (require 'epa-file)
40 ;; (epa-file-mode)
41
42 ;; before you put some data in ~/.authinfo.gpg (the default place)
43
44 ;;; Code:
45
46 (eval-when-compile (require 'cl))
47 (eval-when-compile (require 'netrc))
48
49 (defgroup auth-source nil
50   "Authentication sources."
51   :version "23.1" ;; No Gnus
52   :group 'gnus)
53
54 (defcustom auth-source-protocols '((imap "imap" "imaps" "143" "993")
55                                    (pop3 "pop3" "pop" "pop3s" "110" "995")
56                                    (ssh  "ssh" "22")
57                                    (sftp "sftp" "115")
58                                    (smtp "smtp" "25"))
59   "List of authentication protocols and their names"
60
61   :group 'auth-source
62   :version "23.1" ;; No Gnus
63   :type '(repeat :tag "Authentication Protocols"
64                  (cons :tag "Protocol Entry"
65                        (symbol :tag "Protocol")
66                        (repeat :tag "Names"
67                                (string :tag "Name")))))
68
69 ;;; generate all the protocols in a format Customize can use
70 (defconst auth-source-protocols-customize
71   (mapcar (lambda (a)
72             (let ((p (car-safe a)))
73               (list 'const 
74                     :tag (upcase (symbol-name p))
75                     p)))
76           auth-source-protocols))
77
78 ;;; this default will be changed to ~/.authinfo.gpg
79 (defcustom auth-sources '((:source "~/.authinfo.enc" :host t :protocol t))
80   "List of authentication sources.
81
82 Each entry is the authentication type with optional properties."
83   :group 'auth-source
84   :version "23.1" ;; No Gnus
85   :type `(repeat :tag "Authentication Sources"
86                  (list :tag "Source definition"
87                        (const :format "" :value :source)
88                        (string :tag "Authentication Source")
89                        (const :format "" :value :host)
90                        (choice :tag "Host (machine) choice"
91                                (const :tag "Any" t)
92                                (regexp :tag "Host (machine) regular expression (TODO)")
93                                (const :tag "Fallback" nil))
94                        (const :format "" :value :protocol)
95                        (choice :tag "Protocol"
96                                (const :tag "Any" t)
97                                (const :tag "Fallback" nil)
98                                ,@auth-source-protocols-customize))))
99
100 ;; temp for debugging
101 ;; (unintern 'auth-source-protocols)
102 ;; (unintern 'auth-sources)
103 ;; (customize-variable 'auth-sources)
104 ;; (setq auth-sources nil)
105 ;; (format "%S" auth-sources)
106 ;; (customize-variable 'auth-source-protocols)
107 ;; (setq auth-source-protocols nil)
108 ;; (format "%S" auth-source-protocols)
109 ;; (auth-source-pick "a" 'imap)
110 ;; (auth-source-user-or-password "login" "imap.myhost.com" 'imap)
111 ;; (auth-source-user-or-password "password" "imap.myhost.com" 'imap)
112 ;; (auth-source-user-or-password-imap "login" "imap.myhost.com")
113 ;; (auth-source-user-or-password-imap "password" "imap.myhost.com")
114 ;; (auth-source-protocol-defaults 'imap)
115
116 (defun auth-source-pick (host protocol &optional fallback)
117   "Parse `auth-sources' for HOST, and PROTOCOL matches.
118
119 Returns fallback choices (where PROTOCOL or HOST are nil) with FALLBACK t."
120   (interactive "sHost: \nsProtocol: \n") ;for testing
121   (let (choices)
122     (dolist (choice auth-sources)
123       (let ((h (plist-get choice :host))
124             (p (plist-get choice :protocol)))
125         (when (and
126                (or (equal t h)
127                    (and (stringp h) (string-match h host))
128                    (and fallback (equal h nil)))
129                (or (equal t p)
130                    (and (symbolp p) (equal p protocol))
131                    (and fallback (equal p nil))))
132           (push choice choices))))
133     (if choices
134         choices
135       (unless fallback
136         (auth-source-pick host protocol t)))))
137
138 (defun auth-source-user-or-password (mode host protocol)
139   "Find user or password (from the string MODE) matching HOST and PROTOCOL."
140   (let (found)
141     (dolist (choice (auth-source-pick host protocol))
142       (setq found (netrc-machine-user-or-password 
143                    mode
144                    (plist-get choice :source)
145                    (list host)
146                    (list (format "%s" protocol))
147                    (auth-source-protocol-defaults protocol)))
148       (when found
149         (return found)))))
150
151 (defun auth-source-protocol-defaults (protocol)
152   "Return a list of default ports and names for PROTOCOL."
153   (cdr-safe (assoc protocol auth-source-protocols)))
154
155 (defun auth-source-user-or-password-imap (mode host)
156   (auth-source-user-or-password mode host 'imap))
157
158 (defun auth-source-user-or-password-pop3 (mode host)
159   (auth-source-user-or-password mode host 'pop3))
160
161 (defun auth-source-user-or-password-ssh (mode host)
162   (auth-source-user-or-password mode host 'ssh))
163
164 (defun auth-source-user-or-password-sftp (mode host)
165   (auth-source-user-or-password mode host 'sftp))
166
167 (defun auth-source-user-or-password-smtp (mode host)
168   (auth-source-user-or-password mode host 'smtp))
169
170 (provide 'auth-source)
171
172 ;; arch-tag: ff1afe78-06e9-42c2-b693-e9f922cbe4ab
173 ;;; auth-source.el ends here