aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaiki Ueno2011-07-01 10:34:38 +0900
committerDaiki Ueno2011-07-01 10:34:38 +0900
commitcdf4d4551d9e2b91fb0127ba8162e94910f514bf (patch)
treec250531ed3c65bf7cd8e64b0d56169f8dfad2879
parent65afde5c65de1628ce6524b68a51cdc398aef52f (diff)
downloademacs-cdf4d4551d9e2b91fb0127ba8162e94910f514bf.tar.gz
emacs-cdf4d4551d9e2b91fb0127ba8162e94910f514bf.zip
Add public key encryption support to plstore.
* plstore.el (plstore-select-keys, plstore-encrypt-to): New variable. (plstore-save): Support public key encryption. (plstore--init-from-buffer): New function. (plstore-open): Use it; fix error when opening a non-existent file. (plstore-revert): Use plstore--init-from-buffer.
-rw-r--r--lisp/gnus/ChangeLog8
-rw-r--r--lisp/gnus/plstore.el106
2 files changed, 88 insertions, 26 deletions
diff --git a/lisp/gnus/ChangeLog b/lisp/gnus/ChangeLog
index bd7c81f5624..50082d6039b 100644
--- a/lisp/gnus/ChangeLog
+++ b/lisp/gnus/ChangeLog
@@ -1,5 +1,13 @@
12011-07-01 Daiki Ueno <ueno@unixuser.org> 12011-07-01 Daiki Ueno <ueno@unixuser.org>
2 2
3 * plstore.el (plstore-select-keys, plstore-encrypt-to): New variable.
4 (plstore-save): Support public key encryption.
5 (plstore--init-from-buffer): New function.
6 (plstore-open): Use it; fix error when opening a non-existent file.
7 (plstore-revert): Use plstore--init-from-buffer.
8
92011-07-01 Daiki Ueno <ueno@unixuser.org>
10
3 * auth-source.el (auth-source-backend): Fix :initarg for data slot. 11 * auth-source.el (auth-source-backend): Fix :initarg for data slot.
4 12
52011-06-30 Katsumi Yamaoka <yamaoka@jpl.org> 132011-06-30 Katsumi Yamaoka <yamaoka@jpl.org>
diff --git a/lisp/gnus/plstore.el b/lisp/gnus/plstore.el
index 392437d1dea..8111c4c226e 100644
--- a/lisp/gnus/plstore.el
+++ b/lisp/gnus/plstore.el
@@ -44,6 +44,40 @@
44 44
45(require 'epg) 45(require 'epg)
46 46
47(defgroup plstore nil
48 "Searchable, partially encrypted, persistent plist store"
49 :version "24.1"
50 :group 'files)
51
52(defcustom plstore-select-keys 'silent
53 "Control whether or not to pop up the key selection dialog.
54
55If t, always asks user to select recipients.
56If nil, query user only when `plstore-encrypt-to' is not set.
57If neither t nor nil, doesn't ask user. In this case, symmetric
58encryption is used."
59 :type '(choice (const :tag "Ask always" t)
60 (const :tag "Ask when recipients are not set" nil)
61 (const :tag "Don't ask" silent))
62 :group 'plstore)
63
64(defvar plstore-encrypt-to nil
65 "*Recipient(s) used for encrypting secret entries.
66May either be a string or a list of strings.")
67
68(put 'plstore-encrypt-to 'safe-local-variable
69 (lambda (val)
70 (or (stringp val)
71 (and (listp val)
72 (catch 'safe
73 (mapc (lambda (elt)
74 (unless (stringp elt)
75 (throw 'safe nil)))
76 val)
77 t)))))
78
79(put 'plstore-encrypt-to 'permanent-local t)
80
47(defvar plstore-cache-passphrase-for-symmetric-encryption nil) 81(defvar plstore-cache-passphrase-for-symmetric-encryption nil)
48(defvar plstore-passphrase-alist nil) 82(defvar plstore-passphrase-alist nil)
49 83
@@ -107,35 +141,39 @@
107(defun plstore-get-file (this) 141(defun plstore-get-file (this)
108 (buffer-file-name (plstore--get-buffer this))) 142 (buffer-file-name (plstore--get-buffer this)))
109 143
144(defun plstore--init-from-buffer (plstore)
145 (goto-char (point-min))
146 (when (looking-at ";;; public entries\n")
147 (forward-line)
148 (plstore--set-alist plstore (read (point-marker)))
149 (forward-sexp)
150 (forward-char)
151 (when (looking-at ";;; secret entries\n")
152 (forward-line)
153 (plstore--set-encrypted-data plstore (read (point-marker))))
154 (plstore--merge-secret plstore)))
155
110;;;###autoload 156;;;###autoload
111(defun plstore-open (file) 157(defun plstore-open (file)
112 "Create a plstore instance associated with FILE." 158 "Create a plstore instance associated with FILE."
113 (let ((store (vector 159 (with-current-buffer (find-file-noselect file)
114 (find-file-noselect file) 160 ;; make the buffer invisible from user
115 nil ;plist (plist) 161 (rename-buffer (format " plstore %s" (buffer-file-name)))
116 nil ;encrypted data (string) 162 (let ((store (vector
117 nil ;secret plist (plist) 163 (current-buffer)
118 nil ;merged plist (plist) 164 nil ;plist (plist)
119 ))) 165 nil ;encrypted data (string)
120 (plstore-revert store) 166 nil ;secret plist (plist)
121 store)) 167 nil ;merged plist (plist)
168 )))
169 (plstore--init-from-buffer store)
170 store)))
122 171
123(defun plstore-revert (plstore) 172(defun plstore-revert (plstore)
124 "Replace current data in PLSTORE with the file on disk." 173 "Replace current data in PLSTORE with the file on disk."
125 (with-current-buffer (plstore--get-buffer plstore) 174 (with-current-buffer (plstore--get-buffer plstore)
126 (revert-buffer t t) 175 (revert-buffer t t)
127 ;; make the buffer invisible from user 176 (plstore--init-from-buffer plstore)))
128 (rename-buffer (format " plstore %s" (buffer-file-name)))
129 (goto-char (point-min))
130 (when (looking-at ";;; public entries\n")
131 (forward-line)
132 (plstore--set-alist plstore (read (point-marker)))
133 (forward-sexp)
134 (forward-char)
135 (when (looking-at ";;; secret entries\n")
136 (forward-line)
137 (plstore--set-encrypted-data plstore (read (point-marker))))
138 (plstore--merge-secret plstore))))
139 177
140(defun plstore-close (plstore) 178(defun plstore-close (plstore)
141 "Destroy a plstore instance PLSTORE." 179 "Destroy a plstore instance PLSTORE."
@@ -304,20 +342,36 @@ SECRET-KEYS is a plist containing secret data."
304 "Save the contents of PLSTORE associated with a FILE." 342 "Save the contents of PLSTORE associated with a FILE."
305 (with-current-buffer (plstore--get-buffer plstore) 343 (with-current-buffer (plstore--get-buffer plstore)
306 (erase-buffer) 344 (erase-buffer)
307 (insert ";;; public entries\n" (pp-to-string (plstore--get-alist plstore))) 345 (insert ";;; public entries -*- mode: emacs-lisp -*- \n"
346 (pp-to-string (plstore--get-alist plstore)))
308 (if (plstore--get-secret-alist plstore) 347 (if (plstore--get-secret-alist plstore)
309 (let ((context (epg-make-context 'OpenPGP)) 348 (let ((context (epg-make-context 'OpenPGP))
310 (pp-escape-newlines nil) 349 (pp-escape-newlines nil)
350 (recipients
351 (cond
352 ((listp plstore-encrypt-to) plstore-encrypt-to)
353 ((stringp plstore-encrypt-to) (list plstore-encrypt-to))))
311 cipher) 354 cipher)
312 (epg-context-set-armor context t) 355 (epg-context-set-armor context t)
313 (epg-context-set-passphrase-callback 356 (epg-context-set-passphrase-callback
314 context 357 context
315 (cons #'plstore-passphrase-callback-function 358 (cons #'plstore-passphrase-callback-function
316 plstore)) 359 plstore))
317 (setq cipher (epg-encrypt-string context 360 (setq cipher (epg-encrypt-string
318 (pp-to-string 361 context
319 (plstore--get-secret-alist plstore)) 362 (pp-to-string
320 nil)) 363 (plstore--get-secret-alist plstore))
364 (if (or (eq plstore-select-keys t)
365 (and (null plstore-select-keys)
366 (not (local-variable-p 'plstore-encrypt-to
367 (current-buffer)))))
368 (epa-select-keys
369 context
370 "Select recipents for encryption.
371If no one is selected, symmetric encryption will be performed. "
372 recipients)
373 (if plstore-encrypt-to
374 (epg-list-keys context recipients)))))
321 (insert ";;; secret entries\n" (pp-to-string cipher)))) 375 (insert ";;; secret entries\n" (pp-to-string cipher))))
322 (save-buffer))) 376 (save-buffer)))
323 377