Michael Elkins wrote:
> I see a potential problem here:  If the user has manually requested
> encryption or disabled it for the current message, but has
> opportunistic encryption enabled, it may override what the user has
> set manually.

I've been thinking about the various options, including adding a
msg->security bit, but so far I think they all introduce more problems
than they solve.  (Turning the behavior off without any indication why
could be confusing too, and then we perhaps should provide a way to
re-enable it.  Adding UI around the option opens a can of worms...)

For now, I'm attaching modified patches 5 and 6 in the series, with
just two changes: disabling when crypt_autoencrypt is set, and more
documentation to describe how the option works.  The documentation now
mentions that the encrypt setting will be changed by this option unless
you manually set it *after* editing the message and recipients.

Of course, if this option doesn't look like it should be applied, I
understand.  I just wanted to get these (easy to implement) changes out
for review first to see if they have merit.

-Kevin
# HG changeset patch
# User Kevin McCarthy <ke...@8t8.us>
# Date 1383097831 25200
#      Tue Oct 29 18:50:31 2013 -0700
# Node ID 239c402ecb6fe30fb47459873b6cfa1155ca7ef0
# Parent  289f0f8a9c3c8792b9118b787e3154a2abb0a4d2
Implement crypt_opportunistic_encrypt().

This function will be called to flip encryption on and off based on
message recipients.

diff --git a/crypt.c b/crypt.c
--- a/crypt.c
+++ b/crypt.c
@@ -702,17 +702,17 @@
   mutt_unlink (tempfname);
 
   if ((WithCrypto & APPLICATION_PGP))
     unset_option (OPTDONTHANDLEPGPKEYS);
 }
 
 
 
-int crypt_get_keys (HEADER *msg, char **keylist)
+int crypt_get_keys (HEADER *msg, char **keylist, int auto_mode)
 {
   ADDRESS *adrlist = NULL, *last = NULL;
   const char *fqdn = mutt_fqdn (1);
 
   /* Do a quick check to make sure that we can find all of the encryption
    * keys if the user has requested this service.
    */
 
@@ -727,45 +727,71 @@
   rfc822_append (last ? &last : &adrlist, msg->env->bcc, 0);
 
   if (fqdn)
     rfc822_qualify (adrlist, fqdn);
   adrlist = mutt_remove_duplicates (adrlist);
 
   *keylist = NULL;
 
-  if (msg->security & ENCRYPT)
+  if (auto_mode || (msg->security & ENCRYPT))
   {
      if ((WithCrypto & APPLICATION_PGP)
          && (msg->security & APPLICATION_PGP))
      {
-       if ((*keylist = crypt_pgp_findkeys (adrlist, 0)) == NULL)
+       if ((*keylist = crypt_pgp_findkeys (adrlist, auto_mode)) == NULL)
        {
            rfc822_free_address (&adrlist);
            return (-1);
        }
        unset_option (OPTPGPCHECKTRUST);
      }
      if ((WithCrypto & APPLICATION_SMIME)
          && (msg->security & APPLICATION_SMIME))
      {
-       if ((*keylist = crypt_smime_findkeys (adrlist, 0)) == NULL)
+       if ((*keylist = crypt_smime_findkeys (adrlist, auto_mode)) == NULL)
        {
            rfc822_free_address (&adrlist);
            return (-1);
        }
      }
   }
 
   rfc822_free_address (&adrlist);
     
   return (0);
 }
 
 
