comparison lisp/allout.el @ 111984:f5276a518424

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.
author Ken Manheimer <ken.manheimer@gmail.com>
date Thu, 16 Dec 2010 02:39:17 -0500
parents a348c631aeb8
children a933a2eaafaf
comparison
equal deleted inserted replaced
111983:a348c631aeb8 111984:f5276a518424
1916 Topics pending encryption are, by default, automatically 1916 Topics pending encryption are, by default, automatically
1917 encrypted during file saves, including checkpoint saves, to avoid 1917 encrypted during file saves, including checkpoint saves, to avoid
1918 exposing the plain text of encrypted topics in the file system. 1918 exposing the plain text of encrypted topics in the file system.
1919 If the content of the topic containing the cursor was encrypted 1919 If the content of the topic containing the cursor was encrypted
1920 for a save, it is automatically decrypted for continued editing. 1920 for a save, it is automatically decrypted for continued editing.
1921
1922 PROBLEM: Attempting symmetric decryption with an incorrect key
1923 not only fails, but the incorrect key seems to be associated with
1924 the specific entry in the gpg cache, so that you do not get an
1925 opportunity to override the incorrect key and decrypt that
1926 entry. (Decryption of other entries is not affected.) To clear
1927 this problem, clear your gpg-agent's cache by sending it a '-HUP'
1928 signal.
1921 1929
1922 See `allout-toggle-current-subtree-encryption' function docstring 1930 See `allout-toggle-current-subtree-encryption' function docstring
1923 and `allout-encrypt-unencrypted-on-saves' customization variable 1931 and `allout-encrypt-unencrypted-on-saves' customization variable
1924 for details. 1932 for details.
1925 1933
5973 5981
5974 Allout uses emacs 'epg' libary to perform encryption. Symmetric 5982 Allout uses emacs 'epg' libary to perform encryption. Symmetric
5975 and keypair encryption are supported. All encryption is ascii 5983 and keypair encryption are supported. All encryption is ascii
5976 armored. 5984 armored.
5977 5985
5978 When encrypting, optional KEYMODE-CUE universal argument greater 5986 Entry encryption defaults to symmetric key mode unless keypair
5979 than 1 causes prompting for recipients for public-key keypair 5987 recipients are associated with the file \(see
5980 encryption. Otherwise a symmetric mode is assumed for 5988 `epa-file-encrypt-to') or the function is invoked with a
5989 \(KEYMODE-CUE) universal argument greater than 1.
5990
5991 When encrypting, KEYMODE-CUE universal argument greater than 1
5992 causes prompting for recipients for public-key keypair
5993 encryption. Selecting no recipients results in symmetric key
5981 encryption. 5994 encryption.
5995
5996 Further, encrypting with a KEYMODE-CUE universal argument greater
5997 than 4 - eg, preceded by a doubled Ctrl-U - causes association of
5998 the specified recipients with the file, replacing those currently
5999 associated with it. This can be used to deassociate any
6000 recipients with the file, by selecting no recipients in the
6001 dialog.
5982 6002
5983 Encrypted topic's bullets are set to a `~' to signal that the 6003 Encrypted topic's bullets are set to a `~' to signal that the
5984 contents of the topic (body and subtopics, but not heading) is 6004 contents of the topic (body and subtopics, but not heading) is
5985 pending encryption or encrypted. `*' asterisk immediately after 6005 pending encryption or encrypted. `*' asterisk immediately after
5986 the bullet signals that the body is encrypted, its absence means 6006 the bullet signals that the body is encrypted, its absence means
6002 (allout-toggle-subtree-encryption keymode-cue))) 6022 (allout-toggle-subtree-encryption keymode-cue)))
6003 ;;;_ > allout-toggle-subtree-encryption (&optional keymode-cue) 6023 ;;;_ > allout-toggle-subtree-encryption (&optional keymode-cue)
6004 (defun allout-toggle-subtree-encryption (&optional keymode-cue) 6024 (defun allout-toggle-subtree-encryption (&optional keymode-cue)
6005 "Encrypt clear text or decrypt encoded topic contents (body and subtopics.) 6025 "Encrypt clear text or decrypt encoded topic contents (body and subtopics.)
6006 6026
6007 When encrypting, optional KEYMODE-CUE universal argument greater than 6027 Entry encryption defaults to symmetric key mode unless keypair
6008 1 provokes prompting for recipients for public-key keypair 6028 recipients are associated with the file \(see
6009 encryption, otherwise a symmetric-mode passphrase is solicited. 6029 `epa-file-encrypt-to') or the function is invoked with a
6010 6030 \(KEYMODE-CUE) universal argument greater than 1.
6011 Encryption depends on the emacs epg library. 6031
6032 When encrypting, KEYMODE-CUE universal argument greater than 1
6033 causes prompting for recipients for public-key keypair
6034 encryption. Selecting no recipients results in symmetric key
6035 encryption.
6036
6037 Further, encrypting with a KEYMODE-CUE universal argument greater
6038 than 4 - eg, preceded by a doubled Ctrl-U - causes association of
6039 the specified recipients with the file, replacing those currently
6040 associated with it. This can be used to deassociate any
6041 recipients with the file, by selecting no recipients in the
6042 dialog.
6043
6044 Encryption and decryption uses the emacs epg library.
6012 6045
6013 Encrypted text will be ascii-armored. 6046 Encrypted text will be ascii-armored.
6014 6047
6015 See `allout-toggle-current-subtree-encryption' for more details." 6048 See `allout-toggle-current-subtree-encryption' for more details."
6016 6049
6028 (after-bullet-pos (point)) 6061 (after-bullet-pos (point))
6029 (was-encrypted 6062 (was-encrypted
6030 (progn (if (= (point-max) after-bullet-pos) 6063 (progn (if (= (point-max) after-bullet-pos)
6031 (error "no body to encrypt")) 6064 (error "no body to encrypt"))
6032 (allout-encrypted-topic-p))) 6065 (allout-encrypted-topic-p)))
6033 (keypair-mode (> (prefix-numeric-value keymode-cue) 1))
6034 (was-collapsed (if (not (search-forward "\n" nil t)) 6066 (was-collapsed (if (not (search-forward "\n" nil t))
6035 nil 6067 nil
6036 (backward-char 1) 6068 (backward-char 1)
6037 (allout-hidden-p))) 6069 (allout-hidden-p)))
6038 (subtree-beg (1+ (point))) 6070 (subtree-beg (1+ (point)))
6072 (allout-adjust-file-variable "buffer-file-coding-system" 6104 (allout-adjust-file-variable "buffer-file-coding-system"
6073 buffer-file-coding-system))) 6105 buffer-file-coding-system)))
6074 6106
6075 (setq result-text 6107 (setq result-text
6076 (allout-encrypt-string subject-text was-encrypted 6108 (allout-encrypt-string subject-text was-encrypted
6077 (current-buffer) keypair-mode)) 6109 (current-buffer) keymode-cue))
6078 6110
6079 ;; Replace the subtree with the processed product. 6111 ;; Replace the subtree with the processed product.
6080 (allout-unprotected 6112 (allout-unprotected
6081 (progn 6113 (progn
6082 (set-buffer allout-buffer) 6114 (set-buffer allout-buffer)
6103 ;; Add the is-encrypted bullet qualifier: 6135 ;; Add the is-encrypted bullet qualifier:
6104 (goto-char after-bullet-pos) 6136 (goto-char after-bullet-pos)
6105 (insert "*")))) 6137 (insert "*"))))
6106 (run-hook-with-args 'allout-structure-added-hook 6138 (run-hook-with-args 'allout-structure-added-hook
6107 bullet-pos subtree-end)))) 6139 bullet-pos subtree-end))))
6108 ;;;_ > allout-encrypt-string (text decrypt allout-buffer keypair-mode 6140 ;;;_ > allout-encrypt-string (text decrypt allout-buffer keymode-cue
6109 ;;; &optional rejected) 6141 ;;; &optional rejected)
6110 (defun allout-encrypt-string (text decrypt allout-buffer keypair-mode 6142 (defun allout-encrypt-string (text decrypt allout-buffer keymode-cue
6111 &optional rejected) 6143 &optional rejected)
6112 "Encrypt or decrypt message TEXT. 6144 "Encrypt or decrypt message TEXT.
6113 6145
6114 Returns the resulting string, or nil if the transformation fails. 6146 Returns the resulting string, or nil if the transformation fails.
6115 6147
6116 If DECRYPT is true (default false), then decrypt instead of encrypt. 6148 If DECRYPT is true (default false), then decrypt instead of encrypt.
6117 6149
6118 ALLOUT-BUFFER identifies the buffer containing the text. 6150 ALLOUT-BUFFER identifies the buffer containing the text.
6119 6151
6120 If KEYPAIR-MODE is non-nil, encryption involves prompting for 6152 Entry encryption defaults to symmetric key mode unless keypair
6121 keypair recipients. 6153 recipients are associated with the file \(see
6154 `epa-file-encrypt-to') or the function is invoked with a
6155 \(KEYMODE-CUE) universal argument greater than 1.
6156
6157 When encrypting, KEYMODE-CUE universal argument greater than 1
6158 causes prompting for recipients for public-key keypair
6159 encryption. Selecting no recipients results in symmetric key
6160 encryption.
6161
6162 Further, encrypting with a KEYMODE-CUE universal argument greater
6163 than 4 - eg, preceded by a doubled Ctrl-U - causes association of
6164 the specified recipients with the file, replacing those currently
6165 associated with it. This can be used to deassociate any
6166 recipients with the file, by selecting no recipients in the
6167 dialog.
6122 6168
6123 Optional REJECTED is for internal use, to convey the number of 6169 Optional REJECTED is for internal use, to convey the number of
6124 rejections due to matches against 6170 rejections due to matches against
6125 `allout-encryption-ciphertext-rejection-regexps', as limited by 6171 `allout-encryption-ciphertext-rejection-regexps', as limited by
6126 `allout-encryption-ciphertext-rejection-ceiling'." 6172 `allout-encryption-ciphertext-rejection-ceiling'."
6127 6173
6128 (require 'epg) 6174 (require 'epg)
6129 (require 'epa) 6175 (require 'epa)
6130 6176
6131 (let* ((epg-context (epg-make-context nil t)) 6177 (let* ((epg-context (let* ((context (epg-make-context nil t)))
6178 (epg-context-set-passphrase-callback
6179 context #'epa-passphrase-callback-function)
6180 context))
6132 (encoding (with-current-buffer allout-buffer 6181 (encoding (with-current-buffer allout-buffer
6133 buffer-file-coding-system)) 6182 buffer-file-coding-system))
6134 (multibyte (with-current-buffer allout-buffer 6183 (multibyte (with-current-buffer allout-buffer
6135 enable-multibyte-characters)) 6184 enable-multibyte-characters))
6136 ;; "sanitization" avoids encryption results that are outline structure. 6185 ;; "sanitization" avoids encryption results that are outline structure.
6143 (allout-get-configvar-values 6192 (allout-get-configvar-values
6144 rejection-regexps))) 6193 rejection-regexps)))
6145 (rejected (or rejected 0)) 6194 (rejected (or rejected 0))
6146 (rejections-left (- allout-encryption-ciphertext-rejection-ceiling 6195 (rejections-left (- allout-encryption-ciphertext-rejection-ceiling
6147 rejected)) 6196 rejected))
6148 (keypair-message (concat "Select encryption recipients.\n Not" 6197 (keypair-mode (cond (decrypt 'decrypting)
6149 " selecting any causes" 6198 ((<= (prefix-numeric-value keymode-cue) 1)
6150 " symmetric encryption. ")) 6199 'default)
6200 ((<= (prefix-numeric-value keymode-cue) 4)
6201 'prompt)
6202 ((> (prefix-numeric-value keymode-cue) 4)
6203 'prompt-save)))
6204 (keypair-message (concat "Select encryption recipients.\n"
6205 "Symmetric encryption is done if no"
6206 " recipients are selected. "))
6207 (encrypt-to (and (boundp 'epa-file-encrypt-to) epa-file-encrypt-to))
6151 recipients 6208 recipients
6152 massaged-text 6209 massaged-text
6153 result-text 6210 result-text
6154 ) 6211 )
6155 6212
6172 (save-match-data 6229 (save-match-data
6173 (while (re-search-forward re nil t) 6230 (while (re-search-forward re nil t)
6174 (replace-match replacement nil nil)))))) 6231 (replace-match replacement nil nil))))))
6175 (setq massaged-text (buffer-substring-no-properties (point-min) 6232 (setq massaged-text (buffer-substring-no-properties (point-min)
6176 (point-max)))) 6233 (point-max))))
6234 ;; determine key mode and, if keypair, recipients:
6235 (setq recipients
6236 (case keypair-mode
6237
6238 (decrypting nil)
6239
6240 (default (if encrypt-to (epg-list-keys epg-context encrypt-to)))
6241
6242 ((prompt prompt-save)
6243 (save-window-excursion
6244 (epa-select-keys epg-context keypair-message)))))
6245
6177 (setq result-text 6246 (setq result-text
6178 (if decrypt 6247 (if decrypt
6179 (epg-decrypt-string epg-context 6248 (epg-decrypt-string epg-context
6180 (encode-coding-string massaged-text 6249 (encode-coding-string massaged-text
6181 (or encoding 'utf-8))) 6250 (or encoding 'utf-8)))
6182 (epg-encrypt-string epg-context 6251 (epg-encrypt-string epg-context
6183 (encode-coding-string massaged-text 6252 (encode-coding-string massaged-text
6184 (or encoding 'utf-8)) 6253 (or encoding 'utf-8))
6185 (and keypair-mode 6254 recipients)))
6186 (epa-select-keys epg-context
6187 keypair-message)))))
6188 6255
6189 ;; validate result -- non-empty 6256 ;; validate result -- non-empty
6257 (if (not result-text)
6258 (error "%scryption failed." (if decrypt "De" "En")))
6259
6260
6261 (when (eq keypair-mode 'prompt-save)
6262 ;; set epa-file-encrypt-to in the buffer:
6263 (setq epa-file-encrypt-to (mapcar (lambda (key)
6264 (epg-user-id-string
6265 (car (epg-key-user-id-list key))))
6266 recipients))
6267 ;; change the file variable:
6268 (allout-adjust-file-variable "epa-file-encrypt-to" epa-file-encrypt-to))
6269
6190 (cond 6270 (cond
6191 ((not result-text)
6192 (error "%scryption failed." (if decrypt "De" "En")))
6193
6194 ;; Retry (within limit) if ciphertext contains rejections: 6271 ;; Retry (within limit) if ciphertext contains rejections:
6195 ((and (not decrypt) 6272 ((and (not decrypt)
6196 ;; Check for disqualification of this ciphertext: 6273 ;; Check for disqualification of this ciphertext:
6197 (let ((regexps reject-ciphertext-regexps) 6274 (let ((regexps reject-ciphertext-regexps)
6198 reject-it) 6275 reject-it)