aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Eggert2011-08-15 22:58:30 -0700
committerPaul Eggert2011-08-15 22:58:30 -0700
commit3f74064edab68e5620fade9b802e863cb110afd2 (patch)
tree5631c5c98220f0a63f8552996e576b435e5b41ae
parentfe5c5d37807dbf2d224de5fe9cf821d8292112b1 (diff)
parent04963aa8ff62058b9795c3e3217630515470fcff (diff)
downloademacs-3f74064edab68e5620fade9b802e863cb110afd2.tar.gz
emacs-3f74064edab68e5620fade9b802e863cb110afd2.zip
Merge from trunk.
-rw-r--r--etc/NEWS5
-rw-r--r--lisp/ChangeLog17
-rw-r--r--lisp/epa-mail.el75
-rw-r--r--lisp/epa.el41
-rw-r--r--lisp/mail/rmail.el106
5 files changed, 227 insertions, 17 deletions
diff --git a/etc/NEWS b/etc/NEWS
index 1a788e7f6f9..8707a8b0adc 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -820,6 +820,11 @@ on a D-Bus without simultaneously registering a property or a method.
820*** The option `ange-ftp-binary-file-name-regexp' has changed its 820*** The option `ange-ftp-binary-file-name-regexp' has changed its
821default value to "". 821default value to "".
822 822
823** Rmail
824
825*** The command `rmail-epa-decrypt' decrypts OpenPGP data
826in the Rmail incoming message.
827
823** VC and related modes 828** VC and related modes
824 829
825*** Support for pulling on distributed version control systems. 830*** Support for pulling on distributed version control systems.
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 7116a152605..70d34fb7117 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,20 @@
12011-08-16 Richard Stallman <rms@gnu.org>
2
3 * epa-mail.el: Handle GnuPG group definitions.
4 (epa-mail-group-alist, epa-mail-group-modtime)
5 (epa-mail-gnupg-conf-file): New variables.
6 (epa-mail-parse-groups, epa-mail-sync-groups)
7 (epa-mail-expand-recipient-1, epa-mail-expand-recipients-2)
8 (epa-mail-expand-recipients): New functions.
9 (epa-mail-encrypt): Call epa-mail-expand-recipients.
10
11 * mail/rmail.el (rmail-epa-decrypt): New command.
12
13 * epa.el (epa-decrypt-region): New arg MAKE-BUFFER-FUNCTION.
14 Don't bind buffer-read-only, just inhibit-read-only.
15 (epa--find-coding-system-for-mime-charset): Fix the non-xemacs case.
16 (epa-decrypt-armor-in-region): Make error message clearer.
17
12011-08-15 Stefan Monnier <monnier@iro.umontreal.ca> 182011-08-15 Stefan Monnier <monnier@iro.umontreal.ca>
2 19
3 * minibuffer.el (completion-pcm--merge-completions): Don't merge "a1b" 20 * minibuffer.el (completion-pcm--merge-completions): Don't merge "a1b"
diff --git a/lisp/epa-mail.el b/lisp/epa-mail.el
index a3f11f78675..e6f6c0ec2b1 100644
--- a/lisp/epa-mail.el
+++ b/lisp/epa-mail.el
@@ -50,6 +50,9 @@
50 "A minor-mode for composing encrypted/clearsigned mails." 50 "A minor-mode for composing encrypted/clearsigned mails."
51 nil " epa-mail" epa-mail-mode-map) 51 nil " epa-mail" epa-mail-mode-map)
52 52
53;;; ??? Could someone please clarify this doc string?
54;;; In particular, what does USAGE look like
55;;; and what does it mean? -- rms
53(defun epa-mail--find-usable-key (keys usage) 56(defun epa-mail--find-usable-key (keys usage)
54 "Find a usable key from KEYS for USAGE." 57 "Find a usable key from KEYS for USAGE."
55 (catch 'found 58 (catch 'found
@@ -63,6 +66,71 @@
63 (setq pointer (cdr pointer)))) 66 (setq pointer (cdr pointer))))
64 (setq keys (cdr keys))))) 67 (setq keys (cdr keys)))))
65 68
69(defvar epa-mail-group-alist nil
70 "Alist of GnuPG mail groups (`group' commands in `.gnupg/gpg.conf').
71Each element has the form (GROUPNAME ADDRESSES...).
72t means the list is not yet read in.")
73
74(defvar epa-mail-group-modtime nil
75 "The modification time of `~/.gnupg/gpg.conf' file when last examined.")
76
77(defvar epa-mail-gnupg-conf-file "~/.gnupg/gpg.conf"
78 "File name of GnuPG configuration file that specifies recipient groups.")
79
80(defun epa-mail-parse-groups ()
81 "Parse `~/.gnupg/gpg.conf' and set `epa-mail-group-alist' from it."
82 (let (aliases)
83 (with-temp-buffer
84 (insert-file-contents-literally epa-mail-gnupg-conf-file)
85
86 (while (re-search-forward "^[ \t]*group[ \t]*" nil t)
87 (if (looking-at "\\([^= \t]+\\)[ \t]*=[ \t]*\\([^ \t\n]+\\)")
88 (push (cons (match-string-no-properties 1)
89 (split-string (match-string-no-properties 2)))
90 aliases))))
91 (setq epa-mail-group-alist aliases)))
92
93(defun epa-mail-sync-groups ()
94 "Update GnuPG groups from file if necessary."
95 (if (file-exists-p epa-mail-gnupg-conf-file)
96 (let ((modtime (nth 5 (file-attributes epa-mail-gnupg-conf-file))))
97 (if (not (equal epa-mail-group-modtime modtime))
98 (progn
99 (setq epa-mail-group-modtime modtime)
100 (epa-mail-parse-groups))))
101 (setq epa-mail-group-alist nil)))
102
103(defun epa-mail-expand-recipient-1 (recipient)
104 "Expand RECIPIENT once thru `epa-mail-group-alist'.
105Returns the list of names it stands for, or nil if it isn't a group."
106 ;; Load the alias list if not loaded before.
107 (let (alist-elt)
108 (setq alist-elt (assoc recipient epa-mail-group-alist))
109 (cdr alist-elt)))
110
111(defun epa-mail-expand-recipients-2 (recipients)
112 "Expand list RECIPIENTS once thru `epa-mail-group-alist'.
113Returns the list of names they stand for."
114 ;; Load the alias list if not loaded before.
115 (let (output)
116 (dolist (r recipients)
117 (let ((expanded (epa-mail-expand-recipient-1 r)))
118 (if expanded
119 (dolist (xr expanded)
120 (unless (member xr output)
121 (push xr output)))
122 (unless (member r output)
123 (push r output)))))
124 (nreverse output)))
125
126(defun epa-mail-expand-recipients (recipients)
127 "Expand RECIPIENTS thru `epa-mail-group-alist' until it stops changing."
128 (epa-mail-sync-groups)
129 (while (not (equal recipients
130 (setq recipients
131 (epa-mail-expand-recipients-2 recipients)))))
132 recipients)
133
66;;;###autoload 134;;;###autoload
67(defun epa-mail-decrypt () 135(defun epa-mail-decrypt ()
68 "Decrypt OpenPGP armors in the current buffer. 136 "Decrypt OpenPGP armors in the current buffer.
@@ -140,6 +208,13 @@ Don't use this command in Lisp programs!"
140 (setq recipients (delete "" 208 (setq recipients (delete ""
141 (split-string recipients 209 (split-string recipients
142 "[ \t\n]*,[ \t\n]*")))) 210 "[ \t\n]*,[ \t\n]*"))))
211
212 ;; Process all the recipients thru the list of GnuPG groups.
213 ;; Expand GnuPG group names to what they stand for.
214 ;; The code below, and elsewhere, that checks that names have keys
215 ;; does not know about these group names.
216 (setq recipients (epa-mail-expand-recipients recipients))
217
143 (goto-char (point-min)) 218 (goto-char (point-min))
144 (if (search-forward mail-header-separator nil t) 219 (if (search-forward mail-header-separator nil t)
145 (forward-line)) 220 (forward-line))
diff --git a/lisp/epa.el b/lisp/epa.el
index e2fafc753d7..f0ec1ece0d1 100644
--- a/lisp/epa.el
+++ b/lisp/epa.el
@@ -803,10 +803,15 @@ If no one is selected, symmetric encryption will be performed. ")))
803 (file-name-nondirectory cipher)))) 803 (file-name-nondirectory cipher))))
804 804
805;;;###autoload 805;;;###autoload
806(defun epa-decrypt-region (start end) 806(defun epa-decrypt-region (start end &optional make-buffer-function)
807 "Decrypt the current region between START and END. 807 "Decrypt the current region between START and END.
808 808
809Don't use this command in Lisp programs! 809If MAKE-BUFFER-FUNCTION is non-nil, call it to prepare an output buffer.
810It should return that buffer. If it copies the input, it should
811delete the text now being decrypted. It should leave point at the
812proper place to insert the plaintext.
813
814Be careful about using this command in Lisp programs!
810Since this function operates on regions, it does some tricks such 815Since this function operates on regions, it does some tricks such
811as coding-system detection and unibyte/multibyte conversion. If 816as coding-system detection and unibyte/multibyte conversion. If
812you are sure how the data in the region should be treated, you 817you are sure how the data in the region should be treated, you
@@ -838,16 +843,19 @@ For example:
838 (or coding-system-for-read 843 (or coding-system-for-read
839 (get-text-property start 'epa-coding-system-used) 844 (get-text-property start 'epa-coding-system-used)
840 'undecided))) 845 'undecided)))
841 (if (y-or-n-p "Replace the original text? ") 846 (if make-buffer-function
842 (let ((inhibit-read-only t) 847 (with-current-buffer (funcall make-buffer-function)
843 buffer-read-only) 848 (let ((inhibit-read-only t))
844 (delete-region start end) 849 (insert plain)))
845 (goto-char start) 850 (if (y-or-n-p "Replace the original text? ")
846 (insert plain)) 851 (let ((inhibit-read-only t))
847 (with-output-to-temp-buffer "*Temp*" 852 (delete-region start end)
848 (set-buffer standard-output) 853 (goto-char start)
849 (insert plain) 854 (insert plain))
850 (epa-info-mode))) 855 (with-output-to-temp-buffer "*Temp*"
856 (set-buffer standard-output)
857 (insert plain)
858 (epa-info-mode))))
851 (if (epg-context-result-for context 'verify) 859 (if (epg-context-result-for context 'verify)
852 (epa-display-info (epg-verify-result-to-string 860 (epa-display-info (epg-verify-result-to-string
853 (epg-context-result-for context 'verify))))))) 861 (epg-context-result-for context 'verify)))))))
@@ -856,12 +864,13 @@ For example:
856 (if (featurep 'xemacs) 864 (if (featurep 'xemacs)
857 (if (fboundp 'find-coding-system) 865 (if (fboundp 'find-coding-system)
858 (find-coding-system mime-charset)) 866 (find-coding-system mime-charset))
867 ;; Find the first coding system which corresponds to MIME-CHARSET.
859 (let ((pointer (coding-system-list))) 868 (let ((pointer (coding-system-list)))
860 (while (and pointer 869 (while (and pointer
861 (eq (coding-system-get (car pointer) 'mime-charset) 870 (not (eq (coding-system-get (car pointer) 'mime-charset)
862 mime-charset)) 871 mime-charset)))
863 (setq pointer (cdr pointer))) 872 (setq pointer (cdr pointer)))
864 pointer))) 873 (car pointer))))
865 874
866;;;###autoload 875;;;###autoload
867(defun epa-decrypt-armor-in-region (start end) 876(defun epa-decrypt-armor-in-region (start end)
@@ -880,7 +889,7 @@ See the reason described in the `epa-decrypt-region' documentation."
880 armor-end (re-search-forward "^-----END PGP MESSAGE-----$" 889 armor-end (re-search-forward "^-----END PGP MESSAGE-----$"
881 nil t)) 890 nil t))
882 (unless armor-end 891 (unless armor-end
883 (error "No armor tail")) 892 (error "Encryption armor beginning has no matching end"))
884 (goto-char armor-start) 893 (goto-char armor-start)
885 (let ((coding-system-for-read 894 (let ((coding-system-for-read
886 (or coding-system-for-read 895 (or coding-system-for-read
diff --git a/lisp/mail/rmail.el b/lisp/mail/rmail.el
index c43ec9e5611..9b4bbf91823 100644
--- a/lisp/mail/rmail.el
+++ b/lisp/mail/rmail.el
@@ -4249,7 +4249,7 @@ TEXT and INDENT are not used."
4249 ;; rmail-output expands non-absolute filenames against rmail-default-file. 4249 ;; rmail-output expands non-absolute filenames against rmail-default-file.
4250 ;; What is the point of that, anyway? 4250 ;; What is the point of that, anyway?
4251 (rmail-output (expand-file-name token)))) 4251 (rmail-output (expand-file-name token))))
4252 4252
4253;; Functions for setting, getting and encoding the POP password. 4253;; Functions for setting, getting and encoding the POP password.
4254;; The password is encoded to prevent it from being easily accessible 4254;; The password is encoded to prevent it from being easily accessible
4255;; to "prying eyes." Obviously, this encoding isn't "real security," 4255;; to "prying eyes." Obviously, this encoding isn't "real security,"
@@ -4300,6 +4300,110 @@ encoded string (and the same mask) will decode the string."
4300 (setq i (1+ i))) 4300 (setq i (1+ i)))
4301 (concat string-vector))) 4301 (concat string-vector)))
4302 4302
4303(defun rmail-epa-decrypt ()
4304 "Decrypt OpenPGP armors in current message."
4305 (interactive)
4306
4307 ;; Save the current buffer here for cleanliness, in case we
4308 ;; change it in one of the calls to `epa-decrypt-region'.
4309
4310 (save-excursion
4311 (let (new-buffer not-first-armor)
4312 (goto-char (point-min))
4313
4314 ;; In case the encrypted data is inside a mime attachment,
4315 ;; show it. This is a kludge; to be clean, it should not
4316 ;; modify the buffer, but I don't see how to do that.
4317 (when (search-forward "octet-stream" nil t)
4318 (beginning-of-line)
4319 (forward-button 1)
4320 (if (looking-at "Show")
4321 (rmail-mime-toggle-hidden)))
4322
4323 ;; Now find all armored messages in the buffer
4324 ;; and decrypt them one by one.
4325 (goto-char (point-min))
4326 (while (re-search-forward "-----BEGIN PGP MESSAGE-----$" nil t)
4327 (let (armor-start armor-end
4328 (coding-system-for-read coding-system-for-read))
4329 (setq armor-start (match-beginning 0)
4330 armor-end (re-search-forward "^-----END PGP MESSAGE-----$"
4331 nil t))
4332 (unless armor-end
4333 (error "Encryption armor beginning has no matching end"))
4334 (goto-char armor-start)
4335
4336 ;; Because epa--find-coding-system-for-mime-charset not autoloaded.
4337 (require 'epa)
4338
4339 ;; Use the charset specified in the armor.
4340 (unless coding-system-for-read
4341 (if (re-search-forward "^Charset: \\(.*\\)" armor-end t)
4342 (setq coding-system-for-read
4343 (epa--find-coding-system-for-mime-charset
4344 (intern (downcase (match-string 1)))))))
4345
4346 ;; Advance over this armor.
4347 (goto-char armor-end)
4348
4349 ;; Decrypt it, maybe in place, maybe making new buffer.
4350 (epa-decrypt-region
4351 armor-start armor-end
4352 ;; Call back this function to prepare the output.
4353 (lambda ()
4354 (if (or not-first-armor
4355 (y-or-n-p "Replace the original message? "))
4356 ;; User wants to decrypt in place,
4357 ;; or this isn't the first armor.
4358 ;; We only ask the question for the first armor.
4359 (let ((inhibit-read-only t))
4360 (delete-region armor-start armor-end)
4361 (goto-char armor-start)
4362 (current-buffer))
4363 ;; User says not to replace the original text.
4364 (or new-buffer
4365 (let ((from-buffer
4366 (if (rmail-buffers-swapped-p)
4367 rmail-view-buffer rmail-buffer))
4368 (from-pruned (rmail-msg-is-pruned))
4369 (beg (rmail-msgbeg rmail-current-message))
4370 (end (rmail-msgend rmail-current-message)))
4371 (with-current-buffer (generate-new-buffer "*Decrypt*")
4372 (setq buffer-read-only nil)
4373 (insert-buffer-substring from-buffer beg end)
4374 (rmail-mode)
4375 ;; This should be pruned if the original message was.
4376 (unless from-pruned (rmail-toggle-header))
4377 (goto-char (point-min))
4378
4379 ;; Find the first armor in the text we just copied.
4380 ;; What we copied may not be identical
4381 ;; to the initial text.
4382 (re-search-forward "-----BEGIN PGP MESSAGE-----$")
4383 (setq armor-start (match-beginning 0))
4384 (re-search-forward "^-----END PGP MESSAGE-----$")
4385 (setq armor-end (point))
4386 ;; Delete it and put point there.
4387 (let ((inhibit-read-only t))
4388 (delete-region armor-start armor-end))
4389 (goto-char armor-start)
4390 (setq new-buffer (current-buffer))
4391 ;; Return; epa-decrypt-region will insert plaintext.
4392 ))))))
4393
4394 (setq not-first-armor t)
4395
4396 ;; If we copied the buffer, switch to the copy
4397 ;; for the rest of this loop.
4398 ;; Point is the only buffer pointer that is live here,
4399 ;; and it was properly set in NEW-BUFFER by `epa-decrypt-region'
4400 ;; when it inserted the decrypted epa
4401 (if new-buffer (set-buffer new-buffer))))
4402
4403 ;; If we decrypted into a new buffer, show it.
4404 (if new-buffer
4405 (display-buffer new-buffer)))))
4406
4303;;;; Desktop support 4407;;;; Desktop support
4304 4408
4305(defun rmail-restore-desktop-buffer (desktop-buffer-file-name 4409(defun rmail-restore-desktop-buffer (desktop-buffer-file-name