|
|
1.1 root 1: Date: Thu, 25 Feb 93 22:39:33 -0800
2: Message-Id: <[email protected]>
3: From: [email protected] (Stainless Steel Rat)
4: Subject: GNU Emacs front-end for PGP
5:
6: This is my first mostly-working PGP front-end for GNU Emacs. It works in
7: Rmail, and should work in VM. I don't recommend using it with mh-e due to
8: the radically different method of dealing with files and buffers (ie,
9: decrypted buffers won't be saved). It doesn't have any of the niceties
10: installed yet; I've been going for 36 hours now, and I need some sleep.
11:
12: The known problems are documented; the unknown ones I want to hear about.
13:
14: The decryption code could be better, except that I haven't gotten the
15: process filter to work the way I want; this brute-force version works, if
16: barely.
17:
18: ;;; -*-Emacs-Lisp-*-
19:
20: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
21: ;;; File: pgp.el v 1.0
22: ;;; Description: PGP Public Key system front-end
23: ;;; Author: Richard Pieri, [email protected]
24: ;;; Created: Fri Dec 25 12:25:42 1992
25: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
26:
27: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
28: ;;; Caveat: it is inherently insecure to use PGP or any other encryption
29: ;;; system on a multi-user system. There are just too many ways for someone
30: ;;; to spy on what you are doing. It is highly recommended that you keep
31: ;;; your private keys (secring.pgp) on write-protected mountable floppies
32: ;;; and you keep these disks in a secure place.
33: ;;;
34: ;;; Additionally, the distributed PGP 2.1 code won't use the PGPPASS
35: ;;; environment variable. The "#ifndef UNIX" on line 423 of pgp.c must be
36: ;;; changed to "#ifdef UNIX"; this may break PGP on other platforms (in fact
37: ;;; I can pretty much guarantee it).
38: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
39:
40: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
41: ;;; Known Bugs:
42: ;;; + There is no checking to see if you have entered an invalid pass phrase
43: ;;; in pgp-decrypt-message. If you do, then everything will seem to freeze
44: ;;; as PGP awaits a valid pass phrase.
45: ;;; + The encryption/decryption functions send all standard error output to
46: ;;; /dev/null: you never get to see any of the informational messages.
47: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
48:
49: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
50: ;;; History:
51: ;;; Stainless Steel Rat, Feb 25, 1993: rewrote the decryption code based on
52: ;;; suggestions and code written by Robert Anderson
53: ;;; <[email protected]>.
54: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
55:
56: ;; This is free software; you can redistribute it and/or modify
57: ;; it under the terms of the GNU General Public License as published by
58: ;; the Free Software Foundation.
59:
60: ;; This software is distributed in the hope that it will be useful,
61: ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
62: ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
63: ;; GNU General Public License for more details.
64:
65: ;; For a copy of the GNU General Public License write to
66: ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
67:
68: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
69: ;;; Installation:
70: ;;;
71: ;;; Edit pgp-program to point to the executable for PGP on your system. Then
72: ;;; byte-compile this file, put it in your load-path. Finally, put the command
73: ;;; (load "pgp") in your .emacs file. Enjoy.
74: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
75:
76: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
77: ;;; Variables
78: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
79:
80: (defvar pgp-program "/usr/local/bin/pgp"
81: "Path to PGP program.")
82:
83: (defvar pgp-path (getenv "PGPPATH")
84: "This should match your PGPPATH environment variable.")
85:
86: (defvar pgp-temp (concat pgp-path "/pgptemp.pgp")
87: "Scratch file used by pgp -f.")
88:
89: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
90: ;;; Functions
91: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
92:
93: ;;; This still needs a bit of work because it won't work as a filter.
94: ;;; At least I haven't figured out how to make it works as a filter...
95: (defun pgp-insert-public-key-block ()
96: "Insert your PGP Public Key Block at point."
97: (interactive)
98: (save-window-excursion
99: ;; delete temp files
100: (if (file-exists-p pgp-temp)
101: (delete-file pgp-temp))
102: (if (file-exists-p (concat pgp-path "/pgptemp.asc"))
103: (delete-file (concat pgp-path "/pgptemp.asc")))
104: ;; extract key into temp file
105: (shell-command (concat pgp-program " -kxa $USER " pgp-temp))
106: ;; and insert into the current buffer at point
107: (insert-file (concat pgp-path "/pgptemp.asc"))
108: ))
109:
110: (defun pgp-encrypt-message (userid)
111: "Encrypt from mail-header-separator to (point-max), replacing clear text
112: with cyphertext and the Public Key message delimiters.
113:
114: Note that this function is inherently flawed as you will never see any of
115: PGP's informational messages."
116: (interactive "sRecipient's userid: ")
117: (save-window-excursion
118: (save-excursion
119: ;; set region between mail-header-separator and the end of the buffer
120: (goto-char (point-min))
121: (search-forward mail-header-separator)
122: (forward-char 1)
123: (let ((start (point))
124: (end (point-max)))
125: ;; and encypher it
126: (shell-command-on-region
127: start end (concat pgp-program " -fea " userid " 2>/dev/null") t))
128: )))
129:
130: (defun pgp-decrypt-message ()
131: "Decrypt the PGP message between the BEGIN/END PGP MESSAGE delimiters,
132: replacing cyphertext with clear text in the current buffer.
133:
134: Note that this function is inherently flawed as you will never see any of
135: PGP's informational messages.
136:
137: Note that this function may be a security hole. If a pass phrase is in
138: memory when GNU Emacs crashes, it will appear in the core file. Anyone with
139: a half-decent grasp of hash tables will be able to extract your pass phrase
140: from the core file."
141: (interactive)
142: (save-window-excursion
143: (save-excursion
144: ;; delete temp file
145: (if (file-exists-p pgp-temp)
146: (delete-file pgp-temp))
147: ;; get pass phrase and put it into the environment list
148: (let ((passphrase (pgp-read-passwd "Enter pass phrase: ")))
149: (pgp-set-passphrase passphrase)
150: ;; save buffer-read-only status, and make the buffer writable
151: (let ((buffer-status buffer-read-only))
152: ;; set a region around the PGP message and decypher it
153: (setq buffer-read-only nil)
154: (goto-char (point-min))
155: (search-forward "-----BEGIN PGP MESSAGE-----")
156: (beginning-of-line)
157: (push-mark)
158: (search-forward "-----END PGP MESSAGE-----")
159: (forward-char 1)
160: (shell-command-on-region
161: (point) (mark) (concat pgp-program " -f 2>/dev/null") t)
162: ;; clear the pass phrase from memory and restore buffer status
163: (pgp-clear-passphrase)
164: (setq buffer-read-only buffer-status))
165: ))))
166:
167: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
168: ;;; Password support. Some of this is blatantly taken from ange-ftp.el
169: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
170:
171: (defun pgp-read-passwd (prompt &optional default)
172: "Read a password from the user. Echos a . for each character typed.
173: End with RET, LFD, or ESC. DEL or C-h rubs out. ^U kills line.
174: Optional DEFAULT is password to start with."
175: (let ((pass (if default default ""))
176: (c 0)
177: (echo-keystrokes 0)
178: (cursor-in-echo-area t))
179: (while (and (/= c ?\r) (/= c ?\n) (/= c ?\e))
180: (message "%s%s"
181: prompt
182: (make-string (length pass) ?.))
183: (setq c (read-char))
184: (if (= c ?\C-u)
185: (setq pass "")
186: (if (and (/= c ?\b) (/= c ?\177))
187: (setq pass (concat pass (char-to-string c)))
188: (if (> (length pass) 0)
189: (setq pass (substring pass 0 -1))))))
190: (pgp-repaint-minibuffer)
191: (substring pass 0 -1)))
192:
193: (defun pgp-repaint-minibuffer ()
194: "Gross hack to set minibuf_message = 0, so that the contents of the
195: minibuffer will show."
196: (if (eq (selected-window) (minibuffer-window))
197: (if (fboundp 'allocate-event)
198: ;; lemacs
199: (let ((unread-command-event (character-to-event ?\C-m
200: (allocate-event)))
201: (enable-recursive-minibuffers t))
202: (read-from-minibuffer "" nil pgp-tmp-keymap nil))
203: ;; v18 GNU Emacs
204: (let ((unread-command-char ?\C-m)
205: (enable-recursive-minibuffers t))
206: (read-from-minibuffer "" nil pgp-tmp-keymap nil)))))
207:
208: (defun stripstrlist (l str)
209: "Strip from list-of-strings L any string which matches STR."
210: (cond (l (cond ((string-match str (car l))
211: (stripstrlist (cdr l) str))
212: (t (cons (car l) (stripstrlist (cdr l) str)))))))
213:
214: (defun pgp-set-passphrase (arg)
215: "Set PGPPASS environment variable from argument."
216: (interactive "sPGP pass phrase: ")
217: (setq process-environment
218: (cons (concat "PGPPASS=" arg)
219: (stripstrlist process-environment "^PGPPASS="))))
220:
221: (defun pgp-clear-passphrase ()
222: "Clear PGPPASS environment variable."
223: (interactive)
224: (setq process-environment (stripstrlist process-environment "^PGPPASS=")))
225:
226: --Rat PGP Public Key Block available upon request
227: ||||| | | | | | | | | | | | | | | | | | | | | | | |||||
228: Northeastern's Stainless Steel Rat [email protected]
229: And now we meet again, for the first time, for the last time. --Dark Helmet
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.