- (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)))))
-
-(defun pgg-read-passphrase (prompt &optional key)
- (when pgg-cache-passphrase
- (password-read prompt (setq key (pgg-truncate-key-identifier key)))))
-
-(defun pgg-add-passphrase-cache (key passphrase)
- (let ((password-cache-expiry pgg-passphrase-cache-expiry))
- (password-cache-add (setq key (pgg-truncate-key-identifier key))
- passphrase)))
-
-(defun pgg-remove-passphrase-cache (key)
- (password-cache-remove key))
+ (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))
+
+(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))))
+
+(if (fboundp 'clear-string)
+ (defalias 'pgg-clear-string 'clear-string)
+ (defun pgg-clear-string (string)
+ (fillarray string ?_)))
+
+(declare-function pgg-clear-string "pgg" (string))
+
+(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
+ (pgg-clear-string passphrase)
+ (unintern key pgg-passphrase-cache))
+ (when old-timer
+ (pgg-cancel-timer old-timer)
+ (unintern interned-timer-key pgg-pending-timers))))