* mu4e/crypto: beginnings of crypto (verification, decryption) support. WIP!

This commit is contained in:
djcb 2012-08-01 17:07:11 +03:00
parent 00dcfaec26
commit 136d0f2875
4 changed files with 97 additions and 63 deletions

View File

@ -217,7 +217,7 @@ The server output is as follows:
;; received a pong message
((plist-get sexp :pong)
(funcall mu4e-pong-func
(plist-get sexp :version) (plist-get sexp :doccount)))
(plist-get sexp :props)))
;; received a contacts message
((plist-get sexp :contacts)
@ -464,7 +464,8 @@ argument). Optionally, if IMAGES is non-nil, backend will any
images attached to the message, and return them as temp files. The
result will be delivered to the function registered as
`mu4e-message-func'."
(mu4e~proc-send-command "view %s extract-images:%s"
(mu4e~proc-send-command
"view %s extract-images:%s extract-encrypted:true"
(mu4e--docid-msgid-param docid-or-msgid)
(if images "true" "false")))

View File

@ -629,17 +629,21 @@ FUNC (if non-nil) afterwards."
;; set up the 'pong' handler func
(lexical-let ((func func))
(setq mu4e-pong-func
(lambda (version doccount)
(unless (string= version mu4e-mu-version)
(mu4e-error "mu server has version %s, but we need %s"
version mu4e-mu-version))
(when func (funcall func))
(when (and mu4e-update-interval (null mu4e~update-timer))
(setq mu4e~update-timer
(run-at-time
0 mu4e-update-interval 'mu4e-update-mail)))
(mu4e-message "Started mu4e with %d message%s in store"
doccount (if (= doccount 1) "" "s")))))
(lambda (props)
(let ((version (plist-get props :version))
(doccount (plist-get props :doccount)))
(unless (string= version mu4e-mu-version)
(mu4e-error "mu server has version %s, but we need %s"
version mu4e-mu-version))
(when func (funcall func))
(when (and mu4e-update-interval (null mu4e~update-timer))
(setq mu4e~update-timer
(run-at-time
0 mu4e-update-interval 'mu4e-update-mail)))
(mu4e-message "Started mu4e with %d message%s in store"
doccount (if (= doccount 1) "" "s"))
;; save the props we got from the server
(setq mu4e~server-props props)))))
;; send the ping
(mu4e~proc-ping)
;; get the address list if it's not already set.

View File

@ -134,12 +134,15 @@ see `mu4e-headers-visible-lines' and
(defcustom mu4e-auto-retrieve-keys nil
"Attempt to automatically retrieve public keys when needed."
:type 'boolean
:group 'mu4e-compose)
:group 'mu4e-crypto)
(defcustom mu4e-use-agent nil
"Attempt to use GPG-agent when it is available."
:type 'boolean
:group 'mu4e-compose)
(defcustom mu4e-decryption-policy 'auto
"Policy for dealing with encrypted parts. The setting is a symbol:
* `auto': try to decrypt automatically
* `ask': ask before decrypting anything
* `no': don't try to decrypt anything."
:type 'symbol
:group 'mu4e-crypto)
;; completion; we put them here rather than in mu4e-compose, as mu4e-utils needs
;; the variables.
@ -489,6 +492,10 @@ Note, :sortable does not work for custom header fields.")
used by the completion functions in mu4e-compose, and filled when
mu4e starts.")
(defvar mu4e~server-props nil
"Properties we receive from the mu4e server process (in the
'pong-handler').")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; our handlers funcs

View File

@ -38,6 +38,8 @@
(require 'comint)
(require 'browse-url)
(require 'button)
(require 'epa)
(require 'epg)
(eval-when-compile (byte-compile-disable-warning 'cl-functions))
(require 'cl)
@ -54,12 +56,6 @@ complete list of available headers, see `mu4e-header-info'."
:type (list 'symbol)
:group 'mu4e-view)
(defcustom mu4e-view-date-format "%c"
"Date format to use in the message view, in the format of
`format-time-string'."
:type 'string
:group 'mu4e-view)
(defcustom mu4e-view-show-addresses nil
"Whether to initially show full e-mail addresses for contacts in
address fields, rather than only their names. Note that you can
@ -75,15 +71,13 @@ messages, but you can always toggle between wrapped/unwrapped
display with `mu4e-view-toggle-wrap-lines (default keybinding: <w>)."
:group 'mu4e-view)
(defcustom mu4e-view-wrap-lines nil
"Whether to automatically wrap lines in the body of messages when
viewing them. Note that wrapping does not work well with all
messages, but you can always toggle between wrapped/unwrapped
display with `mu4e-view-toggle-wrap-lines (default keybinding: <w>)."
(defcustom mu4e-view-date-format "%c"
"Date format to use in the message view, in the format of
`format-time-string'."
:type 'string
:group 'mu4e-view)
(defcustom mu4e-view-hide-cited nil
(defcustom mu4e-view-hide-cited nil
"Whether to automatically hide cited parts of messages (as
determined by the presence of '> ' at the beginning of the
line). Note that you can always toggle between hidden/unhidden
@ -198,7 +192,11 @@ plist."
(t (mu4e-error "Unsupported field: %S" field)))))
mu4e-view-fields "")
"\n"
(mu4e-body-text msg)))
(mu4e-body-text msg)
;; ;; decrypt maybe; depends on whether there are any such parts
;; ;; and the value of `mu4e-view-decrypt-parts'
;; (mu4e~decrypt-parts-maybe msg)
))
(defun mu4e-view (msg headersbuf &optional refresh)
@ -383,43 +381,67 @@ is nil, and otherwise open it."
(member 'inline (plist-get part :type)))
(plist-get msg :parts)))
(attstr
(mapconcat
(lambda (part)
(let ((index (plist-get part :index))
(name (plist-get part :name))
(size (plist-get part :size))
(map (make-sparse-keymap)))
(incf id)
(puthash id index mu4e~view-attach-map)
(define-key map [mouse-2]
(mu4e~view-open-save-attach-func msg id nil))
(define-key map [?\M-\r]
(mu4e~view-open-save-attach-func msg id nil))
(define-key map [S-mouse-2]
(mu4e~view-open-save-attach-func msg id t))
(define-key map (kbd "<S-return>")
(mu4e~view-open-save-attach-func msg id t))
(concat
(propertize (format "[%d]" id) 'face 'mu4e-view-attach-number-face)
(propertize name 'face 'mu4e-view-link-face
'keymap map 'mouse-face 'highlight)
(when (and size (> size 0))
(concat (format "(%s)"
(propertize (mu4e-display-size size)
'face 'mu4e-view-header-key-face)))))))
attachments ", ")))
(unless (zerop id)
(mu4e~view-construct-header
:attachments (format "%s (%d)" attstr id) t))))
(mapconcat
(lambda (part)
(let ((index (plist-get part :index))
(name (plist-get part :name))
(size (plist-get part :size))
(map (make-sparse-keymap)))
(incf id)
(puthash id index mu4e~view-attach-map)
(define-key map [mouse-2]
(mu4e~view-open-save-attach-func msg id nil))
(define-key map [?\M-\r]
(mu4e~view-open-save-attach-func msg id nil))
(define-key map [S-mouse-2]
(mu4e~view-open-save-attach-func msg id t))
(define-key map (kbd "<S-return>")
(mu4e~view-open-save-attach-func msg id t))
(concat
(propertize (format "[%d]" id)
'face 'mu4e-view-attach-number-face)
(propertize name 'face 'mu4e-view-link-face
'keymap map 'mouse-face 'highlight)
(when (and size (> size 0))
(concat (format "(%s)"
(propertize (mu4e-display-size size)
'face 'mu4e-view-header-key-face)))))))
attachments ", ")))
(when attachments
(mu4e~view-construct-header :attachments attstr t))))
;; (defun mu4e~decrypt-parts-maybe (msg)
;; "Decrypt maybe; depends on whether there are any such parts
;; and the value of `mu4e-view-decrypt-parts'."
;; (let ((str ""))
;; (mu4e-view-for-each-part msg
;; (lambda (msg part)
;; (when (member 'encrypted (plist-get part :type))
;; (let ((file (plist-get part :temp)))
;; (when (and file (file-exists-p file))
;; ;; if our mu-server was build with crypto support, we only use EPA
;; ;; to push the password into gpg's memory
;; (let* ((decr
;; (condition-case nil
;; (epg-decrypt-file (epg-make-context epa-protocol) file nil)
;; (err (mu4e-error "Decryption failed: %S" err))))
;; (decr
;; (if (and decr (plist-get mu4e~server-props :crypto))
;; )))) ;; TODO: reload message
;; ;; otherwise, we try to handle it here.
;; )
;; decr))))))))
(defun mu4e-view-for-each-part (msg func)
"Apply FUNC to each part in MSG. FUNC should be a function taking two arguments;
"Apply FUNC to each part in MSG. FUNC should be a function taking
two arguments:
1. the message MSG, and
2. a plist describing the attachment. The plist looks like:
(:index 1 :name \"test123.doc\"
:mime-type \"application/msword\" :attachment t :size 1234)."
(dolist (part (mu4e-msg-field msg :parts))
(funcall func msg part)))
(dolist (part (mu4e-msg-field msg :parts))
(funcall func msg part)))
(defvar mu4e-view-mode-map nil