* epg-pgp50i.el: New file.
authorueno <ueno>
Fri, 14 Jul 2006 10:20:00 +0000 (10:20 +0000)
committerueno <ueno>
Fri, 14 Jul 2006 10:20:00 +0000 (10:20 +0000)
ChangeLog
epg-pgp50i.el [new file with mode: 0644]

index f93833b..7abc7a8 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2006-07-14  Daiki Ueno  <ueno@unixuser.org>
+
+       * epg-pgp50i.el: New file.
+
 2006-07-13  Daiki Ueno  <ueno@unixuser.org>
 
        * acinclude.m4 (AC_PATH_GPG): New macro.
diff --git a/epg-pgp50i.el b/epg-pgp50i.el
new file mode 100644 (file)
index 0000000..781308a
--- /dev/null
@@ -0,0 +1,169 @@
+(eval-when-compile (require 'epg))
+
+(defvar epg-pgp50i-pgpv-program "pgpv")
+
+(defconst epg-pgp50i-message-alist
+  '(("Message is encrypted." .
+     "MESSAGE_IS_ENCRYPTED")
+    ("Need a pass phrase to decrypt private key:" .
+     "NEED_PASSPHRASE_TO_DECRYPT_KEY")
+    ("Enter pass phrase: " .
+     "ENTER_PASSPHRASE")
+    ("Pass phrase is good." .
+     "GOOD_PASSPHRASE")
+    ("Cannot decrypt message.  It can only be decrypted by:" .
+     "CANNOT_DECRYPT")))
+
+(defvar epg-pgp50i-status nil)
+
+(defun epg-pgp50i--start (context program args)
+  (let ((args (append '("--headers" "--language=us" "--batchmode=0" "--force")
+                     (if (epg-context-armor context) '("--armor"))
+                     (if (epg-context-textmode context) '("--textmode"))
+                     (if (epg-context-output-file context)
+                         (list "-o" (epg-context-output-file context)))
+                     args))
+       (coding-system-for-write 'binary)
+       process-connection-type
+       (orig-mode (default-file-modes))
+       (buffer (generate-new-buffer " *epg*"))
+       process)
+    (if epg-debug
+       (save-excursion
+         (unless epg-debug-buffer
+           (setq epg-debug-buffer (generate-new-buffer " *epg-debug*")))
+         (set-buffer epg-debug-buffer)
+         (goto-char (point-max))
+         (insert (format "%s %s\n"
+                         program
+                         (mapconcat #'identity args " ")))))
+    (with-current-buffer buffer
+      (make-local-variable 'epg-read-point)
+      (setq epg-read-point (point-min))
+      (make-local-variable 'epg-pending-status-list)
+      (setq epg-pending-status-list nil)
+      (make-local-variable 'epg-key-id)
+      (setq epg-key-id nil)
+      (make-local-variable 'epg-context)
+      (setq epg-context context)
+      (make-local-variable 'epg-pgp50i-status)
+      (setq epg-pgp50i-status nil))
+    (unwind-protect
+       (progn
+         (set-default-file-modes 448)
+         (setq process
+               (apply #'start-process "epg" buffer program args)))
+      (set-default-file-modes orig-mode))
+    (set-process-filter process #'epg-pgp50i--process-filter)
+    (set-process-sentinel process #'ignore)
+    (epg-context-set-process context process)))
+
+(defun epg-pgp50i--process-filter (process input)
+  (if epg-debug
+      (save-excursion
+       (unless epg-debug-buffer
+         (setq epg-debug-buffer (generate-new-buffer " *epg-debug*")))
+       (set-buffer epg-debug-buffer)
+       (goto-char (point-max))
+       (insert input)))
+  (if (buffer-live-p (process-buffer process))
+      (save-excursion
+       (set-buffer (process-buffer process))
+       (goto-char (point-max))
+       (insert input)
+       (unless epg-pgp50i-status
+         (goto-char epg-read-point)
+         (while (not (eobp))
+           (save-excursion
+             (if (looking-at
+                  "\\(PRI\\|INF\\|QRY\\|STA\\|WRN\\|ERR\\):  \\(.*\\)")
+                 (let ((message (match-string 2))
+                       (pointer epg-pgp50i-message-alist)
+                       status symbol)
+                   (while pointer
+                     (if (string-match (car (car pointer)) message)
+                         (setq status (cdr (car pointer))
+                               pointer nil))
+                     (setq pointer (cdr pointer)))
+                   (when status
+                     (unless (looking-at ".*\n")
+                       (end-of-line)
+                       (insert "\n"))
+                     (if (member status epg-pending-status-list)
+                         (setq epg-pending-status-list nil))
+                     (setq symbol (intern-soft (concat "epg-pgp50i--status-"
+                                                       status)))
+                     (if (and symbol
+                              (fboundp symbol))
+                         (unwind-protect
+                             (progn
+                               (setq epg-pgp50i-status status)
+                               (funcall symbol epg-context message))
+                           (setq epg-pgp50i-status nil)))))))
+           (forward-line)
+           (setq epg-read-point (point)))))))
+
+(defun epg-pgp50i--wait-for-line (context)
+  (if (eq (process-status (epg-context-process context)) 'run)
+      (save-excursion
+       (set-buffer (process-buffer (epg-context-process context)))
+       (goto-char epg-read-point)
+       (beginning-of-line 2)
+       (while (and (eq (process-status (epg-context-process context)) 'run)
+                   (not (if (looking-at ".*\n")
+                            (setq epg-read-point (point)))))
+         (accept-process-output (epg-context-process context) 1))
+       (buffer-substring (point) (progn (end-of-line) (point))))))
+
+(defun epg-pgp50i--status-ENTER_PASSPHRASE (context status)
+  (epg--status-GET_HIDDEN context "passphrase."))
+
+(defun epg-pgp50i--status-NEED_PASSPHRASE_TO_DECRYPT_KEY (context status)
+  (let ((line (epg-pgp50i--wait-for-line context))
+       user-id entry)
+    (when (and line
+              (string-match "[ 0-9]+ bits, Key ID \\([0-9A-F]+\\)" line))
+      (setq epg-key-id (match-string 1 line)
+           line (epg-pgp50i--wait-for-line context))
+      (when (and line
+                (string-match "\"\\([^\"]+\\)\"" line))
+       (setq user-id (match-string 1 line)
+             entry (assoc epg-key-id epg-user-id-alist))
+       (if entry
+           (setcdr entry user-id)
+         (setq epg-user-id-alist (cons (cons epg-key-id user-id)
+                                       epg-user-id-alist)))))))
+
+(defadvice epg-start-decrypt
+  (around epg-pgp50i activate)
+  (if (eq (epg-context-protocol (ad-get-arg 0)) 'CMS)
+      ad-do-it
+    (unless (epg-data-file (ad-get-arg 1))
+      (error "Not a file"))
+    (epg-context-set-operation context 'decrypt)
+    (epg-context-set-result (ad-get-arg 0) nil)
+    (epg-pgp50i--start context epg-pgp50i-pgpv-program
+                      (list (epg-data-file (ad-get-arg 1))))
+    (epg-wait-for-status (ad-get-arg 0) '("GOOD_PASSPHRASE"))))
+
+(defadvice epg-start-verify
+  (around epg-pgp50i activate)
+  (if (eq (epg-context-protocol (ad-get-arg 0)) 'CMS)
+      ad-do-it
+    (error "Not implemented yet")))
+
+(defadvice epg-start-sign
+  (around epg-pgp50i activate)
+  (if (eq (epg-context-protocol (ad-get-arg 0)) 'CMS)
+      ad-do-it
+    (error "Not implemented yet")))
+
+(defadvice epg-start-encrypt
+  (around epg-pgp50i activate)
+  (if (eq (epg-context-protocol (ad-get-arg 0)) 'CMS)
+      ad-do-it
+    (error "Not implemented yet")))
+
+(provide 'epg-pgp50i)
+
+;;; epg-pgp50i.el ends here
\ No newline at end of file