NeoMutt  2022-04-29-145-g9b6a0e
Teaching an old dog new tricks
DOXYGEN
send_menu()

Ask the user whether to sign and/or encrypt the email. More...

+ Collaboration diagram for send_menu():

Functions

SecurityFlags pgp_gpgme_send_menu (struct Email *e)
 Implements CryptModuleSpecs::send_menu() -. More...
 
SecurityFlags smime_gpgme_send_menu (struct Email *e)
 Implements CryptModuleSpecs::send_menu() -. More...
 
SecurityFlags pgp_class_send_menu (struct Email *e)
 Implements CryptModuleSpecs::send_menu() -. More...
 
SecurityFlags smime_class_send_menu (struct Email *e)
 Implements CryptModuleSpecs::send_menu() -. More...
 

Detailed Description

Ask the user whether to sign and/or encrypt the email.

Parameters
eEmail
Return values
numFlags, e.g. APPLICATION_PGP | SEC_ENCRYPT

Function Documentation

◆ pgp_gpgme_send_menu()

SecurityFlags pgp_gpgme_send_menu ( struct Email e)

Implements CryptModuleSpecs::send_menu() -.

Definition at line 4330 of file crypt_gpgme.c.

4331 {
4332  return gpgme_send_menu(e, false);
4333 }
static SecurityFlags gpgme_send_menu(struct Email *e, bool is_smime)
Show the user the encryption/signing menu.
Definition: crypt_gpgme.c:4169
+ Here is the call graph for this function:

◆ smime_gpgme_send_menu()

SecurityFlags smime_gpgme_send_menu ( struct Email e)

Implements CryptModuleSpecs::send_menu() -.

Definition at line 4338 of file crypt_gpgme.c.

4339 {
4340  return gpgme_send_menu(e, true);
4341 }
+ Here is the call graph for this function:

◆ pgp_class_send_menu()

SecurityFlags pgp_class_send_menu ( struct Email e)

Implements CryptModuleSpecs::send_menu() -.

Definition at line 1877 of file pgp.c.

