emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Fix needed for communication with gpg-agent


From: Chong Yidong
Subject: Re: Fix needed for communication with gpg-agent
Date: Thu, 22 Feb 2007 12:31:54 -0500
User-agent: Gnus/5.11 (Gnus v5.11) Emacs/22.0.93 (gnu/linux)

> Another solution might be to cannibalize the ansi-term code, and have
> the pinentry program run in an elisp terminal.  I looked into this,
> and concluded that it is a big job.  It should be left till after the
> release.

FWIW, here is a patch that implements the idea I outlined above.  I
have tested it, and it works with the curses version of pinentry.

Admittedly, it is a rather naughty solution: GPG is called through an
elisp terminal (as implemented by `make-term' in term.el), with a
modified process filter whose purpose is to send GPG the string to be
encrypted when required.  The terminal is run in a recursive editing
level, so that the user can input to pinentry if necessary; the
process sentinel is modified to call `exit-recursive-edit' when GPG
exits, to return control to pgg-gpg-process-region.

*** emacs/lisp/pgg-gpg.el.~1.22.~       2007-02-18 11:07:52.000000000 -0500
--- emacs/lisp/pgg-gpg.el       2007-02-22 12:23:11.000000000 -0500
***************
*** 60,65 ****
--- 60,67 ----
  (defvar pgg-gpg-user-id nil
    "GnuPG ID of your default identity.")
  
+ (defvar pgg-gpg-term-input nil)
+ 
  (defun pgg-gpg-process-region (start end passphrase program args)
    (let* ((use-agent (and (null passphrase) (pgg-gpg-use-agent-p)))
         (output-file-name (pgg-make-temp-file "pgg-output"))
***************
*** 83,114 ****
        (erase-buffer))
      (unwind-protect
        (progn
!         (set-default-file-modes 448)
!         (let ((coding-system-for-write 'binary))
!           (setq process
!                 (apply #'start-process "*GnuPG*" errors-buffer
!                        program args)))
!         (set-process-sentinel process #'ignore)
!         (when passphrase
!           (setq passphrase-with-newline (concat passphrase "\n"))
!           (if pgg-passphrase-coding-system
!               (progn
!                 (setq encoded-passphrase-with-new-line
!                       (encode-coding-string
!                        passphrase-with-newline
!                        (coding-system-change-eol-conversion
!                         pgg-passphrase-coding-system 'unix)))
!                 (pgg-clear-string passphrase-with-newline))
!             (setq encoded-passphrase-with-new-line passphrase-with-newline
!                   passphrase-with-newline nil))
!           (process-send-string process encoded-passphrase-with-new-line))
!         (process-send-region process start end)
!         (process-send-eof process)
!         (while (eq 'run (process-status process))
!           (accept-process-output process 5))
!         (setq status (process-status process)
!               exit-status (process-exit-status process))
!         (delete-process process)
          (with-current-buffer (get-buffer-create output-buffer)
            (buffer-disable-undo)
            (erase-buffer)
--- 85,130 ----
        (erase-buffer))
      (unwind-protect
        (progn
!         (if (and (not window-system) use-agent)
!             (let ((term-term-name "vt100")
!                   (buf (current-buffer)))
!               (apply #'make-term "GPGTERM" "gpg" nil args)
!               (switch-to-buffer "*GPGTERM*")
!               (set (make-local-variable 'pgg-gpg-term-input)
!                    (list buf start end))
!               (setq process (get-buffer-process "*GPGTERM*"))
!               (term-char-mode)
!               (set-process-filter process 'pgg-gpg-filter)
!               (set-process-sentinel process 'pgg-gpg-sentinel)
!               (recursive-edit)
!               (setq exit-status (process-exit-status process)))
!           (set-default-file-modes 448)
!           (let ((coding-system-for-write 'binary))
!             (setq process
!                   (apply #'start-process "*GnuPG*" errors-buffer
!                          program args)))
!           (set-process-sentinel process #'ignore)
!           (accept-process-output process nil nil 1)
!           (when passphrase
!             (setq passphrase-with-newline (concat passphrase "\n"))
!             (if pgg-passphrase-coding-system
!                 (progn
!                   (setq encoded-passphrase-with-new-line
!                         (encode-coding-string
!                          passphrase-with-newline
!                          (coding-system-change-eol-conversion
!                           pgg-passphrase-coding-system 'unix)))
!                   (pgg-clear-string passphrase-with-newline))
!               (setq encoded-passphrase-with-new-line passphrase-with-newline
!                     passphrase-with-newline nil))
!             (process-send-string process encoded-passphrase-with-new-line))
!           (process-send-region process start end)
!           (process-send-eof process)
!           (while (eq 'run (process-status process))
!             (accept-process-output process 5))
!           (setq status (process-status process)
!                 exit-status (process-exit-status process))
!           (delete-process process))
          (with-current-buffer (get-buffer-create output-buffer)
            (buffer-disable-undo)
            (erase-buffer)
***************
*** 132,137 ****
--- 148,174 ----
          (delete-file output-file-name))
        (set-default-file-modes orig-mode))))
  
+ (defun pgg-gpg-filter (proc str)
+   (if (and (string-match "writing to" str) pgg-gpg-term-input)
+       (let ((buf   (nth 0 pgg-gpg-term-input))
+           (start (nth 1 pgg-gpg-term-input))
+           (end   (nth 2 pgg-gpg-term-input)))
+       (erase-buffer)
+       (with-current-buffer buf
+         (process-send-region proc start end)
+         (process-send-eof proc)
+         (process-send-eof proc)
+         (setq pgg-gpg-filter-args nil)))
+     (term-emulate-terminal proc str)))
+ 
+ (defun pgg-gpg-sentinel (proc msg)
+   (let ((buffer (process-buffer proc)))
+     (when (memq (process-status proc) '(signal exit))
+       (delete-process proc)
+       (unless (null (buffer-name buffer))
+       (kill-buffer buffer))
+       (exit-recursive-edit))))
+ 
  (defun pgg-gpg-possibly-cache-passphrase (passphrase &optional key notruncate)
    (if (and passphrase
           pgg-cache-passphrase




reply via email to

[Prev in Thread] Current Thread [Next in Thread]