epa-mail.el 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. ;;; epa-mail.el --- the EasyPG Assistant, minor-mode for mail composer -*- lexical-binding: t -*-
  2. ;; Copyright (C) 2006-2012 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. Don't use this command in Lisp programs!"
  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. Don't use this command in Lisp programs!"
  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. Don't use this command in Lisp programs!"
  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. (epa-sign-region start end signers mode))
  96. ;;;###autoload
  97. (defun epa-mail-encrypt (start end recipients sign signers)
  98. "Encrypt the current buffer.
  99. The buffer is expected to contain a mail message.
  100. Don't use this command in Lisp programs!"
  101. (interactive
  102. (save-excursion
  103. (let ((verbose current-prefix-arg)
  104. (config (epg-configuration))
  105. (context (epg-make-context epa-protocol))
  106. recipients-string recipients recipient-key sign)
  107. (goto-char (point-min))
  108. (save-restriction
  109. (narrow-to-region (point)
  110. (if (search-forward mail-header-separator nil 0)
  111. (match-beginning 0)
  112. (point)))
  113. (setq recipients-string
  114. (mapconcat #'identity
  115. (nconc (mail-fetch-field "to" nil nil t)
  116. (mail-fetch-field "cc" nil nil t)
  117. (mail-fetch-field "bcc" nil nil t))
  118. ","))
  119. (setq recipients
  120. (mail-strip-quoted-names
  121. (with-temp-buffer
  122. (insert "to: " recipients-string "\n")
  123. (expand-mail-aliases (point-min) (point-max))
  124. (car (mail-fetch-field "to" nil nil t))))))
  125. (if recipients
  126. (setq recipients (delete ""
  127. (split-string recipients
  128. "[ \t\n]*,[ \t\n]*"))))
  129. ;; Process all the recipients thru the list of GnuPG groups.
  130. ;; Expand GnuPG group names to what they stand for.
  131. (setq recipients
  132. (apply #'nconc
  133. (mapcar
  134. (lambda (recipient)
  135. (or (epg-expand-group config recipient)
  136. (list recipient)))
  137. recipients)))
  138. (goto-char (point-min))
  139. (if (search-forward mail-header-separator nil t)
  140. (forward-line))
  141. (setq epa-last-coding-system-specified
  142. (or coding-system-for-write
  143. (epa--select-safe-coding-system (point) (point-max))))
  144. (list (point) (point-max)
  145. (if verbose
  146. (epa-select-keys
  147. context
  148. "Select recipients for encryption.
  149. If no one is selected, symmetric encryption will be performed. "
  150. recipients)
  151. (if recipients
  152. (mapcar
  153. (lambda (recipient)
  154. (setq recipient-key
  155. (epa-mail--find-usable-key
  156. (epg-list-keys
  157. (epg-make-context epa-protocol)
  158. (if (string-match "@" recipient)
  159. (concat "<" recipient ">")
  160. recipient))
  161. 'encrypt))
  162. (unless (or recipient-key
  163. (y-or-n-p
  164. (format
  165. "No public key for %s; skip it? "
  166. recipient)))
  167. (error "No public key for %s" recipient))
  168. recipient-key)
  169. recipients)))
  170. (setq sign (if verbose (y-or-n-p "Sign? ")))
  171. (if sign
  172. (epa-select-keys context
  173. "Select keys for signing. "))))))
  174. ;; Don't let some read-only text stop us from encrypting.
  175. (let ((inhibit-read-only t))
  176. (epa-encrypt-region start end recipients sign signers)))
  177. ;;;###autoload
  178. (defun epa-mail-import-keys ()
  179. "Import keys in the OpenPGP armor format in the current buffer.
  180. The buffer is expected to contain a mail message.
  181. Don't use this command in Lisp programs!"
  182. (interactive)
  183. (epa-import-armor-in-region (point-min) (point-max)))
  184. ;;;###autoload
  185. (define-minor-mode epa-global-mail-mode
  186. "Minor mode to hook EasyPG into Mail mode.
  187. With a prefix argument ARG, enable the mode if ARG is positive,
  188. and disable it otherwise. If called from Lisp, enable the mode
  189. if ARG is omitted or nil."
  190. :global t :init-value nil :group 'epa-mail :version "23.1"
  191. (remove-hook 'mail-mode-hook 'epa-mail-mode)
  192. (if epa-global-mail-mode
  193. (add-hook 'mail-mode-hook 'epa-mail-mode)))
  194. (provide 'epa-mail)
  195. ;;; epa-mail.el ends here