NeoMutt  2023-05-17-56-ga67199
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 3933 of file crypt_gpgme.c.

3934{
3935 return gpgme_send_menu(e, false);
3936}
static SecurityFlags gpgme_send_menu(struct Email *e, bool is_smime)
Show the user the encryption/signing menu.
Definition: crypt_gpgme.c:3772
+ 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 3941 of file crypt_gpgme.c.

3942{
3943 return gpgme_send_menu(e, true);
3944}
+ 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 1898 of file pgp.c.

1899{
1900 struct PgpKeyInfo *p = NULL;
1901 const char *prompt = NULL;
1902 const char *letters = NULL;
1903 const char *choices = NULL;
1904 char promptbuf[1024] = { 0 };
1905 int choice;
1906
1907 if (!(WithCrypto & APPLICATION_PGP))
1908 return e->security;
1909
1910 /* If autoinline and no crypto options set, then set inline. */
1911 const bool c_pgp_auto_inline = cs_subset_bool(NeoMutt->sub, "pgp_auto_inline");
1912 if (c_pgp_auto_inline &&
1913 !((e->security & APPLICATION_PGP) && (e->security & (SEC_SIGN | SEC_ENCRYPT))))
1914 {
1915 e->security |= SEC_INLINE;
1916 }
1917
1919
1920 char *mime_inline = NULL;
1921 if (e->security & SEC_INLINE)
1922 {
1923 /* L10N: The next string MUST have the same highlighted letter
1924 One of them will appear in each of the three strings marked "(inline"), below. */
1925 mime_inline = _("PGP/M(i)ME");
1926 }
1927 else
1928 {
1929 /* L10N: The previous string MUST have the same highlighted letter
1930 One of them will appear in each of the three strings marked "(inline"), below. */
1931 mime_inline = _("(i)nline");
1932 }
1933 /* Opportunistic encrypt is controlling encryption. Allow to toggle
1934 * between inline and mime, but not turn encryption on or off.
1935 * NOTE: "Signing" and "Clearing" only adjust the sign bit, so we have different
1936 * letter choices for those. */
1937 const bool c_crypt_opportunistic_encrypt = cs_subset_bool(NeoMutt->sub, "crypt_opportunistic_encrypt");
1938 if (c_crypt_opportunistic_encrypt && (e->security & SEC_OPPENCRYPT))
1939 {
1940 if (e->security & (SEC_ENCRYPT | SEC_SIGN))
1941 {
1942 snprintf(promptbuf, sizeof(promptbuf),
1943 /* L10N: PGP options (inline) (opportunistic encryption is on) */
1944 _("PGP (s)ign, sign (a)s, %s format, (c)lear, or (o)ppenc mode off?"),
1945 mime_inline);
1946 prompt = promptbuf;
1947 /* L10N: PGP options (inline) (opportunistic encryption is on)
1948 The 'i' is from the "PGP/M(i)ME" or "(i)nline", above. */
1949 letters = _("saico");
1950 choices = "SaiCo";
1951 }
1952 else
1953 {
1954 /* L10N: PGP options (opportunistic encryption is on) */
1955 prompt = _("PGP (s)ign, sign (a)s, (c)lear, or (o)ppenc mode off?");
1956 /* L10N: PGP options (opportunistic encryption is on) */
1957 letters = _("saco");
1958 choices = "SaCo";
1959 }
1960 }
1961 else if (c_crypt_opportunistic_encrypt)
1962 {
1963 /* Opportunistic encryption option is set, but is toggled off
1964 * for this message. */
1965 /* When the message is not selected for signing or encryption, the toggle
1966 * between PGP/MIME and Traditional doesn't make sense. */
1967 if (e->security & (SEC_ENCRYPT | SEC_SIGN))
1968 {
1969 snprintf(promptbuf, sizeof(promptbuf),
1970 /* L10N: PGP options (inline) (opportunistic encryption is off) */
1971 _("PGP (e)ncrypt, (s)ign, sign (a)s, (b)oth, %s format, (c)lear, or (o)ppenc mode?"),
1972 mime_inline);
1973 prompt = promptbuf;
1974 /* L10N: PGP options (inline) (opportunistic encryption is off)
1975 The 'i' is from the "PGP/M(i)ME" or "(i)nline", above. */
1976 letters = _("esabico");
1977 choices = "esabicO";
1978 }
1979 else
1980 {
1981 /* L10N: PGP options (opportunistic encryption is off) */
1982 prompt = _("PGP (e)ncrypt, (s)ign, sign (a)s, (b)oth, (c)lear, or (o)ppenc mode?");
1983 /* L10N: PGP options (opportunistic encryption is off) */
1984 letters = _("esabco");
1985 choices = "esabcO";
1986 }
1987 }
1988 else
1989 {
1990 /* Opportunistic encryption is unset */
1991 if (e->security & (SEC_ENCRYPT | SEC_SIGN))
1992 {
1993 snprintf(promptbuf, sizeof(promptbuf),
1994 /* L10N: PGP options (inline) */
1995 _("PGP (e)ncrypt, (s)ign, sign (a)s, (b)oth, %s format, or (c)lear?"),
1996 mime_inline);
1997 prompt = promptbuf;
1998 /* L10N: PGP options (inline)
1999 The 'i' is from the "PGP/M(i)ME" or "(i)nline", above. */
2000 letters = _("esabic");
2001 choices = "esabic";
2002 }
2003 else
2004 {
2005 /* L10N: PGP options */
2006 prompt = _("PGP (e)ncrypt, (s)ign, sign (a)s, (b)oth, or (c)lear?");
2007 /* L10N: PGP options */
2008 letters = _("esabc");
2009 choices = "esabc";
2010 }
2011 }
2012
2013 choice = mutt_multi_choice(prompt, letters);
2014 if (choice > 0)
2015 {
2016 switch (choices[choice - 1])
2017 {
2018 case 'a': /* sign (a)s */
2019 OptPgpCheckTrust = false;
2020
2021 p = pgp_ask_for_key(_("Sign as: "), NULL, KEYFLAG_NO_FLAGS, PGP_SECRING);
2022 if (p)
2023 {
2024 char input_signas[128] = { 0 };
2025 snprintf(input_signas, sizeof(input_signas), "0x%s", pgp_fpr_or_lkeyid(p));
2026 cs_subset_str_string_set(NeoMutt->sub, "pgp_sign_as", input_signas, NULL);
2027 pgp_key_free(&p);
2028
2029 e->security |= SEC_SIGN;
2030
2031 crypt_pgp_void_passphrase(); /* probably need a different passphrase */
2032 }
2033 break;
2034
2035 case 'b': /* (b)oth */
2036 e->security |= (SEC_ENCRYPT | SEC_SIGN);
2037 break;
2038
2039 case 'C':
2040 e->security &= ~SEC_SIGN;
2041 break;
2042
2043 case 'c': /* (c)lear */
2044 e->security &= ~(SEC_ENCRYPT | SEC_SIGN);
2045 break;
2046
2047 case 'e': /* (e)ncrypt */
2048 e->security |= SEC_ENCRYPT;
2049 e->security &= ~SEC_SIGN;
2050 break;
2051
2052 case 'i': /* toggle (i)nline */
2053 e->security ^= SEC_INLINE;
2054 break;
2055
2056 case 'O': /* oppenc mode on */
2059 break;
2060
2061 case 'o': /* oppenc mode off */
2062 e->security &= ~SEC_OPPENCRYPT;
2063 break;
2064
2065 case 'S': /* (s)ign in oppenc mode */
2066 e->security |= SEC_SIGN;
2067 break;
2068
2069 case 's': /* (s)ign */
2070 e->security &= ~SEC_ENCRYPT;
2071 e->security |= SEC_SIGN;
2072 break;
2073 }
2074 }
2075
2076 return e->security;
2077}
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:1035
void crypt_pgp_void_passphrase(void)
Wrapper for CryptModuleSpecs::void_passphrase()
Definition: cryptglue.c:191
bool OptPgpCheckTrust
(pseudo) used by dlg_select_pgp_key()
Definition: globals.c:83
#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
char * pgp_fpr_or_lkeyid(struct PgpKeyInfo *k)
Get the fingerprint or long keyid.
Definition: pgp.c:235
struct PgpKeyInfo * pgp_ask_for_key(char *tag, const char *whatfor, KeyFlags abilities, enum PgpRing keyring)
Ask the user for a PGP key.
Definition: pgpkey.c:179
@ 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:413
+ 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 2190 of file smime.c.

2191{
2192 struct SmimeKey *key = NULL;
2193 const char *prompt = NULL;
2194 const char *letters = NULL;
2195 const char *choices = NULL;
2196 int choice;
2197
2199 return e->security;
2200
2202
2203 /* Opportunistic encrypt is controlling encryption.
2204 * NOTE: "Signing" and "Clearing" only adjust the sign bit, so we have different
2205 * letter choices for those. */
2206 const bool c_crypt_opportunistic_encrypt = cs_subset_bool(NeoMutt->sub, "crypt_opportunistic_encrypt");
2207 if (c_crypt_opportunistic_encrypt && (e->security & SEC_OPPENCRYPT))
2208 {
2209 /* L10N: S/MIME options (opportunistic encryption is on) */
2210 prompt = _("S/MIME (s)ign, encrypt (w)ith, sign (a)s, (c)lear, or (o)ppenc mode off?");
2211 /* L10N: S/MIME options (opportunistic encryption is on) */
2212 letters = _("swaco");
2213 choices = "SwaCo";
2214 }
2215 else if (c_crypt_opportunistic_encrypt)
2216 {
2217 /* Opportunistic encryption option is set, but is toggled off
2218 * for this message. */
2219 /* L10N: S/MIME options (opportunistic encryption is off) */
2220 prompt = _("S/MIME (e)ncrypt, (s)ign, encrypt (w)ith, sign (a)s, (b)oth, (c)lear, or (o)ppenc mode?");
2221 /* L10N: S/MIME options (opportunistic encryption is off) */
2222 letters = _("eswabco");
2223 choices = "eswabcO";
2224 }
2225 else
2226 {
2227 /* Opportunistic encryption is unset */
2228 /* L10N: S/MIME options */
2229 prompt = _("S/MIME (e)ncrypt, (s)ign, encrypt (w)ith, sign (a)s, (b)oth, or (c)lear?");
2230 /* L10N: S/MIME options */
2231 letters = _("eswabc");
2232 choices = "eswabc";
2233 }
2234
2235 choice = mutt_multi_choice(prompt, letters);
2236 if (choice > 0)
2237 {
2238 switch (choices[choice - 1])
2239 {
2240 case 'a': /* sign (a)s */
2241 key = smime_ask_for_key(_("Sign as: "), KEYFLAG_CANSIGN, false);
2242 if (key)
2243 {
2244 cs_subset_str_string_set(NeoMutt->sub, "smime_sign_as", key->hash, NULL);
2245 smime_key_free(&key);
2246
2247 e->security |= SEC_SIGN;
2248
2249 /* probably need a different passphrase */
2251 }
2252
2253 break;
2254
2255 case 'b': /* (b)oth */
2256 e->security |= (SEC_ENCRYPT | SEC_SIGN);
2257 break;
2258
2259 case 'c': /* (c)lear */
2260 e->security &= ~(SEC_ENCRYPT | SEC_SIGN);
2261 break;
2262
2263 case 'C':
2264 e->security &= ~SEC_SIGN;
2265 break;
2266
2267 case 'e': /* (e)ncrypt */
2268 e->security |= SEC_ENCRYPT;
2269 e->security &= ~SEC_SIGN;
2270 break;
2271
2272 case 'O': /* oppenc mode on */
2275 break;
2276
2277 case 'o': /* oppenc mode off */
2278 e->security &= ~SEC_OPPENCRYPT;
2279 break;
2280
2281 case 'S': /* (s)ign in oppenc mode */
2282 e->security |= SEC_SIGN;
2283 break;
2284
2285 case 's': /* (s)ign */
2286 e->security &= ~SEC_ENCRYPT;
2287 e->security |= SEC_SIGN;
2288 break;
2289
2290 case 'w': /* encrypt (w)ith */
2291 {
2292 e->security |= SEC_ENCRYPT;
2293 do
2294 {
2295 struct Buffer errmsg = buf_make(0);
2296 int rc = CSR_SUCCESS;
2297 switch (mutt_multi_choice(_("Choose algorithm family: (1) DES, (2) RC2, (3) AES, or (c)lear?"),
2298 // L10N: Options for: Choose algorithm family: (1) DES, (2) RC2, (3) AES, or (c)lear?
2299 _("123c")))
2300 {
2301 case 1:
2302 switch (choice = mutt_multi_choice(_("(1) DES, (2) Triple-DES?"),
2303 // L10N: Options for: (1) DES, (2) Triple-DES
2304 _("12")))
2305 {
2306 case 1:
2307 rc = cs_subset_str_string_set(NeoMutt->sub, "smime_encrypt_with",
2308 "des", &errmsg);
2309 break;
2310 case 2:
2311 rc = cs_subset_str_string_set(NeoMutt->sub, "smime_encrypt_with",
2312 "des3", &errmsg);
2313 break;
2314 }
2315 break;
2316
2317 case 2:
2318 switch (choice = mutt_multi_choice(_("(1) RC2-40, (2) RC2-64, (3) RC2-128?"),
2319 // L10N: Options for: (1) RC2-40, (2) RC2-64, (3) RC2-128
2320 _("123")))
2321 {
2322 case 1:
2323 rc = cs_subset_str_string_set(NeoMutt->sub, "smime_encrypt_with",
2324 "rc2-40", &errmsg);
2325 break;
2326 case 2:
2327 rc = cs_subset_str_string_set(NeoMutt->sub, "smime_encrypt_with",
2328 "rc2-64", &errmsg);
2329 break;
2330 case 3:
2331 rc = cs_subset_str_string_set(NeoMutt->sub, "smime_encrypt_with",
2332 "rc2-128", &errmsg);
2333 break;
2334 }
2335 break;
2336
2337 case 3:
2338 switch (choice = mutt_multi_choice(_("(1) AES128, (2) AES192, (3) AES256?"),
2339 // L10N: Options for: (1) AES128, (2) AES192, (3) AES256
2340 _("123")))
2341 {
2342 case 1:
2343 rc = cs_subset_str_string_set(NeoMutt->sub, "smime_encrypt_with",
2344 "aes128", &errmsg);
2345 break;
2346 case 2:
2347 rc = cs_subset_str_string_set(NeoMutt->sub, "smime_encrypt_with",
2348 "aes192", &errmsg);
2349 break;
2350 case 3:
2351 rc = cs_subset_str_string_set(NeoMutt->sub, "smime_encrypt_with",
2352 "aes256", &errmsg);
2353 break;
2354 }
2355 break;
2356
2357 case 4:
2358 rc = cs_subset_str_string_set(NeoMutt->sub, "smime_encrypt_with",
2359 NULL, &errmsg);
2360 /* (c)lear */
2361 /* fallthrough */
2362 case -1: /* Ctrl-G or Enter */
2363 choice = 0;
2364 break;
2365 }
2366
2367 if ((CSR_RESULT(rc) != CSR_SUCCESS) && !buf_is_empty(&errmsg))
2368 mutt_error("%s", buf_string(&errmsg));
2369
2370 buf_dealloc(&errmsg);
2371 } while (choice == -1);
2372 break;
2373 }
2374 }
2375 }
2376
2377 return e->security;
2378}
void buf_dealloc(struct Buffer *buf)
Release the memory allocated by a buffer.
Definition: buffer.c:383
bool buf_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:303
struct Buffer buf_make(size_t size)
Make a new buffer on the stack.
Definition: buffer.c:70
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:90
#define CSR_RESULT(x)
Definition: set.h:52
#define CSR_SUCCESS
Action completed successfully.
Definition: set.h:35
void crypt_smime_void_passphrase(void)
Wrapper for CryptModuleSpecs::void_passphrase()
Definition: cryptglue.c:413
#define mutt_error(...)
Definition: logging2.h:90
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: lib.h:91
#define KEYFLAG_CANSIGN
Key is suitable for signing.
Definition: lib.h:127
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:741
static void smime_key_free(struct SmimeKey **keylist)
Free a list of SMIME keys.
Definition: smime.c:114
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: