mml-sec.el (mml-secure-bcc-is-safe): Keep old Emacsen compatibility
[gnus] / lisp / mml-sec.el
index c349631..fd01098 100644 (file)
@@ -1,26 +1,23 @@
 ;;; mml-sec.el --- A package with security functions for MML documents
 
-;; Copyright (C) 2000, 2001, 2002, 2003, 2004,
-;;   2005, 2006, 2007 Free Software Foundation, Inc.
+;; Copyright (C) 2000-2015 Free Software Foundation, Inc.
 
 ;; Author: Simon Josefsson <simon@josefsson.org>
 
 ;; This file is part of GNU Emacs.
 
-;; GNU Emacs is free software; you can redistribute it and/or modify
+;; GNU Emacs is free software: you can redistribute it and/or modify
 ;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 3, or (at your option)
-;; any later version.
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
 
 ;; GNU Emacs is distributed in the hope that it will be useful,
 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 ;; GNU General Public License for more details.
 
 ;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING.  If not, write to the
-;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-;; Boston, MA 02110-1301, USA.
+;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
 
 ;;; Commentary:
 
 
 (eval-when-compile (require 'cl))
 
-(if (locate-library "password-cache")
-    (require 'password-cache)
-  (require 'password))
-
+(autoload 'gnus-subsetp "gnus-util")
+(autoload 'mail-strip-quoted-names "mail-utils")
 (autoload 'mml2015-sign "mml2015")
 (autoload 'mml2015-encrypt "mml2015")
 (autoload 'mml1991-sign "mml1991")
 (autoload 'mml1991-encrypt "mml1991")
+(autoload 'message-fetch-field "message")
 (autoload 'message-goto-body "message")
 (autoload 'mml-insert-tag "mml")
 (autoload 'mml-smime-sign "mml-smime")
@@ -111,18 +107,39 @@ details."
   :group 'message
   :type 'boolean)
 
-(defcustom mml-secure-cache-passphrase password-cache
+(defcustom mml-secure-cache-passphrase
+  (if (boundp 'password-cache)
+      password-cache
+    t)
   "If t, cache passphrase."
   :group 'message
   :type 'boolean)
 
-(defcustom mml-secure-passphrase-cache-expiry password-cache-expiry
+(defcustom mml-secure-passphrase-cache-expiry
+  (if (boundp 'password-cache-expiry)
+      password-cache-expiry
+    16)
   "How many seconds the passphrase is cached.
 Whether the passphrase is cached at all is controlled by
 `mml-secure-cache-passphrase'."
   :group 'message
   :type 'integer)
 
+(defcustom mml-secure-safe-bcc-list nil
+  "List of e-mail addresses that are safe to use in Bcc headers.
+EasyPG encrypts e-mails to Bcc addresses, and the encrypted e-mail
+by default identifies the used encryption keys, giving away the
+Bcc'ed identities.  Clearly, this contradicts the original goal of
+*blind* copies.
+For an academic paper explaining the problem, see URL
+`http://crypto.stanford.edu/portia/papers/bb-bcc.pdf'.
+Use this variable to specify e-mail addresses whose owners do not
+mind if they are identifiable as recipients.  This may be useful if
+you use Bcc headers to encrypt e-mails to yourself."
+  :version "25.1"
+  :group 'message
+  :type '(repeat string))
+
 ;;; Configuration/helper functions
 
 (defun mml-signencrypt-style (method &optional style)
@@ -273,6 +290,36 @@ Use METHOD if given.  Else use `mml-secure-method' or
   (interactive)
   (mml-secure-part "smime"))
 
+(defun mml-secure-is-encrypted-p ()
+  "Check whether secure encrypt tag is present."
+  (save-excursion
+    (goto-char (point-min))
+    (re-search-forward
+     (concat "^" (regexp-quote mail-header-separator) "\n"
+            "<#secure[^>]+encrypt")
+     nil t)))
+
+(defun mml-secure-bcc-is-safe ()
+  "Check whether usage of Bcc is safe (or absent).
+Bcc usage is safe in two cases: first, if the current message does
+not contain an MML secure encrypt tag;
+second, if the Bcc addresses are a subset of `mml-secure-safe-bcc-list'.
+In all other cases, ask the user whether Bcc usage is safe.
+Raise error if user answers no.
+Note that this function does not produce a meaningful return value:
+either an error is raised or not."
+  (when (mml-secure-is-encrypted-p)
+    (let ((bcc (mail-strip-quoted-names (message-fetch-field "bcc"))))
+      (when bcc
+       (let ((bcc-list (mapcar #'cadr
+                               (mail-extract-address-components bcc t))))
+         (unless (gnus-subsetp bcc-list mml-secure-safe-bcc-list)
+           (unless (yes-or-no-p "Message for encryption contains Bcc header.\
+  This may give away all Bcc'ed identities to all recipients.\
+  Are you sure that this is safe?\
+  (Customize `mml-secure-safe-bcc-list' to avoid this warning.) ")
+             (error "Aborted"))))))))
+
 ;; defuns that add the proper <#secure ...> tag to the top of the message body
 (defun mml-secure-message (method &optional modesym)
   (let ((mode (prin1-to-string modesym))
@@ -308,11 +355,11 @@ Use METHOD if given.  Else use `mml-secure-method' or
 
 
 (defun mml-secure-message-sign (&optional method)
-  "Add MML tags to sign this MML part.
+  "Add MML tags to sign the entire message.
 Use METHOD if given. Else use `mml-secure-method' or
 `mml-default-sign-method'."
   (interactive)
-  (mml-secure-part
+  (mml-secure-message
    (or method mml-secure-method mml-default-sign-method)
    'sign))
 
@@ -380,5 +427,4 @@ If called with a prefix argument, only encrypt (do NOT sign)."
 
 (provide 'mml-sec)
 
-;;; arch-tag: 111c56e7-df5e-4287-87d7-93ed2911ec6c
 ;;; mml-sec.el ends here