Sync with emiko-1_14.
[elisp/semi.git] / mime-mc.el
1 ;;; mime-mc.el --- Mailcrypt interface for SEMI
2
3 ;; Copyright (C) 1996,1997,1998 MORIOKA Tomohiko
4
5 ;; Author: MORIOKA Tomohiko <morioka@jaist.ac.jp>
6 ;; Keywords: PGP, security, MIME, multimedia, mail, news
7
8 ;; This file is part of SEMI (Secure Emacs MIME Interface).
9
10 ;; This program is free software; you can redistribute it and/or
11 ;; modify it under the terms of the GNU General Public License as
12 ;; published by the Free Software Foundation; either version 2, or (at
13 ;; your option) any later version.
14
15 ;; This program is distributed in the hope that it will be useful, but
16 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18 ;; General Public License for more details.
19
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GNU Emacs; see the file COPYING.  If not, write to the
22 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
23 ;; Boston, MA 02110-1301, USA.
24
25 ;;; Code:
26
27 (require 'mailcrypt)
28 (eval-and-compile (load "mc-pgp"))
29
30 (defun mime-mc-pgp-generic-parser (result)
31   (let ((ret (mc-pgp-generic-parser result)))
32     (if (consp ret)
33         (vector (car ret)(cdr ret)))))
34
35 (defun mime-mc-process-region
36   (beg end passwd program args parser &optional buffer boundary)
37   (let ((obuf (current-buffer))
38         (process-connection-type nil)
39         mybuf result rgn proc)
40     (unwind-protect
41         (progn
42           (setq mybuf (or buffer (generate-new-buffer " *mailcrypt temp")))
43           (set-buffer mybuf)
44           (erase-buffer)
45           (set-buffer obuf)
46           (buffer-disable-undo mybuf)
47           (setq proc
48                 (apply 'start-process "*PGP*" mybuf program args))
49           (if passwd
50               (progn
51                 (process-send-string proc (concat passwd "\n"))
52                 (or mc-passwd-timeout (mc-deactivate-passwd t))))
53           (process-send-region proc beg end)
54           (process-send-eof proc)
55           (while (eq 'run (process-status proc))
56             (accept-process-output proc 5))
57           (setq result (process-exit-status proc))
58           ;; Hack to force a status_notify() in Emacs 19.29
59           (delete-process proc)
60           (set-buffer mybuf)
61           (goto-char (point-max))
62           (if (re-search-backward "\nProcess \\*PGP.*\n\\'" nil t)
63               (delete-region (match-beginning 0) (match-end 0)))
64           (goto-char (point-min))
65           ;; CRNL -> NL
66           (while (search-forward "\r\n" nil t)
67             (replace-match "\n"))
68           ;; Hurm.  FIXME; must get better result codes.
69           (if (stringp result)
70               (error "%s exited abnormally: '%s'" program result)
71             (setq rgn (funcall parser result))
72             ;; If the parser found something, migrate it
73             (if (consp rgn)
74                 (progn
75                   (set-buffer obuf)
76                   (if boundary
77                       (save-restriction
78                         (narrow-to-region beg end)
79                         (goto-char beg)
80                         (insert (format "--%s\n" boundary))
81                         (goto-char (point-max))
82                         (insert (format "\n--%s
83 Content-Type: application/pgp-signature
84 Content-Transfer-Encoding: 7bit
85
86 " boundary))
87                         (insert-buffer-substring mybuf (car rgn) (cdr rgn))
88                         (goto-char (point-max))
89                         (insert (format "\n--%s--\n" boundary)))
90                     (delete-region beg end)
91                     (goto-char beg)
92                     (insert-buffer-substring mybuf (car rgn) (cdr rgn)))
93                   (set-buffer mybuf)
94                   (delete-region (car rgn) (cdr rgn)))))
95           ;; Return nil on failure and exit code on success
96           (if rgn result))
97       ;; Cleanup even on nonlocal exit
98       (if (and proc (eq 'run (process-status proc)))
99           (interrupt-process proc))
100       (set-buffer obuf)
101       (or buffer (null mybuf) (kill-buffer mybuf)))))
102
103 (defun mime-mc-pgp-sign-region (start end &optional id unclear boundary)
104   ;; (if (not (boundp 'mc-pgp-user-id))
105   ;;     (load "mc-pgp")
106   ;;   )
107   (let ((process-environment process-environment)
108         (buffer (get-buffer-create mc-buffer-name))
109         passwd args key
110         (parser (function mc-pgp-generic-parser))
111         (pgp-path mc-pgp-path))
112     (setq key (mc-pgp-lookup-key (or id mc-pgp-user-id)))
113     (setq passwd
114           (mc-activate-passwd
115            (cdr key)
116            (format "PGP passphrase for %s (%s): " (car key) (cdr key))))
117     (setenv "PGPPASSFD" "0")
118     (setq args
119           (cons
120            (if boundary
121                "-fbast"
122              "-fast")
123            (list "+verbose=1" "+language=en"
124                  (format "+clearsig=%s" (if unclear "off" "on"))
125                  "+batchmode" "-u" (cdr key))))
126     (if mc-pgp-comment
127         (setq args (cons (format "+comment=%s" mc-pgp-comment) args)))
128     (message "Signing as %s..." (car key))
129     (if (mime-mc-process-region
130          start end passwd pgp-path args parser buffer boundary)
131         (progn
132           (if boundary
133               (progn
134                 (goto-char (point-min))
135                 (insert
136                  (format "\
137 --[[multipart/signed; protocol=\"application/pgp-signature\";
138  boundary=\"%s\"; micalg=pgp-md5][7bit]]\n" boundary))
139                 ))
140           (message "Signing as %s...done" (car key))
141           t)
142       nil)))
143
144 (defun mime-mc-pgp-encrypt-region (recipients start end &optional id sign)
145   (let ((mc-pgp-always-sign (if (eq sign 'maybe)
146                                 mc-pgp-always-sign
147                               'never)))
148     (mc-pgp-encrypt-region
149      (mc-split "\\([ \t\n]*,[ \t\n]*\\)+" recipients)
150      start end id nil)))
151
152                 
153 ;;; @ end
154 ;;;
155
156 (provide 'mime-mc)
157
158 ;;; mime-mc.el ends here