X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/56388398e7a1251497f002072c061002ec9d9e81..affa9d2b30dab558bcba32a204500a848ed2e052:/lisp/epa.el diff --git a/lisp/epa.el b/lisp/epa.el index 21c4e70a9e..d4f4fab2ee 100644 --- a/lisp/epa.el +++ b/lisp/epa.el @@ -1,15 +1,16 @@ -;;; epa.el --- the EasyPG Assistant -;; Copyright (C) 2006, 2007, 2008 Free Software Foundation, Inc. +;;; epa.el --- the EasyPG Assistant -*- lexical-binding: t -*- + +;; Copyright (C) 2006-2011 Free Software Foundation, Inc. ;; Author: Daiki Ueno ;; Keywords: PGP, GnuPG ;; This file is part of GNU Emacs. -;; GNU Emacs is free software; you can redistribute it and/or modify +;; GNU Emacs is free software: you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation; either version 3, or (at your option) -;; any later version. +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. ;; GNU Emacs is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -17,9 +18,7 @@ ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -;; Boston, MA 02110-1301, USA. +;; along with GNU Emacs. If not, see . ;;; Code: @@ -45,13 +44,6 @@ the separate window." :type 'integer :group 'epa) -(defcustom epa-global-minor-modes '(epa-global-dired-mode - epa-global-mail-mode - epa-file-mode) - "Globally defined minor modes to hook into other modes." - :type '(repeat symbol) - :group 'epa) - (defgroup epa-faces nil "Faces for epa-mode." :version "23.1" @@ -208,7 +200,8 @@ You should bind this variable with `let', but do not set it globally.") (defvar epa-last-coding-system-specified nil) (defvar epa-key-list-mode-map - (let ((keymap (make-sparse-keymap))) + (let ((keymap (make-sparse-keymap)) + (menu-map (make-sparse-keymap))) (define-key keymap "m" 'epa-mark-key) (define-key keymap "u" 'epa-unmark-key) (define-key keymap "d" 'epa-decrypt-file) @@ -224,6 +217,36 @@ You should bind this variable with `let', but do not set it globally.") (define-key keymap " " 'scroll-up) (define-key keymap [delete] 'scroll-down) (define-key keymap "q" 'epa-exit-buffer) + (define-key keymap [menu-bar epa-key-list-mode] (cons "Keys" menu-map)) + (define-key menu-map [epa-key-list-unmark-key] + '(menu-item "Unmark Key" epa-unmark-key + :help "Unmark a key")) + (define-key menu-map [epa-key-list-mark-key] + '(menu-item "Mark Key" epa-mark-key + :help "Mark a key")) + (define-key menu-map [separator-epa-file] '(menu-item "--")) + (define-key menu-map [epa-verify-file] + '(menu-item "Verify File..." epa-verify-file + :help "Verify FILE")) + (define-key menu-map [epa-sign-file] + '(menu-item "Sign File..." epa-sign-file + :help "Sign FILE by SIGNERS keys selected")) + (define-key menu-map [epa-decrypt-file] + '(menu-item "Decrypt File..." epa-decrypt-file + :help "Decrypt FILE")) + (define-key menu-map [epa-encrypt-file] + '(menu-item "Encrypt File..." epa-encrypt-file + :help "Encrypt FILE for RECIPIENTS")) + (define-key menu-map [separator-epa-key-list] '(menu-item "--")) + (define-key menu-map [epa-key-list-delete-keys] + '(menu-item "Delete keys" epa-delete-keys + :help "Delete Marked Keys")) + (define-key menu-map [epa-key-list-import-keys] + '(menu-item "Import Keys" epa-import-keys + :help "Import keys from a file")) + (define-key menu-map [epa-key-list-export-keys] + '(menu-item "Export Keys" epa-export-keys + :help "Export marked keys to a file")) keymap)) (defvar epa-key-mode-map @@ -236,44 +259,6 @@ You should bind this variable with `let', but do not set it globally.") (define-key keymap "q" 'delete-window) keymap)) -(defvar epa-menu nil) - -(defconst epa-menu-items - '("Encryption/Decryption" - ("Decrypt" - ["File" epa-decrypt-file - :help "Decrypt a file"] - ["Region" epa-decrypt-region - :help "Decrypt the current region"]) - ("Verify" - ["File" epa-verify-file - :help "Verify digital signature of a file"] - ["Region" epa-verify-region - :help "Verify digital signature of the current region"]) - ("Sign" - ["File" epa-sign-file - :help "Create digital signature of a file"] - ["Region" epa-sign-region - :help "Create digital signature of the current region"]) - ("Encrypt" - ["File" epa-encrypt-file - :help "Encrypt a file"] - ["Region" epa-encrypt-region - :help "Encrypt the current region"]) - "----" - ["Browse keyring" epa-list-keys - :help "Browse your public keyring"] - ("Import keys" - ["File" epa-import-keys - :help "Import public keys from a file"] - ["Region" epa-import-keys-region - :help "Import public keys from the current region"]) - ("Export key" - ["To a File" epa-export-keys - :help "Export public keys to a file"] - ["To a Buffer" epa-insert-keys - :help "Insert public keys after the current point"]))) - (defvar epa-exit-buffer-function #'bury-buffer) (define-widget 'epa-key 'push-button @@ -284,8 +269,9 @@ You should bind this variable with `let', but do not set it globally.") :action 'epa--key-widget-action :help-echo 'epa--key-widget-help-echo) -(defun epa--key-widget-action (widget &optional event) - (epa--show-key (widget-get widget :value))) +(defun epa--key-widget-action (widget &optional _event) + (save-selected-window + (epa--show-key (widget-get widget :value)))) (defun epa--key-widget-value-create (widget) (let* ((key (widget-get widget :value)) @@ -343,7 +329,7 @@ You should bind this variable with `let', but do not set it globally.") (make-local-variable 'epa-exit-buffer-function) (make-local-variable 'revert-buffer-function) (setq revert-buffer-function 'epa--key-list-revert-buffer) - (run-hooks 'epa-key-list-mode-hook)) + (run-mode-hooks 'epa-key-list-mode-hook)) (defun epa-key-mode () "Major mode for a key description." @@ -360,7 +346,7 @@ You should bind this variable with `let', but do not set it globally.") ;; if buffer-file-name is not set. (font-lock-set-defaults) (make-local-variable 'epa-exit-buffer-function) - (run-hooks 'epa-key-mode-hook)) + (run-mode-hooks 'epa-key-mode-hook)) (defun epa-info-mode () "Major mode for `epa-info-buffer'." @@ -371,7 +357,7 @@ You should bind this variable with `let', but do not set it globally.") truncate-lines t buffer-read-only t) (use-local-map epa-info-mode-map) - (run-hooks 'epa-info-mode-hook)) + (run-mode-hooks 'epa-info-mode-hook)) (defun epa-mark-key (&optional arg) "Mark a key on the current line. @@ -474,12 +460,11 @@ If ARG is non-nil, mark the key." (list nil))) (epa--list-keys name t)) -(defun epa--key-list-revert-buffer (&optional ignore-auto noconfirm) +(defun epa--key-list-revert-buffer (&optional _ignore-auto _noconfirm) (apply #'epa--list-keys epa-list-keys-arguments)) (defun epa--marked-keys () - (or (save-excursion - (set-buffer epa-keys-buffer) + (or (with-current-buffer epa-keys-buffer (goto-char (point-min)) (let (keys key) (while (re-search-forward "^\\*" nil t) @@ -487,18 +472,15 @@ If ARG is non-nil, mark the key." 'epa-key)) (setq keys (cons key keys)))) (nreverse keys))) - (save-excursion - (beginning-of-line) - (let ((key (get-text-property (point) 'epa-key))) - (if key - (list key)))))) + (let ((key (get-text-property (point-at-bol) 'epa-key))) + (if key + (list key))))) (defun epa--select-keys (prompt keys) - (save-excursion - (unless (and epa-keys-buffer - (buffer-live-p epa-keys-buffer)) - (setq epa-keys-buffer (generate-new-buffer "*Keys*"))) - (set-buffer epa-keys-buffer) + (unless (and epa-keys-buffer + (buffer-live-p epa-keys-buffer)) + (setq epa-keys-buffer (generate-new-buffer "*Keys*"))) + (with-current-buffer epa-keys-buffer (epa-key-list-mode) (let ((inhibit-read-only t) buffer-read-only) @@ -508,13 +490,13 @@ If ARG is non-nil, mark the key." - `\\[epa-mark-key]' to mark a key on the line - `\\[epa-unmark-key]' to unmark a key on the line\n")) (widget-create 'link - :notify (lambda (&rest ignore) (abort-recursive-edit)) + :notify (lambda (&rest _ignore) (abort-recursive-edit)) :help-echo (substitute-command-keys "Click here or \\[abort-recursive-edit] to cancel") "Cancel") (widget-create 'link - :notify (lambda (&rest ignore) (exit-recursive-edit)) + :notify (lambda (&rest _ignore) (exit-recursive-edit)) :help-echo (substitute-command-keys "Click here or \\[exit-recursive-edit] to finish") @@ -525,13 +507,12 @@ If ARG is non-nil, mark the key." (set-keymap-parent (current-local-map) widget-keymap) (setq epa-exit-buffer-function #'abort-recursive-edit) (goto-char (point-min)) - (pop-to-buffer (current-buffer))) + (let ((display-buffer-mark-dedicated 'soft)) + (pop-to-buffer (current-buffer)))) (unwind-protect (progn (recursive-edit) (epa--marked-keys)) - (if (get-buffer-window epa-keys-buffer) - (delete-window (get-buffer-window epa-keys-buffer))) (kill-buffer epa-keys-buffer)))) ;;;###autoload @@ -543,9 +524,7 @@ NAMES is a list of strings to be matched with keys. If it is nil, all the keys are listed. If SECRET is non-nil, list secret keys instead of public keys." (let ((keys (epg-list-keys context names secret))) - (if (> (length keys) 1) - (epa--select-keys prompt keys) - keys))) + (epa--select-keys prompt keys))) (defun epa--show-key (key) (let* ((primary-sub-key (car (epg-key-sub-key-list key))) @@ -603,7 +582,11 @@ If SECRET is non-nil, list secret keys instead of public keys." (epg-sub-key-creation-time (car pointer))) (error "????-??-??")) (if (epg-sub-key-expiration-time (car pointer)) - (format "\n\tExpires: %s" + (format (if (time-less-p (current-time) + (epg-sub-key-expiration-time + (car pointer))) + "\n\tExpires: %s" + "\n\tExpired: %s") (condition-case nil (format-time-string "%Y-%m-%d" (epg-sub-key-expiration-time @@ -628,8 +611,7 @@ If SECRET is non-nil, list secret keys instead of public keys." (setq epa-info-buffer (generate-new-buffer "*Info*"))) (if (get-buffer-window epa-info-buffer) (delete-window (get-buffer-window epa-info-buffer))) - (save-excursion - (set-buffer epa-info-buffer) + (with-current-buffer epa-info-buffer (let ((inhibit-read-only t) buffer-read-only) (erase-buffer) @@ -648,12 +630,17 @@ If SECRET is non-nil, list secret keys instead of public keys." (defun epa-display-verify-result (verify-result) (epa-display-info (epg-verify-result-to-string verify-result))) -(make-obsolete 'epa-display-verify-result 'epa-display-info) +(make-obsolete 'epa-display-verify-result 'epa-display-info "23.1") (defun epa-passphrase-callback-function (context key-id handback) (if (eq key-id 'SYM) - (read-passwd "Passphrase for symmetric encryption: " - (eq (epg-context-operation context) 'encrypt)) + (read-passwd + (format "Passphrase for symmetric encryption%s: " + ;; Add the file name to the prompt, if any. + (if (stringp handback) + (format " for %s" handback) + "")) + (eq (epg-context-operation context) 'encrypt)) (read-passwd (if (eq key-id 'PIN) "Passphrase for PIN: " @@ -662,7 +649,7 @@ If SECRET is non-nil, list secret keys instead of public keys." (format "Passphrase for %s %s: " key-id (cdr entry)) (format "Passphrase for %s: " key-id))))))) -(defun epa-progress-callback-function (context what char current total +(defun epa-progress-callback-function (_context what _char current total handback) (message "%s%d%% (%d/%d)" (or handback (concat what ": ")) @@ -729,8 +716,7 @@ If SECRET is non-nil, list secret keys instead of public keys." (setq type 'detached)) ((eq c ??) (with-output-to-temp-buffer "*Help*" - (save-excursion - (set-buffer standard-output) + (with-current-buffer standard-output (insert "\ n - Create a normal signature c - Create a cleartext signature @@ -738,7 +724,8 @@ d - Create a detached signature ? - Show this help ")))) (t - (setq type 'normal)))))) + (setq type 'normal)))) + type)) ;;;###autoload (defun epa-sign-file (file signers mode) @@ -812,7 +799,20 @@ If no one is selected, symmetric encryption will be performed. "))) (defun epa-decrypt-region (start end) "Decrypt the current region between START and END. -Don't use this command in Lisp programs!" +Don't use this command in Lisp programs! +Since this function operates on regions, it does some tricks such +as coding-system detection and unibyte/multibyte conversion. If +you are sure how the data in the region should be treated, you +should consider using the string based counterpart +`epg-decrypt-string', or the file based counterpart +`epg-decrypt-file' instead. + +For example: + +\(let ((context (epg-make-context 'OpenPGP))) + (decode-coding-string + (epg-decrypt-string context (buffer-substring start end)) + 'utf-8))" (interactive "r") (save-excursion (let ((context (epg-make-context epa-protocol)) @@ -829,7 +829,8 @@ Don't use this command in Lisp programs!" (setq plain (epa--decode-coding-string plain (or coding-system-for-read - (get-text-property start 'epa-coding-system-used)))) + (get-text-property start 'epa-coding-system-used) + 'undecided))) (if (y-or-n-p "Replace the original text? ") (let ((inhibit-read-only t) buffer-read-only) @@ -859,7 +860,8 @@ Don't use this command in Lisp programs!" (defun epa-decrypt-armor-in-region (start end) "Decrypt OpenPGP armors in the current region between START and END. -Don't use this command in Lisp programs!" +Don't use this command in Lisp programs! +See the reason described in the `epa-decrypt-region' documentation." (interactive "r") (save-excursion (save-restriction @@ -885,7 +887,20 @@ Don't use this command in Lisp programs!" (defun epa-verify-region (start end) "Verify the current region between START and END. -Don't use this command in Lisp programs!" +Don't use this command in Lisp programs! +Since this function operates on regions, it does some tricks such +as coding-system detection and unibyte/multibyte conversion. If +you are sure how the data in the region should be treated, you +should consider using the string based counterpart +`epg-verify-string', or the file based counterpart +`epg-verify-file' instead. + +For example: + +\(let ((context (epg-make-context 'OpenPGP))) + (decode-coding-string + (epg-verify-string context (buffer-substring start end)) + 'utf-8))" (interactive "r") (let ((context (epg-make-context epa-protocol)) plain) @@ -904,7 +919,8 @@ Don't use this command in Lisp programs!" (setq plain (epa--decode-coding-string plain (or coding-system-for-read - (get-text-property start 'epa-coding-system-used)))) + (get-text-property start 'epa-coding-system-used) + 'undecided))) (if (y-or-n-p "Replace the original text? ") (let ((inhibit-read-only t) buffer-read-only) @@ -924,7 +940,8 @@ Don't use this command in Lisp programs!" "Verify OpenPGP cleartext signed messages in the current region between START and END. -Don't use this command in Lisp programs!" +Don't use this command in Lisp programs! +See the reason described in the `epa-verify-region' documentation." (interactive "r") (save-excursion (save-restriction @@ -947,14 +964,26 @@ Don't use this command in Lisp programs!" (eval-and-compile (if (fboundp 'select-safe-coding-system) (defalias 'epa--select-safe-coding-system 'select-safe-coding-system) - (defun epa--select-safe-coding-system (from to) + (defun epa--select-safe-coding-system (_from _to) buffer-file-coding-system))) ;;;###autoload (defun epa-sign-region (start end signers mode) "Sign the current region between START and END by SIGNERS keys selected. -Don't use this command in Lisp programs!" +Don't use this command in Lisp programs! +Since this function operates on regions, it does some tricks such +as coding-system detection and unibyte/multibyte conversion. If +you are sure how the data should be treated, you should consider +using the string based counterpart `epg-sign-string', or the file +based counterpart `epg-sign-file' instead. + +For example: + +\(let ((context (epg-make-context 'OpenPGP))) + (epg-sign-string + context + (encode-coding-string (buffer-substring start end) 'utf-8)))" (interactive (let ((verbose current-prefix-arg)) (setq epa-last-coding-system-specified @@ -1022,7 +1051,20 @@ Uses the `derived-mode-parent' property of the symbol to trace backwards." (defun epa-encrypt-region (start end recipients sign signers) "Encrypt the current region between START and END for RECIPIENTS. -Don't use this command in Lisp programs!" +Don't use this command in Lisp programs! +Since this function operates on regions, it does some tricks such +as coding-system detection and unibyte/multibyte conversion. If +you are sure how the data should be treated, you should consider +using the string based counterpart `epg-encrypt-string', or the +file based counterpart `epg-encrypt-file' instead. + +For example: + +\(let ((context (epg-make-context 'OpenPGP))) + (epg-encrypt-string + context + (encode-coding-string (buffer-substring start end) 'utf-8) + nil))" (interactive (let ((verbose current-prefix-arg) (context (epg-make-context epa-protocol)) @@ -1077,9 +1119,7 @@ If no one is selected, symmetric encryption will be performed. ") ;;;###autoload (defun epa-delete-keys (keys &optional allow-secret) - "Delete selected KEYS. - -Don't use this command in Lisp programs!" + "Delete selected KEYS." (interactive (let ((keys (epa--marked-keys))) (unless keys @@ -1090,13 +1130,11 @@ Don't use this command in Lisp programs!" (message "Deleting...") (epg-delete-keys context keys allow-secret) (message "Deleting...done") - (apply #'epa-list-keys epa-list-keys-arguments))) + (apply #'epa--list-keys epa-list-keys-arguments))) ;;;###autoload (defun epa-import-keys (file) - "Import keys from FILE. - -Don't use this command in Lisp programs!" + "Import keys from FILE." (interactive "fFile: ") (setq file (expand-file-name file)) (let ((context (epg-make-context epa-protocol))) @@ -1111,13 +1149,11 @@ Don't use this command in Lisp programs!" (epa-display-info (epg-import-result-to-string (epg-context-result-for context 'import)))) (if (eq major-mode 'epa-key-list-mode) - (apply #'epa-list-keys epa-list-keys-arguments)))) + (apply #'epa--list-keys epa-list-keys-arguments)))) ;;;###autoload (defun epa-import-keys-region (start end) - "Import keys from the region. - -Don't use this command in Lisp programs!" + "Import keys from the region." (interactive "r") (let ((context (epg-make-context epa-protocol))) (message "Importing...") @@ -1134,9 +1170,7 @@ Don't use this command in Lisp programs!" ;;;###autoload (defun epa-import-armor-in-region (start end) "Import keys in the OpenPGP armor format in the current region -between START and END. - -Don't use this command in Lisp programs!" +between START and END." (interactive "r") (save-excursion (save-restriction @@ -1156,9 +1190,7 @@ Don't use this command in Lisp programs!" ;;;###autoload (defun epa-export-keys (keys file) - "Export selected KEYS to FILE. - -Don't use this command in Lisp programs!" + "Export selected KEYS to FILE." (interactive (let ((keys (epa--marked-keys)) default-name) @@ -1185,9 +1217,7 @@ Don't use this command in Lisp programs!" ;;;###autoload (defun epa-insert-keys (keys) - "Insert selected KEYS after the point. - -Don't use this command in Lisp programs!" + "Insert selected KEYS after the point." (interactive (list (epa-select-keys (epg-make-context epa-protocol) "Select keys to export. "))) @@ -1218,28 +1248,6 @@ Don't use this command in Lisp programs!" ;; (message "Signing keys...done"))) ;; (make-obsolete 'epa-sign-keys "Do not use.") -;;;###autoload -(define-minor-mode epa-mode - "Minor mode to hook EasyPG into various modes. -See `epa-global-minor-modes'." - :global t :init-value nil :group 'epa :version "23.1" - (unless epa-menu - (easy-menu-define epa-menu nil "EasyPG Assistant global menu" - epa-menu-items)) - (easy-menu-remove-item nil '("Tools") "Encryption/Decryption") - (if epa-mode - (easy-menu-add-item nil '("Tools") epa-menu)) - (let ((modes epa-global-minor-modes) - symbol) - (while modes - (setq symbol (car modes)) - (if (and symbol - (fboundp symbol)) - (funcall symbol epa-mode) - (message "`%S' not found" (car modes))) - (setq modes (cdr modes))))) - (provide 'epa) -;; arch-tag: 38d20ced-20d5-4137-b17a-f206335423d7 ;;; epa.el ends here