Mercurial > emacs
comparison lisp/pgg.el @ 66519:20539524a670
(pgg-decrypt): Passing along 'passphrase' in call to pgg-decrypt-region.
(pgg-pending-timers): A new hash for tracking the passphrase cache
timers, so that new ones supercede old ones.
(pgg-add-passphrase-to-cache): Renamed from
`pgg-add-passphrase-cache' to reduce confusion (all callers
changed). Modified to cancel old timers when new ones are added.
(pgg-remove-passphrase-from-cache): Renamed from
`pgg-remove-passphrase-cache' to reduce confusion (all callers
changed). Modified to cancel old timers when their keys are
removed from the cache.
(pgg-cancel-timer): In Emacs, an alias for cancel-timer; in
XEmacs, an indirection to delete-itimer.
(pgg-read-passphrase-from-cache, pgg-read-passphrase): Extracted
pgg-read-passphrase-from-cache from pgg-read-passphrase so users
can only check cache without risk of prompting. Corrected bug in
notruncate behavior.
(pgg-read-passphrase-from-cache, pgg-read-passphrase)
(pgg-add-passphrase-cache, pgg-remove-passphrase-cache): Added
informative docstrings.
(pgg-decrypt): Convey provided passphrase in subordinate call to
pgg-decrypt-region.
(pgg-encrypt-region, pgg-encrypt-symmetric-region)
(pgg-encrypt-symmetric, pgg-encrypt, pgg-decrypt-region)
(pgg-decrypt, pgg-sign-region, pgg-sign): Add optional
'passphrase' argument, so the passphrase can be managed externally
and then passed in to the system.
(pgg-read-passphrase, pgg-add-passphrase-cache)
(pgg-remove-passphrase-cache): Add optional 'notruncate' argument,
so the passphrase cache can be used reliably with identifiers
besides a pgp packet's key id.
(pgg-encrypt-symmetric, pgg-encrypt-symmetric-region):
New user commands for symmetric encryption.
author | Eli Zaretskii <eliz@gnu.org> |
---|---|
date | Sat, 29 Oct 2005 11:29:41 +0000 |
parents | c82982d6cbc4 |
children | 3bd95f4f2941 |
comparison
equal
deleted
inserted
replaced
66518:7cc22b3f2300 | 66519:20539524a670 |
---|---|
2 | 2 |
3 ;; Copyright (C) 1999, 2000, 2002, 2003, 2004, | 3 ;; Copyright (C) 1999, 2000, 2002, 2003, 2004, |
4 ;; 2005 Free Software Foundation, Inc. | 4 ;; 2005 Free Software Foundation, Inc. |
5 | 5 |
6 ;; Author: Daiki Ueno <ueno@unixuser.org> | 6 ;; Author: Daiki Ueno <ueno@unixuser.org> |
7 ;; Symmetric encryption added by: Sascha Wilde <wilde@sha-bang.de> | |
7 ;; Created: 1999/10/28 | 8 ;; Created: 1999/10/28 |
8 ;; Keywords: PGP | 9 ;; Keywords: PGP |
9 | 10 |
10 ;; This file is part of GNU Emacs. | 11 ;; This file is part of GNU Emacs. |
11 | 12 |
65 (let ((window (or (get-buffer-window buffer 'visible) | 66 (let ((window (or (get-buffer-window buffer 'visible) |
66 (split-window-vertically)))) | 67 (split-window-vertically)))) |
67 (set-window-buffer window buffer) | 68 (set-window-buffer window buffer) |
68 (shrink-window-if-larger-than-buffer window))) | 69 (shrink-window-if-larger-than-buffer window))) |
69 | 70 |
71 ;; XXX `pgg-display-output-buffer' is a horrible name for this function. | |
72 ;; It should be something like `pgg-situate-output-or-display-error'. | |
70 (defun pgg-display-output-buffer (start end status) | 73 (defun pgg-display-output-buffer (start end status) |
74 "Situate en/decryption results or pop up an error buffer. | |
75 | |
76 Text from START to END is replaced by contents of output buffer if STATUS | |
77 is true, or else the output buffer is displayed." | |
71 (if status | 78 (if status |
72 (progn | 79 (pgg-situate-output start end) |
73 (delete-region start end) | 80 (pgg-display-error-buffer))) |
74 (insert-buffer-substring pgg-output-buffer) | 81 |
75 (decode-coding-region start (point) buffer-file-coding-system)) | 82 (defun pgg-situate-output (start end) |
76 (let ((temp-buffer-show-function | 83 "Place en/decryption result in place of current text from START to END." |
77 (function pgg-temp-buffer-show-function))) | 84 (delete-region start end) |
78 (with-output-to-temp-buffer pgg-echo-buffer | 85 (insert-buffer-substring pgg-output-buffer) |
79 (set-buffer standard-output) | 86 (decode-coding-region start (point) buffer-file-coding-system)) |
80 (insert-buffer-substring pgg-errors-buffer))))) | 87 |
88 (defun pgg-display-error-buffer () | |
89 "Pop up an error buffer indicating the reason for an en/decryption failure." | |
90 (let ((temp-buffer-show-function | |
91 (function pgg-temp-buffer-show-function))) | |
92 (with-output-to-temp-buffer pgg-echo-buffer | |
93 (set-buffer standard-output) | |
94 (insert-buffer-substring pgg-errors-buffer)))) | |
81 | 95 |
82 (defvar pgg-passphrase-cache (make-vector 7 0)) | 96 (defvar pgg-passphrase-cache (make-vector 7 0)) |
83 | 97 |
84 (defun pgg-read-passphrase (prompt &optional key) | 98 (defvar pgg-pending-timers (make-vector 7 0) |
85 (or (and pgg-cache-passphrase | 99 "Hash table for managing scheduled pgg cache management timers. |
86 key (setq key (pgg-truncate-key-identifier key)) | 100 |
87 (symbol-value (intern-soft key pgg-passphrase-cache))) | 101 We associate key and timer, so the timer can be cancelled if a new |
102 timeout for the key is set while an old one is still pending.") | |
103 | |
104 (defun pgg-read-passphrase (prompt &optional key notruncate) | |
105 "Using PROMPT, obtain passphrase for KEY from cache or user. | |
106 | |
107 Truncate the key to 8 trailing characters unless NOTRUNCATE is true | |
108 \(default false). | |
109 | |
110 Custom variables `pgg-cache-passphrase' and `pgg-passphrase-cache-expiry' | |
111 regulate cache behavior." | |
112 (or (pgg-read-passphrase-from-cache key notruncate) | |
88 (read-passwd prompt))) | 113 (read-passwd prompt))) |
114 | |
115 (defun pgg-read-passphrase-from-cache (key &optional notruncate) | |
116 "Obtain passphrase for KEY from time-limited passphrase cache. | |
117 | |
118 Truncate the key to 8 trailing characters unless NOTRUNCATE is true | |
119 \(default false). | |
120 | |
121 Custom variables `pgg-cache-passphrase' and `pgg-passphrase-cache-expiry' | |
122 regulate cache behavior." | |
123 (and pgg-cache-passphrase | |
124 key (or notruncate | |
125 (setq key (pgg-truncate-key-identifier key))) | |
126 (symbol-value (intern-soft key pgg-passphrase-cache)))) | |
127 | |
128 (defun pgg-add-passphrase-to-cache (key passphrase &optional notruncate) | |
129 "Associate KEY with PASSPHRASE in time-limited passphrase cache. | |
130 | |
131 Truncate the key to 8 trailing characters unless NOTRUNCATE is true | |
132 \(default false). | |
133 | |
134 Custom variables `pgg-cache-passphrase' and `pgg-passphrase-cache-expiry' | |
135 regulate cache behavior." | |
136 | |
137 (let* ((key (if notruncate key (pgg-truncate-key-identifier key))) | |
138 (interned-timer-key (intern-soft key pgg-pending-timers)) | |
139 (old-timer (symbol-value interned-timer-key)) | |
140 new-timer) | |
141 (when old-timer | |
142 (cancel-timer old-timer) | |
143 (unintern interned-timer-key pgg-pending-timers)) | |
144 (set (intern key pgg-passphrase-cache) | |
145 passphrase) | |
146 (set (intern key pgg-pending-timers) | |
147 (pgg-run-at-time pgg-passphrase-cache-expiry nil | |
148 #'pgg-remove-passphrase-from-cache | |
149 key notruncate)))) | |
150 | |
151 (defun pgg-remove-passphrase-from-cache (key &optional notruncate) | |
152 "Omit passphrase associated with KEY in time-limited passphrase cache. | |
153 | |
154 Truncate the key to 8 trailing characters unless NOTRUNCATE is true | |
155 \(default false). | |
156 | |
157 This is a no-op if there is not entry for KEY (eg, it's already expired. | |
158 | |
159 The memory for the passphrase is filled with underscores to clear any | |
160 references to it. | |
161 | |
162 Custom variables `pgg-cache-passphrase' and `pgg-passphrase-cache-expiry' | |
163 regulate cache behavior." | |
164 (let* ((passphrase (pgg-read-passphrase-from-cache key notruncate)) | |
165 (key (if notruncate key (pgg-truncate-key-identifier key))) | |
166 (interned-timer-key (intern-soft key pgg-pending-timers)) | |
167 (old-timer (symbol-value interned-timer-key))) | |
168 (when passphrase | |
169 (fillarray passphrase ?_) | |
170 (unintern key pgg-passphrase-cache)) | |
171 (when old-timer | |
172 (pgg-cancel-timer old-timer) | |
173 (unintern interned-timer-key pgg-pending-timers)))) | |
89 | 174 |
90 (eval-when-compile | 175 (eval-when-compile |
91 (defmacro pgg-run-at-time-1 (time repeat function args) | 176 (defmacro pgg-run-at-time-1 (time repeat function args) |
92 (when (featurep 'xemacs) | 177 (when (featurep 'xemacs) |
93 (if (condition-case nil | 178 (if (condition-case nil |
149 1e-9 (if time (max time 1e-9) 1e-9) | 234 1e-9 (if time (max time 1e-9) 1e-9) |
150 nil t itimers ,repeat ,function ,args)))))) | 235 nil t itimers ,repeat ,function ,args)))))) |
151 | 236 |
152 (eval-and-compile | 237 (eval-and-compile |
153 (if (featurep 'xemacs) | 238 (if (featurep 'xemacs) |
154 (defun pgg-run-at-time (time repeat function &rest args) | 239 (progn |
155 "Emulating function run as `run-at-time'. | 240 (defun pgg-run-at-time (time repeat function &rest args) |
241 "Emulating function run as `run-at-time'. | |
156 TIME should be nil meaning now, or a number of seconds from now. | 242 TIME should be nil meaning now, or a number of seconds from now. |
157 Return an itimer object which can be used in either `delete-itimer' | 243 Return an itimer object which can be used in either `delete-itimer' |
158 or `cancel-timer'." | 244 or `cancel-timer'." |
159 (pgg-run-at-time-1 time repeat function args)) | 245 (pgg-run-at-time-1 time repeat function args)) |
160 (defalias 'pgg-run-at-time 'run-at-time))) | 246 (defun pgg-cancel-timer (timer) |
161 | 247 "Emulate cancel-timer for xemacs." |
162 (defun pgg-add-passphrase-cache (key passphrase) | 248 (let ((delete-itimer 'delete-itimer)) |
163 (setq key (pgg-truncate-key-identifier key)) | 249 (funcall delete-itimer timer))) |
164 (set (intern key pgg-passphrase-cache) | 250 ) |
165 passphrase) | 251 (defalias 'pgg-run-at-time 'run-at-time) |
166 (pgg-run-at-time pgg-passphrase-cache-expiry nil | 252 (defalias 'pgg-cancel-timer 'cancel-timer))) |
167 #'pgg-remove-passphrase-cache | |
168 key)) | |
169 | |
170 (defun pgg-remove-passphrase-cache (key) | |
171 (let ((passphrase (symbol-value (intern-soft key pgg-passphrase-cache)))) | |
172 (when passphrase | |
173 (fillarray passphrase ?_) | |
174 (unintern key pgg-passphrase-cache)))) | |
175 | 253 |
176 (defmacro pgg-convert-lbt-region (start end lbt) | 254 (defmacro pgg-convert-lbt-region (start end lbt) |
177 `(let ((pgg-conversion-end (set-marker (make-marker) ,end))) | 255 `(let ((pgg-conversion-end (set-marker (make-marker) ,end))) |
178 (goto-char ,start) | 256 (goto-char ,start) |
179 (case ,lbt | 257 (case ,lbt |
220 | 298 |
221 ;;; @ interface functions | 299 ;;; @ interface functions |
222 ;;; | 300 ;;; |
223 | 301 |
224 ;;;###autoload | 302 ;;;###autoload |
225 (defun pgg-encrypt-region (start end rcpts &optional sign) | 303 (defun pgg-encrypt-region (start end rcpts &optional sign passphrase) |
226 "Encrypt the current region between START and END for RCPTS. | 304 "Encrypt the current region between START and END for RCPTS. |
227 If optional argument SIGN is non-nil, do a combined sign and encrypt." | 305 |
306 If optional argument SIGN is non-nil, do a combined sign and encrypt. | |
307 | |
308 If optional PASSPHRASE is not specified, it will be obtained from the | |
309 passphrase cache or user." | |
228 (interactive | 310 (interactive |
229 (list (region-beginning)(region-end) | 311 (list (region-beginning)(region-end) |
230 (split-string (read-string "Recipients: ") "[ \t,]+"))) | 312 (split-string (read-string "Recipients: ") "[ \t,]+"))) |
231 (let ((status | 313 (let ((status |
232 (pgg-save-coding-system start end | 314 (pgg-save-coding-system start end |
233 (pgg-invoke "encrypt-region" (or pgg-scheme pgg-default-scheme) | 315 (pgg-invoke "encrypt-region" (or pgg-scheme pgg-default-scheme) |
234 (point-min) (point-max) rcpts sign)))) | 316 (point-min) (point-max) rcpts sign passphrase)))) |
235 (when (interactive-p) | 317 (when (interactive-p) |
236 (pgg-display-output-buffer start end status)) | 318 (pgg-display-output-buffer start end status)) |
237 status)) | 319 status)) |
238 | 320 |
239 ;;;###autoload | 321 ;;;###autoload |
240 (defun pgg-encrypt (rcpts &optional sign start end) | 322 (defun pgg-encrypt-symmetric-region (start end &optional passphrase) |
323 "Encrypt the current region between START and END symmetric with passphrase. | |
324 | |
325 If optional PASSPHRASE is not specified, it will be obtained from the | |
326 cache or user." | |
327 (interactive "r") | |
328 (let ((status | |
329 (pgg-save-coding-system start end | |
330 (pgg-invoke "encrypt-symmetric-region" | |
331 (or pgg-scheme pgg-default-scheme) | |
332 (point-min) (point-max) passphrase)))) | |
333 (when (interactive-p) | |
334 (pgg-display-output-buffer start end status)) | |
335 status)) | |
336 | |
337 ;;;###autoload | |
338 (defun pgg-encrypt-symmetric (&optional start end passphrase) | |
339 "Encrypt the current buffer using a symmetric, rather than key-pair, cipher. | |
340 | |
341 If optional arguments START and END are specified, only encrypt within | |
342 the region. | |
343 | |
344 If optional PASSPHRASE is not specified, it will be obtained from the | |
345 passphrase cache or user." | |
346 (interactive) | |
347 (let* ((start (or start (point-min))) | |
348 (end (or end (point-max))) | |
349 (status (pgg-encrypt-symmetric-region start end passphrase))) | |
350 (when (interactive-p) | |
351 (pgg-display-output-buffer start end status)) | |
352 status)) | |
353 | |
354 ;;;###autoload | |
355 (defun pgg-encrypt (rcpts &optional sign start end passphrase) | |
241 "Encrypt the current buffer for RCPTS. | 356 "Encrypt the current buffer for RCPTS. |
357 | |
242 If optional argument SIGN is non-nil, do a combined sign and encrypt. | 358 If optional argument SIGN is non-nil, do a combined sign and encrypt. |
359 | |
243 If optional arguments START and END are specified, only encrypt within | 360 If optional arguments START and END are specified, only encrypt within |
244 the region." | 361 the region. |
362 | |
363 If optional PASSPHRASE is not specified, it will be obtained from the | |
364 passphrase cache or user." | |
245 (interactive (list (split-string (read-string "Recipients: ") "[ \t,]+"))) | 365 (interactive (list (split-string (read-string "Recipients: ") "[ \t,]+"))) |
246 (let* ((start (or start (point-min))) | 366 (let* ((start (or start (point-min))) |
247 (end (or end (point-max))) | 367 (end (or end (point-max))) |
248 (status (pgg-encrypt-region start end rcpts sign))) | 368 (status (pgg-encrypt-region start end rcpts sign passphrase))) |
249 (when (interactive-p) | 369 (when (interactive-p) |
250 (pgg-display-output-buffer start end status)) | 370 (pgg-display-output-buffer start end status)) |
251 status)) | 371 status)) |
252 | 372 |
253 ;;;###autoload | 373 ;;;###autoload |
254 (defun pgg-decrypt-region (start end) | 374 (defun pgg-decrypt-region (start end &optional passphrase) |
255 "Decrypt the current region between START and END." | 375 "Decrypt the current region between START and END. |
376 | |
377 If optional PASSPHRASE is not specified, it will be obtained from the | |
378 passphrase cache or user." | |
256 (interactive "r") | 379 (interactive "r") |
257 (let* ((buf (current-buffer)) | 380 (let* ((buf (current-buffer)) |
258 (status | 381 (status |
259 (pgg-save-coding-system start end | 382 (pgg-save-coding-system start end |
260 (pgg-invoke "decrypt-region" (or pgg-scheme pgg-default-scheme) | 383 (pgg-invoke "decrypt-region" (or pgg-scheme pgg-default-scheme) |
261 (point-min) (point-max))))) | 384 (point-min) (point-max) passphrase)))) |
262 (when (interactive-p) | 385 (when (interactive-p) |
263 (pgg-display-output-buffer start end status)) | 386 (pgg-display-output-buffer start end status)) |
264 status)) | 387 status)) |
265 | 388 |
266 ;;;###autoload | 389 ;;;###autoload |
267 (defun pgg-decrypt (&optional start end) | 390 (defun pgg-decrypt (&optional start end passphrase) |
268 "Decrypt the current buffer. | 391 "Decrypt the current buffer. |
392 | |
269 If optional arguments START and END are specified, only decrypt within | 393 If optional arguments START and END are specified, only decrypt within |
270 the region." | 394 the region. |
395 | |
396 If optional PASSPHRASE is not specified, it will be obtained from the | |
397 passphrase cache or user." | |
271 (interactive "") | 398 (interactive "") |
272 (let* ((start (or start (point-min))) | 399 (let* ((start (or start (point-min))) |
273 (end (or end (point-max))) | 400 (end (or end (point-max))) |
274 (status (pgg-decrypt-region start end))) | 401 (status (pgg-decrypt-region start end passphrase))) |
275 (when (interactive-p) | 402 (when (interactive-p) |
276 (pgg-display-output-buffer start end status)) | 403 (pgg-display-output-buffer start end status)) |
277 status)) | 404 status)) |
278 | 405 |
279 ;;;###autoload | 406 ;;;###autoload |
280 (defun pgg-sign-region (start end &optional cleartext) | 407 (defun pgg-sign-region (start end &optional cleartext passphrase) |
281 "Make the signature from text between START and END. | 408 "Make the signature from text between START and END. |
409 | |
282 If the optional 3rd argument CLEARTEXT is non-nil, it does not create | 410 If the optional 3rd argument CLEARTEXT is non-nil, it does not create |
283 a detached signature. | 411 a detached signature. |
412 | |
284 If this function is called interactively, CLEARTEXT is enabled | 413 If this function is called interactively, CLEARTEXT is enabled |
285 and the the output is displayed." | 414 and the the output is displayed. |
415 | |
416 If optional PASSPHRASE is not specified, it will be obtained from the | |
417 passphrase cache or user." | |
286 (interactive "r") | 418 (interactive "r") |
287 (let ((status (pgg-save-coding-system start end | 419 (let ((status (pgg-save-coding-system start end |
288 (pgg-invoke "sign-region" (or pgg-scheme pgg-default-scheme) | 420 (pgg-invoke "sign-region" (or pgg-scheme pgg-default-scheme) |
289 (point-min) (point-max) | 421 (point-min) (point-max) |
290 (or (interactive-p) cleartext))))) | 422 (or (interactive-p) cleartext) |
291 (when (interactive-p) | 423 passphrase)))) |
292 (pgg-display-output-buffer start end status)) | 424 (when (interactive-p) |
293 status)) | 425 (pgg-display-output-buffer start end status)) |
294 | 426 status)) |
295 ;;;###autoload | 427 |
296 (defun pgg-sign (&optional cleartext start end) | 428 ;;;###autoload |
429 (defun pgg-sign (&optional cleartext start end passphrase) | |
297 "Sign the current buffer. | 430 "Sign the current buffer. |
431 | |
298 If the optional argument CLEARTEXT is non-nil, it does not create a | 432 If the optional argument CLEARTEXT is non-nil, it does not create a |
299 detached signature. | 433 detached signature. |
434 | |
300 If optional arguments START and END are specified, only sign data | 435 If optional arguments START and END are specified, only sign data |
301 within the region. | 436 within the region. |
437 | |
302 If this function is called interactively, CLEARTEXT is enabled | 438 If this function is called interactively, CLEARTEXT is enabled |
303 and the the output is displayed." | 439 and the the output is displayed. |
440 | |
441 If optional PASSPHRASE is not specified, it will be obtained from the | |
442 passphrase cache or user." | |
304 (interactive "") | 443 (interactive "") |
305 (let* ((start (or start (point-min))) | 444 (let* ((start (or start (point-min))) |
306 (end (or end (point-max))) | 445 (end (or end (point-max))) |
307 (status (pgg-sign-region start end (or (interactive-p) cleartext)))) | 446 (status (pgg-sign-region start end |
308 (when (interactive-p) | 447 (or (interactive-p) cleartext) |
309 (pgg-display-output-buffer start end status)) | 448 passphrase))) |
310 status)) | 449 (when (interactive-p) |
311 | 450 (pgg-display-output-buffer start end status)) |
451 status)) | |
452 | |
312 ;;;###autoload | 453 ;;;###autoload |
313 (defun pgg-verify-region (start end &optional signature fetch) | 454 (defun pgg-verify-region (start end &optional signature fetch) |
314 "Verify the current region between START and END. | 455 "Verify the current region between START and END. |
315 If the optional 3rd argument SIGNATURE is non-nil, it is treated as | 456 If the optional 3rd argument SIGNATURE is non-nil, it is treated as |
316 the detached signature of the current region. | 457 the detached signature of the current region. |