5 "EasyPG Assistant, GUI for EasyPG."
8 (defgroup epa-faces nil
12 (defvar epa-buffer nil)
14 (defface epa-trust-full-face
15 '((((class color) (background dark))
16 (:foreground "PaleTurquoise" :bold t))
19 "Face used for displaying the trust-full addon."
21 (defvar epa-trust-full-face 'epa-trust-full-face)
23 (defface epa-trust-disabled-face
24 '((((class color) (background dark))
25 (:foreground "PaleTurquoise" :italic t))
28 "Face used for displaying the disabled trust."
30 (defvar epa-trust-disabled-face 'epa-trust-disabled-face)
32 (defface epa-trust-unknown-face
35 "Face used for displaying the trust-unknown addon."
37 (defvar epa-trust-unknown-face 'epa-trust-unknown-face)
39 (defface epa-trust-marginal-face
41 (:italic t :inverse-video t)))
42 "Face used for displaying the trust-marginal addon."
44 (defvar epa-trust-marginal-face 'epa-trust-marginal-face)
46 (defface epa-user-id-face
49 (:foreground "lightyellow"))
52 (:foreground "blue4"))
55 "Face used for displaying the user-id addon."
57 (defvar epa-user-id-face 'epa-user-id-face)
59 (defcustom epa-validity-face-alist
60 '((?o . epa-trust-unknown-face)
61 (?i . epa-trust-disabled-face)
62 (?d . epa-trust-disabled-face)
63 (?r . epa-trust-disabled-face)
64 (?e . epa-trust-disabled-face)
65 (?- . epa-trust-unknown-face)
66 (?q . epa-trust-unknown-face)
67 (?n . epa-trust-disabled-face)
68 (?m . epa-trust-marginal-face)
69 (?f . epa-trust-full-face)
70 (?u . epa-trust-full-face)
71 (? . epa-trust-full-face))
72 "An alist mapping marks on epa-buffer to faces."
76 (defcustom epa-font-lock-keywords
77 '(("^[* ]\\([-oidreqnmfu ]\\)\\s-+\\(\\S-+\\)\\s-+\\(.*\\)"
78 (2 (cdr (assq (aref (match-string 1) 0)
79 epa-validity-face-alist)))
80 (3 epa-user-id-face)))
81 "Default expressions to addon in epa-mode."
82 :type '(repeat (list string))
86 (let ((keymap (make-sparse-keymap)))
87 (define-key keymap "m" 'epa-command-mark-key)
88 (define-key keymap "u" 'epa-command-unmark-key)
89 (define-key keymap "n" 'epa-command-next-line)
90 (define-key keymap "p" 'previous-line)
91 (define-key keymap "e" 'epa-command-encrypt-file)
92 (define-key keymap "s" 'epa-command-sign-file)
93 (define-key keymap " " 'scroll-up)
94 (define-key keymap [delete] 'scroll-down)
95 (define-key keymap "q" 'bury-buffer)
99 "Major mode for displaying addon list.
100 All normal editing commands are turned off."
101 (kill-all-local-variables)
102 (buffer-disable-undo)
103 (setq major-mode 'epa-mode
107 (use-local-map epa-mode-map)
108 (make-local-variable 'font-lock-defaults)
109 (setq font-lock-defaults '(epa-font-lock-keywords t))
110 ;; In XEmacs, auto-initialization of font-lock is not effective
111 ;; if buffer-file-name is not set.
112 (font-lock-set-defaults)
113 (make-local-variable 'epa-marked-keys)
114 (run-hooks 'epa-mode-hook))
119 (setq epa-buffer (generate-new-buffer "*EPA*")))
120 (set-buffer epa-buffer)
122 (let ((inhibit-read-only t)
124 configuration pointer entry point)
126 (insert "EasyPG Assistant\n\n")
127 (setq configuration (epg-configuration))
128 (if (setq entry (assq 'version configuration))
129 (insert (format "GnuPG %s\n" (cdr entry))))
130 (if (setq entry (assq 'pubkey configuration))
131 (insert (format "Pubkey: %s\n"
136 epg-pubkey-algorithm-alist))
138 (format "(unknown: %d)" algorithm)))
140 (if (setq entry (assq 'cipher configuration))
141 (insert (format "Cipher: %s\n"
146 epg-cipher-algorithm-alist))
148 (format "(unknown: %d)" algorithm)))
150 (if (setq entry (assq 'digest configuration))
151 (insert (format "Hash: %s\n"
156 epg-digest-algorithm-alist))
158 (format "(unknown: %d)" algorithm)))
160 (if (setq entry (assq 'compress configuration))
161 (insert (format "Compression: %s\n"
166 epg-compress-algorithm-alist))
168 (format "(unknown: %d)" algorithm)))
170 (insert "\nSecret keys:\n\n")
171 (setq pointer (epg-list-keys nil t))
174 (setq entry (cdr (assq 'sec (car pointer))))
175 (setq key-id (cdr (assq 'key-id entry)))
176 (insert (format " %s %s\n"
178 (cdr (assq 'user-id (assq 'uid (car pointer))))))
179 (put-text-property point (point) 'epa-key-id key-id)
180 (put-text-property point (point) 'epa-key-secret t)
181 (setq pointer (cdr pointer)))
182 (insert "\nPublic keys:\n\n")
183 (setq pointer (epg-list-keys nil))
186 (setq entry (cdr (assq 'pub (car pointer))))
187 (setq key-id (cdr (assq 'key-id entry)))
188 (insert (format " %s %s %s\n"
189 (or (cdr (assq 'trust entry)) ? )
191 (cdr (assq 'user-id (assq 'uid (car pointer))))))
192 (put-text-property point (point) 'epa-key-id key-id)
193 (setq pointer (cdr pointer)))
194 (goto-char (point-min))
195 (pop-to-buffer (current-buffer))
196 (delete-other-windows)))
199 (let ((key-id (get-text-property (point) 'epa-key-id))
202 (setq point (next-single-property-change (point) 'epa-key-id))
205 (setq key-id (get-text-property (point) 'epa-key-id))))
208 (defun epa-command-mark-key (key-id)
211 (unless (eq major-mode 'epa-mode)
212 (error "Not in `epa-mode'"))
213 (list (epa-key-id))))
214 (let ((point (point))
215 (inhibit-read-only t)
218 (not (equal (get-text-property point 'epa-key-id) key-id)))
219 (setq point (next-single-property-change point)))
221 (error "Key %s not found" key-id))
227 (put-text-property point (point) 'epa-key-id key-id)
230 (defun epa-command-unmark-key (key-id)
233 (unless (eq major-mode 'epa-mode)
234 (error "Not in `epa-mode'"))
235 (list (epa-key-id))))
236 (let ((point (point))
237 (inhibit-read-only t)
240 (not (equal (get-text-property point 'epa-key-id) key-id)))
241 (setq point (next-single-property-change point)))
243 (error "Key %s not found" key-id))
249 (put-text-property point (point) 'epa-key-id key-id)
252 (defun epa-command-next-line (count)
254 (if (get-text-property (point) 'epa-key-id)
256 (let ((point (next-single-property-change (point) 'epa-key-id)))
258 (get-text-property point 'epa-key-id))
259 (goto-char point)))))
261 (defun epa-command-encrypt-file (plain cipher recipients sign)
264 (set-buffer epa-buffer)
265 (goto-char (point-min))
266 (let (plain recipients)
267 (while (re-search-forward "^\\*" nil t)
268 (unless (get-text-property (point) 'epa-key-secret)
269 (setq recipients (cons (get-text-property (point) 'epa-key-id)
271 (list (setq plain (expand-file-name (read-file-name "Plain file: ")))
273 (read-file-name (format "Cipher file (default %s.gpg) "
274 (file-name-nondirectory plain))
275 (file-name-directory plain)
276 (concat plain ".gpg")))
278 current-prefix-arg))))
279 (message "Encrypting %s..." (file-name-nondirectory plain))
280 (epg-encrypt-file (epg-make-context)
283 (expand-file-name cipher)
285 (message "Encrypting %s...done" (file-name-nondirectory plain)))
287 (defun epa-command-sign-file (plain signature detached signers)
290 (set-buffer epa-buffer)
291 (goto-char (point-min))
292 (let ((extension (if current-prefix-arg ".sig" ".gpg"))
294 (while (re-search-forward "^\\*" nil t)
295 (if (get-text-property (point) 'epa-key-secret)
296 (setq signers (cons (get-text-property (point) 'epa-key-id)
299 (list (setq plain (expand-file-name (read-file-name "Plain file: ")))
301 (read-file-name (format "Signature file (default %s%s) "
302 (file-name-nondirectory plain)
304 (file-name-directory plain)
305 (concat plain extension)))
308 (let ((context (epg-make-context)))
309 (epg-context-set-signers context signers)
310 (message "Signing %s..." (file-name-nondirectory plain))
311 (epg-sign-file context
314 (if detached 'detached))
315 (message "Signing %s...done" (file-name-nondirectory plain))))