;;; -*- Emacs-Lisp -*-
(defvar epg-modules
- '(epg epg-file))
+ '(epg epf))
(defun epg-compile-modules (modules)
(let ((load-path (cons nil load-path))
2006-04-12 Daiki Ueno <ueno@unixuser.org>
+ * epf.el: Renamed from epg-file.el.
+
+2006-04-12 Daiki Ueno <ueno@unixuser.org>
+
* epg.el (epg-status-GET_BOOL): New function.
(epg-status-GET_LINE): New function.
(epg-prompt-alist): New variable, to be filled.
AUTOMAKE_OPTIONS = no-dependencies
-EXTRA_DIST = epg.el epg-file.el pgg-epg.el
+EXTRA_DIST = epg.el epf.el pgg-epg.el
CLEANFILES = auto-autoloads.el custom-load.el *.elc
FLAGS ?= -batch -q -no-site-file
crypt++, alpaca.el, hedgehog. To try this, add the following line to
your ~/.emacs and C-x C-f ~/test.txt.gpg.
-(require 'epg-file)
+(require 'epf)
** Gnus/PGG backend
** EasyPG avoides potential security flaws of Emacs
-*** `call-process-region' writes data in region to temporary files
+See "Security consideration" section.
-`call-process-region' writes data in region to temporary files.
-EasyPG do _not_ use `call-process-region' to communicate with a gpg
+** GnuPG features are directly accessible from Emacs
+
+Other competitors provide only specific features of GnuPG since they
+still support PGP 2.*, 5.*, 6.*. As the name indicates, EasyPG is
+inspired by GPGME (GnuPG Made Easy), and the library interface is
+close to GPGME. With EasyPG you can benefit from a lot of features of
+GnuPG.
+
+* Security consideration
+
+** `call-process-region' writes data in region to a temporary file
+
+`call-process-region' writes data in region to a temporary file.
+EasyPG does *not* use `call-process-region' to communicate with a gpg
subprocess.
-*** `(fillarray string 0)' is not enough to clear passphrases
+** `(fillarray string 0)' is not enough to clear passphrases
If Emacs crashed and dumps core, passphrase strings in memory are also
dumped within the core file. `read-passwd' function clears passphrase
strings may be moved elsewhere in memory.
Fortunately, there is gpg-agent to cache passphrases in more secure
-way, so EasyPG dares _not_ to cache passphrase. Elisp programs can
+way, so EasyPG dares *not* to cache passphrase. Elisp programs can
set `epg-context-passphrase-callback' to cache user's passphrases.
-** GnuPG features are directly accessible from Emacs
-
-Other competitors provide only specific features of GnuPG since they
-still support PGP 2.*, 5.*, 6.*. As the name indicates, EasyPG is
-inspired by GPGME (GnuPG Made Easy), and the library interface is
-close to GPGME. With EasyPG you can benefit from a lot of features of
-GnuPG.
--- /dev/null
+;;; epf.el --- transparent file encryption utility
+;; Copyright (C) 1999, 2000, 2002, 2003, 2004,
+;; 2005, 2006 Free Software Foundation, Inc.
+;; Copyright (C) 2006 Daiki Ueno
+
+;; Author: Daiki Ueno <ueno@unixuser.org>
+;; Naoto Morishima <naoto@morishima.net>
+;; Keywords: PGP, GnuPG
+
+;; This file is part of EasyPG.
+
+;; This program 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.
+
+;; This program 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., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+
+;; epf.el is based on hedgehog.el by Naoto Morishima.
+;; http://www.morishima.net/~naoto/software/hedgehog/index.php.ja
+
+;;; Code:
+
+(require 'epg)
+
+(defgroup epf ()
+ "Transparent file encryption utility of EasyPG."
+ :group 'epg)
+
+(defcustom epf-name-regexp "\\.gpg\\'"
+ "Regexp that matches filenames that are assumed to be encrypted
+with GnuPG."
+ :type 'regexp
+ :group 'epf)
+
+(defun epf-handler (operation &rest args)
+ (let ((epf-operation (get operation 'epf)))
+ (if epf-operation
+ (apply epf-operation args)
+ (epf-run-real-handler operation args))))
+
+(defun epf-run-real-handler (operation args)
+ (let ((inhibit-file-name-handlers
+ (cons 'epf-handler
+ (and (eq inhibit-file-name-operation operation)
+ inhibit-file-name-handlers)))
+ (inhibit-file-name-operation operation))
+ (apply operation args)))
+
+(defvar buffer-file-type)
+(defvar last-coding-system-used)
+(defun epf-write-region (start end filename &optional append visit
+ lockname mustbenew)
+ (let* ((visit-file (if (stringp visit)
+ (expand-file-name visit)
+ (expand-file-name filename)))
+ ;; XXX: Obtain the value returned by choose_write_coding_system
+ (coding-system (condition-case nil
+ (epf-run-real-handler
+ 'write-region (list start end "/"))
+ (file-error (if (boundp 'last-coding-system-used)
+ last-coding-system-used
+ buffer-file-coding-system))))
+ ;; start and end are normally buffer positions
+ ;; specifying the part of the buffer to write.
+ ;; If start is nil, that means to use the entire buffer contents.
+ ;; If start is a string, then output that string to the file
+ ;; instead of any buffer contents; end is ignored.
+ (string (encode-coding-string (cond
+ ((stringp start)
+ start)
+ ((null start)
+ (buffer-string))
+ (t
+ (buffer-substring start end)))
+ coding-system)))
+ (with-temp-buffer
+ (if (fboundp 'set-buffer-multibyte)
+ (set-buffer-multibyte nil))
+ ;; Optional fourth argument append if non-nil means
+ ;; append to existing file contents (if any). If it is an integer,
+ ;; seek to that offset in the file before writing.
+ (if (and append (file-exists-p filename))
+ ;; Enable passphrase cache on this temp buffer
+ (let ((coding-system-for-read 'binary))
+ ;; set visit to t so that passphrase is cached
+ (insert-file-contents filename t)
+ (setq buffer-file-name nil)))
+ ;; Insert data to encrypt
+ (goto-char (if (integerp append) (1+ append) (point-max)))
+ (delete-region (point) (min (+ (point) (length string)) (point-max)))
+ (insert string)
+
+ (let ((coding-system-for-write 'binary)
+ (coding-system-for-read 'binary)
+ (context (epg-make-context))
+ recipients
+ string
+ cipher)
+ (while (not (equal (setq string
+ (read-string "To (end with an empty line): "))
+ ""))
+ (setq recipients (cons string recipients)))
+ (when (setq cipher (epg-encrypt-string context (buffer-string)
+ recipients))
+ (if (and (memq system-type '(ms-dos windows-nt))
+ (boundp 'buffer-file-type))
+ (setq buffer-file-type t))
+ (epf-run-real-handler
+ 'write-region
+ (list cipher nil filename nil 'not-visit lockname mustbenew)))))
+ ;; Optional fifth argument visit, if t or a string, means
+ ;; set the last-save-file-modtime of buffer to this file's modtime
+ ;; and mark buffer not modified.
+ ;; If visit is a string, it is a second file name;
+ ;; the output goes to filename, but the buffer is marked as visiting visit.
+ ;; visit is also the file name to lock and unlock for clash detection.
+ ;; If visit is neither t nor nil nor a string,
+ ;; that means do not display the "Wrote file" message.
+ (when (or (eq visit t) (stringp visit))
+ (setq buffer-file-name filename)
+ (set-visited-file-modtime))
+ (if (stringp visit)
+ (setq buffer-file-name visit))
+ (when (or (eq visit t) (eq visit nil) (stringp visit))
+ (message "Wrote %s" visit-file))
+ (if (boundp 'last-coding-system-used)
+ (setq last-coding-system-used coding-system))
+ nil))
+
+(defun epf-insert-file-contents (filename &optional visit beg end replace)
+ (barf-if-buffer-read-only)
+ (setq filename (expand-file-name filename))
+ (let ((filename (expand-file-name filename))
+ (length 0))
+ (if (file-exists-p filename)
+ (let ((local-file
+ (let ((inhibit-file-name-operation
+ (when (eq inhibit-file-name-operation
+ 'insert-file-contents)
+ 'file-local-copy)))
+ (file-local-copy filename)))
+ (coding-system-for-read 'binary)
+ (context (epg-make-context))
+ string)
+ (unwind-protect
+ (progn
+ (setq string (epg-decrypt-file context (or local-file
+ filename))
+ length (length string))
+ (if replace
+ (goto-char (point-min)))
+ (save-excursion
+ (let ((buffer-file-name (if visit nil buffer-file-name)))
+ (save-restriction
+ (narrow-to-region (point) (point))
+ (insert (decode-coding-string string 'undecided)))
+ (if replace
+ (delete-region (point) (point-max))))))
+ (when (and local-file (file-exists-p local-file))
+ (delete-file local-file)))))
+ ;; If second argument visit is non-nil, the buffer's visited filename
+ ;; and last save file modtime are set, and it is marked unmodified.
+ (when visit
+ (unlock-buffer)
+ (setq buffer-file-name filename)
+ (set-visited-file-modtime))
+
+ ;; If visiting and the file does not exist, visiting is completed
+ ;; before the error is signaled.
+ (if (and visit (not (file-exists-p filename)))
+ (signal 'file-error (list "Opening input file" filename)))
+
+ ;; Returns list of absolute file name and number of characters inserted.
+ (list filename length)))
+
+(put 'write-region 'epf 'epf-write-region)
+(put 'insert-file-contents 'epf 'epf-insert-file-contents)
+
+(unless (rassq 'epf-handler file-name-handler-alist)
+ (setq file-name-handler-alist
+ (cons (cons epf-name-regexp 'epf-handler)
+ file-name-handler-alist)
+ auto-mode-alist
+ (cons (list epf-name-regexp nil 'strip-suffix)
+ auto-mode-alist)))
+
+(provide 'epf)
+
+;;; epf.el ends here
+++ /dev/null
-;;; epg-file.el --- transparent file encryption utility
-;; Copyright (C) 1999, 2000, 2002, 2003, 2004,
-;; 2005, 2006 Free Software Foundation, Inc.
-;; Copyright (C) 2006 Daiki Ueno
-
-;; Author: Daiki Ueno <ueno@unixuser.org>
-;; Naoto Morishima <naoto@morishima.net>
-;; Keywords: PGP, GnuPG
-
-;; This file is part of EasyPG.
-
-;; This program 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.
-
-;; This program 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., 51 Franklin Street, Fifth Floor,
-;; Boston, MA 02110-1301, USA.
-
-;;; Commentary:
-
-;; epg-file.el is based on hedgehog.el by Naoto Morishima.
-;; http://www.morishima.net/~naoto/software/hedgehog/index.php.ja
-
-;;; Code:
-
-(require 'epg)
-
-(defgroup epg-file ()
- "Transparent file encryption utility of EasyPG."
- :group 'epg)
-
-(defcustom epg-file-name-regexp "\\.gpg\\'"
- "Regexp that matches filenames that are assumed to be encrypted
-with GnuPG."
- :type 'regexp
- :group 'epg-file)
-
-(defun epg-file-handler (operation &rest args)
- (let ((epg-file-operation (get operation 'epg-file)))
- (if epg-file-operation
- (apply epg-file-operation args)
- (epg-file-run-real-handler operation args))))
-
-(defun epg-file-run-real-handler (operation args)
- (let ((inhibit-file-name-handlers
- (cons 'epg-file-handler
- (and (eq inhibit-file-name-operation operation)
- inhibit-file-name-handlers)))
- (inhibit-file-name-operation operation))
- (apply operation args)))
-
-(defvar buffer-file-type)
-(defvar last-coding-system-used)
-(defun epg-file-write-region (start end filename &optional append visit
- lockname mustbenew)
- (let* ((visit-file (if (stringp visit)
- (expand-file-name visit)
- (expand-file-name filename)))
- ;; XXX: Obtain the value returned by choose_write_coding_system
- (coding-system (condition-case nil
- (epg-file-run-real-handler
- 'write-region (list start end "/"))
- (file-error (if (boundp 'last-coding-system-used)
- last-coding-system-used
- buffer-file-coding-system))))
- ;; start and end are normally buffer positions
- ;; specifying the part of the buffer to write.
- ;; If start is nil, that means to use the entire buffer contents.
- ;; If start is a string, then output that string to the file
- ;; instead of any buffer contents; end is ignored.
- (string (encode-coding-string (cond
- ((stringp start)
- start)
- ((null start)
- (buffer-string))
- (t
- (buffer-substring start end)))
- coding-system)))
- (with-temp-buffer
- (if (fboundp 'set-buffer-multibyte)
- (set-buffer-multibyte nil))
- ;; Optional fourth argument append if non-nil means
- ;; append to existing file contents (if any). If it is an integer,
- ;; seek to that offset in the file before writing.
- (if (and append (file-exists-p filename))
- ;; Enable passphrase cache on this temp buffer
- (let ((coding-system-for-read 'binary))
- ;; set visit to t so that passphrase is cached
- (insert-file-contents filename t)
- (setq buffer-file-name nil)))
- ;; Insert data to encrypt
- (goto-char (if (integerp append) (1+ append) (point-max)))
- (delete-region (point) (min (+ (point) (length string)) (point-max)))
- (insert string)
-
- (let ((coding-system-for-write 'binary)
- (coding-system-for-read 'binary)
- (context (epg-make-context))
- recipients
- string
- cipher)
- (while (not (equal (setq string
- (read-string "To (end with an empty line): "))
- ""))
- (setq recipients (cons string recipients)))
- (when (setq cipher (epg-encrypt-string context (buffer-string)
- recipients))
- (if (and (memq system-type '(ms-dos windows-nt))
- (boundp 'buffer-file-type))
- (setq buffer-file-type t))
- (epg-file-run-real-handler
- 'write-region
- (list cipher nil filename nil 'not-visit lockname mustbenew)))))
- ;; Optional fifth argument visit, if t or a string, means
- ;; set the last-save-file-modtime of buffer to this file's modtime
- ;; and mark buffer not modified.
- ;; If visit is a string, it is a second file name;
- ;; the output goes to filename, but the buffer is marked as visiting visit.
- ;; visit is also the file name to lock and unlock for clash detection.
- ;; If visit is neither t nor nil nor a string,
- ;; that means do not display the "Wrote file" message.
- (when (or (eq visit t) (stringp visit))
- (setq buffer-file-name filename)
- (set-visited-file-modtime))
- (if (stringp visit)
- (setq buffer-file-name visit))
- (when (or (eq visit t) (eq visit nil) (stringp visit))
- (message "Wrote %s" visit-file))
- (if (boundp 'last-coding-system-used)
- (setq last-coding-system-used coding-system))
- nil))
-
-(defun epg-file-insert-file-contents (filename &optional visit beg end replace)
- (barf-if-buffer-read-only)
- (setq filename (expand-file-name filename))
- (let ((filename (expand-file-name filename))
- (length 0))
- (if (file-exists-p filename)
- (let ((local-file
- (let ((inhibit-file-name-operation
- (when (eq inhibit-file-name-operation
- 'insert-file-contents)
- 'file-local-copy)))
- (file-local-copy filename)))
- (coding-system-for-read 'binary)
- (context (epg-make-context))
- string)
- (unwind-protect
- (progn
- (setq string (epg-decrypt-file context (or local-file
- filename))
- length (length string))
- (if replace
- (goto-char (point-min)))
- (save-excursion
- (let ((buffer-file-name (if visit nil buffer-file-name)))
- (save-restriction
- (narrow-to-region (point) (point))
- (insert (decode-coding-string string 'undecided)))
- (if replace
- (delete-region (point) (point-max))))))
- (when (and local-file (file-exists-p local-file))
- (delete-file local-file)))))
- ;; If second argument visit is non-nil, the buffer's visited filename
- ;; and last save file modtime are set, and it is marked unmodified.
- (when visit
- (unlock-buffer)
- (setq buffer-file-name filename)
- (set-visited-file-modtime))
-
- ;; If visiting and the file does not exist, visiting is completed
- ;; before the error is signaled.
- (if (and visit (not (file-exists-p filename)))
- (signal 'file-error (list "Opening input file" filename)))
-
- ;; Returns list of absolute file name and number of characters inserted.
- (list filename length)))
-
-(put 'write-region 'epg-file 'epg-file-write-region)
-(put 'insert-file-contents 'epg-file 'epg-file-insert-file-contents)
-
-(unless (assoc epg-file-name-regexp file-name-handler-alist)
- (setq file-name-handler-alist
- (cons (cons epg-file-name-regexp 'epg-file-handler)
- file-name-handler-alist)))
-
-(unless (assoc epg-file-name-regexp auto-mode-alist)
- (setq auto-mode-alist
- (cons (list epg-file-name-regexp nil 'strip-suffix)
- auto-mode-alist)))
-
-(provide 'epg-file)
-
-;;; epg-file.el ends here