]> granicus.if.org Git - neomutt/commitdiff
Add ui elements for oppenc mode.
authorKevin McCarthy <kevin@8t8.us>
Mon, 30 Mar 2015 22:45:56 +0000 (15:45 -0700)
committerKevin McCarthy <kevin@8t8.us>
Mon, 30 Mar 2015 22:45:56 +0000 (15:45 -0700)
Add a status message to the Security line when oppenc is enabled.

For each send menu, add the ability to toggle it on or off.
When enabled, the menus won't show the (e)ncrypt or (b)oth options,
and the (c)lear function only clears the SIGN bit when it is active.

Change the gpgme_send_menu() to directly use the ENCRYPT and SIGN
flags instead of the PGPENCRYPT/SIGN and SMIMEENCRYPT/SMIME flags.
Using the latter sometimes resulted in the APPLICATION bit unset, which made
oppenc unhappy.

The send_menus previously used a switch statement using choice numbers.
Since the menus now vary based on the oppenc option and message bit
being set, these were all changed to convert the numbers back to a
choice letter.

compose.c
crypt-gpgme.c
pgp.c
smime.c

index 021540f4b5c1caa2a91a24583a58a9efc5bb59a4..9d870608fb2e816c979fc25dd7db2a2343b3f549 100644 (file)
--- a/compose.c
+++ b/compose.c
@@ -141,6 +141,9 @@ static void redraw_crypt_lines (HEADER *msg)
       addstr (_(" (S/MIME)"));
   }
 
+  if (option (OPTCRYPTOPPORTUNISTICENCRYPT) && (msg->security & OPPENCRYPT))
+      addstr (_(" (OppEnc mode)"));
+
   clrtoeol ();
   move (HDR_CRYPTINFO, 0);
   clrtoeol ();
@@ -1237,7 +1240,8 @@ int mutt_compose_menu (HEADER *msg,   /* structure for new message */
            mutt_clear_error ();
            break;
          }
-         msg->security = 0;
+         msg->security &= ~APPLICATION_SMIME;
+         msg->security |= APPLICATION_PGP;
        }
        msg->security = crypt_pgp_send_menu (msg, &menu->redraw);
        redraw_crypt_lines (msg);
@@ -1263,7 +1267,8 @@ int mutt_compose_menu (HEADER *msg,   /* structure for new message */
             mutt_clear_error ();
             break;
          }
-         msg->security = 0;
+         msg->security &= ~APPLICATION_PGP;
+         msg->security |= APPLICATION_SMIME;
        }
        msg->security = crypt_smime_send_menu(msg, &menu->redraw);
        redraw_crypt_lines (msg);
