epa-mail.el 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. ;;; epa-mail.el --- the EasyPG Assistant, minor-mode for mail composer -*- lexical-binding: t -*-
  2. ;; Copyright (C) 2006-2017 Free Software Foundation, Inc.
  3. ;; Author: Daiki Ueno <ueno@unixuser.org>
  4. ;; Keywords: PGP, GnuPG, mail, message
  5. ;; Package: epa
  6. ;; This file is part of GNU Emacs.
  7. ;; GNU Emacs is free software: you can redistribute it and/or modify
  8. ;; it under the terms of the GNU General Public License as published by
  9. ;; the Free Software Foundation, either version 3 of the License, or
  10. ;; (at your option) any later version.
  11. ;; GNU Emacs is distributed in the hope that it will be useful,
  12. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. ;; GNU General Public License for more details.
  15. ;; You should have received a copy of the GNU General Public License
  16. ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
  17. ;;; Code:
  18. (require 'epa)
  19. (require 'mail-utils)
  20. (defvar epa-mail-mode-map
  21. (let ((keymap (make-sparse-keymap)))
  22. (define-key keymap "\C-c\C-ed" 'epa-mail-decrypt)
  23. (define-key keymap "\C-c\C-ev" 'epa-mail-verify)
  24. (define-key keymap "\C-c\C-es" 'epa-mail-sign)
  25. (define-key keymap "\C-c\C-ee" 'epa-mail-encrypt)
  26. (define-key keymap "\C-c\C-ei" 'epa-mail-import-keys)
  27. (define-key keymap "\C-c\C-eo" 'epa-insert-keys)
  28. (define-key keymap "\C-c\C-e\C-d" 'epa-mail-decrypt)
  29. (define-key keymap "\C-c\C-e\C-v" 'epa-mail-verify)
  30. (define-key keymap "\C-c\C-e\C-s" 'epa-mail-sign)
  31. (define-key keymap "\C-c\C-e\C-e" 'epa-mail-encrypt)
  32. (define-key keymap "\C-c\C-e\C-i" 'epa-mail-import-keys)
  33. (define-key keymap "\C-c\C-e\C-o" 'epa-insert-keys)
  34. keymap))
  35. (defvar epa-mail-mode-hook nil)
  36. (defvar epa-mail-mode-on-hook nil)
  37. (defvar epa-mail-mode-off-hook nil)
  38. ;;;###autoload
  39. (define-minor-mode epa-mail-mode
  40. "A minor-mode for composing encrypted/clearsigned mails.
  41. With a prefix argument ARG, enable the mode if ARG is positive,
  42. and disable it otherwise. If called from Lisp, enable the mode
  43. if ARG is omitted or nil."
  44. nil " epa-mail" epa-mail-mode-map)
  45. (defun epa-mail--find-usable-key (keys usage)
  46. "Find a usable key from KEYS for USAGE.
  47. USAGE would be `sign' or `encrypt'."
  48. (catch 'found
  49. (while keys
  50. (let ((pointer (epg-key-sub-key-list (car keys))))
  51. (while pointer
  52. (if (and (memq usage (epg-sub-key-capability (car pointer)))
  53. (not (memq (epg-sub-key-validity (car pointer))
  54. '(revoked expired))))
  55. (throw 'found (car keys)))
  56. (setq pointer (cdr pointer))))
  57. (setq keys (cdr keys)))))
  58. ;;;###autoload
  59. (defun epa-mail-decrypt ()
  60. "Decrypt OpenPGP armors in the current buffer.
  61. The buffer is expected to contain a mail message."
  62. (declare (interactive-only t))
  63. (interactive)
  64. (epa-decrypt-armor-in-region (point-min) (point-max)))
  65. ;;;###autoload
  66. (defun epa-mail-verify ()
  67. "Verify OpenPGP cleartext signed messages in the current buffer.
  68. The buffer is expected to contain a mail message."
  69. (declare (interactive-only t))
  70. (interactive)
  71. (epa-verify-cleartext-in-region (point-min) (point-max)))
  72. ;;;###autoload
  73. (defun epa-mail-sign (start end signers mode)
  74. "Sign the current buffer.
  75. The buffer is expected to contain a mail message."
  76. (declare (interactive-only t))
  77. (interactive
  78. (save-excursion
  79. (goto-char (point-min))
  80. (if (search-forward mail-header-separator nil t)
  81. (forward-line))
  82. (setq epa-last-coding-system-specified
  83. (or coding-system-for-write
  84. (epa--select-safe-coding-system (point) (point-max))))
  85. (let ((verbose current-prefix-arg))
  86. (list (point) (point-max)
  87. (if verbose
  88. (epa-select-keys (epg-make-context epa-protocol)
  89. "Select keys for signing.
  90. If no one is selected, default secret key is used. "
  91. nil t))
  92. (if verbose
  93. (epa--read-signature-type)
  94. 'clear)))))
  95. (let ((inhibit-read-only t))
  96. (epa-sign-region start end signers mode)))
  97. (defun epa-mail-default-recipients ()
  98. "Return the default list of encryption recipients for a mail buffer."
  99. (let ((config (epg-configuration))
  100. recipients-string real-recipients)
  101. (save-excursion
  102. (goto-char (point-min))
  103. (save-restriction
  104. (narrow-to-region (point)
  105. (if (search-forward mail-header-separator nil 0)
  106. (match-beginning 0)
  107. (point)))
  108. (setq recipients-string
  109. (mapconcat #'identity
  110. (nconc (mail-fetch-field "to" nil nil t)
  111. (mail-fetch-field "cc" nil nil t)
  112. (mail-fetch-field "bcc" nil nil t))
  113. ","))
  114. (setq recipients-string
  115. (mail-strip-quoted-names
  116. (with-temp-buffer
  117. (insert "to: " recipients-string "\n")
  118. (expand-mail-aliases (point-min) (point-max))
  119. (car (mail-fetch-field "to" nil nil t))))))
  120. (setq real-recipients
  121. (split-string recipients-string "," t "[ \t\n]*"))
  122. ;; Process all the recipients thru the list of GnuPG groups.
  123. ;; Expand GnuPG group names to what they stand for.
  124. (setq real-recipients
  125. (apply #'nconc
  126. (mapcar
  127. (lambda (recipient)
  128. (or (epg-expand-group config recipient)
  129. (list recipient)))
  130. real-recipients)))
  131. ;; Process all the recipients thru the user's list
  132. ;; of encryption aliases.
  133. (setq real-recipients
  134. (apply #'nconc
  135. (mapcar
  136. (lambda (recipient)
  137. (let ((tem (assoc recipient epa-mail-aliases)))
  138. (if tem (cdr tem)
  139. (list recipient))))
  140. real-recipients)))
  141. )))
  142. ;;;###autoload
  143. (defun epa-mail-encrypt (&optional recipients signers)
  144. "Encrypt the outgoing mail message in the current buffer.
  145. Takes the recipients from the text in the header in the buffer
  146. and translates them through `epa-mail-aliases'.
  147. With prefix argument, asks you to select among them interactively
  148. and also whether and how to sign.
  149. Called from Lisp, the optional argument RECIPIENTS is a list
  150. of recipient addresses, t to perform symmetric encryption,
  151. or nil meaning use the defaults.
  152. SIGNERS is a list of keys to sign the message with."
  153. (interactive
  154. (let ((verbose current-prefix-arg)
  155. (context (epg-make-context epa-protocol)))
  156. (list (if verbose
  157. (or (epa-select-keys
  158. context
  159. "Select recipients for encryption.
  160. If no one is selected, symmetric encryption will be performed. "
  161. (epa-mail-default-recipients))
  162. t))
  163. (and verbose (y-or-n-p "Sign? ")
  164. (epa-select-keys context
  165. "Select keys for signing. ")))))
  166. (let (start recipient-keys default-recipients)
  167. (save-excursion
  168. (setq recipient-keys
  169. (cond ((eq recipients t)
  170. nil)
  171. (recipients recipients)
  172. (t
  173. (setq default-recipients
  174. (epa-mail-default-recipients))
  175. ;; Convert recipients to keys.
  176. (apply
  177. 'nconc
  178. (mapcar
  179. (lambda (recipient)
  180. (let ((recipient-key
  181. (epa-mail--find-usable-key
  182. (epg-list-keys
  183. (epg-make-context epa-protocol)
  184. (if (string-match "@" recipient)
  185. (concat "<" recipient ">")
  186. recipient))
  187. 'encrypt)))
  188. (unless (or recipient-key
  189. (y-or-n-p
  190. (format
  191. "No public key for %s; skip it? "
  192. recipient)))
  193. (error "No public key for %s" recipient))
  194. (if recipient-key (list recipient-key))))
  195. default-recipients)))))
  196. (goto-char (point-min))
  197. (if (search-forward mail-header-separator nil t)
  198. (forward-line))
  199. (setq start (point))
  200. (setq epa-last-coding-system-specified
  201. (or coding-system-for-write
  202. (epa--select-safe-coding-system (point) (point-max)))))
  203. ;; Don't let some read-only text stop us from encrypting.
  204. (let ((inhibit-read-only t))
  205. (epa-encrypt-region start (point-max) recipient-keys signers signers))))
  206. ;;;###autoload
  207. (defun epa-mail-import-keys ()
  208. "Import keys in the OpenPGP armor format in the current buffer.
  209. The buffer is expected to contain a mail message."
  210. (declare (interactive-only t))
  211. (interactive)
  212. (epa-import-armor-in-region (point-min) (point-max)))
  213. ;;;###autoload
  214. (define-minor-mode epa-global-mail-mode
  215. "Minor mode to hook EasyPG into Mail mode.
  216. With a prefix argument ARG, enable the mode if ARG is positive,
  217. and disable it otherwise. If called from Lisp, enable the mode
  218. if ARG is omitted or nil."
  219. :global t :init-value nil :group 'epa-mail :version "23.1"
  220. (remove-hook 'mail-mode-hook 'epa-mail-mode)
  221. (if epa-global-mail-mode
  222. (add-hook 'mail-mode-hook 'epa-mail-mode)))
  223. (provide 'epa-mail)
  224. ;;; epa-mail.el ends here