+/*
+ * Check if all recipients keys can be automatically determined.
+ * Enable encryption if they can, otherwise disable encryption.
+ */
+
+void crypt_opportunistic_encrypt(HEADER *msg)
+{
+  char *pgpkeylist = NULL;
+
+  /* crypt_autoencrypt should override crypt_opportunistic_encrypt */
+  if (option (OPTCRYPTAUTOENCRYPT))
+    return;
+
+  crypt_get_keys (msg, &pgpkeylist, 1);
+  if (pgpkeylist != NULL )
+  {
+    msg->security |= ENCRYPT;
+    FREE (&pgpkeylist);
+  }
+  else
+  {
+    msg->security &= ~ENCRYPT;
+  }
+}
+
+
 
 static void crypt_fetch_signatures (BODY ***signatures, BODY *a, int *n)
 {
   if (!WithCrypto)
     return;
 
   for (; a; a = a->next)
   {
diff --git a/mutt_crypt.h b/mutt_crypt.h
--- a/mutt_crypt.h
+++ b/mutt_crypt.h
@@ -135,18 +135,24 @@
    values if there are any. */
 int crypt_query (BODY *m);
 
 /* Fixme: To be documented. */
 void crypt_extract_keys_from_messages (HEADER *h);
 
 /* Do a quick check to make sure that we can find all of the
    encryption keys if the user has requested this service. 
-   Return the list of keys in KEYLIST. */
-int crypt_get_keys (HEADER *msg, char **keylist);
+   Return the list of keys in KEYLIST.
+   If auto_mode is true, only keys that can be determined without
+   prompting will be used.  */
+int crypt_get_keys (HEADER *msg, char **keylist, int auto_mode);
+
+/* Check if all recipients keys can be automatically determined.
+ * Enable encryption if they can, otherwise disable encryption.  */
+void crypt_opportunistic_encrypt(HEADER *msg);
 
 /* Forget a passphrase and display a message. */
 void crypt_forget_passphrase (void);
 
 /* Check that we have a usable passphrase, ask if not. */
 int crypt_valid_passphrase (int);
 
 /* Write the message body/part A described by state S to a the given
diff --git a/send.c b/send.c
--- a/send.c
+++ b/send.c
@@ -1635,17 +1635,17 @@
   
   if (WithCrypto)
   {
     if (msg->security)  
     {
       /* save the decrypted attachments */
       clear_content = msg->content;
   
-      if ((crypt_get_keys (msg, &pgpkeylist) == -1) ||
+      if ((crypt_get_keys (msg, &pgpkeylist, 0) == -1) ||
           mutt_protect (msg, pgpkeylist) == -1)
       {
         msg->content = mutt_remove_multipart (msg->content);
         
 	FREE (&pgpkeylist);
         
         decode_descriptions (msg->content);
         goto main_loop;
# HG changeset patch
# User Kevin McCarthy <ke...@8t8.us>
# Date 1383099785 25200
#      Tue Oct 29 19:23:05 2013 -0700
# Node ID 0fd4a3151f467a810e68e7e2f95cfc947c53a4f6
# Parent  239c402ecb6fe30fb47459873b6cfa1155ca7ef0
Add the crypt_opportunistic_encrypt option and calls.

This patch creates the OPTCRYPTOPPORTUNISTICENCRYPT option and
documentation.

It also adds calls to crypt_opportunistic_encrypt() during initial
message composition, after updating to, cc, or bcc, and after editing
the message (if edit_headers is enabled).

diff --git a/compose.c b/compose.c
--- a/compose.c
+++ b/compose.c
@@ -521,24 +521,39 @@
 	menu->pagelen = LINES - HDR_ATTACH - 2;
 	break;
       case OP_COMPOSE_EDIT_FROM:
 	menu->redraw = edit_address_list (HDR_FROM, &msg->env->from);
         mutt_message_hook (NULL, msg, M_SEND2HOOK);
 	break;
       case OP_COMPOSE_EDIT_TO:
 	menu->redraw = edit_address_list (HDR_TO, &msg->env->to);
+	if (option (OPTCRYPTOPPORTUNISTICENCRYPT))
+	{
+	  crypt_opportunistic_encrypt (msg);
+	  redraw_crypt_lines (msg);
+	}
         mutt_message_hook (NULL, msg, M_SEND2HOOK);
         break;
       case OP_COMPOSE_EDIT_BCC:
 	menu->redraw = edit_address_list (HDR_BCC, &msg->env->bcc);
+	if (option (OPTCRYPTOPPORTUNISTICENCRYPT))
+	{
+	  crypt_opportunistic_encrypt (msg);
+	  redraw_crypt_lines (msg);
+	}
         mutt_message_hook (NULL, msg, M_SEND2HOOK);
 	break;
       case OP_COMPOSE_EDIT_CC:
 	menu->redraw = edit_address_list (HDR_CC, &msg->env->cc);
+	if (option (OPTCRYPTOPPORTUNISTICENCRYPT))
+	{
+	  crypt_opportunistic_encrypt (msg);
+	  redraw_crypt_lines (msg);
+	}
         mutt_message_hook (NULL, msg, M_SEND2HOOK);	
         break;
       case OP_COMPOSE_EDIT_SUBJECT:
 	if (msg->env->subject)
 	  strfcpy (buf, msg->env->subject, sizeof (buf));
 	else
 	  buf[0] = 0;
 	if (mutt_get_field ("Subject: ", buf, sizeof (buf), 0) == 0)
@@ -588,16 +603,18 @@
 	  mutt_env_to_local (msg->env);
 	  mutt_edit_headers (NONULL (Editor), msg->content->filename, msg,
 			     fcc, fcclen);
 	  if (mutt_env_to_idna (msg->env, &tag, &err))
 	  {
 	    mutt_error (_("Bad IDN in \"%s\": '%s'"), tag, err);
 	    FREE (&err);
 	  }
+	  if (option (OPTCRYPTOPPORTUNISTICENCRYPT))
+	    crypt_opportunistic_encrypt (msg);
 	}
 	else
 	{
 	  /* this is grouped with OP_COMPOSE_EDIT_HEADERS because the
 	     attachment list could change if the user invokes ~v to edit
 	     the message with headers, in which we need to execute the
 	     code below to regenerate the index array */
 	  mutt_builtin_editor (msg->content->filename, msg, cur);
diff --git a/init.h b/init.h
--- a/init.h
+++ b/init.h
@@ -486,16 +486,33 @@
   { "crypt_autosmime",	DT_BOOL, R_NONE, OPTCRYPTAUTOSMIME, 1 },
   /*
   ** .pp
   ** This variable controls whether or not mutt may automatically enable
   ** S/MIME encryption/signing for messages. See also $$crypt_autoencrypt,
   ** $$crypt_replyencrypt,
   ** $$crypt_autosign, $$crypt_replysign and $$smime_is_default.
   */
+  { "crypt_opportunistic_encrypt", DT_BOOL, R_NONE, OPTCRYPTOPPORTUNISTICENCRYPT, 0 },
+  /*
+  ** .pp
+  ** Setting this variable will cause Mutt to automatically enable and
+  ** disable encryption, based on whether all message recipient keys
+  ** can be located by mutt.
+  ** .pp
+  ** When this option is enabled, mutt will determine the encryption
+  ** setting each time the TO, CC, and BCC lists are edited.  If
+  ** $$edit_headers is set, mutt will also do so each time the message
+  ** is edited.  If you wish to manually enable/disable encryption with
+  ** this option set, you should do so after editing the message and
+  ** recipients, to avoid mutt changing your setting.
+  ** .pp
+  ** \fBNote:\fP this option has no effect when $$crypt_autoencrypt is enabled.
+  ** (Crypto only)
+   */
   { "pgp_replyencrypt",		DT_SYN,  R_NONE, UL "crypt_replyencrypt", 1  },
   { "crypt_replyencrypt",	DT_BOOL, R_NONE, OPTCRYPTREPLYENCRYPT, 1 },
   /*
   ** .pp
   ** If \fIset\fP, automatically PGP or OpenSSL encrypt replies to messages which are
   ** encrypted.
   ** (Crypto only)
   */
diff --git a/mutt.h b/mutt.h
--- a/mutt.h
+++ b/mutt.h
@@ -455,16 +455,17 @@
   OPTCRYPTUSEPKA,
 
   /* PGP options */
   
   OPTCRYPTAUTOSIGN,
   OPTCRYPTAUTOENCRYPT,
   OPTCRYPTAUTOPGP,
   OPTCRYPTAUTOSMIME,
+  OPTCRYPTOPPORTUNISTICENCRYPT,
   OPTCRYPTREPLYENCRYPT,
   OPTCRYPTREPLYSIGN,
   OPTCRYPTREPLYSIGNENCRYPTED,
   OPTCRYPTTIMESTAMP,
   OPTSMIMEISDEFAULT,
   OPTASKCERTLABEL,
   OPTSDEFAULTDECRYPTKEY,
   OPTPGPIGNORESUB,
diff --git a/send.c b/send.c
--- a/send.c
+++ b/send.c
@@ -1466,17 +1466,17 @@
     if (WithCrypto & APPLICATION_PGP && (msg->security & (ENCRYPT | SIGN)))
     {
       if (option (OPTPGPAUTOINLINE))
 	msg->security |= INLINE;
       if (option (OPTPGPREPLYINLINE) && cur && (cur->security & INLINE))
 	msg->security |= INLINE;
     }
 
-    if (msg->security)
+    if (msg->security || option (OPTCRYPTOPPORTUNISTICENCRYPT))
     {
       /* 
        * When replying / forwarding, use the original message's
        * crypto system.  According to the documentation,
        * smime_is_default should be disregarded here.
        * 
        * Problem: At least with forwarding, this doesn't really
        * make much sense. Should we have an option to completely
@@ -1503,16 +1503,22 @@
 	  msg->security |= APPLICATION_SMIME;
 	else if ((WithCrypto & APPLICATION_PGP) && option (OPTCRYPTAUTOPGP))
 	  msg->security |= APPLICATION_PGP;
 	else if ((WithCrypto & APPLICATION_SMIME) && option (OPTCRYPTAUTOSMIME))
 	  msg->security |= APPLICATION_SMIME;
       }
     }
 
+    /* opportunistic encrypt relys on SMIME or PGP already being selected */
+    if (option (OPTCRYPTOPPORTUNISTICENCRYPT))
+    {
+      crypt_opportunistic_encrypt(msg);
+    }
+
     /* No permissible mechanisms found.  Don't sign or encrypt. */
     if (!(msg->security & (APPLICATION_SMIME|APPLICATION_PGP)))
       msg->security = 0;
   }
 
   /* specify a default fcc.  if we are in batchmode, only save a copy of
    * the message if the value of $copy is yes or ask-yes */
 

Attachment: signature.asc
Description: Digital signature

Reply via email to