index 78b4a967beaacc73468b1e333ad9b9e1767590e7..db3b73d76464f5f2e65d723bff52ad315eafa4d3 100644 (file)
@@ -4580,82 +4580,146 @@ static int gpgme_send_menu (HEADER *msg, int *redraw, int is_smime)
 {
   crypt_key_t *p;
   char input_signas[SHORT_STRING];
+  char *prompt, *letters, *choices;
   int choice;
 
-  if (msg->security & APPLICATION_PGP)
-    is_smime = 0;
-  else if (msg->security & APPLICATION_SMIME)
-    is_smime = 1;
-
   if (is_smime)
-    choice = mutt_multi_choice (
-    _("S/MIME (e)ncrypt, (s)ign, sign (a)s, (b)oth, (p)gp or (c)lear?"),
-             _("esabpfc"));
-  else 
-    choice = mutt_multi_choice (
-    _("PGP (e)ncrypt, (s)ign, sign (a)s, (b)oth, s/(m)ime or (c)lear?"),
-                _("esabmfc"));
+    msg->security |= APPLICATION_SMIME;
+  else
+    msg->security |= APPLICATION_PGP;
 
-  switch (choice)
+  /*
+   * Opportunistic encrypt is controlling encryption.
+   * NOTE: "Signing" and "Clearing" only adjust the sign bit, so we have different
+   *       letter choices for those.
+   */
+  if (option (OPTCRYPTOPPORTUNISTICENCRYPT) && (msg->security & OPPENCRYPT))
   {
-  case 1: /* (e)ncrypt */
-    msg->security |= (is_smime ? SMIMEENCRYPT : PGPENCRYPT);
-    msg->security &= ~(is_smime ? SMIMESIGN : PGPSIGN);
-    break;
-
-  case 2: /* (s)ign */
-    msg->security |= (is_smime? SMIMESIGN :PGPSIGN);
-    msg->security &= ~(is_smime ? SMIMEENCRYPT : PGPENCRYPT);
-    break;
-
-  case 3: /* sign (a)s */
-/*      unset_option(OPTCRYPTCHECKTRUST); */
-    if ((p = crypt_ask_for_key (_("Sign as: "), NULL, KEYFLAG_CANSIGN,
-                                is_smime? APPLICATION_SMIME:APPLICATION_PGP,
-                                NULL)))
+    if (is_smime)
     {
-      snprintf (input_signas, sizeof (input_signas), "0x%s", crypt_keyid (p));
-      mutt_str_replace (is_smime? &SmimeDefaultKey : &PgpSignAs, input_signas);
-      crypt_free_key (&p); 
-      
-      msg->security |= (is_smime? SMIMESIGN:PGPSIGN);
+      prompt = _("S/MIME (s)ign, sign (a)s, (p)gp, (c)lear, or (o)ppenc mode off? ");
+      letters = _("sapfco");
+      choices = "SapFCo";
     }
-#if 0
     else
     {
-      msg->security &= (is_smime? ~SMIMESIGN : ~PGPSIGN);
+      prompt = _("PGP (s)ign, sign (a)s, s/(m)ime, (c)lear, or (o)ppenc mode off? ");
+      letters = _("samfco");
+      choices = "SamFCo";
     }
-#endif
-    *redraw = REDRAW_FULL;
-    break;
-
-  case 4: /* (b)oth */
-    msg->security = (is_smime? (SMIMEENCRYPT|SMIMESIGN):(PGPENCRYPT|PGPSIGN));
-    break;
-
-  case 5: /* (p)gp or s/(m)ime */
-    is_smime = !is_smime;
-    break;
-
-  case 6: /* (f)orget it */
-  case 7: /* (c)lear */
-    msg->security = 0;
-    break;
   }
-
-  if (choice == 6 || choice == 7)
-    ;
-  else if (is_smime)
+  /*
+   * Opportunistic encryption option is set, but is toggled off
+   * for this message.
+   */
+  else if (option (OPTCRYPTOPPORTUNISTICENCRYPT))
+  {
+    if (is_smime)
     {
-      msg->security &= ~APPLICATION_PGP;
-      msg->security |= APPLICATION_SMIME;
+      prompt = _("S/MIME (e)ncrypt, (s)ign, sign (a)s, (b)oth, (p)gp, (c)lear, or (o)ppenc mode? ");
+      letters = _("esabpfco");
+      choices = "esabpfcO";
     }
+    else
+    {
+      prompt = _("PGP (e)ncrypt, (s)ign, sign (a)s, (b)oth, s/(m)ime, (c)lear, or (o)ppenc mode? ");
+      letters = _("esabmfco");
+      choices = "esabmfcO";
+    }
+  }
+  /*
+   * Opportunistic encryption is unset
+   */
   else
+  {
+    if (is_smime)
     {
-      msg->security &= ~APPLICATION_SMIME;
-      msg->security |= APPLICATION_PGP;
+      prompt = _("S/MIME (e)ncrypt, (s)ign, sign (a)s, (b)oth, (p)gp or (c)lear? ");
+      letters = _("esabpfc");
+      choices = "esabpfc";
     }
-  
+    else
+    {
+      prompt = _("PGP (e)ncrypt, (s)ign, sign (a)s, (b)oth, s/(m)ime or (c)lear? ");
+      letters = _("esabmfc");
+      choices = "esabmfc";
+    }
+  }
+
+  choice = mutt_multi_choice (prompt, letters);
+  if (choice > 0)
+  {
+    switch (choices[choice - 1])
+    {
+    case 'e': /* (e)ncrypt */
+      msg->security |= ENCRYPT;
+      msg->security &= ~SIGN;
+      break;
+
+    case 's': /* (s)ign */
+      msg->security &= ~ENCRYPT;
+      msg->security |= SIGN;
+      break;
+
+    case 'S': /* (s)ign in oppenc mode */
+      msg->security |= SIGN;
+      break;
+
+    case 'a': /* sign (a)s */
+      if ((p = crypt_ask_for_key (_("Sign as: "), NULL, KEYFLAG_CANSIGN,
+                                  is_smime? APPLICATION_SMIME:APPLICATION_PGP,
+                                  NULL)))
+      {
+        snprintf (input_signas, sizeof (input_signas), "0x%s", crypt_keyid (p));
+        mutt_str_replace (is_smime? &SmimeDefaultKey : &PgpSignAs, input_signas);
+        crypt_free_key (&p); 
+
+        msg->security |= SIGN;
+      }
+      *redraw = REDRAW_FULL;
+      break;
+
+    case 'b': /* (b)oth */
+      msg->security |= (ENCRYPT | SIGN);
+      break;
+
+    case 'p': /* (p)gp or s/(m)ime */
+    case 'm':
+      is_smime = !is_smime;
+      if (is_smime)
+      {
+        msg->security &= ~APPLICATION_PGP;
+        msg->security |= APPLICATION_SMIME;
+      }
+      else
+      {
+        msg->security &= ~APPLICATION_SMIME;
+        msg->security |= APPLICATION_PGP;
+      }
+      crypt_opportunistic_encrypt (msg);
+      break;
+
+    case 'f': /* (f)orget it */
+    case 'c': /* (c)lear */
+      msg->security &= ~(ENCRYPT | SIGN);
+      break;
+
+    case 'F': /* (f)orget it or (c)lear in oppenc mode */
+    case 'C':
+      msg->security &= ~SIGN;
+      break;
+
+    case 'O': /* oppenc mode on */
+      msg->security |= OPPENCRYPT;
+      crypt_opportunistic_encrypt (msg);
+      break;
+
+    case 'o': /* oppenc mode off */
+      msg->security &= ~OPPENCRYPT;
+      break;
+    }
+  }
+
   return (msg->security);
 }
 
