# HG changeset patch # User Ken Manheimer # Date 1292485157 18000 # Node ID f5276a51842456b3e398f07cc50641d2f248a786 # Parent a348c631aeb8b694184807922b76120f31034381 respect epa-file-encrypt-to, defaulting to it when encrypting, if set, and adjusting the value (as a file local variable and an active buffer setting) with the result of epa-select-keys. note the problem with caching of incorrect symmetric decryption keys. (allout-toggle-current-subtree-encryption), (allout-toggle-subtree-encryption): Adjust docstrings to reflect defaulting policy change. (allout-encrypt-string): keymod-cue rather than keypair-mode, which is interpreted here. Use the epa-passphrase-callback-function, in case the user is using GnuPG v1. Support saving of the selected keypair recipients when invoked with a keymode-cue > 4. diff -r a348c631aeb8 -r f5276a518424 lisp/allout.el --- a/lisp/allout.el Fri Dec 10 17:09:57 2010 -0500 +++ b/lisp/allout.el Thu Dec 16 02:39:17 2010 -0500 @@ -1919,6 +1919,14 @@ If the content of the topic containing the cursor was encrypted for a save, it is automatically decrypted for continued editing. +PROBLEM: Attempting symmetric decryption with an incorrect key +not only fails, but the incorrect key seems to be associated with +the specific entry in the gpg cache, so that you do not get an +opportunity to override the incorrect key and decrypt that +entry. (Decryption of other entries is not affected.) To clear +this problem, clear your gpg-agent's cache by sending it a '-HUP' +signal. + See `allout-toggle-current-subtree-encryption' function docstring and `allout-encrypt-unencrypted-on-saves' customization variable for details. @@ -5975,11 +5983,23 @@ and keypair encryption are supported. All encryption is ascii armored. -When encrypting, optional KEYMODE-CUE universal argument greater -than 1 causes prompting for recipients for public-key keypair -encryption. Otherwise a symmetric mode is assumed for +Entry encryption defaults to symmetric key mode unless keypair +recipients are associated with the file \(see +`epa-file-encrypt-to') or the function is invoked with a +\(KEYMODE-CUE) universal argument greater than 1. + +When encrypting, KEYMODE-CUE universal argument greater than 1 +causes prompting for recipients for public-key keypair +encryption. Selecting no recipients results in symmetric key encryption. +Further, encrypting with a KEYMODE-CUE universal argument greater +than 4 - eg, preceded by a doubled Ctrl-U - causes association of +the specified recipients with the file, replacing those currently +associated with it. This can be used to deassociate any +recipients with the file, by selecting no recipients in the +dialog. + Encrypted topic's bullets are set to a `~' to signal that the contents of the topic (body and subtopics, but not heading) is pending encryption or encrypted. `*' asterisk immediately after @@ -6004,11 +6024,24 @@ (defun allout-toggle-subtree-encryption (&optional keymode-cue) "Encrypt clear text or decrypt encoded topic contents (body and subtopics.) -When encrypting, optional KEYMODE-CUE universal argument greater than -1 provokes prompting for recipients for public-key keypair -encryption, otherwise a symmetric-mode passphrase is solicited. - -Encryption depends on the emacs epg library. +Entry encryption defaults to symmetric key mode unless keypair +recipients are associated with the file \(see +`epa-file-encrypt-to') or the function is invoked with a +\(KEYMODE-CUE) universal argument greater than 1. + +When encrypting, KEYMODE-CUE universal argument greater than 1 +causes prompting for recipients for public-key keypair +encryption. Selecting no recipients results in symmetric key +encryption. + +Further, encrypting with a KEYMODE-CUE universal argument greater +than 4 - eg, preceded by a doubled Ctrl-U - causes association of +the specified recipients with the file, replacing those currently +associated with it. This can be used to deassociate any +recipients with the file, by selecting no recipients in the +dialog. + +Encryption and decryption uses the emacs epg library. Encrypted text will be ascii-armored. @@ -6030,7 +6063,6 @@ (progn (if (= (point-max) after-bullet-pos) (error "no body to encrypt")) (allout-encrypted-topic-p))) - (keypair-mode (> (prefix-numeric-value keymode-cue) 1)) (was-collapsed (if (not (search-forward "\n" nil t)) nil (backward-char 1) @@ -6074,7 +6106,7 @@ (setq result-text (allout-encrypt-string subject-text was-encrypted - (current-buffer) keypair-mode)) + (current-buffer) keymode-cue)) ;; Replace the subtree with the processed product. (allout-unprotected @@ -6105,9 +6137,9 @@ (insert "*")))) (run-hook-with-args 'allout-structure-added-hook bullet-pos subtree-end)))) -;;;_ > allout-encrypt-string (text decrypt allout-buffer keypair-mode +;;;_ > allout-encrypt-string (text decrypt allout-buffer keymode-cue ;;; &optional rejected) -(defun allout-encrypt-string (text decrypt allout-buffer keypair-mode +(defun allout-encrypt-string (text decrypt allout-buffer keymode-cue &optional rejected) "Encrypt or decrypt message TEXT. @@ -6117,8 +6149,22 @@ ALLOUT-BUFFER identifies the buffer containing the text. -If KEYPAIR-MODE is non-nil, encryption involves prompting for -keypair recipients. +Entry encryption defaults to symmetric key mode unless keypair +recipients are associated with the file \(see +`epa-file-encrypt-to') or the function is invoked with a +\(KEYMODE-CUE) universal argument greater than 1. + +When encrypting, KEYMODE-CUE universal argument greater than 1 +causes prompting for recipients for public-key keypair +encryption. Selecting no recipients results in symmetric key +encryption. + +Further, encrypting with a KEYMODE-CUE universal argument greater +than 4 - eg, preceded by a doubled Ctrl-U - causes association of +the specified recipients with the file, replacing those currently +associated with it. This can be used to deassociate any +recipients with the file, by selecting no recipients in the +dialog. Optional REJECTED is for internal use, to convey the number of rejections due to matches against @@ -6128,7 +6174,10 @@ (require 'epg) (require 'epa) - (let* ((epg-context (epg-make-context nil t)) + (let* ((epg-context (let* ((context (epg-make-context nil t))) + (epg-context-set-passphrase-callback + context #'epa-passphrase-callback-function) + context)) (encoding (with-current-buffer allout-buffer buffer-file-coding-system)) (multibyte (with-current-buffer allout-buffer @@ -6145,9 +6194,17 @@ (rejected (or rejected 0)) (rejections-left (- allout-encryption-ciphertext-rejection-ceiling rejected)) - (keypair-message (concat "Select encryption recipients.\n Not" - " selecting any causes" - " symmetric encryption. ")) + (keypair-mode (cond (decrypt 'decrypting) + ((<= (prefix-numeric-value keymode-cue) 1) + 'default) + ((<= (prefix-numeric-value keymode-cue) 4) + 'prompt) + ((> (prefix-numeric-value keymode-cue) 4) + 'prompt-save))) + (keypair-message (concat "Select encryption recipients.\n" + "Symmetric encryption is done if no" + " recipients are selected. ")) + (encrypt-to (and (boundp 'epa-file-encrypt-to) epa-file-encrypt-to)) recipients massaged-text result-text @@ -6174,6 +6231,18 @@ (replace-match replacement nil nil)))))) (setq massaged-text (buffer-substring-no-properties (point-min) (point-max)))) + ;; determine key mode and, if keypair, recipients: + (setq recipients + (case keypair-mode + + (decrypting nil) + + (default (if encrypt-to (epg-list-keys epg-context encrypt-to))) + + ((prompt prompt-save) + (save-window-excursion + (epa-select-keys epg-context keypair-message))))) + (setq result-text (if decrypt (epg-decrypt-string epg-context @@ -6182,15 +6251,23 @@ (epg-encrypt-string epg-context (encode-coding-string massaged-text (or encoding 'utf-8)) - (and keypair-mode - (epa-select-keys epg-context - keypair-message))))) + recipients))) ;; validate result -- non-empty + (if (not result-text) + (error "%scryption failed." (if decrypt "De" "En"))) + + + (when (eq keypair-mode 'prompt-save) + ;; set epa-file-encrypt-to in the buffer: + (setq epa-file-encrypt-to (mapcar (lambda (key) + (epg-user-id-string + (car (epg-key-user-id-list key)))) + recipients)) + ;; change the file variable: + (allout-adjust-file-variable "epa-file-encrypt-to" epa-file-encrypt-to)) + (cond - ((not result-text) - (error "%scryption failed." (if decrypt "De" "En"))) - ;; Retry (within limit) if ciphertext contains rejections: ((and (not decrypt) ;; Check for disqualification of this ciphertext: