mirror of https://github.com/djcb/mu.git
* crypto/mu4e: support signature verification in mu4e (WIP)
This commit is contained in:
parent
991dd52763
commit
dde3f09c76
|
@ -60,7 +60,7 @@ dir already existed, or has been created, nil otherwise."
|
|||
((yes-or-no-p (mu4e-format "%s does not exist yes. Create now?" dir))
|
||||
(mu4e~proc-mkdir dir))
|
||||
(t nil)))
|
||||
|
||||
|
||||
(defun mu4e-format (frm &rest args)
|
||||
"Create [mu4e]-prefixed string based on format FRM and ARGS."
|
||||
(concat
|
||||
|
@ -77,7 +77,7 @@ user-input, don't show anyhting."
|
|||
"Create [mu4e]-prefixed error based on format FRM and ARGS."
|
||||
(mu4e-log 'error (apply 'mu4e-format frm args))
|
||||
(message "%s" (apply 'mu4e-format frm args)))
|
||||
|
||||
|
||||
(defun mu4e~read-char-choice (prompt choices)
|
||||
"Compatiblity wrapper for `read-char-choice', which is emacs-24
|
||||
only."
|
||||
|
@ -526,8 +526,8 @@ process."
|
|||
(defun mu4e-error-handler (errcode errmsg)
|
||||
"Handler function for showing an error."
|
||||
(case errcode
|
||||
(4 (mu4e-message "No matches for this search query."))
|
||||
(t (mu4e-message "Error %d: %s" errcode errmsg))))
|
||||
(4 (mu4e-error "No matches for this search query."))
|
||||
(t (mu4e-error "Error %d: %s" errcode errmsg))))
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
|
||||
|
|
|
@ -122,6 +122,24 @@ else: don't split (show either headers or messages, not both) Also
|
|||
see `mu4e-headers-visible-lines' and
|
||||
`mu4e-headers-visible-columns'.")
|
||||
|
||||
|
||||
|
||||
|
||||
;; crypto
|
||||
(defgroup mu4e-crypto nil
|
||||
"Crypto-related settings."
|
||||
:group 'mu4e)
|
||||
|
||||
(defcustom mu4e-auto-retrieve-keys nil
|
||||
"Attempt to automatically retrieve public keys when needed."
|
||||
:type 'boolean
|
||||
:group 'mu4e-compose)
|
||||
|
||||
(defcustom mu4e-use-agent nil
|
||||
"Attempt to use GPG-agent when it is available."
|
||||
:type 'boolean
|
||||
:group 'mu4e-compose)
|
||||
|
||||
;; completion; we put them here rather than in mu4e-compose, as mu4e-utils needs
|
||||
;; the variables.
|
||||
|
||||
|
@ -273,6 +291,7 @@ flag set)."
|
|||
"Face for special header values in the message view."
|
||||
:group 'mu4e-faces)
|
||||
|
||||
|
||||
(defface mu4e-view-link-face
|
||||
'((t :inherit font-lock-type-face :underline t))
|
||||
"Face for showing URLs and attachments in the message view."
|
||||
|
@ -350,6 +369,17 @@ flag set)."
|
|||
headers)."
|
||||
:group 'mu4e-faces)
|
||||
|
||||
(defface mu4e-ok-face
|
||||
'((t :inherit font-lock-comment-face :bold t :slant normal))
|
||||
"Face for things that are okay."
|
||||
:group 'mu4e-faces)
|
||||
|
||||
(defface mu4e-warning-face
|
||||
'((t :inherit font-lock-warning-face :bold t :slant normal))
|
||||
"Face for warnings / error."
|
||||
:group 'mu4e-faces)
|
||||
|
||||
|
||||
|
||||
;; headers info
|
||||
(defconst mu4e-header-info
|
||||
|
@ -403,7 +433,7 @@ headers)."
|
|||
( :name "Signature"
|
||||
:shortname "Sgn"
|
||||
:help "Check for the cryptographic signature"
|
||||
:sortable nil))
|
||||
:sortable nil))
|
||||
(:subject .
|
||||
( :name "Subject"
|
||||
:shortname "Subject"
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
(require 'filladapt nil 'noerror)
|
||||
(require 'comint)
|
||||
(require 'browse-url)
|
||||
(require 'button)
|
||||
|
||||
(eval-when-compile (byte-compile-disable-warning 'cl-functions))
|
||||
(require 'cl)
|
||||
|
@ -331,7 +332,7 @@ at POINT, or if nil, at (point)."
|
|||
(propertize (symbol-name flag) 'face 'mu4e-view-special-header-value-face))
|
||||
flags
|
||||
(propertize ", " 'face 'mu4e-view-header-value-face)) t))
|
||||
|
||||
|
||||
(defun mu4e~view-construct-signature-header (msg)
|
||||
"Construct a Signature: header, if there are any signed parts."
|
||||
(let* ((parts (plist-get msg :parts))
|
||||
|
@ -339,14 +340,20 @@ at POINT, or if nil, at (point)."
|
|||
(remove-if 'null
|
||||
(mapcar (lambda (part) (plist-get part :signature)) parts)))
|
||||
(val (when verdicts
|
||||
(mapconcat (lambda (v) (symbol-name v)) verdicts ", ")))
|
||||
(mapconcat
|
||||
(lambda (v)
|
||||
(propertize (symbol-name v)
|
||||
'face (if (eq v 'good) 'mu4e-ok-face 'mu4e-warning-face)))
|
||||
verdicts ", ")))
|
||||
(btn (when val
|
||||
(with-temp-buffer
|
||||
(insert-text-button "Details") (buffer-string))))
|
||||
(val (when val
|
||||
(concat (propertize val 'face 'mu4e-view-special-header-value-face)
|
||||
" (" btn ")"))))
|
||||
(mu4e~view-construct-header :signature val t)))
|
||||
(insert-text-button "Details"
|
||||
'msg msg
|
||||
'action (lambda (b)
|
||||
(mu4e-view-verify-msg-popup (button-get b 'msg))))
|
||||
(buffer-string))))
|
||||
(val (when val (concat val " (" btn ")"))))
|
||||
(mu4e~view-construct-header :signature val t)))
|
||||
|
||||
(defun mu4e~view-open-save-attach-func (msg attachnum is-open)
|
||||
"Return a function that offers to save attachment NUM. If IS-OPEN
|
||||
|
@ -441,6 +448,8 @@ is nil, and otherwise open it."
|
|||
(define-key map "t" 'mu4e-view-mark-subthread)
|
||||
(define-key map "T" 'mu4e-view-mark-thread)
|
||||
|
||||
(define-key map "v" 'mu4e-view-verify-msg-popup)
|
||||
|
||||
(define-key map "j" 'mu4e~headers-jump-to-maildir)
|
||||
|
||||
(define-key map "g" 'mu4e-view-go-to-url)
|
||||
|
@ -1113,6 +1122,32 @@ the results."
|
|||
(let ((path (mu4e-field-at-point :path)))
|
||||
(mu4e-process-file-through-pipe path cmd)))
|
||||
|
||||
(defconst mu4e~verify-buffer-name " *mu4e-verify*")
|
||||
|
||||
(defun mu4e-view-verify-msg-popup (&optional msg)
|
||||
"Pop-up a little signature verification window for (optional) MSG
|
||||
or message-at-point."
|
||||
(interactive)
|
||||
(let* ((path (if msg (plist-get msg :path) (mu4e-field-at-point :path)))
|
||||
(cmd (format "%s verify --verbose %s"
|
||||
mu4e-mu-binary
|
||||
(shell-quote-argument path)))
|
||||
(output (shell-command-to-string cmd))
|
||||
;; create a new one
|
||||
(buf (get-buffer-create mu4e~verify-buffer-name))
|
||||
(win (or (get-buffer-window buf)
|
||||
(split-window-vertically (- (window-height) 6)))))
|
||||
(with-selected-window win
|
||||
(let ((inhibit-read-only t))
|
||||
;; (set-window-dedicated-p win t)
|
||||
(switch-to-buffer buf)
|
||||
(erase-buffer)
|
||||
(insert output)
|
||||
(goto-char (point-min))
|
||||
(local-set-key "q" 'kill-buffer-and-window)))
|
||||
(select-window win)))
|
||||
|
||||
|
||||
(defun mu4e~view-quit-buffer ()
|
||||
"Quit the mu4e-view buffer. This is a rather complex function, to
|
||||
ensure we don't disturb other windows."
|
||||
|
|
|
@ -828,6 +828,8 @@ misc
|
|||
w toggle line wrapping
|
||||
h toggle showing cited parts
|
||||
|
||||
v show details about the cryptographic signature
|
||||
|
||||
. show the raw message view. 'q' takes you back.
|
||||
C-+,C-- increase / decrease the number of headers shown
|
||||
H get help
|
||||
|
@ -941,6 +943,28 @@ As mentioned, by default @t{mu4e} prefers the text-version of an e-mail
|
|||
message over the html version. You can change this by setting
|
||||
@code{mu4e-view-prefer-html} to @t{t}.
|
||||
|
||||
@subsection Verifying signatures
|
||||
|
||||
Some e-mail messages are cryptographically signed, and @t{mu4e} can check the
|
||||
validity of the signatures@footnote{Signature-verification is only available
|
||||
if @t{mu} was built with crypto-support; this requires at least @t{mu} version 0.9.9
|
||||
and @t{GMime 2.6}, and the @t{gpg} program}.
|
||||
|
||||
If a message has a signature, the message view shows an extra header
|
||||
@t{Signature:} (assuming it is part of your @code{mu4e-view-fields}), and one
|
||||
or more 'verdicts' of the signatures found; either @t{good}, @t{bad} or
|
||||
@t{error}. For instance:
|
||||
|
||||
@verbatim
|
||||
Signature: good, error (Details)
|
||||
@end verbatim
|
||||
|
||||
You can see the details of the signature verification by activating the
|
||||
@t{Details} or pressing @key{v}. This will pop-up a little window with the
|
||||
details of the signatures found and whether they could be verified or not.
|
||||
|
||||
For more information, see the @t{mu-verify} manual page.
|
||||
|
||||
@node Editor view
|
||||
@section Editor view
|
||||
|
||||
|
@ -2041,7 +2065,7 @@ Now, let's make a @t{mu4e} configuration for this:
|
|||
|
||||
(require 'smtpmail)
|
||||
(setq message-send-mail-function 'smtpmail-send-it
|
||||
starttls-use-gnutls t
|
||||
starttls-use-gnutls t
|
||||
smtpmail-starttls-credentials '(("smtp.gmail.com" 587 nil nil))
|
||||
smtpmail-auth-credentials '(("smtp.gmail.com" 587 "USERNAME@@gmail.com" nil))
|
||||
smtpmail-default-smtp-server "smtp.gmail.com"
|
||||
|
@ -2051,7 +2075,7 @@ Now, let's make a @t{mu4e} configuration for this:
|
|||
;; alternatively, for emacs-24 you can use:
|
||||
;;(setq message-send-mail-function 'smtpmail-send-it
|
||||
;; smtpmail-stream-type 'starttls
|
||||
;; smtpmail-default-smtp-server "smtp.gmail.com"
|
||||
;; smtpmail-default-smtp-server "smtp.gmail.com"
|
||||
;; smtpmail-smtp-server "smtp.gmail.com"
|
||||
;; smtpmail-smtp-service 587)
|
||||
|
||||
|
|
Loading…
Reference in New Issue