diff --git a/pgp.c b/pgp.c
index 665fb3f24bccb84c3bb20d4283afdb9b93051a84..ddc1e35ce54361456e2cfb6c24994cf2e4ec3037 100644 (file)
--- a/pgp.c
+++ b/pgp.c
@@ -1576,8 +1576,12 @@ BODY *pgp_traditional_encryptsign (BODY *a, int flags, char *keylist)
 
 int pgp_send_menu (HEADER *msg, int *redraw)
 {
+  pgp_key_t p;
+  char input_signas[SHORT_STRING];
+  char *prompt, *letters, *choices;
+  char promptbuf[LONG_STRING];
   int choice;
-  
+
   if (!(WithCrypto & APPLICATION_PGP))
     return msg->security;
 
@@ -1585,93 +1589,145 @@ int pgp_send_menu (HEADER *msg, int *redraw)
   if (option (OPTPGPAUTOINLINE) && 
       !((msg->security & APPLICATION_PGP) && (msg->security & (SIGN|ENCRYPT))))
     msg->security |= INLINE;
-  
-  /* When the message is not selected for signing or encryption, the toggle
-   * between PGP/MIME and Traditional doesn't make sense.
+
+  msg->security |= APPLICATION_PGP;
+
+  /*
+   * Opportunistic encrypt is controlling encryption.  Allow to toggle
+   * between inline and mime, but not turn encryption on or off.
+   * NOTE: "Signing" and "Clearing" only adjust the sign bit, so we have different
+   *       letter choices for those.
    */
-  if (msg->security & (ENCRYPT | SIGN))
+  if (option (OPTCRYPTOPPORTUNISTICENCRYPT) && (msg->security & OPPENCRYPT))
   {
-    char prompt[LONG_STRING];
-
-    snprintf (prompt, sizeof (prompt), 
-       _("PGP (e)ncrypt, (s)ign, sign (a)s, (b)oth, %s format, or (c)lear? "),
-       (msg->security & INLINE) ? _("PGP/M(i)ME") : _("(i)nline"));
+    if (msg->security & (ENCRYPT | SIGN))
+    {
+      snprintf (promptbuf, sizeof (promptbuf),
+          _("PGP (s)ign, sign (a)s, %s format, (c)lear, or (o)ppenc mode off? "),
+          (msg->security & INLINE) ? _("PGP/M(i)ME") : _("(i)nline"));
+      prompt = promptbuf;
+      letters = _("safcoi");
+      choices = "SaFCoi";
+    }
+    else
+    {
+      prompt = _("PGP (s)ign, sign (a)s, (c)lear, or (o)ppenc mode off? ");
+      letters = _("safco");
+      choices = "SaFCo";
+    }
+  }
+  /*
+   * Opportunistic encryption option is set, but is toggled off
+   * for this message.
+   */
+  else if (option (OPTCRYPTOPPORTUNISTICENCRYPT))
+  {
+    /* When the message is not selected for signing or encryption, the toggle
+    * between PGP/MIME and Traditional doesn't make sense.
+    */
+    if (msg->security & (ENCRYPT | SIGN))
+    {
 
-    /* The keys accepted for this prompt *must* match the order in the second
-     * version in the else clause since the switch statement below depends on
-     * it.  The 'i' key is appended in this version.
-     */
-    choice = mutt_multi_choice (prompt, _("esabfci"));
+      snprintf (promptbuf, sizeof (promptbuf), 
+          _("PGP (e)ncrypt, (s)ign, sign (a)s, (b)oth, %s format, (c)lear, or (o)ppenc mode? "),
+          (msg->security & INLINE) ? _("PGP/M(i)ME") : _("(i)nline"));
+      prompt = promptbuf;
+      letters = _("esabfcoi");
+      choices = "esabfcOi";
+    }
+    else
+    {
+      prompt = _("PGP (e)ncrypt, (s)ign, sign (a)s, (b)oth, (c)lear, or (o)ppenc mode? ");
+      letters = _("esabfco");
+      choices = "esabfcO";
+    }
   }
+  /*
+   * Opportunistic encryption is unset
+   */
   else
   {
-    /* The keys accepted *must* be a prefix of the accepted keys in the "if"
-     * clause above since the switch statement below depends on it.
-     */
-    choice = mutt_multi_choice(_("PGP (e)ncrypt, (s)ign, sign (a)s, (b)oth, or (c)lear? "),
-       _("esabfc"));
+    if (msg->security & (ENCRYPT | SIGN))
+    {
+
+      snprintf (promptbuf, sizeof (promptbuf), 
+          _("PGP (e)ncrypt, (s)ign, sign (a)s, (b)oth, %s format, or (c)lear? "),
+          (msg->security & INLINE) ? _("PGP/M(i)ME") : _("(i)nline"));
+      prompt = promptbuf;
+      letters = _("esabfci");
+      choices = "esabfci";
+    }
+    else
+    {
+      prompt = _("PGP (e)ncrypt, (s)ign, sign (a)s, (b)oth, or (c)lear? ");
+      letters = _("esabfc");
+      choices = "esabfc";
+    }
   }
 
-  switch (choice)
+  choice = mutt_multi_choice (prompt, letters);
+  if (choice > 0)
   {
-    case 1: /* (e)ncrypt */
+    switch (choices[choice - 1])
+    {
+    case 'e': /* (e)ncrypt */
       msg->security |= ENCRYPT;
       msg->security &= ~SIGN;
       break;
 
-  case 2: /* (s)ign */
-    msg->security |= SIGN;
-    msg->security &= ~ENCRYPT;
-    break;
+    case 's': /* (s)ign */
+      msg->security &= ~ENCRYPT;
+      msg->security |= SIGN;
+      break;
 
-  case 3: /* sign (a)s */
-    {
-      pgp_key_t p;
-      char input_signas[SHORT_STRING];
+    case 'S': /* (s)ign in oppenc mode */
+      msg->security |= SIGN;
+      break;
 
+    case 'a': /* sign (a)s */
       unset_option(OPTPGPCHECKTRUST);
 
       if ((p = pgp_ask_for_key (_("Sign as: "), NULL, 0, PGP_SECRING)))
       {
-       snprintf (input_signas, sizeof (input_signas), "0x%s",
-           pgp_keyid (p));
-       mutt_str_replace (&PgpSignAs, input_signas);
-       pgp_free_key (&p);
+        snprintf (input_signas, sizeof (input_signas), "0x%s",
+            pgp_keyid (p));
+        mutt_str_replace (&PgpSignAs, input_signas);
+        pgp_free_key (&p);
 
-       msg->security |= SIGN;
+        msg->security |= SIGN;
 
-       crypt_pgp_void_passphrase ();  /* probably need a different passphrase */
+        crypt_pgp_void_passphrase ();  /* probably need a different passphrase */
       }
-#if 0
-      else
-      {
-       msg->security &= ~SIGN;
-      }
-#endif
-
       *redraw = REDRAW_FULL;
-    } break;
+      break;
 
-  case 4: /* (b)oth */
-    msg->security |= (ENCRYPT | SIGN);
-    break;
+    case 'b': /* (b)oth */
+      msg->security |= (ENCRYPT | SIGN);
+      break;
 
-  case 5: /* (f)orget it */
-  case 6: /* (c)lear     */
-    msg->security = 0;
-    break;
+    case 'f': /* (f)orget it */
+    case 'c': /* (c)lear     */
+      msg->security &= ~(ENCRYPT | SIGN);
+      break;
 
-  case 7: /* toggle (i)nline */
-    msg->security ^= INLINE;
-    break;
-  }
+    case 'F': /* (f)orget it or (c)lear in oppenc mode */
+    case 'C':
+      msg->security &= ~SIGN;
+      break;
 
-  if (msg->security)
-  {
-    if (! (msg->security & (ENCRYPT | SIGN)))
-      msg->security = 0;
-    else
-      msg->security |= APPLICATION_PGP;
+    case 'O': /* oppenc mode on */
+      msg->security |= OPPENCRYPT;
+      crypt_opportunistic_encrypt (msg);
+      break;
+
+    case 'o': /* oppenc mode off */
+      msg->security &= ~OPPENCRYPT;
+      break;
+
+    case 'i': /* toggle (i)nline */
+      msg->security ^= INLINE;
+      break;
+    }
   }
 
   return (msg->security);
diff --git a/smime.c b/smime.c
index b7e17cd5c68e7b65b93799012e171f90ed352f32..378a1f0b5b1e381fc86db79819fb507e4964be2e 100644 (file)
--- a/smime.c
+++ b/smime.c
@@ -1908,137 +1908,179 @@ int smime_application_smime_handler (BODY *m, STATE *s)
 int smime_send_menu (HEADER *msg, int *redraw)
 {
   char *p;
+  char *prompt, *letters, *choices;
+  int choice;
 
   if (!(WithCrypto & APPLICATION_SMIME))
     return msg->security;
 
-  switch (mutt_multi_choice (_("S/MIME (e)ncrypt, (s)ign, encrypt (w)ith, sign (a)s, (b)oth, or (c)lear? "),
-                            _("eswabfc")))
+  msg->security |= APPLICATION_SMIME;
+
+  /*
+   * Opportunistic encrypt is controlling encryption.
+   * NOTE: "Signing" and "Clearing" only adjust the sign bit, so we have different
+   *       letter choices for those.
+   */
+  if (option (OPTCRYPTOPPORTUNISTICENCRYPT) && (msg->security & OPPENCRYPT))
+  {
+    prompt = _("S/MIME (s)ign, encrypt (w)ith, sign (a)s, (c)lear, or (o)ppenc mode off? ");
+    letters = _("swafco");
+    choices = "SwaFCo";
+  }
+  /*
+   * Opportunistic encryption option is set, but is toggled off
+   * for this message.
+   */
+  else if (option (OPTCRYPTOPPORTUNISTICENCRYPT))
+  {
+    prompt = _("S/MIME (e)ncrypt, (s)ign, encrypt (w)ith, sign (a)s, (b)oth, (c)lear, or (o)ppenc mode? ");
+    letters = _("eswabfco");
+    choices = "eswabfcO";
+  }
+  /*
+   * Opportunistic encryption is unset
+   */
+  else
   {
-  case 1: /* (e)ncrypt */
-    msg->security |= ENCRYPT;
-    msg->security &= ~SIGN;
-    break;
+    prompt = _("S/MIME (e)ncrypt, (s)ign, encrypt (w)ith, sign (a)s, (b)oth, or (c)lear? ");
+    letters = _("eswabfc");
+    choices = "eswabfc";
+  }
 
-  case 3: /* encrypt (w)ith */
-    {
-      int choice = 0;
 
+  choice = mutt_multi_choice (prompt, letters);
+  if (choice > 0)
+  {
+    switch (choices[choice - 1])
+    {
+    case 'e': /* (e)ncrypt */
       msg->security |= ENCRYPT;
-      do
+      msg->security &= ~SIGN;
+      break;
+
+    case 'w': /* encrypt (w)ith */
       {
-        /* I use "dra" because "123" is recognized anyway */
-        switch (mutt_multi_choice (_("Choose algorithm family:"
-                                     " 1: DES, 2: RC2, 3: AES,"
-                                     " or (c)lear? "),
-                                   _("drac")))
+        msg->security |= ENCRYPT;
+        do
         {
-        case 1:
-          switch (choice = mutt_multi_choice (_("1: DES, 2: Triple-DES "),
-                                              _("dt")))
+          /* I use "dra" because "123" is recognized anyway */
+          switch (mutt_multi_choice (_("Choose algorithm family:"
+                                      " 1: DES, 2: RC2, 3: AES,"
+                                      " or (c)lear? "),
+                                    _("drac")))
           {
           case 1:
-            mutt_str_replace (&SmimeCryptAlg, "des");
-            break;
-          case 2:
-            mutt_str_replace (&SmimeCryptAlg, "des3");
+            switch (choice = mutt_multi_choice (_("1: DES, 2: Triple-DES "),
+                                                _("dt")))
+            {
+            case 1:
+              mutt_str_replace (&SmimeCryptAlg, "des");
+              break;
+            case 2:
+              mutt_str_replace (&SmimeCryptAlg, "des3");
+              break;
+            }
             break;
-          }
-          break;
 
-        case 2:
-          switch (choice = mutt_multi_choice (_("1: RC2-40, 2: RC2-64, 3: RC2-128 "),
-                                              _("468")))
-          {
-          case 1:
-            mutt_str_replace (&SmimeCryptAlg, "rc2-40");
-            break;
           case 2:
-            mutt_str_replace (&SmimeCryptAlg, "rc2-64");
+            switch (choice = mutt_multi_choice (_("1: RC2-40, 2: RC2-64, 3: RC2-128 "),
+                                                _("468")))
+            {
+            case 1:
+              mutt_str_replace (&SmimeCryptAlg, "rc2-40");
+              break;
+            case 2:
+              mutt_str_replace (&SmimeCryptAlg, "rc2-64");
+              break;
+            case 3:
+              mutt_str_replace (&SmimeCryptAlg, "rc2-128");
+              break;
+            }
             break;
+
           case 3:
-            mutt_str_replace (&SmimeCryptAlg, "rc2-128");
+            switch (choice = mutt_multi_choice (_("1: AES128, 2: AES192, 3: AES256 "),
+                                                _("895")))
+            {
+            case 1:
+              mutt_str_replace (&SmimeCryptAlg, "aes128");
+              break;
+            case 2:
+              mutt_str_replace (&SmimeCryptAlg, "aes192");
+              break;
+            case 3:
+              mutt_str_replace (&SmimeCryptAlg, "aes256");
+              break;
+            }
             break;
-          }
-          break;
 
-        case 3:
-          switch (choice = mutt_multi_choice (_("1: AES128, 2: AES192, 3: AES256 "),
-                                              _("895")))
-          {
-          case 1:
-            mutt_str_replace (&SmimeCryptAlg, "aes128");
-            break;
-          case 2:
-            mutt_str_replace (&SmimeCryptAlg, "aes192");
-            break;
-          case 3:
-            mutt_str_replace (&SmimeCryptAlg, "aes256");
+          case 4: /* (c)lear */
+            FREE (&SmimeCryptAlg);
+            /* fallback */
+          case -1: /* Ctrl-G or Enter */
+            choice = 0;
             break;
           }
-          break;
+        } while (choice == -1);
+      }
+      break;
+
+    case 's': /* (s)ign */
+    case 'S': /* (s)ign in oppenc mode */
+      if(!SmimeDefaultKey)
+      {
+        *redraw = REDRAW_FULL;
 
-        case 4: /* (c)lear */
-          FREE (&SmimeCryptAlg);
-          /* fallback */
-        case -1: /* Ctrl-G or Enter */
-          choice = 0;
+        if ((p = smime_ask_for_key (_("Sign as: "), NULL, 0)))
+          mutt_str_replace (&SmimeDefaultKey, p);
+        else
           break;
-        }
-      } while (choice == -1);
-    }
-    break;
+      }
+      if (choices[choice - 1] == 's')
+        msg->security &= ~ENCRYPT;
+      msg->security |= SIGN;
+      break;
 
-  case 2: /* (s)ign */
-      
-    if(!SmimeDefaultKey)
-    {
-      *redraw = REDRAW_FULL;
+    case 'a': /* sign (a)s */
 
-      if ((p = smime_ask_for_key (_("Sign as: "), NULL, 0)))
+      if ((p = smime_ask_for_key (_("Sign as: "), NULL, 0))) 
+      {
         mutt_str_replace (&SmimeDefaultKey, p);
-      else
-        break;
-    }
+          
+        msg->security |= SIGN;
 
-    msg->security |= SIGN;
-    msg->security &= ~ENCRYPT;
-    break;
+        /* probably need a different passphrase */
+        crypt_smime_void_passphrase ();
+      }
 
-  case 4: /* sign (a)s */
+      *redraw = REDRAW_FULL;
+      break;
 
-    if ((p = smime_ask_for_key (_("Sign as: "), NULL, 0))) 
-    {
-      mutt_str_replace (&SmimeDefaultKey, p);
-       
-      msg->security |= SIGN;
+    case 'b': /* (b)oth */
+      msg->security |= (ENCRYPT | SIGN);
+      break;
 
-      /* probably need a different passphrase */
-      crypt_smime_void_passphrase ();
-    }
-#if 0
-    else
-      msg->security &= ~SIGN;
-#endif
+    case 'f': /* (f)orget it */
+    case 'c': /* (c)lear */
+      msg->security &= ~(ENCRYPT | SIGN);
+      break;
 
-    *redraw = REDRAW_FULL;
-    break;
+    case 'F': /* (f)orget it or (c)lear in oppenc mode */
+    case 'C':
+      msg->security &= ~SIGN;
+      break;
 
-  case 5: /* (b)oth */
-    msg->security |= (ENCRYPT | SIGN);
-    break;
+    case 'O': /* oppenc mode on */
+      msg->security |= OPPENCRYPT;
+      crypt_opportunistic_encrypt (msg);
+      break;
 
-  case 6: /* (f)orget it */
-  case 7: /* (c)lear */
-    msg->security = 0;
-    break;
+    case 'o': /* oppenc mode off */
+      msg->security &= ~OPPENCRYPT;
+      break;
+    }
   }
 
-  if (msg->security && msg->security != APPLICATION_SMIME)
-    msg->security |= APPLICATION_SMIME;
-  else
-    msg->security = 0;
-
   return (msg->security);
 }