From: ueno Date: Fri, 14 Jul 2006 10:20:00 +0000 (+0000) Subject: * epg-pgp50i.el: New file. X-Git-Tag: epg-0_0_4~13 X-Git-Url: http://git.chise.org/gitweb/?a=commitdiff_plain;h=09adbe4b6eb9a3c4423cfe881eeec2b036f380eb;p=elisp%2Fepg.git * epg-pgp50i.el: New file. --- diff --git a/ChangeLog b/ChangeLog index f93833b..7abc7a8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2006-07-14 Daiki Ueno + + * epg-pgp50i.el: New file. + 2006-07-13 Daiki Ueno * acinclude.m4 (AC_PATH_GPG): New macro. diff --git a/epg-pgp50i.el b/epg-pgp50i.el new file mode 100644 index 0000000..781308a --- /dev/null +++ b/epg-pgp50i.el @@ -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