1878 {
1879  struct PgpKeyInfo *p = NULL;
1880  const char *prompt = NULL;
1881  const char *letters = NULL;
1882  const char *choices = NULL;
1883  char promptbuf[1024];
1884  int choice;
1885 
1886  if (!(WithCrypto & APPLICATION_PGP))
1887  return e->security;
1888 
1889  /* If autoinline and no crypto options set, then set inline. */
1890  const bool c_pgp_auto_inline = cs_subset_bool(NeoMutt->sub, "pgp_auto_inline");
1891  if (c_pgp_auto_inline &&
1892  !((e->security & APPLICATION_PGP) && (e->security & (SEC_SIGN | SEC_ENCRYPT))))
1893  {
1894  e->security |= SEC_INLINE;
1895  }
1896 
1897  e->security |= APPLICATION_PGP;
1898 
1899  char *mime_inline = NULL;
1900  if (e->security & SEC_INLINE)
1901  {
1902  /* L10N: The next string MUST have the same highlighted letter
1903  One of them will appear in each of the three strings marked "(inline"), below. */
1904  mime_inline = _("PGP/M(i)ME");
1905  }
1906  else
1907  {
1908  /* L10N: The previous string MUST have the same highlighted letter
1909  One of them will appear in each of the three strings marked "(inline"), below. */
1910  mime_inline = _("(i)nline");
1911  }
1912  /* Opportunistic encrypt is controlling encryption. Allow to toggle
1913  * between inline and mime, but not turn encryption on or off.
1914  * NOTE: "Signing" and "Clearing" only adjust the sign bit, so we have different
1915  * letter choices for those. */
1916  const bool c_crypt_opportunistic_encrypt = cs_subset_bool(NeoMutt->sub, "crypt_opportunistic_encrypt");
1917  if (c_crypt_opportunistic_encrypt && (e->security & SEC_OPPENCRYPT))
1918  {
1919  if (e->security & (SEC_ENCRYPT | SEC_SIGN))
1920  {
1921  snprintf(promptbuf, sizeof(promptbuf),
1922  /* L10N: PGP options (inline) (opportunistic encryption is on) */
1923  _("PGP (s)ign, sign (a)s, %s format, (c)lear, or (o)ppenc mode off?"),
1924  mime_inline);
1925  prompt = promptbuf;
1926  /* L10N: PGP options (inline) (opportunistic encryption is on)
1927  The 'i' is from the "PGP/M(i)ME" or "(i)nline", above. */
1928  letters = _("saico");
1929  choices = "SaiCo";
1930  }
1931  else
1932  {
1933  /* L10N: PGP options (opportunistic encryption is on) */
1934  prompt = _("PGP (s)ign, sign (a)s, (c)lear, or (o)ppenc mode off?");
1935  /* L10N: PGP options (opportunistic encryption is on) */
1936  letters = _("saco");
1937  choices = "SaCo";
1938  }
1939  }
1940  /* Opportunistic encryption option is set, but is toggled off
1941  * for this message. */
1942  else if (c_crypt_opportunistic_encrypt)
1943  {
1944  /* When the message is not selected for signing or encryption, the toggle
1945  * between PGP/MIME and Traditional doesn't make sense. */
1946  if (e->security & (SEC_ENCRYPT | SEC_SIGN))
1947  {
1948  snprintf(promptbuf, sizeof(promptbuf),
1949  /* L10N: PGP options (inline) (opportunistic encryption is off) */
1950  _("PGP (e)ncrypt, (s)ign, sign (a)s, (b)oth, %s format, (c)lear, or (o)ppenc mode?"),
1951  mime_inline);
1952  prompt = promptbuf;
1953  /* L10N: PGP options (inline) (opportunistic encryption is off)
1954  The 'i' is from the "PGP/M(i)ME" or "(i)nline", above. */
1955  letters = _("esabico");
1956  choices = "esabicO";
1957  }
1958  else
1959  {
1960  /* L10N: PGP options (opportunistic encryption is off) */
1961  prompt = _("PGP (e)ncrypt, (s)ign, sign (a)s, (b)oth, (c)lear, or (o)ppenc mode?");
1962  /* L10N: PGP options (opportunistic encryption is off) */
1963  letters = _("esabco");
1964  choices = "esabcO";
1965  }
1966  }
1967  /* Opportunistic encryption is unset */
1968  else
1969  {
1970  if (e->security & (SEC_ENCRYPT | SEC_SIGN))
1971  {
1972  snprintf(promptbuf, sizeof(promptbuf),
1973  /* L10N: PGP options (inline) */
1974  _("PGP (e)ncrypt, (s)ign, sign (a)s, (b)oth, %s format, or (c)lear?"),
1975  mime_inline);
1976  prompt = promptbuf;
1977  /* L10N: PGP options (inline)
1978  The 'i' is from the "PGP/M(i)ME" or "(i)nline", above. */
1979  letters = _("esabic");
1980  choices = "esabic";
1981  }
1982  else
1983  {
1984  /* L10N: PGP options */
1985  prompt = _("PGP (e)ncrypt, (s)ign, sign (a)s, (b)oth, or (c)lear?");
1986  /* L10N: PGP options */
1987  letters = _("esabc");
1988  choices = "esabc";
1989  }
1990  }
1991 
1992  choice = mutt_multi_choice(prompt, letters);
1993  if (choice > 0)
1994  {
1995  switch (choices[choice - 1])
1996  {
1997  case 'a': /* sign (a)s */
1998  OptPgpCheckTrust = false;
1999 
2000  p = pgp_ask_for_key(_("Sign as: "), NULL, KEYFLAG_NO_FLAGS, PGP_SECRING);
2001  if (p)
2002  {
2003  char input_signas[128];
2004  snprintf(input_signas, sizeof(input_signas), "0x%s", pgp_fpr_or_lkeyid(p));
2005  cs_subset_str_string_set(NeoMutt->sub, "pgp_sign_as", input_signas, NULL);
2006  pgp_key_free(&p);
2007 
2008  e->security |= SEC_SIGN;
2009 
2010  crypt_pgp_void_passphrase(); /* probably need a different passphrase */
2011  }
2012  break;
2013 
2014  case 'b': /* (b)oth */
2015  e->security |= (SEC_ENCRYPT | SEC_SIGN);
2016  break;
2017 
2018  case 'C':
2019  e->security &= ~SEC_SIGN;
2020  break;
2021 
2022  case 'c': /* (c)lear */
2023  e->security &= ~(SEC_ENCRYPT | SEC_SIGN);
2024  break;
2025 
2026  case 'e': /* (e)ncrypt */
2027  e->security |= SEC_ENCRYPT;
2028  e->security &= ~SEC_SIGN;
2029  break;
2030 
2031  case 'i': /* toggle (i)nline */
2032  e->security ^= SEC_INLINE;
2033  break;
2034 
2035  case 'O': /* oppenc mode on */
2036  e->security |= SEC_OPPENCRYPT;
2038  break;
2039 
2040  case 'o': /* oppenc mode off */
2041  e->security &= ~SEC_OPPENCRYPT;
2042  break;
2043 
2044  case 'S': /* (s)ign in oppenc mode */
2045  e->security |= SEC_SIGN;
2046  break;
2047 
2048  case 's': /* (s)ign */
2049  e->security &= ~SEC_ENCRYPT;
2050  e->security |= SEC_SIGN;
2051  break;
2052  }
2053  }
2054 
2055  return e->security;
2056 }
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
void crypt_opportunistic_encrypt(struct Email *e)
Can all recipients be determined.
Definition: crypt.c:1025
void crypt_pgp_void_passphrase(void)
Wrapper for CryptModuleSpecs::void_passphrase()
Definition: cryptglue.c:191
#define _(a)
Definition: message.h:28
#define SEC_INLINE
Email has an inline signature.
Definition: lib.h:85
#define SEC_OPPENCRYPT
Opportunistic encrypt mode.
Definition: lib.h:86
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: lib.h:90
#define KEYFLAG_NO_FLAGS
No flags are set.
Definition: lib.h:126
#define SEC_ENCRYPT
Email is encrypted.
Definition: lib.h:78
#define WithCrypto
Definition: lib.h:116
#define SEC_SIGN
Email is signed.
Definition: lib.h:79
bool OptPgpCheckTrust
(pseudo) used by dlg_select_pgp_key()
Definition: options.h:54
char * pgp_fpr_or_lkeyid(struct PgpKeyInfo *k)
Get the fingerprint or long keyid.
Definition: pgp.c:234
struct PgpKeyInfo * pgp_ask_for_key(char *tag, char *whatfor, KeyFlags abilities, enum PgpRing keyring)
Ask the user for a PGP key.
Definition: pgpkey.c:180
@ PGP_SECRING
Secret keys.
Definition: pgpkey.h:40
void pgp_key_free(struct PgpKeyInfo **kpp)
Free a PGP key info.
Definition: pgplib.c:199
int mutt_multi_choice(const char *prompt, const char *letters)
Offer the user a multiple choice question.
Definition: question.c:54
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/lib.h pgplib....
Definition: email.h:41
Container for Accounts, Notifications.
Definition: neomutt.h:37
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
Information about a PGP key.
Definition: pgplib.h:47
int cs_subset_str_string_set(const struct ConfigSubset *sub, const char *name, const char *value, struct Buffer *err)
Set a config item by string.
Definition: subset.c:408
+ Here is the call graph for this function:

