diff options
| author | Daiki Ueno | 2011-07-01 10:34:38 +0900 |
|---|---|---|
| committer | Daiki Ueno | 2011-07-01 10:34:38 +0900 |
| commit | cdf4d4551d9e2b91fb0127ba8162e94910f514bf (patch) | |
| tree | c250531ed3c65bf7cd8e64b0d56169f8dfad2879 | |
| parent | 65afde5c65de1628ce6524b68a51cdc398aef52f (diff) | |
| download | emacs-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/ChangeLog | 8 | ||||
| -rw-r--r-- | lisp/gnus/plstore.el | 106 |
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 @@ | |||
| 1 | 2011-07-01 Daiki Ueno <ueno@unixuser.org> | 1 | 2011-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 | |||
| 9 | 2011-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 | ||
| 5 | 2011-06-30 Katsumi Yamaoka <yamaoka@jpl.org> | 13 | 2011-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 | |||
| 55 | If t, always asks user to select recipients. | ||
| 56 | If nil, query user only when `plstore-encrypt-to' is not set. | ||
| 57 | If neither t nor nil, doesn't ask user. In this case, symmetric | ||
| 58 | encryption 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. | ||
| 66 | May 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. | ||
| 371 | If 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 | ||