From mboxrd@z Thu Jan 1 00:00:00 1970 X-Msuck: nntp://news.gmane.io/gmane.emacs.gnus.general/56210 Path: main.gmane.org!not-for-mail From: Ted Zlatanov Newsgroups: gmane.emacs.gnus.general Subject: Re: netrc.el now supports encoded files Date: Tue, 27 Jan 2004 14:44:42 -0500 Organization: =?koi8-r?q?=F4=C5=CF=C4=CF=D2=20=FA=CC=C1=D4=C1=CE=CF=D7?= @ Cienfuegos Sender: ding-owner@lists.math.uh.edu Message-ID: <4nektljhw5.fsf@collins.bwh.harvard.edu> References: <4n3caut1yy.fsf@collins.bwh.harvard.edu> <4nptdx99g3.fsf@collins.bwh.harvard.edu> <4nwu84y967.fsf@collins.bwh.harvard.edu> <4nfzesy6h9.fsf@collins.bwh.harvard.edu> <4nisjmhzd0.fsf@collins.bwh.harvard.edu> NNTP-Posting-Host: deer.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Trace: sea.gmane.org 1075233212 8757 80.91.224.253 (27 Jan 2004 19:53:32 GMT) X-Complaints-To: usenet@sea.gmane.org NNTP-Posting-Date: Tue, 27 Jan 2004 19:53:32 +0000 (UTC) Cc: Karl Berry , kyle_jones@wonderworks.com Original-X-From: ding-owner+M4750@lists.math.uh.edu Tue Jan 27 20:53:13 2004 Return-path: Original-Received: from malifon.math.uh.edu ([129.7.128.13]) by deer.gmane.org with esmtp (Exim 3.35 #1 (Debian)) id 1AlZCW-0001Uw-00 for ; Tue, 27 Jan 2004 20:48:45 +0100 Original-Received: from localhost ([127.0.0.1] helo=lists.math.uh.edu) by malifon.math.uh.edu with smtp (Exim 3.20 #1) id 1AlZAI-0000Kd-00; Tue, 27 Jan 2004 13:46:26 -0600 Original-Received: from justine.libertine.org ([66.139.78.221] ident=postfix) by malifon.math.uh.edu with esmtp (Exim 3.20 #1) id 1AlZA7-0000KX-00 for ding@lists.math.uh.edu; Tue, 27 Jan 2004 13:46:16 -0600 Original-Received: from clifford.bwh.harvard.edu (clifford.bwh.harvard.edu [134.174.9.41]) by justine.libertine.org (Postfix) with ESMTP id E17773A004A for ; Tue, 27 Jan 2004 13:46:12 -0600 (CST) Original-Received: from collins.bwh.harvard.edu (collins [134.174.9.80]) by clifford.bwh.harvard.edu (8.10.2+Sun/8.11.0) with ESMTP id i0RJipU09418; Tue, 27 Jan 2004 14:44:51 -0500 (EST) Original-Received: from collins.bwh.harvard.edu (localhost [127.0.0.1]) by collins.bwh.harvard.edu (8.12.9+Sun/8.11.0) with ESMTP id i0RJigvl002349; Tue, 27 Jan 2004 14:44:42 -0500 (EST) Original-Received: (from tzz@localhost) by collins.bwh.harvard.edu (8.12.9+Sun/8.12.9/Submit) id i0RJigiA002346; Tue, 27 Jan 2004 14:44:42 -0500 (EST) Original-To: ding@gnus.org X-Face: bd.DQ~'29fIs`T_%O%C\g%6jW)yi[zuz6;d4V0`@y-~$#3P_Ng{@m+e4o<4P'#(_GJQ%TT= D}[Ep*b!\e,fBZ'j_+#"Ps?s2!4H2-Y"sx" Mail-Followup-To: ding@gnus.org, Karl Berry , kyle_jones@wonderworks.com In-Reply-To: <4nisjmhzd0.fsf@collins.bwh.harvard.edu> (Ted Zlatanov's message of "Thu, 08 Jan 2004 17:03:39 -0500") User-Agent: Gnus/5.110002 (No Gnus v0.2) Emacs/21.3.50 (usg-unix-v) Precedence: bulk Xref: main.gmane.org gmane.emacs.gnus.general:56210 X-Report-Spam: http://spam.gmane.org/gmane.emacs.gnus.general:56210 --=-=-= On Thu, 08 Jan 2004, tzz@lifelogs.com wrote: > Without gencrypt.el, gnus-encrypt.el will provide four options: > OpenSSL encoding (I'll just copy what I have in netrc.el), GPG > encoding (simple command-line invocation with --armor), base64 > encoding, and no encoding. I've finished the GPG and one built-in cipher for gnus-encrypt.el. Attached is the code. I need a few people to test it, and any feedback is appreciated of course. OpenSSL and base64 encodings were not implemented because I didn't think they were really necessary. OpenSSL support will probably come through gencrypt.el when that's released. If the *encoding* fails, the file is saved in plain text. If the *decoding* fails, we load the encoded file. Tough break. The built-in XOR filter is actually pretty nice. It's not good encryption, but it's definitely a step up from base64, and it had decent speed when I tried it. The major issue is that, for simplicity, gnus-encrypt.el only works with whole buffers. I don't think more will be necessary for Gnus development, although the gencrypt.el code will definitely support encoding of regions and such. If and when gnus-encrypt.el goes into the Gnus CVS, I will start adding support for it everywhere in Gnus. Without setting gnus-encrypt-file-alist, users will see absolutely no effect from the gnus-encrypt functions. Ted --=-=-= Content-Type: application/emacs-lisp Content-Disposition: attachment; filename=gnus-encrypt.el Content-Transfer-Encoding: quoted-printable ;;; gnus-encrypt.el --- file encryption routines for Gnus ;; Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc. ;; Author: Teodor Zlatanov ;; Keywords: files ;; This file is part of GNU Emacs. ;; GNU Emacs is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation; either version 2, or (at your option) ;; any later version. ;; GNU Emacs is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with GNU Emacs; see the file COPYING. If not, write to the ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, ;; Boston, MA 02111-1307, USA. ;;; Commentary: ;;; This module addresses data encryption under Gnus. Page breaks are ;;; used for grouping declarations and documentation relating to each ;;; particular aspect. ;;; Code: ;; autoload password (eval-and-compile (autoload 'password-read "password")) (eval-and-compile (autoload 'pgg-gpg-decrypt-region "pgg-gpg") (autoload 'pgg-gpg-encrypt-region "pgg-gpg")) (defgroup gnus-encrypt nil "Gnus encryption configuration.") (defcustom gnus-encrypt-file-alist nil "List of file names or regexes matched with encryptions. Format example: '((\"/home/tzz/alpha\" gpg \"AES\") ; GPG on single file ;; xor encryption on all files matching \"beta\" (\"beta\" gnus-encrypt-xor \"Semi-Secret\"))." :type '(repeat (list :tag "Encryption entry" (radio :tag "What to encrypt" (file :tag "Filename") (regexp :tag "Regular expression match")) (radio :tag "How to encrypt it" (list :tag "GPG Encryption" (const :tag "GPG Program" gpg) (radio :tag "Choose a cipher" (const :tag "3DES Encryption" "3DES") (const :tag "CAST5 Encryption" "CAST5") (const :tag "Blowfish Encryption" "BLOWFISH") (const :tag "AES Encryption" "AES") (const :tag "AES192 Encryption" "AES192") (const :tag "AES256 Encryption" "AES256") (const :tag "Twofish Encryption" "TWOFISH") (string :tag "Cipher Name"))) (list :tag "Built-in simple XOR" (const :tag "XOR Encryption" gnus-encrypt-xor) (string :tag "XOR Cipher Value (seed value)"))))) :group 'gnus-encrypt) ;; TODO: now, load gencrypt.el and if successful, modify the ;; custom-type of gnus-encrypt-file-alist to add the gencrypt.el options ;; (plist-get (symbol-plist 'gnus-encrypt-file-alist) 'custom-type) (defcustom gnus-encrypt-gpg-path (executable-find "gpg") "Path to the GPG program." :type '(radio (file :tag "Location of the GPG executable") (const :tag "GPG is not installed" nil)) :group 'gnus-encrypt) (defvar gnus-encrypt-temp-prefix "gnus-encrypt" "Prefix for temporary filenames") (defun gnus-encrypt-find-model (filename) "Given a filename, find a gnus-encrypt-file-alist entry" (dolist (entry gnus-encrypt-file-alist) (let ((match (nth 0 entry)) (model (nth 1 entry))) (when (or (eq match filename) (string-match match filename)) (return model))))) (defun gnus-encrypt-insert-file-contents (file) "Decrypt FILE into the current buffer." (interactive "fFile to insert: ") (let* ((model (gnus-encrypt-find-model file)) (method (nth 0 model)) (cipher (nth 1 model)) (passphrase (password-read (format "%s password for cipher %s? " (symbol-name method) cipher) (format "gnus-encrypt-password-%s-%s" (symbol-name method) cipher))) (buffer-file-coding-system 'binary) (coding-system-for-read 'binary) status-ok) (insert-file-contents file) (cond ((eq method 'gpg) (setq status-ok (gnus-encrypt-gpg-decode-buffer passphrase cipher t))) ((eq method 'gnus-encrypt-xor) (setq status-ok (gnus-encrypt-xor-decode-buffer passphrase cipher t))= )) (if status-ok (gnus-message 9 "%s was decrypted with %s (cipher %s)" file (symbol-name method) cipher) (gnus-error 5 "%s was NOT decrypted with %s (cipher %s)" file (symbol-name method) cipher)))) (defun gnus-encrypt-write-file-contents (file) "Encrypt the current buffer to FILE, then continue normally." (interactive "fFile to write: ") (let* ((model (gnus-encrypt-find-model file)) (method (nth 0 model)) (cipher (nth 1 model)) (contents (buffer-string)) (passphrase (password-read (format "%s password for cipher %s? " (symbol-name method) cipher) (format "gnus-encrypt-password-%s-%s" (symbol-name method) cipher))) status-ok) (cond ((eq method 'gpg) (setq status-ok (gnus-encrypt-gpg-encode-buffer passphrase cipher t))) ((eq method 'gnus-encrypt-xor) (setq status-ok (gnus-encrypt-xor-encode-buffer passphrase cipher t))= )) (if status-ok (gnus-message 9 "%s was encrypted with %s (cipher %s)" file (symbol-name method) cipher) (gnus-error 5 "%s was NOT encrypted with %s (cipher %s)" file (symbol-name method) cipher)) ;; do not confirm overwrites (write-file file nil))) ;; undo-if-error is ignored (defun gnus-encrypt-xor-encode-buffer (passphrase cipher undo-if-error) (gnus-encrypt-xor-process-buffer passphrase cipher t)) ;; undo-if-error is ignored (defun gnus-encrypt-xor-decode-buffer (passphrase cipher undo-if-error) (gnus-encrypt-xor-process-buffer passphrase cipher nil)) (defun gnus-encrypt-xor-process-buffer (passphrase cipher &optional encode) "Given PASSPHRASE, xor-encode or decode the contents of the current buffe= r." (let* ((bs (buffer-string)) ;; passphrase-sum is a simple additive checksum of the ;; passphrase and the cipher (passphrase-sum (when (stringp passphrase) (apply '+ (append cipher passphrase nil)))) new-list) (delete-region (point-min) (point-max)) (goto-char (point-min)) (if encode (progn (dolist (x (append bs nil)) (setq new-list (cons (logxor x passphrase-sum) new-list))) (dolist (x new-list) (insert (format "%d " x)))) (progn (setq new-list (reverse (split-string bs))) (dolist (x new-list) (setq x (string-to-int x)) (insert (format "%c" (logxor x passphrase-sum)))))) t)) (defun gnus-encrypt-gpg-encode-buffer (passphrase cipher undo-if-error) (gnus-encrypt-gpg-process-buffer passphrase cipher t undo-if-error)) (defun gnus-encrypt-gpg-decode-buffer (passphrase cipher undo-if-error) (gnus-encrypt-gpg-process-buffer passphrase cipher nil undo-if-error)) (defun gnus-encrypt-gpg-process-buffer (passphrase=20 cipher=20 &optional encode undo-if-error) "With PASSPHRASE, use GPG to encode or decode the contents of the current= buffer." (let ((program gnus-encrypt-gpg-path) (old-buffer-string (buffer-string)) (input (buffer-substring-no-properties (point-min) (point-max))) (temp-file (make-temp-file gnus-encrypt-temp-prefix)) (default-enable-multibyte-characters nil) (args `("--cipher-algo" ,cipher "--status-fd" "2" "--logger-fd" "2" "--passphrase-fd" "0" "--no-tty")) exit-status) (when encode (setq args=20 (append args '("--symmetric" "--armor")))) (if program (progn (delete-region (point-min) (point-max)) (goto-char (point-min)) (when passphrase (insert passphrase "\n")) (insert input) (setq exit-status (apply #'call-process-region (point-min) (point-max) program t `(t ,temp-file) nil args)) (unless (equal exit-status 0) (setq exit-status nil) (when undo-if-error (delete-region (point-min) (point-max)) (goto-char (point-min)) (insert old-buffer-string)) (with-temp-buffer (when (file-exists-p temp-file) (insert-file-contents temp-file) (delete-file temp-file)) (gnus-error 5 (format "%s exited abnormally: '%s' [%s]" program exit-status (buffer-string)))))) (gnus-error 5 "GPG is not installed.")) exit-status)) (provide 'gnus-encrypt) ;;; gnus-encrypt.el ends here --=-=-=--