NeoMutt  2022-04-29-323-g5fcc6c
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 3908 of file crypt_gpgme.c.

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

3917{
3918 return gpgme_send_menu(e, true);
3919}
+ 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] = { 0 };
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
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] = { 0 };
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 */
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:1023
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: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: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
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 */
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:67
bool mutt_buffer_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:260
void mutt_buffer_dealloc(struct Buffer *buf)
Release the memory allocated by a buffer.
Definition: buffer.c:309
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: