Mercurial > emacs
changeset 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 | 7cc22b3f2300 |
children | 67afcf271a8f |
files | lisp/pgg.el |
diffstat | 1 files changed, 199 insertions(+), 58 deletions(-) [+] |
line wrap: on
line diff
--- a/lisp/pgg.el Sat Oct 29 05:09:05 2005 +0000 +++ b/lisp/pgg.el Sat Oct 29 11:29:41 2005 +0000 @@ -4,6 +4,7 @@ ;; 2005 Free Software Foundation, Inc. ;; Author: Daiki Ueno <ueno@unixuser.org> +;; Symmetric encryption added by: Sascha Wilde <wilde@sha-bang.de> ;; Created: 1999/10/28 ;; Keywords: PGP @@ -67,26 +68,110 @@ (set-window-buffer window buffer) (shrink-window-if-larger-than-buffer window))) +;; XXX `pgg-display-output-buffer' is a horrible name for this function. +;; It should be something like `pgg-situate-output-or-display-error'. (defun pgg-display-output-buffer (start end status) + "Situate en/decryption results or pop up an error buffer. + +Text from START to END is replaced by contents of output buffer if STATUS +is true, or else the output buffer is displayed." (if status - (progn - (delete-region start end) - (insert-buffer-substring pgg-output-buffer) - (decode-coding-region start (point) buffer-file-coding-system)) - (let ((temp-buffer-show-function - (function pgg-temp-buffer-show-function))) - (with-output-to-temp-buffer pgg-echo-buffer - (set-buffer standard-output) - (insert-buffer-substring pgg-errors-buffer))))) + (pgg-situate-output start end) + (pgg-display-error-buffer))) + +(defun pgg-situate-output (start end) + "Place en/decryption result in place of current text from START to END." + (delete-region start end) + (insert-buffer-substring pgg-output-buffer) + (decode-coding-region start (point) buffer-file-coding-system)) + +(defun pgg-display-error-buffer () + "Pop up an error buffer indicating the reason for an en/decryption failure." + (let ((temp-buffer-show-function + (function pgg-temp-buffer-show-function))) + (with-output-to-temp-buffer pgg-echo-buffer + (set-buffer standard-output) + (insert-buffer-substring pgg-errors-buffer)))) (defvar pgg-passphrase-cache (make-vector 7 0)) -(defun pgg-read-passphrase (prompt &optional key) - (or (and pgg-cache-passphrase - key (setq key (pgg-truncate-key-identifier key)) - (symbol-value (intern-soft key pgg-passphrase-cache))) +(defvar pgg-pending-timers (make-vector 7 0) + "Hash table for managing scheduled pgg cache management timers. + +We associate key and timer, so the timer can be cancelled if a new +timeout for the key is set while an old one is still pending.") + +(defun pgg-read-passphrase (prompt &optional key notruncate) + "Using PROMPT, obtain passphrase for KEY from cache or user. + +Truncate the key to 8 trailing characters unless NOTRUNCATE is true +\(default false). + +Custom variables `pgg-cache-passphrase' and `pgg-passphrase-cache-expiry' +regulate cache behavior." + (or (pgg-read-passphrase-from-cache key notruncate) (read-passwd prompt))) +(defun pgg-read-passphrase-from-cache (key &optional notruncate) + "Obtain passphrase for KEY from time-limited passphrase cache. + +Truncate the key to 8 trailing characters unless NOTRUNCATE is true +\(default false). + +Custom variables `pgg-cache-passphrase' and `pgg-passphrase-cache-expiry' +regulate cache behavior." + (and pgg-cache-passphrase + key (or notruncate + (setq key (pgg-truncate-key-identifier key))) + (symbol-value (intern-soft key pgg-passphrase-cache)))) + +(defun pgg-add-passphrase-to-cache (key passphrase &optional notruncate) + "Associate KEY with PASSPHRASE in time-limited passphrase cache. + +Truncate the key to 8 trailing characters unless NOTRUNCATE is true +\(default false). + +Custom variables `pgg-cache-passphrase' and `pgg-passphrase-cache-expiry' +regulate cache behavior." + + (let* ((key (if notruncate key (pgg-truncate-key-identifier key))) + (interned-timer-key (intern-soft key pgg-pending-timers)) + (old-timer (symbol-value interned-timer-key)) + new-timer) + (when old-timer + (cancel-timer old-timer) + (unintern interned-timer-key pgg-pending-timers)) + (set (intern key pgg-passphrase-cache) + passphrase) + (set (intern key pgg-pending-timers) + (pgg-run-at-time pgg-passphrase-cache-expiry nil + #'pgg-remove-passphrase-from-cache + key notruncate)))) + +(defun pgg-remove-passphrase-from-cache (key &optional notruncate) + "Omit passphrase associated with KEY in time-limited passphrase cache. + +Truncate the key to 8 trailing characters unless NOTRUNCATE is true +\(default false). + +This is a no-op if there is not entry for KEY (eg, it's already expired. + +The memory for the passphrase is filled with underscores to clear any +references to it. + +Custom variables `pgg-cache-passphrase' and `pgg-passphrase-cache-expiry' +regulate cache behavior." + (let* ((passphrase (pgg-read-passphrase-from-cache key notruncate)) + (key (if notruncate key (pgg-truncate-key-identifier key))) + (interned-timer-key (intern-soft key pgg-pending-timers)) + (old-timer (symbol-value interned-timer-key))) + (when passphrase + (fillarray passphrase ?_) + (unintern key pgg-passphrase-cache)) + (when old-timer + (pgg-cancel-timer old-timer) + (unintern interned-timer-key pgg-pending-timers)))) + (eval-when-compile (defmacro pgg-run-at-time-1 (time repeat function args) (when (featurep 'xemacs) @@ -151,27 +236,20 @@ (eval-and-compile (if (featurep 'xemacs) - (defun pgg-run-at-time (time repeat function &rest args) - "Emulating function run as `run-at-time'. + (progn + (defun pgg-run-at-time (time repeat function &rest args) + "Emulating function run as `run-at-time'. TIME should be nil meaning now, or a number of seconds from now. Return an itimer object which can be used in either `delete-itimer' or `cancel-timer'." - (pgg-run-at-time-1 time repeat function args)) - (defalias 'pgg-run-at-time 'run-at-time))) - -(defun pgg-add-passphrase-cache (key passphrase) - (setq key (pgg-truncate-key-identifier key)) - (set (intern key pgg-passphrase-cache) - passphrase) - (pgg-run-at-time pgg-passphrase-cache-expiry nil - #'pgg-remove-passphrase-cache - key)) - -(defun pgg-remove-passphrase-cache (key) - (let ((passphrase (symbol-value (intern-soft key pgg-passphrase-cache)))) - (when passphrase - (fillarray passphrase ?_) - (unintern key pgg-passphrase-cache)))) + (pgg-run-at-time-1 time repeat function args)) + (defun pgg-cancel-timer (timer) + "Emulate cancel-timer for xemacs." + (let ((delete-itimer 'delete-itimer)) + (funcall delete-itimer timer))) + ) + (defalias 'pgg-run-at-time 'run-at-time) + (defalias 'pgg-cancel-timer 'cancel-timer))) (defmacro pgg-convert-lbt-region (start end lbt) `(let ((pgg-conversion-end (set-marker (make-marker) ,end))) @@ -222,93 +300,156 @@ ;;; ;;;###autoload -(defun pgg-encrypt-region (start end rcpts &optional sign) +(defun pgg-encrypt-region (start end rcpts &optional sign passphrase) "Encrypt the current region between START and END for RCPTS. -If optional argument SIGN is non-nil, do a combined sign and encrypt." + +If optional argument SIGN is non-nil, do a combined sign and encrypt. + +If optional PASSPHRASE is not specified, it will be obtained from the +passphrase cache or user." (interactive (list (region-beginning)(region-end) (split-string (read-string "Recipients: ") "[ \t,]+"))) (let ((status (pgg-save-coding-system start end (pgg-invoke "encrypt-region" (or pgg-scheme pgg-default-scheme) - (point-min) (point-max) rcpts sign)))) + (point-min) (point-max) rcpts sign passphrase)))) + (when (interactive-p) + (pgg-display-output-buffer start end status)) + status)) + +;;;###autoload +(defun pgg-encrypt-symmetric-region (start end &optional passphrase) + "Encrypt the current region between START and END symmetric with passphrase. + +If optional PASSPHRASE is not specified, it will be obtained from the +cache or user." + (interactive "r") + (let ((status + (pgg-save-coding-system start end + (pgg-invoke "encrypt-symmetric-region" + (or pgg-scheme pgg-default-scheme) + (point-min) (point-max) passphrase)))) (when (interactive-p) (pgg-display-output-buffer start end status)) status)) ;;;###autoload -(defun pgg-encrypt (rcpts &optional sign start end) - "Encrypt the current buffer for RCPTS. -If optional argument SIGN is non-nil, do a combined sign and encrypt. +(defun pgg-encrypt-symmetric (&optional start end passphrase) + "Encrypt the current buffer using a symmetric, rather than key-pair, cipher. + If optional arguments START and END are specified, only encrypt within -the region." - (interactive (list (split-string (read-string "Recipients: ") "[ \t,]+"))) +the region. + +If optional PASSPHRASE is not specified, it will be obtained from the +passphrase cache or user." + (interactive) (let* ((start (or start (point-min))) (end (or end (point-max))) - (status (pgg-encrypt-region start end rcpts sign))) + (status (pgg-encrypt-symmetric-region start end passphrase))) (when (interactive-p) (pgg-display-output-buffer start end status)) status)) ;;;###autoload -(defun pgg-decrypt-region (start end) - "Decrypt the current region between START and END." - (interactive "r") - (let* ((buf (current-buffer)) - (status - (pgg-save-coding-system start end - (pgg-invoke "decrypt-region" (or pgg-scheme pgg-default-scheme) - (point-min) (point-max))))) +(defun pgg-encrypt (rcpts &optional sign start end passphrase) + "Encrypt the current buffer for RCPTS. + +If optional argument SIGN is non-nil, do a combined sign and encrypt. + +If optional arguments START and END are specified, only encrypt within +the region. + +If optional PASSPHRASE is not specified, it will be obtained from the +passphrase cache or user." + (interactive (list (split-string (read-string "Recipients: ") "[ \t,]+"))) + (let* ((start (or start (point-min))) + (end (or end (point-max))) + (status (pgg-encrypt-region start end rcpts sign passphrase))) (when (interactive-p) (pgg-display-output-buffer start end status)) status)) ;;;###autoload -(defun pgg-decrypt (&optional start end) +(defun pgg-decrypt-region (start end &optional passphrase) + "Decrypt the current region between START and END. + +If optional PASSPHRASE is not specified, it will be obtained from the +passphrase cache or user." + (interactive "r") + (let* ((buf (current-buffer)) + (status + (pgg-save-coding-system start end + (pgg-invoke "decrypt-region" (or pgg-scheme pgg-default-scheme) + (point-min) (point-max) passphrase)))) + (when (interactive-p) + (pgg-display-output-buffer start end status)) + status)) + +;;;###autoload +(defun pgg-decrypt (&optional start end passphrase) "Decrypt the current buffer. + If optional arguments START and END are specified, only decrypt within -the region." +the region. + +If optional PASSPHRASE is not specified, it will be obtained from the +passphrase cache or user." (interactive "") (let* ((start (or start (point-min))) (end (or end (point-max))) - (status (pgg-decrypt-region start end))) + (status (pgg-decrypt-region start end passphrase))) (when (interactive-p) (pgg-display-output-buffer start end status)) status)) ;;;###autoload -(defun pgg-sign-region (start end &optional cleartext) +(defun pgg-sign-region (start end &optional cleartext passphrase) "Make the signature from text between START and END. + If the optional 3rd argument CLEARTEXT is non-nil, it does not create a detached signature. + If this function is called interactively, CLEARTEXT is enabled -and the the output is displayed." +and the the output is displayed. + +If optional PASSPHRASE is not specified, it will be obtained from the +passphrase cache or user." (interactive "r") (let ((status (pgg-save-coding-system start end (pgg-invoke "sign-region" (or pgg-scheme pgg-default-scheme) (point-min) (point-max) - (or (interactive-p) cleartext))))) + (or (interactive-p) cleartext) + passphrase)))) (when (interactive-p) (pgg-display-output-buffer start end status)) status)) ;;;###autoload -(defun pgg-sign (&optional cleartext start end) +(defun pgg-sign (&optional cleartext start end passphrase) "Sign the current buffer. + If the optional argument CLEARTEXT is non-nil, it does not create a detached signature. + If optional arguments START and END are specified, only sign data within the region. + If this function is called interactively, CLEARTEXT is enabled -and the the output is displayed." +and the the output is displayed. + +If optional PASSPHRASE is not specified, it will be obtained from the +passphrase cache or user." (interactive "") (let* ((start (or start (point-min))) (end (or end (point-max))) - (status (pgg-sign-region start end (or (interactive-p) cleartext)))) + (status (pgg-sign-region start end + (or (interactive-p) cleartext) + passphrase))) (when (interactive-p) (pgg-display-output-buffer start end status)) status)) - + ;;;###autoload (defun pgg-verify-region (start end &optional signature fetch) "Verify the current region between START and END.