|
|
1.1 ! root 1: Subject: Using PGP with Emacs Rmail ! 2: Date: 9 Oct 1992 14:39:10 GMT ! 3: From: [email protected] (Robert Anderson) ! 4: Lines: 319 ! 5: ! 6: ! 7: PGP with GNU Emacs Rmail Revision 1 ! 8: ------------------------ October 2, 1992 ! 9: ! 10: Here are some notes on using PGP 2.0 on a Unix platform, using ! 11: the Gnu Emacs "rmail" package to send and receive mail. ! 12: ! 13: First, it is inherently insecure to use PGP, or any encryption ! 14: program, on a multi-user system. There are just too many ways ! 15: for the system operators, or even ordinary users, to spy on what ! 16: you are doing. However, many people are only able to send and ! 17: receive mail on such machines, and it still may be useful for ! 18: them to be able to use PGP. The security is nowhere near as ! 19: great as it would be on a laptop PC which you keep chained to ! 20: your wrist at all times, but it should be good enough for casual ! 21: privacy. ! 22: ! 23: ! 24: FILTERING ! 25: ! 26: ! 27: PGP 2.0 has a "filter" mode invoked with the "-f" switch. Many ! 28: Unix mail reading tools have the ability to pass messages, or ! 29: portions of messages, through filter programs, returning the ! 30: result to the editing buffer. This general approach is what I ! 31: will discuss, as it applies specifically to Gnu Emacs. (I use ! 32: Gnu Emacs version 18.55.3, of Friday, July 26, 1991. But most of ! 33: the features discussed here should apply to almost any current ! 34: Gnu Emacs.) ! 35: ! 36: The Emacs command to pass a portion of a buffer through a filter ! 37: is "shell-command-on-region". On my machine, it is mapped to the ! 38: key M-|, which I activate by typing the escape key and then the ! 39: vertical bar key. By giving a prefix argument to this function, ! 40: which I do by typing control-U just before the M-|, the function ! 41: replaces the text in the buffer with the output of the filter. ! 42: ! 43: ! 44: ENCRYPTION ! 45: ! 46: ! 47: To encrypt a message, then, I first compose the message using the ! 48: "mail" function of Emacs. Then I set the Emacs "region" to ! 49: contain the message text (but not the headers at the top of the ! 50: message). This I do by the function "mark-whole-buffer", which ! 51: is mapped to control-X H on my system, then advancing the "point" ! 52: (cursor) down from the top of the page using control-N until I am ! 53: at the first line of the message I am sending. (This is the line ! 54: just beyond the separator line which Emacs creates called "--text ! 55: follows this line--".) This is how a sample message buffer will ! 56: look at this point: ! 57: ! 58: To: [email protected] ! 59: Subject: Test of PGP with Emacs ! 60: --text follows this line-- ! 61: Dear XYZ: ! 62: I hope you enjoy this encrypted PGP message. ! 63: Love, ABC. ! 64: ! 65: (The cursor is on the "D" of "Dear", and the "mark", which you ! 66: can't see, is at the end of the buffer.) ! 67: ! 68: With the region properly set to enclose the message text, I now ! 69: want to filter the message through PGP. The general idea is to ! 70: use control-U followed by M-|, but a problem arises if I do this. ! 71: ! 72: PGP, when run in filter mode, produces encrypted or decrypted ! 73: output based on its input. But in addition, it also produces a ! 74: few informational messages, such as the version information that ! 75: is printed for every run. PGP goes to some trouble to separate ! 76: these two kinds of output, putting the encrypted output to ! 77: "standard out", and the informational messages to "standard ! 78: error". Unfortunately, Emacs undoes PGP's efforts, combining ! 79: standard out and standard error into one stream. The result is ! 80: that using this Emacs filter function brings back not just the ! 81: encrypted message, but also the PGP informational messages. This ! 82: is what the output looks like: ! 83: ! 84: To: [email protected] ! 85: Subject: Test of PGP with Emacs ! 86: --text follows this line-- ! 87: Pretty Good Privacy 2.0 - Public-key encryption for the masses. ! 88: (c) 1990-1992 Philip Zimmermann, Phil's Pretty Good Software. 2 Sep 92 ! 89: Date: 1992/10/02 22:10 GMT ! 90: ! 91: ! 92: Recipient's public key will be used to encrypt. ! 93: Key for user ID: XYZ ! 94: 382-bit key, Key ID 5E7ADD, created 1992/09/27 ! 95: .-----BEGIN PGP MESSAGE----- ! 96: Version: 2.0 ! 97: ! 98: hDwC2RA+W2deet0BAX4iI1FcS9qz57OA2pd3T/tr7wcwzW5mHocwvlND+Un0aYac ! 99: Kq4qwjxpxr5rY/ABEAymAAAAWnZfbPeqdeXZGkFqCUny9tnVuew9JfSkzaGVIbpS ! 100: aTOxzNcWP7hgHVCW4FUyFgCUmGGBgIbbSUwisrQsMo0lUH4UxUjjKLYav+RGs8Z6 ! 101: 9SG3RzAnnpEdAhSSbQ== ! 102: =zAPP ! 103: -----END PGP MESSAGE----- ! 104: ! 105: This can be cleaned up manually by deleting all the characters ! 106: from the "Pretty Good Privacy" header down to the "." just before ! 107: "-----BEGIN PGP MESSAGE-----". But this is tedious. To avoid ! 108: this problem, I created a very simple shell script which I use to ! 109: run PGP. It looks like this: ! 110: ! 111: : ! 112: exec pgp $* 2>/dev/null ! 113: ! 114: I call this script "pgpq". The first line is just a colon, and ! 115: the second line just remaps standard error to /dev/null, causing ! 116: it to disappear, and passes all arguments along to PGP. The ! 117: result is that PGP's informational messages do not appear back in ! 118: the Emacs buffer when I run it as "pgpq". ! 119: ! 120: With this script, I can encrypt messages to be sent to other ! 121: people within Emacs. First I set the region with control-X H ! 122: followed by a few control-N's. Then I type control-U M-|. Emacs ! 123: prompts with the query "Shell command on region:". For ! 124: encryption of a message to user XYZ, I type: ! 125: ! 126: pgpq -fea XYZ ! 127: ! 128: The command is given as "pgpq" to get a cleaner output as ! 129: described above. The option letter "f" means to use filter mode; ! 130: "e" means to encrypt, and "a" means to get ASCII output. The ! 131: user name comes next. (For information on how to also sign a ! 132: message, see below.) The output of this command, for the example ! 133: above, looks like: ! 134: ! 135: To: [email protected] ! 136: Subject: Test of PGP with Emacs ! 137: --text follows this line-- ! 138: -----BEGIN PGP MESSAGE----- ! 139: Version: 2.0 ! 140: ! 141: hDwC2RA+W2deet0BAX4omw4gByFkFaHFko7qPBVq1Yh7EpgHnbZ5EebqFiQjr61I ! 142: Bz6t1tQZSloNJ4KhTYOmAAAAWi2Ja/oM0LvEi9fumi4IdKDQJ44ihatrM0AEYUi5 ! 143: CVJjj5YCuQUl5XT/s5cG+Gu6R5fTPtmQ94iBmIMUjOw+yEcCkIa5B87PmJJDusMC ! 144: f1K8VWsc2A2oAJIWqg== ! 145: =uvLF ! 146: -----END PGP MESSAGE----- ! 147: ! 148: Assuming user XYZ is on my key ring, the text of the message in ! 149: my buffer has been replaced by the encrypted form of the text. I ! 150: can then send the message on its way as usual. ! 151: ! 152: ! 153: DECRYPTION ! 154: ! 155: ! 156: I decrypt my incoming mail "in place", substituting the decrypted ! 157: text in place of the encrypted message. To do this using the ! 158: Emacs rmail package, the incoming mail message must be made ! 159: writable, using the "rmail-edit-current-message" function, mapped ! 160: to the letter "w" on my system. Then the steps below can be used ! 161: to decrypt the message. Afterwards, the "rmail-cease-edit" ! 162: function, mapped to "control-C control-C" on my system, is used ! 163: to "write back" the decrypted message. (If you like, after ! 164: reading the decrypted message but before writing it back you can ! 165: use "rmail-abort-edit", "control-C control-]" on my system, to ! 166: discard your changes and leave the encrypted message in place.) ! 167: ! 168: Decrypting an incoming message can be done in a similar manner to ! 169: encryption. First I set the Emacs "region" to enclose the PGP ! 170: portion of the message. Then it is piped through the "pgpq" ! 171: filter to get the decrypted result. ! 172: ! 173: However, the new element in the case of decryption is the need to ! 174: enter a pass phrase to activate your secret key. I solve this by ! 175: using the "PGPPASS" environment variable. If PGP is trying to ! 176: read your secret key and this environment variable exists, it ! 177: will try to use the value of this variable as your pass phrase. ! 178: ! 179: So, to do decryption, it is necessary to set this environment ! 180: variable before running the filter. This could be done by ! 181: setting the variable before Emacs is started, so it will inherit ! 182: the value from the shell. However, I use the Emacs variable ! 183: "process-environment", which contains the environment variables ! 184: and their values which are passed to sub-shells and filter ! 185: processes. I wrote a few small Emacs functions to make it easier ! 186: to set and clear PGPPASS from the "process-environment" variable. ! 187: They are: ! 188: ! 189: ! 190: ; PGP support ! 191: ; Strip from list-of-strings l, any string which matches str ! 192: (defun stripstrlist (l str) ! 193: (cond (l (cond ((string-match str (car l)) ! 194: (stripstrlist (cdr l) str)) ! 195: (t (cons (car l) (stripstrlist (cdr l) str))))))) ! 196: ! 197: ; Set PGPPASS environment variable from argument ! 198: (defun pgp-passphrase (arg) ! 199: (interactive "sPGP pass phrase: ") ! 200: (setq process-environment ! 201: (cons (concat "PGPPASS=" arg) ! 202: (stripstrlist process-environment "^PGPPASS=")))) ! 203: ! 204: ; Clear PGPPASS environment variable ! 205: (defun clear-pgp-passphrase () ! 206: (interactive) ! 207: (setq process-environment (stripstrlist process-environment "^PGPPASS="))) ! 208: ! 209: ! 210: I put this code in my Emacs startup file, ".emacs". To use it, I ! 211: do "M-X pgp-passphrase" to set the pass phrase. It prompts me, ! 212: and I enter the pass phrase I use. Generally, I set it once and ! 213: leave it set for the duration of an Emacs session, but I also can ! 214: use "M-X clear-pgp-passphrase" to clear the pass phrase from the ! 215: process-environment variable. ! 216: ! 217: Having set the pass phrase, decryption of incoming messages is ! 218: straightforward. I set the region, do control-U M-X, and when ! 219: Emacs prompts with "Shell command on region:" I reply: ! 220: ! 221: pgpq -f ! 222: ! 223: This causes the message to be decrypted, and the output to be put ! 224: back in the buffer, overwriting the encrypted data. Here is the ! 225: buffer before decryption: ! 226: ! 227: To: [email protected] ! 228: Subject: Test of PGP with Emacs ! 229: --text follows this line-- ! 230: -----BEGIN PGP MESSAGE----- ! 231: Version: 2.0 ! 232: ! 233: hDwC2RA+W2deet0BAX4omw4gByFkFaHFko7qPBVq1Yh7EpgHnbZ5EebqFiQjr61I ! 234: Bz6t1tQZSloNJ4KhTYOmAAAAWi2Ja/oM0LvEi9fumi4IdKDQJ44ihatrM0AEYUi5 ! 235: CVJjj5YCuQUl5XT/s5cG+Gu6R5fTPtmQ94iBmIMUjOw+yEcCkIa5B87PmJJDusMC ! 236: f1K8VWsc2A2oAJIWqg== ! 237: =uvLF ! 238: -----END PGP MESSAGE----- ! 239: ! 240: And here it is after setting the PGP pass phrase, putting the ! 241: region around the "PGP MESSAGE" part, and running "pgpq -f": ! 242: ! 243: To: [email protected] ! 244: Subject: Test of PGP with Emacs ! 245: --text follows this line-- ! 246: Dear XYZ: ! 247: I hope you enjoy this encrypted PGP message. ! 248: Love, ABC. ! 249: ! 250: ! 251: SIGNING AND ENCRYPTING ! 252: ! 253: ! 254: The technique of setting the PGPPASS environment variable also ! 255: allows you to sign your outgoing messages along with encrypting ! 256: them. Use the "M-X pgp-passphrase" command to set your PGP pass ! 257: phrase, then encrypt the outgoing message with the command: ! 258: ! 259: pgpq -safe XYZ ! 260: ! 261: This tells PGP to sign, ascii-encode, use filter mode, and ! 262: encrypt the output for user XYZ. ! 263: ! 264: ! 265: WHEN THINGS GO WRONG ! 266: ! 267: ! 268: Once in a while, you will pass a message through PGP for ! 269: encryption or decryption, and instead of getting replacement ! 270: text, your message simply vanishes. Don't panic. The Emacs ! 271: "undo" function, mapped to control-X U on my system, can be used ! 272: to recover your message. ! 273: ! 274: Probably what happened was that PGP had some problem in either ! 275: encrypting or decrypting the message. Maybe you misspelled the ! 276: User ID so that it wasn't found on the keyring. Or maybe an ! 277: incoming message was mistakenly encrypted in someone else's key, ! 278: or was in a mode which PGP can't handle when used as a filter ! 279: (see below). ! 280: ! 281: The best way to diagnose the problem is to first bring the ! 282: message back with "undo" as just described, then to re-run the ! 283: filter command, but to use "pgp" rather than "pgpq". This will ! 284: cause the PGP informational messages to be put into your buffer. ! 285: Usually these will make clear what the problem is. Give another ! 286: "undo" to get back to the original message after reading this ! 287: output. ! 288: ! 289: ! 290: PROBLEMS AND LIMITATIONS ! 291: ! 292: ! 293: There are some problems associated with using PGP in this mode. ! 294: Probably the biggest is that in decrypting, the informational ! 295: messages are thrown away. This means that you lose information ! 296: about any incoming signed messages as far as whether the ! 297: signatures are valid or not. In fact, you won't even know that ! 298: the messages are signed. ! 299: ! 300: The pgpq script could be enhanced to pipe standard error to some ! 301: filter program that could look at the informational output from ! 302: PGP and print a warning message (which would appear back in the ! 303: buffer along with the decrypted message) if, say, an invalid ! 304: signature was found. More work is needed in this area. ! 305: ! 306: Another problem arises if PGP is used with conventional ! 307: encryption (using the -c flag). Conventional encryption prompts ! 308: for a pass phrase, but it does not check the PGPPASS environment ! 309: variable, or any other such variable. At present, conventional ! 310: encryption and decryption cannot be done in filter mode under ! 311: Emacs. ! 312: ! 313: Any other features of PGP which would require interaction with ! 314: the user, such as decrypting a key and trying to add it to the ! 315: key ring, will also not work in this filter mode. The test cases ! 316: which I have tried work about as well as they can (e.g. when ! 317: decrypting a key in filter mode, PGP shows the contents of the ! 318: key but doesn't ask if it should be added to your key ring), but ! 319: for some of these functions you will have to fire up PGP outside ! 320: of Emacs. ! 321: -- ! 322: ------------ ! 323: Bob Anderson ! 324: [email protected] ! 325:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.