◆ smime_class_send_menu()

SecurityFlags smime_class_send_menu ( struct Email e)

Implements CryptModuleSpecs::send_menu() -.

Definition at line 2157 of file smime.c.

2158 {
2159  struct SmimeKey *key = NULL;
2160  const char *prompt = NULL;
2161  const char *letters = NULL;
2162  const char *choices = NULL;
2163  int choice;
2164 
2165  if (!(WithCrypto & APPLICATION_SMIME))
2166  return e->security;
2167 
2169 
2170  /* Opportunistic encrypt is controlling encryption.
2171  * NOTE: "Signing" and "Clearing" only adjust the sign bit, so we have different
2172  * letter choices for those. */
2173  const bool c_crypt_opportunistic_encrypt = cs_subset_bool(NeoMutt->sub, "crypt_opportunistic_encrypt");
2174  if (c_crypt_opportunistic_encrypt && (e->security & SEC_OPPENCRYPT))
2175  {
2176  /* L10N: S/MIME options (opportunistic encryption is on) */
2177  prompt = _("S/MIME (s)ign, encrypt (w)ith, sign (a)s, (c)lear, or (o)ppenc mode off?");
2178  /* L10N: S/MIME options (opportunistic encryption is on) */
2179  letters = _("swaco");
2180  choices = "SwaCo";
2181  }
2182  /* Opportunistic encryption option is set, but is toggled off
2183  * for this message. */
2184  else if (c_crypt_opportunistic_encrypt)
2185  {
2186  /* L10N: S/MIME options (opportunistic encryption is off) */
2187  prompt = _("S/MIME (e)ncrypt, (s)ign, encrypt (w)ith, sign (a)s, (b)oth, (c)lear, or (o)ppenc mode?");
2188  /* L10N: S/MIME options (opportunistic encryption is off) */
2189  letters = _("eswabco");
2190  choices = "eswabcO";
2191  }
2192  /* Opportunistic encryption is unset */
2193  else
2194  {
2195  /* L10N: S/MIME options */
2196  prompt = _("S/MIME (e)ncrypt, (s)ign, encrypt (w)ith, sign (a)s, (b)oth, or (c)lear?");
2197  /* L10N: S/MIME options */
2198  letters = _("eswabc");
2199  choices = "eswabc";
2200  }
2201 
2202  choice = mutt_multi_choice(prompt, letters);
2203  if (choice > 0)
2204  {
2205  switch (choices[choice - 1])
2206  {
2207  case 'a': /* sign (a)s */
2208  key = smime_ask_for_key(_("Sign as: "), KEYFLAG_CANSIGN, false);
2209  if (key)
2210  {
2211  cs_subset_str_string_set(NeoMutt->sub, "smime_sign_as", key->hash, NULL);
2212  smime_key_free(&key);
2213 
2214  e->security |= SEC_SIGN;
2215 
2216  /* probably need a different passphrase */
2218  }
2219 
2220  break;
2221 
2222  case 'b': /* (b)oth */
2223  e->security |= (SEC_ENCRYPT | SEC_SIGN);
2224  break;
2225 
2226  case 'c': /* (c)lear */
2227  e->security &= ~(SEC_ENCRYPT | SEC_SIGN);
2228  break;
2229 
2230  case 'C':
2231  e->security &= ~SEC_SIGN;
2232  break;
2233 
2234  case 'e': /* (e)ncrypt */
2235  e->security |= SEC_ENCRYPT;
2236  e->security &= ~SEC_SIGN;
2237  break;
2238 
2239  case 'O': /* oppenc mode on */
2240  e->security |= SEC_OPPENCRYPT;
2242  break;
2243 
2244  case 'o': /* oppenc mode off */
2245  e->security &= ~SEC_OPPENCRYPT;
2246  break;
2247 
2248  case 'S': /* (s)ign in oppenc mode */
2249  e->security |= SEC_SIGN;
2250  break;
2251 
2252  case 's': /* (s)ign */
2253  e->security &= ~SEC_ENCRYPT;
2254  e->security |= SEC_SIGN;
2255  break;
2256 
2257  case 'w': /* encrypt (w)ith */
2258  {
2259  e->security |= SEC_ENCRYPT;
2260  do
2261  {
2262  struct Buffer errmsg = mutt_buffer_make(0);
2263  int rc = CSR_SUCCESS;
2264  switch (mutt_multi_choice(_("Choose algorithm family: (1) DES, (2) RC2, (3) AES, or (c)lear?"),
2265  // L10N: Options for: Choose algorithm family: (1) DES, (2) RC2, (3) AES, or (c)lear?
2266  _("123c")))
2267  {
2268  case 1:
2269  switch (choice = mutt_multi_choice(_("(1) DES, (2) Triple-DES?"),
2270  // L10N: Options for: (1) DES, (2) Triple-DES
2271  _("12")))
2272  {
2273  case 1:
2274  rc = cs_subset_str_string_set(NeoMutt->sub, "smime_encrypt_with",
2275  "des", &errmsg);
2276  break;
2277  case 2:
2278  rc = cs_subset_str_string_set(NeoMutt->sub, "smime_encrypt_with",
2279  "des3", &errmsg);
2280  break;
2281  }
2282  break;
2283 
2284  case 2:
2285  switch (choice = mutt_multi_choice(_("(1) RC2-40, (2) RC2-64, (3) RC2-128?"),
2286  // L10N: Options for: (1) RC2-40, (2) RC2-64, (3) RC2-128
2287  _("123")))
2288  {
2289  case 1:
2290  rc = cs_subset_str_string_set(NeoMutt->sub, "smime_encrypt_with",
2291  "rc2-40", &errmsg);
2292  break;
2293  case 2:
2294  rc = cs_subset_str_string_set(NeoMutt->sub, "smime_encrypt_with",
2295  "rc2-64", &errmsg);
2296  break;
2297  case 3:
2298  rc = cs_subset_str_string_set(NeoMutt->sub, "smime_encrypt_with",
2299  "rc2-128", &errmsg);
2300  break;
2301  }
2302  break;
2303 
2304  case 3:
2305  switch (choice = mutt_multi_choice(_("(1) AES128, (2) AES192, (3) AES256?"),
2306  // L10N: Options for: (1) AES128, (2) AES192, (3) AES256
2307  _("123")))
2308  {
2309  case 1:
2310  rc = cs_subset_str_string_set(NeoMutt->sub, "smime_encrypt_with",
2311  "aes128", &errmsg);
2312  break;
2313  case 2:
2314  rc = cs_subset_str_string_set(NeoMutt->sub, "smime_encrypt_with",
2315  "aes192", &errmsg);
2316  break;
2317  case 3:
2318  rc = cs_subset_str_string_set(NeoMutt->sub, "smime_encrypt_with",
2319  "aes256", &errmsg);
2320  break;
2321  }
2322  break;
2323 
2324  case 4:
2325  rc = cs_subset_str_string_set(NeoMutt->sub, "smime_encrypt_with",
2326  NULL, &errmsg);
2327  /* (c)lear */
2328  /* fallthrough */
2329  case -1: /* Ctrl-G or Enter */
2330  choice = 0;
2331  break;
2332  }
2333 
2334  if ((CSR_RESULT(rc) != CSR_SUCCESS) && !mutt_buffer_is_empty(&errmsg))
2335  mutt_error("%s", mutt_buffer_string(&errmsg));
2336 
2337  mutt_buffer_dealloc(&errmsg);
2338  } while (choice == -1);
2339  break;
2340  }
2341  }
2342  }
2343 
2344  return e->security;
2345 }
struct Buffer mutt_buffer_make(size_t size)
Make a new buffer on the stack.
Definition: buffer.c:63
bool mutt_buffer_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:250
void mutt_buffer_dealloc(struct Buffer *buf)
Release the memory allocated by a buffer.
Definition: buffer.c:292
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:77
void crypt_smime_void_passphrase(void)
Wrapper for CryptModuleSpecs::void_passphrase()
Definition: cryptglue.c:413
#define mutt_error(...)
Definition: logging.h:87
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: lib.h:91
#define KEYFLAG_CANSIGN
Key is suitable for signing.
Definition: lib.h:127
#define CSR_RESULT(x)
Definition: set.h:52
#define CSR_SUCCESS
Action completed successfully.
Definition: set.h:35
static struct SmimeKey * smime_ask_for_key(char *prompt, KeyFlags abilities, bool only_public_key)
Ask the user to select a key.
Definition: smime.c:720
static void smime_key_free(struct SmimeKey **keylist)
Free a list of SMIME keys.
Definition: smime.c:109
String manipulation buffer.
Definition: buffer.h:34
An SIME key.
Definition: smime.h:44
char * hash
Definition: smime.h:46
+ Here is the call graph for this function: