Revision: miles@gnu.org--gnu-2005/gnus--devo--0--patch-151
[gnus] / lisp / mml1991.el
1 ;;; mml1991.el --- Old PGP message format (RFC 1991) support for MML
2 ;; Copyright (C) 1998, 1999, 2000, 2001, 2003, 2005
3 ;;        Free Software Foundation, Inc.
4
5 ;; Author: Sascha Lüdecke <sascha@meta-x.de>,
6 ;;      Simon Josefsson <simon@josefsson.org> (Mailcrypt interface, Gnus glue)
7 ;; Keywords PGP
8
9 ;; This file is part of GNU Emacs.
10
11 ;; GNU Emacs is free software; you can redistribute it and/or modify
12 ;; it under the terms of the GNU General Public License as published by
13 ;; the Free Software Foundation; either version 2, or (at your option)
14 ;; any later version.
15
16 ;; GNU Emacs is distributed in the hope that it will be useful,
17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 ;; GNU General Public License for more details.
20
21 ;; You should have received a copy of the GNU General Public License
22 ;; along with GNU Emacs; see the file COPYING.  If not, write to the
23 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
24 ;; Boston, MA 02110-1301, USA.
25
26 ;;; Commentary:
27
28 ;;; Code:
29
30 (eval-when-compile
31   (require 'cl)
32   (require 'mm-util))
33
34 (autoload 'quoted-printable-decode-region "qp")
35 (autoload 'quoted-printable-encode-region "qp")
36
37 (defvar mml1991-use mml2015-use
38   "The package used for PGP.")
39
40 (defvar mml1991-function-alist
41   '((mailcrypt mml1991-mailcrypt-sign
42                mml1991-mailcrypt-encrypt)
43     (gpg mml1991-gpg-sign
44          mml1991-gpg-encrypt)
45     (pgg mml1991-pgg-sign
46          mml1991-pgg-encrypt))
47   "Alist of PGP functions.")
48
49 ;;; mailcrypt wrapper
50
51 (eval-and-compile
52   (autoload 'mc-sign-generic "mc-toplev"))
53
54 (defvar mml1991-decrypt-function 'mailcrypt-decrypt)
55 (defvar mml1991-verify-function 'mailcrypt-verify)
56
57 (defun mml1991-mailcrypt-sign (cont)
58   (let ((text (current-buffer))
59         headers signature
60         (result-buffer (get-buffer-create "*GPG Result*")))
61     ;; Save MIME Content[^ ]+: headers from signing
62     (goto-char (point-min))
63     (while (looking-at "^Content[^ ]+:") (forward-line))
64     (unless (bobp)
65       (setq headers (buffer-string))
66       (delete-region (point-min) (point)))
67     (goto-char (point-max))
68     (unless (bolp)
69       (insert "\n"))
70     (quoted-printable-decode-region (point-min) (point-max))
71     (with-temp-buffer
72       (setq signature (current-buffer))
73       (insert-buffer-substring text)
74       (unless (mc-sign-generic (message-options-get 'message-sender)
75                                nil nil nil nil)
76         (unless (> (point-max) (point-min))
77           (pop-to-buffer result-buffer)
78           (error "Sign error")))
79       (goto-char (point-min))
80       (while (re-search-forward "\r+$" nil t)
81         (replace-match "" t t))
82       (quoted-printable-encode-region (point-min) (point-max))
83       (set-buffer text)
84       (delete-region (point-min) (point-max))
85       (if headers (insert headers))
86       (insert "\n")
87       (insert-buffer-substring signature)
88       (goto-char (point-max)))))
89
90 (defun mml1991-mailcrypt-encrypt (cont &optional sign)
91   (let ((text (current-buffer))
92         (mc-pgp-always-sign
93          (or mc-pgp-always-sign
94              sign
95              (eq t (or (message-options-get 'message-sign-encrypt)
96                        (message-options-set
97                         'message-sign-encrypt
98                         (or (y-or-n-p "Sign the message? ")
99                             'not))))
100              'never))
101         cipher
102         (result-buffer (get-buffer-create "*GPG Result*")))
103     ;; Strip MIME Content[^ ]: headers since it will be ASCII ARMOURED
104     (goto-char (point-min))
105     (while (looking-at "^Content[^ ]+:") (forward-line))
106     (unless (bobp)
107       (delete-region (point-min) (point)))
108     (mm-with-unibyte-current-buffer
109       (with-temp-buffer
110         (setq cipher (current-buffer))
111         (insert-buffer-substring text)
112         (unless (mc-encrypt-generic
113                  (or
114                   (message-options-get 'message-recipients)
115                   (message-options-set 'message-recipients
116                                        (read-string "Recipients: ")))
117                  nil
118                  (point-min) (point-max)
119                  (message-options-get 'message-sender)
120                  'sign)
121           (unless (> (point-max) (point-min))
122             (pop-to-buffer result-buffer)
123             (error "Encrypt error")))
124         (goto-char (point-min))
125         (while (re-search-forward "\r+$" nil t)
126           (replace-match "" t t))
127         (set-buffer text)
128         (delete-region (point-min) (point-max))
129         ;;(insert "Content-Type: application/pgp-encrypted\n\n")
130         ;;(insert "Version: 1\n\n")
131         (insert "\n")
132         (insert-buffer-substring cipher)
133         (goto-char (point-max))))))
134
135 ;;; gpg wrapper
136
137 (eval-and-compile
138   (autoload 'gpg-sign-cleartext "gpg"))
139
140 (defun mml1991-gpg-sign (cont)
141   (let ((text (current-buffer))
142         headers signature
143         (result-buffer (get-buffer-create "*GPG Result*")))
144     ;; Save MIME Content[^ ]+: headers from signing
145     (goto-char (point-min))
146     (while (looking-at "^Content[^ ]+:") (forward-line))
147     (unless (bobp)
148       (setq headers (buffer-string))
149       (delete-region (point-min) (point)))
150     (goto-char (point-max))
151     (unless (bolp)
152       (insert "\n"))
153     (quoted-printable-decode-region (point-min) (point-max))
154     (with-temp-buffer
155       (unless (gpg-sign-cleartext text (setq signature (current-buffer))
156                                   result-buffer
157                                   nil
158                                   (message-options-get 'message-sender))
159         (unless (> (point-max) (point-min))
160           (pop-to-buffer result-buffer)
161           (error "Sign error")))
162       (goto-char (point-min))
163       (while (re-search-forward "\r+$" nil t)
164         (replace-match "" t t))
165       (quoted-printable-encode-region (point-min) (point-max))
166       (set-buffer text)
167       (delete-region (point-min) (point-max))
168       (if headers (insert headers))
169       (insert "\n")
170       (insert-buffer-substring signature)
171       (goto-char (point-max)))))
172
173 (defun mml1991-gpg-encrypt (cont &optional sign)
174   (let ((text (current-buffer))
175         cipher
176         (result-buffer (get-buffer-create "*GPG Result*")))
177     ;; Strip MIME Content[^ ]: headers since it will be ASCII ARMOURED
178     (goto-char (point-min))
179     (while (looking-at "^Content[^ ]+:") (forward-line))
180     (unless (bobp)
181       (delete-region (point-min) (point)))
182     (mm-with-unibyte-current-buffer
183       (with-temp-buffer
184         (flet ((gpg-encrypt-func 
185                 (sign plaintext ciphertext result recipients &optional
186                       passphrase sign-with-key armor textmode)
187                 (if sign
188                     (gpg-sign-encrypt
189                      plaintext ciphertext result recipients passphrase
190                      sign-with-key armor textmode)
191                   (gpg-encrypt
192                    plaintext ciphertext result recipients passphrase
193                    armor textmode))))
194           (unless (gpg-encrypt-func
195                    sign
196                    text (setq cipher (current-buffer))
197                    result-buffer
198                    (split-string
199                     (or
200                      (message-options-get 'message-recipients)
201                      (message-options-set 'message-recipients
202                                           (read-string "Recipients: ")))
203                     "[ \f\t\n\r\v,]+")
204                    nil
205                    (message-options-get 'message-sender)
206                    t t) ; armor & textmode
207             (unless (> (point-max) (point-min))
208               (pop-to-buffer result-buffer)
209               (error "Encrypt error"))))
210         (goto-char (point-min))
211         (while (re-search-forward "\r+$" nil t)
212           (replace-match "" t t))
213         (set-buffer text)
214         (delete-region (point-min) (point-max))
215         ;;(insert "Content-Type: application/pgp-encrypted\n\n")
216         ;;(insert "Version: 1\n\n")
217         (insert "\n")
218         (insert-buffer-substring cipher)
219         (goto-char (point-max))))))
220
221 ;; pgg wrapper
222
223 (eval-when-compile
224   (defvar pgg-default-user-id)
225   (defvar pgg-errors-buffer)
226   (defvar pgg-output-buffer))
227
228 (defun mml1991-pgg-sign (cont)
229   (let (headers cte)
230     ;; Don't sign headers.
231     (goto-char (point-min))
232     (while (not (looking-at "^$"))
233       (forward-line))
234     (unless (eobp) ;; no headers?
235       (setq headers (buffer-substring (point-min) (point)))
236       (forward-line) ;; skip header/body separator
237       (delete-region (point-min) (point)))
238     (when (string-match "^Content-Transfer-Encoding: \\(.+\\)" headers)
239       (setq cte (intern (match-string 1 headers))))
240     (mm-decode-content-transfer-encoding cte)
241     (unless (let ((pgg-default-user-id
242                    (or (message-options-get 'mml-sender)
243                        pgg-default-user-id)))
244               (pgg-sign-region (point-min) (point-max) t))
245       (pop-to-buffer pgg-errors-buffer)
246       (error "Encrypt error"))
247     (delete-region (point-min) (point-max))
248     (mm-with-unibyte-current-buffer
249       (insert-buffer-substring pgg-output-buffer)
250       (goto-char (point-min))
251       (while (re-search-forward "\r+$" nil t)
252         (replace-match "" t t))
253       (mm-encode-content-transfer-encoding cte)
254       (goto-char (point-min))
255       (when headers
256         (insert headers))
257       (insert "\n"))
258     t))
259
260 (defun mml1991-pgg-encrypt (cont &optional sign)
261   (let (cte)
262     ;; Strip MIME Content[^ ]: headers since it will be ASCII ARMOURED
263     (goto-char (point-min))
264     (while (looking-at "^Content[^ ]+:")
265       (when (looking-at "^Content-Transfer-Encoding: \\(.+\\)")
266         (setq cte (intern (match-string 1))))
267       (forward-line))
268     (unless (bobp)
269       (delete-region (point-min) (point)))
270     (mm-decode-content-transfer-encoding cte)
271     (unless (pgg-encrypt-region
272              (point-min) (point-max) 
273              (split-string
274               (or
275                (message-options-get 'message-recipients)
276                (message-options-set 'message-recipients
277                                     (read-string "Recipients: ")))
278               "[ \f\t\n\r\v,]+")
279              sign)
280       (pop-to-buffer pgg-errors-buffer)
281       (error "Encrypt error"))
282     (delete-region (point-min) (point-max))
283     ;;(insert "Content-Type: application/pgp-encrypted\n\n")
284     ;;(insert "Version: 1\n\n")
285     (insert "\n")
286     (insert-buffer-substring pgg-output-buffer)
287     t))
288
289 ;;;###autoload
290 (defun mml1991-encrypt (cont &optional sign)
291   (let ((func (nth 2 (assq mml1991-use mml1991-function-alist))))
292     (if func
293         (funcall func cont sign)
294       (error "Cannot find encrypt function"))))
295
296 ;;;###autoload
297 (defun mml1991-sign (cont)
298   (let ((func (nth 1 (assq mml1991-use mml1991-function-alist))))
299     (if func
300         (funcall func cont)
301       (error "Cannot find sign function"))))
302
303 (provide 'mml1991)
304
305 ;; Local Variables:
306 ;; coding: iso-8859-1
307 ;; End:
308
309 ;;; arch-tag: e542be18-ab28-4393-9b33-97fe9cf30706
310 ;;; mml1991.el ends here