NeoMutt  2025-09-05-55-g97fc89
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
lib.h File Reference

API for encryption/signing of emails. More...

#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
+ Include dependency graph for lib.h:

Go to the source code of this file.

Macros

#define SEC_NO_FLAGS   0
 No flags are set.
 
#define SEC_ENCRYPT   (1 << 0)
 Email is encrypted.
 
#define SEC_SIGN   (1 << 1)
 Email is signed.
 
#define SEC_GOODSIGN   (1 << 2)
 Email has a valid signature.
 
#define SEC_BADSIGN   (1 << 3)
 Email has a bad signature.
 
#define SEC_PARTSIGN   (1 << 4)
 Not all parts of the email is signed.
 
#define SEC_SIGNOPAQUE   (1 << 5)
 Email has an opaque signature (encrypted)
 
#define SEC_KEYBLOCK   (1 << 6)
 Email has a key attached.
 
#define SEC_INLINE   (1 << 7)
 Email has an inline signature.
 
#define SEC_OPPENCRYPT   (1 << 8)
 Opportunistic encrypt mode.
 
#define SEC_AUTOCRYPT   (1 << 9)
 (Autocrypt) Message will be, or was Autocrypt encrypt+signed
 
#define SEC_AUTOCRYPT_OVERRIDE   (1 << 10)
 (Autocrypt) Indicates manual set/unset of encryption
 
#define APPLICATION_PGP   (1 << 11)
 Use PGP to encrypt/sign.
 
#define APPLICATION_SMIME   (1 << 12)
 Use SMIME to encrypt/sign.
 
#define PGP_TRADITIONAL_CHECKED   (1 << 13)
 Email has a traditional (inline) signature.
 
#define SEC_ALL_FLAGS   ((1 << 14) - 1)
 
#define PGP_ENCRYPT   (APPLICATION_PGP | SEC_ENCRYPT)
 
#define PGP_SIGN   (APPLICATION_PGP | SEC_SIGN)
 
#define PGP_GOODSIGN   (APPLICATION_PGP | SEC_GOODSIGN)
 
#define PGP_KEY   (APPLICATION_PGP | SEC_KEYBLOCK)
 
#define PGP_INLINE   (APPLICATION_PGP | SEC_INLINE)
 
#define SMIME_ENCRYPT   (APPLICATION_SMIME | SEC_ENCRYPT)
 
#define SMIME_SIGN   (APPLICATION_SMIME | SEC_SIGN)
 
#define SMIME_GOODSIGN   (APPLICATION_SMIME | SEC_GOODSIGN)
 
#define SMIME_BADSIGN   (APPLICATION_SMIME | SEC_BADSIGN)
 
#define SMIME_OPAQUE   (APPLICATION_SMIME | SEC_SIGNOPAQUE)
 
#define WithCrypto   (APPLICATION_PGP | APPLICATION_SMIME)
 
#define KEYFLAG_NO_FLAGS   0
 No flags are set.
 
#define KEYFLAG_CANSIGN   (1 << 0)
 Key is suitable for signing.
 
#define KEYFLAG_CANENCRYPT   (1 << 1)
 Key is suitable for encryption.
 
#define KEYFLAG_ISX509   (1 << 2)
 Key is an X.509 key.
 
#define KEYFLAG_SECRET   (1 << 7)
 Key is a secret key.
 
#define KEYFLAG_EXPIRED   (1 << 8)
 Key is expired.
 
#define KEYFLAG_REVOKED   (1 << 9)
 Key is revoked.
 
#define KEYFLAG_DISABLED   (1 << 10)
 Key is marked disabled.
 
#define KEYFLAG_SUBKEY   (1 << 11)
 Key is a subkey.
 
#define KEYFLAG_CRITICAL   (1 << 12)
 Key is marked critical.
 
#define KEYFLAG_PREFER_ENCRYPTION   (1 << 13)
 Key's owner prefers encryption.
 
#define KEYFLAG_PREFER_SIGNING   (1 << 14)
 Key's owner prefers signing.
 
#define KEYFLAG_CANTUSE   (KEYFLAG_DISABLED | KEYFLAG_REVOKED | KEYFLAG_EXPIRED)
 
#define KEYFLAG_RESTRICTIONS   (KEYFLAG_CANTUSE | KEYFLAG_CRITICAL)
 
#define KEYFLAG_ABILITIES   (KEYFLAG_CANSIGN | KEYFLAG_CANENCRYPT | KEYFLAG_PREFER_ENCRYPTION | KEYFLAG_PREFER_SIGNING)
 

Typedefs

typedef uint16_t SecurityFlags
 Flags, e.g. SEC_ENCRYPT.
 
typedef uint16_t KeyFlags
 Flags describing PGP/SMIME keys, e.g. KEYFLAG_CANSIGN.
 

Functions

void crypt_extract_keys_from_messages (struct Mailbox *m, struct EmailArray *ea)
 Extract keys from a message.
 
void crypt_forget_passphrase (void)
 Forget a passphrase and display a message.
 
int crypt_get_keys (struct Email *e, char **keylist, bool oppenc_mode)
 Check we have all the keys we need.
 
void crypt_opportunistic_encrypt (struct Email *e)
 Can all recipients be determined.
 
SecurityFlags crypt_query (struct Body *b)
 Check out the type of encryption used.
 
bool crypt_valid_passphrase (SecurityFlags flags)
 Check that we have a usable passphrase, ask if not.
 
SecurityFlags mutt_is_application_pgp (const struct Body *b)
 Does the message use PGP?
 
SecurityFlags mutt_is_application_smime (struct Body *b)
 Does the message use S/MIME?
 
SecurityFlags mutt_is_malformed_multipart_pgp_encrypted (struct Body *b)
 Check for malformed layout.
 
SecurityFlags mutt_is_multipart_encrypted (struct Body *b)
 Does the message have encrypted parts?
 
SecurityFlags mutt_is_multipart_signed (struct Body *b)
 Is a message signed?
 
int mutt_is_valid_multipart_pgp_encrypted (struct Body *b)
 Is this a valid multi-part encrypted message?
 
int mutt_protected_headers_handler (struct Body *b, struct State *state)
 Handler for protected headers - Implements handler_t -.
 
int mutt_protect (struct Email *e, char *keylist, bool postpone)
 Encrypt and/or sign a message.
 
bool mutt_should_hide_protected_subject (struct Email *e)
 Should NeoMutt hide the protected subject?
 
int mutt_signed_handler (struct Body *b, struct State *state)
 Handler for "multipart/signed" - Implements handler_t -.
 
void crypt_cleanup (void)
 Clean up backend.
 
bool crypt_has_module_backend (SecurityFlags type)
 Is there a crypto backend for a given type?
 
void crypt_init (void)
 Initialise the crypto backends.
 
void crypt_invoke_message (SecurityFlags type)
 Display an informative message.
 
int crypt_pgp_application_handler (struct Body *b_email, struct State *state)
 Wrapper for CryptModuleSpecs::application_handler() - Implements handler_t -.
 
bool crypt_pgp_check_traditional (FILE *fp, struct Body *b, bool just_one)
 Wrapper for CryptModuleSpecs::pgp_check_traditional()
 
int crypt_pgp_decrypt_mime (FILE *fp_in, FILE **fp_out, struct Body *b, struct Body **b_dec)
 Wrapper for CryptModuleSpecs::decrypt_mime()
 
int crypt_pgp_encrypted_handler (struct Body *b_email, struct State *state)
 Wrapper for CryptModuleSpecs::encrypted_handler() - Implements handler_t -.
 
void crypt_pgp_extract_key_from_attachment (FILE *fp, struct Body *b)
 Wrapper for CryptModuleSpecs::pgp_extract_key_from_attachment()
 
void crypt_pgp_invoke_getkeys (struct Address *addr)
 Wrapper for CryptModuleSpecs::pgp_invoke_getkeys()
 
struct Bodycrypt_pgp_make_key_attachment (void)
 Wrapper for CryptModuleSpecs::pgp_make_key_attachment()
 
SecurityFlags crypt_pgp_send_menu (struct Email *e)
 Wrapper for CryptModuleSpecs::send_menu()
 
int crypt_smime_application_handler (struct Body *b_email, struct State *state)
 Wrapper for CryptModuleSpecs::application_handler() - Implements handler_t -.
 
int crypt_smime_decrypt_mime (FILE *fp_in, FILE **fp_out, struct Body *b, struct Body **b_dec)
 Wrapper for CryptModuleSpecs::decrypt_mime()
 
void crypt_smime_getkeys (struct Envelope *env)
 Wrapper for CryptModuleSpecs::smime_getkeys()
 
SecurityFlags crypt_smime_send_menu (struct Email *e)
 Wrapper for CryptModuleSpecs::send_menu()
 
int crypt_smime_verify_sender (struct Email *e, struct Message *msg)
 Wrapper for CryptModuleSpecs::smime_verify_sender()
 
void crypto_module_cleanup (void)
 Clean up the crypto modules.
 
void pgp_gpgme_init (void)
 Initialise the crypto module - Implements CryptModuleSpecs::init() -.
 
int mutt_gpgme_select_secret_key (struct Buffer *keyid)
 Select a private Autocrypt key for a new account.
 
const char * mutt_gpgme_print_version (void)
 Get version of GPGME.
 

Detailed Description

API for encryption/signing of emails.

Authors
  • Richard Russon
  • Pietro Cerutti

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

Definition in file lib.h.

Macro Definition Documentation

◆ SEC_NO_FLAGS

#define SEC_NO_FLAGS   0

No flags are set.

Definition at line 83 of file lib.h.

◆ SEC_ENCRYPT

#define SEC_ENCRYPT   (1 << 0)

Email is encrypted.

Definition at line 84 of file lib.h.

◆ SEC_SIGN

#define SEC_SIGN   (1 << 1)

Email is signed.

Definition at line 85 of file lib.h.

◆ SEC_GOODSIGN

#define SEC_GOODSIGN   (1 << 2)

Email has a valid signature.

Definition at line 86 of file lib.h.

◆ SEC_BADSIGN

#define SEC_BADSIGN   (1 << 3)

Email has a bad signature.

Definition at line 87 of file lib.h.

◆ SEC_PARTSIGN

#define SEC_PARTSIGN   (1 << 4)

Not all parts of the email is signed.

Definition at line 88 of file lib.h.

◆ SEC_SIGNOPAQUE

#define SEC_SIGNOPAQUE   (1 << 5)

Email has an opaque signature (encrypted)

Definition at line 89 of file lib.h.

◆ SEC_KEYBLOCK

#define SEC_KEYBLOCK   (1 << 6)

Email has a key attached.

Definition at line 90 of file lib.h.

◆ SEC_INLINE

#define SEC_INLINE   (1 << 7)

Email has an inline signature.

Definition at line 91 of file lib.h.

◆ SEC_OPPENCRYPT

#define SEC_OPPENCRYPT   (1 << 8)

Opportunistic encrypt mode.

Definition at line 92 of file lib.h.

◆ SEC_AUTOCRYPT

#define SEC_AUTOCRYPT   (1 << 9)

(Autocrypt) Message will be, or was Autocrypt encrypt+signed

Definition at line 93 of file lib.h.

◆ SEC_AUTOCRYPT_OVERRIDE

#define SEC_AUTOCRYPT_OVERRIDE   (1 << 10)

(Autocrypt) Indicates manual set/unset of encryption

Definition at line 94 of file lib.h.

◆ APPLICATION_PGP

#define APPLICATION_PGP   (1 << 11)

Use PGP to encrypt/sign.

Definition at line 96 of file lib.h.

◆ APPLICATION_SMIME

#define APPLICATION_SMIME   (1 << 12)

Use SMIME to encrypt/sign.

Definition at line 97 of file lib.h.

◆ PGP_TRADITIONAL_CHECKED

#define PGP_TRADITIONAL_CHECKED   (1 << 13)

Email has a traditional (inline) signature.

Definition at line 98 of file lib.h.

◆ SEC_ALL_FLAGS

#define SEC_ALL_FLAGS   ((1 << 14) - 1)

Definition at line 100 of file lib.h.

◆ PGP_ENCRYPT

#define PGP_ENCRYPT   (APPLICATION_PGP | SEC_ENCRYPT)

Definition at line 102 of file lib.h.

◆ PGP_SIGN

#define PGP_SIGN   (APPLICATION_PGP | SEC_SIGN)

Definition at line 103 of file lib.h.

◆ PGP_GOODSIGN

#define PGP_GOODSIGN   (APPLICATION_PGP | SEC_GOODSIGN)

Definition at line 104 of file lib.h.

◆ PGP_KEY

#define PGP_KEY   (APPLICATION_PGP | SEC_KEYBLOCK)

Definition at line 105 of file lib.h.

◆ PGP_INLINE

#define PGP_INLINE   (APPLICATION_PGP | SEC_INLINE)

Definition at line 106 of file lib.h.

◆ SMIME_ENCRYPT

#define SMIME_ENCRYPT   (APPLICATION_SMIME | SEC_ENCRYPT)

Definition at line 108 of file lib.h.

◆ SMIME_SIGN

#define SMIME_SIGN   (APPLICATION_SMIME | SEC_SIGN)

Definition at line 109 of file lib.h.

◆ SMIME_GOODSIGN

#define SMIME_GOODSIGN   (APPLICATION_SMIME | SEC_GOODSIGN)

Definition at line 110 of file lib.h.

◆ SMIME_BADSIGN

#define SMIME_BADSIGN   (APPLICATION_SMIME | SEC_BADSIGN)

Definition at line 111 of file lib.h.

◆ SMIME_OPAQUE

#define SMIME_OPAQUE   (APPLICATION_SMIME | SEC_SIGNOPAQUE)

Definition at line 112 of file lib.h.

◆ WithCrypto

#define WithCrypto   (APPLICATION_PGP | APPLICATION_SMIME)

Definition at line 122 of file lib.h.

◆ KEYFLAG_NO_FLAGS

#define KEYFLAG_NO_FLAGS   0

No flags are set.

Definition at line 132 of file lib.h.

◆ KEYFLAG_CANSIGN

#define KEYFLAG_CANSIGN   (1 << 0)

Key is suitable for signing.

Definition at line 133 of file lib.h.

◆ KEYFLAG_CANENCRYPT

#define KEYFLAG_CANENCRYPT   (1 << 1)

Key is suitable for encryption.

Definition at line 134 of file lib.h.

◆ KEYFLAG_ISX509

#define KEYFLAG_ISX509   (1 << 2)

Key is an X.509 key.

Definition at line 135 of file lib.h.

◆ KEYFLAG_SECRET

#define KEYFLAG_SECRET   (1 << 7)

Key is a secret key.

Definition at line 136 of file lib.h.

◆ KEYFLAG_EXPIRED

#define KEYFLAG_EXPIRED   (1 << 8)

Key is expired.

Definition at line 137 of file lib.h.

◆ KEYFLAG_REVOKED

#define KEYFLAG_REVOKED   (1 << 9)

Key is revoked.

Definition at line 138 of file lib.h.

◆ KEYFLAG_DISABLED

#define KEYFLAG_DISABLED   (1 << 10)

Key is marked disabled.

Definition at line 139 of file lib.h.

◆ KEYFLAG_SUBKEY

#define KEYFLAG_SUBKEY   (1 << 11)

Key is a subkey.

Definition at line 140 of file lib.h.

◆ KEYFLAG_CRITICAL

#define KEYFLAG_CRITICAL   (1 << 12)

Key is marked critical.

Definition at line 141 of file lib.h.

◆ KEYFLAG_PREFER_ENCRYPTION

#define KEYFLAG_PREFER_ENCRYPTION   (1 << 13)

Key's owner prefers encryption.

Definition at line 142 of file lib.h.

◆ KEYFLAG_PREFER_SIGNING

#define KEYFLAG_PREFER_SIGNING   (1 << 14)

Key's owner prefers signing.

Definition at line 143 of file lib.h.

◆ KEYFLAG_CANTUSE

#define KEYFLAG_CANTUSE   (KEYFLAG_DISABLED | KEYFLAG_REVOKED | KEYFLAG_EXPIRED)

Definition at line 145 of file lib.h.

◆ KEYFLAG_RESTRICTIONS

#define KEYFLAG_RESTRICTIONS   (KEYFLAG_CANTUSE | KEYFLAG_CRITICAL)

Definition at line 146 of file lib.h.

◆ KEYFLAG_ABILITIES

Definition at line 148 of file lib.h.

Typedef Documentation

◆ SecurityFlags

typedef uint16_t SecurityFlags

Flags, e.g. SEC_ENCRYPT.

Definition at line 82 of file lib.h.

◆ KeyFlags

typedef uint16_t KeyFlags

Flags describing PGP/SMIME keys, e.g. KEYFLAG_CANSIGN.

Definition at line 131 of file lib.h.

Function Documentation

◆ crypt_extract_keys_from_messages()

void crypt_extract_keys_from_messages ( struct Mailbox * m,
struct EmailArray * ea )

Extract keys from a message.

Parameters
mMailbox
eaArray of Emails to process

The extracted keys will be added to the user's keyring.

Definition at line 858 of file crypt.c.

859{
860 if (!WithCrypto)
861 return;
862
863 struct Buffer *tempfile = buf_pool_get();
864 buf_mktemp(tempfile);
865 FILE *fp_out = mutt_file_fopen(buf_string(tempfile), "w");
866 if (!fp_out)
867 {
868 mutt_perror("%s", buf_string(tempfile));
869 goto cleanup;
870 }
871
874
875 struct Email **ep = NULL;
876 ARRAY_FOREACH(ep, ea)
877 {
878 struct Email *e = *ep;
879 struct Message *msg = mx_msg_open(m, e);
880 if (!msg)
881 {
882 continue;
883 }
886 {
887 mx_msg_close(m, &msg);
888 mutt_file_fclose(&fp_out);
889 break;
890 }
891
892 if (((WithCrypto & APPLICATION_PGP) != 0) && (e->security & APPLICATION_PGP))
893 {
895 fflush(fp_out);
896
897 mutt_endwin();
898 puts(_("Trying to extract PGP keys...\n"));
900 }
901
903 {
904 const bool encrypt = e->security & SEC_ENCRYPT;
905 mutt_copy_message(fp_out, e, msg,
908 CH_NO_FLAGS, 0);
909 fflush(fp_out);
910
911 const char *mbox = NULL;
912 if (!TAILQ_EMPTY(&e->env->from))
913 {
915 mbox = buf_string(TAILQ_FIRST(&e->env->from)->mailbox);
916 }
917 else if (!TAILQ_EMPTY(&e->env->sender))
918 {
920 mbox = buf_string(TAILQ_FIRST(&e->env->sender)->mailbox);
921 }
922 if (mbox)
923 {
924 mutt_endwin();
925 puts(_("Trying to extract S/MIME certificates..."));
926 crypt_smime_invoke_import(buf_string(tempfile), mbox);
927 }
928 }
929 mx_msg_close(m, &msg);
930
931 rewind(fp_out);
932 }
933
934 mutt_file_fclose(&fp_out);
935 if (isendwin())
937
938 mutt_file_unlink(buf_string(tempfile));
939
941 OptDontHandlePgpKeys = false;
942
943cleanup:
944 buf_pool_release(&tempfile);
945}
void mutt_expand_aliases(struct AddressList *al)
Expand aliases in a List of Addresses.
Definition alias.c:294
#define ARRAY_FOREACH(elem, head)
Iterate over all elements of the array.
Definition array.h:214
void mutt_parse_mime_message(struct Email *e, FILE *fp)
Parse a MIME email.
Definition commands.c:596
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition buffer.h:96
int mutt_copy_message(FILE *fp_out, struct Email *e, struct Message *msg, CopyMessageFlags cmflags, CopyHeaderFlags chflags, int wraplen)
Copy a message from a Mailbox.
Definition copy.c:908
#define MUTT_CM_DECODE
Decode the message body into text/plain.
Definition copy.h:40
#define MUTT_CM_CHARCONV
Perform character set conversions.
Definition copy.h:44
#define MUTT_CM_DECODE_SMIME
Used for decoding S/MIME messages.
Definition copy.h:48
#define MUTT_CM_NO_FLAGS
No flags are set.
Definition copy.h:37
#define MUTT_CM_DECODE_CRYPT
Definition copy.h:50
#define MUTT_CM_NOHEADER
Don't copy the message header.
Definition copy.h:38
#define CH_NO_FLAGS
No flags are set.
Definition copy.h:53
bool crypt_valid_passphrase(SecurityFlags flags)
Check that we have a usable passphrase, ask if not.
Definition crypt.c:131
void crypt_pgp_invoke_import(const char *fname)
Wrapper for CryptModuleSpecs::pgp_invoke_import()
Definition cryptglue.c:363
void crypt_smime_invoke_import(const char *infile, const char *mailbox)
Wrapper for CryptModuleSpecs::smime_invoke_import()
Definition cryptglue.c:507
int mutt_any_key_to_continue(const char *s)
Prompt the user to 'press any key' and wait.
Definition curs_lib.c:174
void mutt_endwin(void)
Shutdown curses.
Definition curs_lib.c:152
void mutt_file_unlink(const char *s)
Delete a file, carefully.
Definition file.c:159
#define mutt_file_fclose(FP)
Definition file.h:139
#define mutt_file_fopen(PATH, MODE)
Definition file.h:138
bool OptDontHandlePgpKeys
(pseudo) used to extract PGP keys
Definition globals.c:57
#define mutt_perror(...)
Definition logging2.h:94
#define _(a)
Definition message.h:28
int mx_msg_close(struct Mailbox *m, struct Message **ptr)
Close a message.
Definition mx.c:1185
struct Message * mx_msg_open(struct Mailbox *m, struct Email *e)
Return a stream pointer for a message.
Definition mx.c:1139
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition lib.h:96
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition lib.h:97
#define SEC_ENCRYPT
Email is encrypted.
Definition lib.h:84
#define WithCrypto
Definition lib.h:122
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition pool.c:82
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition pool.c:96
#define TAILQ_FIRST(head)
Definition queue.h:780
#define TAILQ_EMPTY(head)
Definition queue.h:778
String manipulation buffer.
Definition buffer.h:36
The envelope/body of an email.
Definition email.h:39
struct Envelope * env
Envelope information.
Definition email.h:68
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/lib.h pgplib....
Definition email.h:43
struct AddressList sender
Email's sender.
Definition envelope.h:63
struct AddressList from
Email's 'From' list.
Definition envelope.h:59
A local copy of an email.
Definition message.h:34
FILE * fp
pointer to the message data
Definition message.h:35
#define buf_mktemp(buf)
Definition tmp.h:33
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ crypt_forget_passphrase()

void crypt_forget_passphrase ( void )

Forget a passphrase and display a message.

Definition at line 89 of file crypt.c.

90{
93
96
97 if (WithCrypto)
98 {
99 /* L10N: Due to the implementation details (e.g. some passwords are managed
100 by gpg-agent) we can't know whether we forgot zero, 1, 12, ...
101 passwords. So in English we use "Passphrases". Your language might
102 have other means to express this. */
103 mutt_message(_("Passphrases forgotten"));
104 }
105}
void crypt_smime_void_passphrase(void)
Wrapper for CryptModuleSpecs::void_passphrase()
Definition cryptglue.c:412
void crypt_pgp_void_passphrase(void)
Wrapper for CryptModuleSpecs::void_passphrase()
Definition cryptglue.c:190
#define mutt_message(...)
Definition logging2.h:92
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ crypt_get_keys()

int crypt_get_keys ( struct Email * e,
char ** keylist,
bool oppenc_mode )

Check we have all the keys we need.

Parameters
[in]eEmail with addresses to match
[out]keylistKeys needed
[in]oppenc_modeIf true, use opportunistic encryption
Return values
0Success
-1Error

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. If oppenc_mode is true, only keys that can be determined without prompting will be used.

Definition at line 961 of file crypt.c.

962{
963 if (!WithCrypto)
964 return 0;
965
966 struct AddressList addrlist = TAILQ_HEAD_INITIALIZER(addrlist);
967 const char *fqdn = mutt_fqdn(true, NeoMutt->sub);
968 const char *self_encrypt = NULL;
969
970 /* Do a quick check to make sure that we can find all of the encryption
971 * keys if the user has requested this service. */
972
973 *keylist = NULL;
974
975#ifdef USE_AUTOCRYPT
976 if (!oppenc_mode && (e->security & SEC_AUTOCRYPT))
977 {
979 return -1;
980 return 0;
981 }
982#endif
983
985 OptPgpCheckTrust = true;
986
987 mutt_addrlist_copy(&addrlist, &e->env->to, false);
988 mutt_addrlist_copy(&addrlist, &e->env->cc, false);
989 mutt_addrlist_copy(&addrlist, &e->env->bcc, false);
990 mutt_addrlist_qualify(&addrlist, fqdn);
991 mutt_addrlist_dedupe(&addrlist);
992
993 if (oppenc_mode || (e->security & SEC_ENCRYPT))
994 {
995 if (((WithCrypto & APPLICATION_PGP) != 0) && (e->security & APPLICATION_PGP))
996 {
997 *keylist = crypt_pgp_find_keys(&addrlist, oppenc_mode);
998 if (!*keylist)
999 {
1000 mutt_addrlist_clear(&addrlist);
1001 return -1;
1002 }
1003 OptPgpCheckTrust = false;
1004 const bool c_pgp_self_encrypt = cs_subset_bool(NeoMutt->sub, "pgp_self_encrypt");
1005 const char *const c_pgp_default_key = cs_subset_string(NeoMutt->sub, "pgp_default_key");
1006 const enum QuadOption c_pgp_encrypt_self = cs_subset_quad(NeoMutt->sub, "pgp_encrypt_self");
1007 if (c_pgp_self_encrypt || (c_pgp_encrypt_self == MUTT_YES))
1008 self_encrypt = c_pgp_default_key;
1009 }
1010 if (((WithCrypto & APPLICATION_SMIME) != 0) && (e->security & APPLICATION_SMIME))
1011 {
1012 *keylist = crypt_smime_find_keys(&addrlist, oppenc_mode);
1013 if (!*keylist)
1014 {
1015 mutt_addrlist_clear(&addrlist);
1016 return -1;
1017 }
1018 const bool c_smime_self_encrypt = cs_subset_bool(NeoMutt->sub, "smime_self_encrypt");
1019 const char *const c_smime_default_key = cs_subset_string(NeoMutt->sub, "smime_default_key");
1020 const enum QuadOption c_smime_encrypt_self = cs_subset_quad(NeoMutt->sub, "smime_encrypt_self");
1021 if (c_smime_self_encrypt || (c_smime_encrypt_self == MUTT_YES))
1022 self_encrypt = c_smime_default_key;
1023 }
1024 }
1025
1026 if (!oppenc_mode && self_encrypt)
1027 {
1028 const size_t keylist_size = mutt_str_len(*keylist);
1029 MUTT_MEM_REALLOC(keylist, keylist_size + mutt_str_len(self_encrypt) + 2, char);
1030 sprintf(*keylist + keylist_size, " %s", self_encrypt);
1031 }
1032
1033 mutt_addrlist_clear(&addrlist);
1034
1035 return 0;
1036}
void mutt_addrlist_copy(struct AddressList *dst, const struct AddressList *src, bool prune)
Copy a list of addresses into another list.
Definition address.c:765
void mutt_addrlist_qualify(struct AddressList *al, const char *host)
Expand local names in an Address list using a hostname.
Definition address.c:680
void mutt_addrlist_clear(struct AddressList *al)
Unlink and free all Address in an AddressList.
Definition address.c:1460
void mutt_addrlist_dedupe(struct AddressList *al)
Remove duplicate addresses.
Definition address.c:1397
@ AUTOCRYPT_REC_NO
Do no use Autocrypt.
Definition lib.h:164
enum AutocryptRec mutt_autocrypt_ui_recommendation(const struct Email *e, char **keylist)
Get the recommended action for an Email.
Definition autocrypt.c:558
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition helpers.c:291
enum QuadOption cs_subset_quad(const struct ConfigSubset *sub, const char *name)
Get a quad-value config item by name.
Definition helpers.c:192
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition helpers.c:47
char * crypt_smime_find_keys(struct AddressList *addrlist, bool oppenc_mode)
Wrapper for CryptModuleSpecs::find_keys()
Definition cryptglue.c:474
char * crypt_pgp_find_keys(struct AddressList *addrlist, bool oppenc_mode)
Wrapper for CryptModuleSpecs::find_keys()
Definition cryptglue.c:315
bool OptPgpCheckTrust
(pseudo) used by dlg_pgp()
Definition globals.c:66
#define MUTT_MEM_REALLOC(pptr, n, type)
Definition memory.h:50
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition string.c:498
#define SEC_AUTOCRYPT
(Autocrypt) Message will be, or was Autocrypt encrypt+signed
Definition lib.h:93
QuadOption
Possible values for a quad-option.
Definition quad.h:36
@ MUTT_YES
User answered 'Yes', or assume 'Yes'.
Definition quad.h:39
#define TAILQ_HEAD_INITIALIZER(head)
Definition queue.h:694
const char * mutt_fqdn(bool may_hide_host, const struct ConfigSubset *sub)
Get the Fully-Qualified Domain Name.
Definition sendlib.c:706
struct AddressList to
Email's 'To' list.
Definition envelope.h:60
struct AddressList cc
Email's 'Cc' list.
Definition envelope.h:61
struct AddressList bcc
Email's 'Bcc' list.
Definition envelope.h:62
Container for Accounts, Notifications.
Definition neomutt.h:43
struct ConfigSubset * sub
Inherited config items.
Definition neomutt.h:47
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ crypt_opportunistic_encrypt()

void crypt_opportunistic_encrypt ( struct Email * e)

Can all recipients be determined.

Parameters
eEmail

Check if all recipients keys can be automatically determined. Enable encryption if they can, otherwise disable encryption.

Definition at line 1045 of file crypt.c.

1046{
1047 if (!WithCrypto)
1048 return;
1049
1050 const bool c_crypt_opportunistic_encrypt = cs_subset_bool(NeoMutt->sub, "crypt_opportunistic_encrypt");
1051 if (!(c_crypt_opportunistic_encrypt && (e->security & SEC_OPPENCRYPT)))
1052 return;
1053
1054 char *pgpkeylist = NULL;
1055
1056 crypt_get_keys(e, &pgpkeylist, true);
1057 if (pgpkeylist)
1058 {
1059 e->security |= SEC_ENCRYPT;
1060 FREE(&pgpkeylist);
1061 }
1062 else
1063 {
1064 e->security &= ~SEC_ENCRYPT;
1065 }
1066}
int crypt_get_keys(struct Email *e, char **keylist, bool oppenc_mode)
Check we have all the keys we need.
Definition crypt.c:961
#define FREE(x)
Definition memory.h:62
#define SEC_OPPENCRYPT
Opportunistic encrypt mode.
Definition lib.h:92
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ crypt_query()

SecurityFlags crypt_query ( struct Body * b)

Check out the type of encryption used.

Parameters
bBody of email
Return values
numFlags, see SecurityFlags
0Error (SEC_NO_FLAGS)

Set the cached status values if there are any.

Definition at line 687 of file crypt.c.

688{
689 if (!WithCrypto || !b)
690 return SEC_NO_FLAGS;
691
693
694 if (b->type == TYPE_APPLICATION)
695 {
698
700 {
702 if (rc && b->goodsig)
703 rc |= SEC_GOODSIGN;
704 if (rc && b->badsig)
705 rc |= SEC_BADSIGN;
706 }
707 }
708 else if (((WithCrypto & APPLICATION_PGP) != 0) && (b->type == TYPE_TEXT))
709 {
711 if (rc && b->goodsig)
712 rc |= SEC_GOODSIGN;
713 }
714
715 if (b->type == TYPE_MULTIPART)
716 {
720
721 if (rc && b->goodsig)
722 rc |= SEC_GOODSIGN;
723#ifdef USE_AUTOCRYPT
724 if (rc && b->is_autocrypt)
725 rc |= SEC_AUTOCRYPT;
726#endif
727 }
728
729 if ((b->type == TYPE_MULTIPART) || (b->type == TYPE_MESSAGE))
730 {
731 SecurityFlags u = b->parts ? SEC_ALL_FLAGS : SEC_NO_FLAGS; /* Bits set in all parts */
732 SecurityFlags w = SEC_NO_FLAGS; /* Bits set in any part */
733
734 for (b = b->parts; b; b = b->next)
735 {
736 const SecurityFlags v = crypt_query(b);
737 u &= v;
738 w |= v;
739 }
740 rc |= u | (w & ~SEC_GOODSIGN);
741
742 if ((w & SEC_GOODSIGN) && !(u & SEC_GOODSIGN))
743 rc |= SEC_PARTSIGN;
744 }
745
746 return rc;
747}
SecurityFlags mutt_is_multipart_signed(struct Body *b)
Is a message signed?
Definition crypt.c:408
SecurityFlags mutt_is_application_smime(struct Body *b)
Does the message use S/MIME?
Definition crypt.c:609
SecurityFlags mutt_is_multipart_encrypted(struct Body *b)
Does the message have encrypted parts?
Definition crypt.c:443
SecurityFlags mutt_is_malformed_multipart_pgp_encrypted(struct Body *b)
Check for malformed layout.
Definition crypt.c:504
SecurityFlags mutt_is_application_pgp(const struct Body *b)
Does the message use PGP?
Definition crypt.c:548
SecurityFlags crypt_query(struct Body *b)
Check out the type of encryption used.
Definition crypt.c:687
@ TYPE_MESSAGE
Type: 'message/*'.
Definition mime.h:35
@ TYPE_MULTIPART
Type: 'multipart/*'.
Definition mime.h:37
@ TYPE_APPLICATION
Type: 'application/*'.
Definition mime.h:33
@ TYPE_TEXT
Type: 'text/*'.
Definition mime.h:38
uint16_t SecurityFlags
Flags, e.g. SEC_ENCRYPT.
Definition lib.h:82
#define SEC_ALL_FLAGS
Definition lib.h:100
#define SEC_GOODSIGN
Email has a valid signature.
Definition lib.h:86
#define SEC_BADSIGN
Email has a bad signature.
Definition lib.h:87
#define SEC_NO_FLAGS
No flags are set.
Definition lib.h:83
#define SEC_PARTSIGN
Not all parts of the email is signed.
Definition lib.h:88
struct Body * parts
parts of a multipart or message/rfc822
Definition body.h:73
bool badsig
Bad cryptographic signature (needed to check encrypted s/mime-signatures)
Definition body.h:43
bool is_autocrypt
Flag autocrypt-decrypted messages for replying.
Definition body.h:50
struct Body * next
next attachment in the list
Definition body.h:72
bool goodsig
Good cryptographic signature.
Definition body.h:45
unsigned int type
content-type primary type, ContentType
Definition body.h:40
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ crypt_valid_passphrase()

bool crypt_valid_passphrase ( SecurityFlags flags)

Check that we have a usable passphrase, ask if not.

Parameters
flagsFlags, see SecurityFlags
Return values
trueSuccess
falseFailed

Definition at line 131 of file crypt.c.

132{
133 bool rc = false;
134
135#ifndef DEBUG
136 disable_coredumps();
137#endif
138
139 if (((WithCrypto & APPLICATION_PGP) != 0) && (flags & APPLICATION_PGP))
141
142 if (((WithCrypto & APPLICATION_SMIME) != 0) && (flags & APPLICATION_SMIME))
144
145 return rc;
146}
bool crypt_smime_valid_passphrase(void)
Wrapper for CryptModuleSpecs::valid_passphrase()
Definition cryptglue.c:421
bool crypt_pgp_valid_passphrase(void)
Wrapper for CryptModuleSpecs::valid_passphrase()
Definition cryptglue.c:199
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_is_application_pgp()

SecurityFlags mutt_is_application_pgp ( const struct Body * b)

Does the message use PGP?

Parameters
bBody of email
Return values
>0Message uses PGP, e.g. PGP_ENCRYPT
0Message doesn't use PGP, (SEC_NO_FLAGS)

Definition at line 548 of file crypt.c.

549{
551 char *p = NULL;
552
553 if (b->type == TYPE_APPLICATION)
554 {
555 if (mutt_istr_equal(b->subtype, "pgp") || mutt_istr_equal(b->subtype, "x-pgp-message"))
556 {
557 p = mutt_param_get(&b->parameter, "x-action");
558 if (p && (mutt_istr_equal(p, "sign") || mutt_istr_equal(p, "signclear")))
559 {
560 t |= PGP_SIGN;
561 }
562
563 p = mutt_param_get(&b->parameter, "format");
564 if (p && mutt_istr_equal(p, "keys-only"))
565 {
566 t |= PGP_KEY;
567 }
568
569 if (t == SEC_NO_FLAGS)
570 t |= PGP_ENCRYPT; /* not necessarily correct, but... */
571 }
572
573 if (mutt_istr_equal(b->subtype, "pgp-signed"))
574 t |= PGP_SIGN;
575
576 if (mutt_istr_equal(b->subtype, "pgp-keys"))
577 t |= PGP_KEY;
578 }
579 else if ((b->type == TYPE_TEXT) && mutt_istr_equal("plain", b->subtype))
580 {
581 if (((p = mutt_param_get(&b->parameter, "x-mutt-action")) ||
582 (p = mutt_param_get(&b->parameter, "x-action")) ||
583 (p = mutt_param_get(&b->parameter, "action"))) &&
584 mutt_istr_startswith(p, "pgp-sign"))
585 {
586 t |= PGP_SIGN;
587 }
588 else if (p && mutt_istr_startswith(p, "pgp-encrypt"))
589 {
590 t |= PGP_ENCRYPT;
591 }
592 else if (p && mutt_istr_startswith(p, "pgp-keys"))
593 {
594 t |= PGP_KEY;
595 }
596 }
597 if (t)
598 t |= PGP_INLINE;
599
600 return t;
601}
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition string.c:672
size_t mutt_istr_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix, ignoring case.
Definition string.c:244
#define PGP_SIGN
Definition lib.h:103
#define PGP_ENCRYPT
Definition lib.h:102
#define PGP_INLINE
Definition lib.h:106
#define PGP_KEY
Definition lib.h:105
char * mutt_param_get(const struct ParameterList *pl, const char *s)
Find a matching Parameter.
Definition parameter.c:85
struct ParameterList parameter
Parameters of the content-type.
Definition body.h:63
char * subtype
content-type subtype
Definition body.h:61
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_is_application_smime()

SecurityFlags mutt_is_application_smime ( struct Body * b)

Does the message use S/MIME?

Parameters
bBody of email
Return values
>0Message uses S/MIME, e.g. SMIME_ENCRYPT
0Message doesn't use S/MIME, (SEC_NO_FLAGS)

Definition at line 609 of file crypt.c.

610{
611 if (!b)
612 return SEC_NO_FLAGS;
613
614 if (((b->type & TYPE_APPLICATION) == 0) || !b->subtype)
615 return SEC_NO_FLAGS;
616
617 char *t = NULL;
618 bool complain = false;
619 /* S/MIME MIME types don't need x- anymore, see RFC2311 */
620 if (mutt_istr_equal(b->subtype, "x-pkcs7-mime") || mutt_istr_equal(b->subtype, "pkcs7-mime"))
621 {
622 t = mutt_param_get(&b->parameter, "smime-type");
623 if (t)
624 {
625 if (mutt_istr_equal(t, "enveloped-data"))
626 return SMIME_ENCRYPT;
627 if (mutt_istr_equal(t, "signed-data"))
628 return SMIME_SIGN | SMIME_OPAQUE;
629 return SEC_NO_FLAGS;
630 }
631 /* Netscape 4.7 uses
632 * Content-Description: S/MIME Encrypted Message
633 * instead of Content-Type parameter */
634 if (mutt_istr_equal(b->description, "S/MIME Encrypted Message"))
635 return SMIME_ENCRYPT;
636 complain = true;
637 }
638 else if (!mutt_istr_equal(b->subtype, "octet-stream"))
639 {
640 return SEC_NO_FLAGS;
641 }
642
643 t = mutt_param_get(&b->parameter, "name");
644
645 if (!t)
646 t = b->d_filename;
647 if (!t)
648 t = b->filename;
649 if (!t)
650 {
651 if (complain)
652 {
653 mutt_message(_("S/MIME messages with no hints on content are unsupported"));
654 }
655 return SEC_NO_FLAGS;
656 }
657
658 /* no .p7c, .p10 support yet. */
659
660 int len = mutt_str_len(t) - 4;
661 if ((len > 0) && (*(t + len) == '.'))
662 {
663 len++;
664 if (mutt_istr_equal((t + len), "p7m"))
665 {
666 /* Not sure if this is the correct thing to do, but
667 * it's required for compatibility with Outlook */
668 return SMIME_SIGN | SMIME_OPAQUE;
669 }
670 else if (mutt_istr_equal((t + len), "p7s"))
671 {
672 return SMIME_SIGN | SMIME_OPAQUE;
673 }
674 }
675
676 return SEC_NO_FLAGS;
677}
#define SMIME_SIGN
Definition lib.h:109
#define SMIME_OPAQUE
Definition lib.h:112
#define SMIME_ENCRYPT
Definition lib.h:108
char * d_filename
filename to be used for the content-disposition header If NULL, filename is used instead.
Definition body.h:56
char * description
content-description
Definition body.h:55
char * filename
When sending a message, this is the file to which this structure refers.
Definition body.h:59
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_is_malformed_multipart_pgp_encrypted()

SecurityFlags mutt_is_malformed_multipart_pgp_encrypted ( struct Body * b)

Check for malformed layout.

Parameters
bBody of email
Return values
numSuccess, see SecurityFlags
0Error, (SEC_NO_FLAGS)

This checks for the malformed layout caused by MS Exchange in some cases:

<multipart/mixed>
<text/plain>
<application/pgp-encrypted> [BASE64-encoded]
<application/octet-stream> [BASE64-encoded]

Definition at line 504 of file crypt.c.

505{
507 return SEC_NO_FLAGS;
508
509 if (!b || (b->type != TYPE_MULTIPART) || !b->subtype || !mutt_istr_equal(b->subtype, "mixed"))
510 {
511 return SEC_NO_FLAGS;
512 }
513
514 b = b->parts;
515 if (!b || (b->type != TYPE_TEXT) || !b->subtype ||
516 !mutt_istr_equal(b->subtype, "plain") || (b->length != 0))
517 {
518 return SEC_NO_FLAGS;
519 }
520
521 b = b->next;
522 if (!b || (b->type != TYPE_APPLICATION) || !b->subtype ||
523 !mutt_istr_equal(b->subtype, "pgp-encrypted"))
524 {
525 return SEC_NO_FLAGS;
526 }
527
528 b = b->next;
529 if (!b || (b->type != TYPE_APPLICATION) || !b->subtype ||
530 !mutt_istr_equal(b->subtype, "octet-stream"))
531 {
532 return SEC_NO_FLAGS;
533 }
534
535 b = b->next;
536 if (b)
537 return SEC_NO_FLAGS;
538
539 return PGP_ENCRYPT;
540}
LOFF_T length
length (in bytes) of attachment
Definition body.h:53
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_is_multipart_encrypted()

SecurityFlags mutt_is_multipart_encrypted ( struct Body * b)

Does the message have encrypted parts?

Parameters
bBody of email
Return values
numMessage has got encrypted parts, see SecurityFlags
0Message hasn't got encrypted parts (SEC_NO_FLAGS)

Definition at line 443 of file crypt.c.

444{
445 if ((WithCrypto & APPLICATION_PGP) == 0)
446 return SEC_NO_FLAGS;
447
448 char *p = NULL;
449
450 if (!b || (b->type != TYPE_MULTIPART) || !b->subtype ||
451 !mutt_istr_equal(b->subtype, "encrypted") ||
452 !(p = mutt_param_get(&b->parameter, "protocol")) ||
453 !mutt_istr_equal(p, "application/pgp-encrypted"))
454 {
455 return SEC_NO_FLAGS;
456 }
457
458 return PGP_ENCRYPT;
459}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_is_multipart_signed()

SecurityFlags mutt_is_multipart_signed ( struct Body * b)

Is a message signed?

Parameters
bBody of email
Return values
numMessage is signed, see SecurityFlags
0Message is not signed (SEC_NO_FLAGS)

Definition at line 408 of file crypt.c.

409{
410 if (!b || (b->type != TYPE_MULTIPART) || !b->subtype || !mutt_istr_equal(b->subtype, "signed"))
411 {
412 return SEC_NO_FLAGS;
413 }
414
415 char *p = mutt_param_get(&b->parameter, "protocol");
416 if (!p)
417 return SEC_NO_FLAGS;
418
419 if (mutt_istr_equal(p, "multipart/mixed"))
420 return SEC_SIGN;
421
422 if (((WithCrypto & APPLICATION_PGP) != 0) && mutt_istr_equal(p, "application/pgp-signature"))
423 {
424 return PGP_SIGN;
425 }
426
427 if (((WithCrypto & APPLICATION_SMIME) != 0) &&
428 (mutt_istr_equal(p, "application/x-pkcs7-signature") ||
429 mutt_istr_equal(p, "application/pkcs7-signature")))
430 {
431 return SMIME_SIGN;
432 }
433
434 return SEC_NO_FLAGS;
435}
#define SEC_SIGN
Email is signed.
Definition lib.h:85
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_is_valid_multipart_pgp_encrypted()

int mutt_is_valid_multipart_pgp_encrypted ( struct Body * b)

Is this a valid multi-part encrypted message?

Parameters
bBody of email
Return values
>0Message is valid, with encrypted parts, e.g. PGP_ENCRYPT
0Message hasn't got encrypted parts

Definition at line 467 of file crypt.c.

468{
470 return 0;
471
472 b = b->parts;
473 if (!b || (b->type != TYPE_APPLICATION) || !b->subtype ||
474 !mutt_istr_equal(b->subtype, "pgp-encrypted"))
475 {
476 return 0;
477 }
478
479 b = b->next;
480 if (!b || (b->type != TYPE_APPLICATION) || !b->subtype ||
481 !mutt_istr_equal(b->subtype, "octet-stream"))
482 {
483 return 0;
484 }
485
486 return PGP_ENCRYPT;
487}
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_protect()

int mutt_protect ( struct Email * e,
char * keylist,
bool postpone )

Encrypt and/or sign a message.

Parameters
eEmail
keylistList of keys to encrypt to (space-separated)
postponeWhen true, signing is automatically disabled
Return values
0Success
-1Error

Definition at line 156 of file crypt.c.

157{
158 struct Body *pbody = NULL, *tmp_pbody = NULL;
159 struct Body *tmp_smime_pbody = NULL;
160 struct Body *tmp_pgp_pbody = NULL;
161 bool has_retainable_sig = false;
162
163 if (!WithCrypto)
164 return -1;
165
166 SecurityFlags security = e->security;
167 int sign = security & (SEC_AUTOCRYPT | SEC_SIGN);
168 if (postpone)
169 {
170 sign = SEC_NO_FLAGS;
171 security &= ~SEC_SIGN;
172 }
173
174 if (!(security & (SEC_ENCRYPT | SEC_AUTOCRYPT)) && !sign)
175 return 0;
176
177 if (sign && !(security & SEC_AUTOCRYPT) && !crypt_valid_passphrase(security))
178 return -1;
179
180 if (((WithCrypto & APPLICATION_PGP) != 0) && !(security & SEC_AUTOCRYPT) &&
181 ((security & PGP_INLINE) == PGP_INLINE))
182 {
183 if ((e->body->type != TYPE_TEXT) || !mutt_istr_equal(e->body->subtype, "plain"))
184 {
185 if (query_quadoption(_("Inline PGP can't be used with attachments. Revert to PGP/MIME?"),
186 NeoMutt->sub, "pgp_mime_auto") != MUTT_YES)
187 {
188 mutt_error(_("Mail not sent: inline PGP can't be used with attachments"));
189 return -1;
190 }
191 }
192 else if (mutt_istr_equal("flowed", mutt_param_get(&e->body->parameter, "format")))
193 {
194 if ((query_quadoption(_("Inline PGP can't be used with format=flowed. Revert to PGP/MIME?"),
195 NeoMutt->sub, "pgp_mime_auto")) != MUTT_YES)
196 {
197 mutt_error(_("Mail not sent: inline PGP can't be used with format=flowed"));
198 return -1;
199 }
200 }
201 else
202 {
203 /* they really want to send it inline... go for it */
204 if (!isendwin())
205 {
206 mutt_endwin();
207 puts(_("Invoking PGP..."));
208 }
209 pbody = crypt_pgp_traditional_encryptsign(e->body, security, keylist);
210 if (pbody)
211 {
212 e->body = pbody;
213 return 0;
214 }
215
216 /* otherwise inline won't work...ask for revert */
217 if (query_quadoption(_("Message can't be sent inline. Revert to using PGP/MIME?"),
218 NeoMutt->sub, "pgp_mime_auto") != MUTT_YES)
219 {
220 mutt_error(_("Mail not sent"));
221 return -1;
222 }
223 }
224
225 /* go ahead with PGP/MIME */
226 }
227
228 if (!isendwin())
229 mutt_endwin();
230
232 tmp_smime_pbody = e->body;
234 tmp_pgp_pbody = e->body;
235
236#ifdef CRYPT_BACKEND_GPGME
237 const bool c_crypt_use_pka = cs_subset_bool(NeoMutt->sub, "crypt_use_pka");
238 if (sign && c_crypt_use_pka)
239#else
240 if (sign)
241#endif
242 {
243 /* Set sender (necessary for e.g. PKA). */
244 const char *mailbox = NULL;
245 struct Address *from = TAILQ_FIRST(&e->env->from);
246 bool free_from = false;
247
248 if (!from)
249 {
250 free_from = true;
252 }
253
254 mailbox = buf_string(from->mailbox);
255 const struct Address *c_envelope_from_address = cs_subset_address(NeoMutt->sub, "envelope_from_address");
256 if (!mailbox && c_envelope_from_address)
257 mailbox = buf_string(c_envelope_from_address->mailbox);
258
259 if (((WithCrypto & APPLICATION_SMIME) != 0) && (security & APPLICATION_SMIME))
261 else if (((WithCrypto & APPLICATION_PGP) != 0) && (security & APPLICATION_PGP))
263
264 if (free_from)
265 mutt_addr_free(&from);
266 }
267
268 const bool c_crypt_protected_headers_write = cs_subset_bool(NeoMutt->sub, "crypt_protected_headers_write");
269 if (c_crypt_protected_headers_write)
270 {
271 const bool c_devel_security = cs_subset_bool(NeoMutt->sub, "devel_security");
272 struct Envelope *protected_headers = mutt_env_new();
273 mutt_env_set_subject(protected_headers, e->env->subject);
274 if (c_devel_security)
275 {
276 mutt_addrlist_copy(&protected_headers->return_path, &e->env->return_path, false);
277 mutt_addrlist_copy(&protected_headers->from, &e->env->from, false);
278 mutt_addrlist_copy(&protected_headers->to, &e->env->to, false);
279 mutt_addrlist_copy(&protected_headers->cc, &e->env->cc, false);
280 mutt_addrlist_copy(&protected_headers->sender, &e->env->sender, false);
281 mutt_addrlist_copy(&protected_headers->reply_to, &e->env->reply_to, false);
282 mutt_addrlist_copy(&protected_headers->mail_followup_to,
283 &e->env->mail_followup_to, false);
284 mutt_addrlist_copy(&protected_headers->x_original_to, &e->env->x_original_to, false);
285 mutt_str_replace(&protected_headers->message_id, e->env->message_id);
286 mutt_list_copy_tail(&protected_headers->references, &e->env->references);
287 mutt_list_copy_tail(&protected_headers->in_reply_to, &e->env->in_reply_to);
288 mutt_env_to_intl(protected_headers, NULL, NULL);
289 }
290 mutt_prepare_envelope(protected_headers, 0, NeoMutt->sub);
291
293 e->body->mime_headers = protected_headers;
294 mutt_param_set(&e->body->parameter, "protected-headers", "v1");
295 }
296
297#ifdef USE_AUTOCRYPT
298 /* A note about e->body->mime_headers. If postpone or send
299 * fails, the mime_headers is cleared out before returning to the
300 * compose menu. So despite the "robustness" code above and in the
301 * gen_gossip_list function below, mime_headers will not be set when
302 * entering mutt_protect().
303 *
304 * This is important to note because the user could toggle
305 * $crypt_protected_headers_write or $autocrypt off back in the
306 * compose menu. We don't want mutt_rfc822_write_header() to write
307 * stale data from one option if the other is set.
308 */
309 const bool c_autocrypt = cs_subset_bool(NeoMutt->sub, "autocrypt");
310 if (c_autocrypt && !postpone && (security & SEC_AUTOCRYPT))
311 {
313 }
314#endif
315
316 if (sign)
317 {
318 if (((WithCrypto & APPLICATION_SMIME) != 0) && (security & APPLICATION_SMIME))
319 {
320 tmp_pbody = crypt_smime_sign_message(e->body, &e->env->from);
321 if (!tmp_pbody)
322 goto bail;
323 pbody = tmp_pbody;
324 tmp_smime_pbody = tmp_pbody;
325 }
326
327 const bool c_pgp_retainable_sigs = cs_subset_bool(NeoMutt->sub, "pgp_retainable_sigs");
328 if (((WithCrypto & APPLICATION_PGP) != 0) && (security & APPLICATION_PGP) &&
329 (!(security & (SEC_ENCRYPT | SEC_AUTOCRYPT)) || c_pgp_retainable_sigs))
330 {
331 tmp_pbody = crypt_pgp_sign_message(e->body, &e->env->from);
332 if (!tmp_pbody)
333 goto bail;
334
335 has_retainable_sig = true;
336 sign = SEC_NO_FLAGS;
337 pbody = tmp_pbody;
338 tmp_pgp_pbody = tmp_pbody;
339 }
340 }
341
342 if (security & (SEC_ENCRYPT | SEC_AUTOCRYPT))
343 {
344 if (((WithCrypto & APPLICATION_SMIME) != 0) && (security & APPLICATION_SMIME))
345 {
346 tmp_pbody = crypt_smime_build_smime_entity(tmp_smime_pbody, keylist);
347 if (!tmp_pbody)
348 {
349 /* signed ? free it! */
350 goto bail;
351 }
352 /* free tmp_body if messages was signed AND encrypted ... */
353 if ((tmp_smime_pbody != e->body) && (tmp_smime_pbody != tmp_pbody))
354 {
355 /* detach and don't delete e->body,
356 * which tmp_smime_pbody->parts after signing. */
357 tmp_smime_pbody->parts = tmp_smime_pbody->parts->next;
358 e->body->next = NULL;
359 mutt_body_free(&tmp_smime_pbody);
360 }
361 pbody = tmp_pbody;
362 }
363
364 if (((WithCrypto & APPLICATION_PGP) != 0) && (security & APPLICATION_PGP))
365 {
366 pbody = crypt_pgp_encrypt_message(e, tmp_pgp_pbody, keylist, sign, &e->env->from);
367 if (!pbody)
368 {
369 /* did we perform a retainable signature? */
370 if (has_retainable_sig)
371 {
372 /* remove the outer multipart layer */
373 tmp_pgp_pbody = mutt_remove_multipart(tmp_pgp_pbody);
374 /* get rid of the signature */
375 mutt_body_free(&tmp_pgp_pbody->next);
376 }
377
378 goto bail;
379 }
380
381 // destroy temporary signature envelope when doing retainable signatures.
382 if (has_retainable_sig)
383 {
384 tmp_pgp_pbody = mutt_remove_multipart(tmp_pgp_pbody);
385 mutt_body_free(&tmp_pgp_pbody->next);
386 }
387 }
388 }
389
390 if (pbody)
391 {
392 e->body = pbody;
393 return 0;
394 }
395
396bail:
398 mutt_param_delete(&e->body->parameter, "protected-headers");
399 return -1;
400}
void mutt_addr_free(struct Address **ptr)
Free a single Address.
Definition address.c:462
const struct Address * cs_subset_address(const struct ConfigSubset *sub, const char *name)
Get an Address config item by name.
int mutt_autocrypt_generate_gossip_list(struct Email *e)
Create the gossip list headers.
Definition autocrypt.c:823
struct Body * crypt_smime_build_smime_entity(struct Body *b, char *certlist)
Wrapper for CryptModuleSpecs::smime_build_smime_entity()
Definition cryptglue.c:496
struct Body * crypt_smime_sign_message(struct Body *b, const struct AddressList *from)
Wrapper for CryptModuleSpecs::sign_message()
Definition cryptglue.c:485
struct Body * crypt_pgp_traditional_encryptsign(struct Body *b, SecurityFlags flags, char *keylist)
Wrapper for CryptModuleSpecs::pgp_traditional_encryptsign()
Definition cryptglue.c:293
struct Body * crypt_pgp_sign_message(struct Body *b, const struct AddressList *from)
Wrapper for CryptModuleSpecs::sign_message()
Definition cryptglue.c:326
void crypt_pgp_set_sender(const char *sender)
Wrapper for CryptModuleSpecs::set_sender()
Definition cryptglue.c:403
void crypt_smime_set_sender(const char *sender)
Wrapper for CryptModuleSpecs::set_sender()
Definition cryptglue.c:538
struct Body * crypt_pgp_encrypt_message(struct Email *e, struct Body *b, char *keylist, int sign, const struct AddressList *from)
Wrapper for CryptModuleSpecs::pgp_encrypt_message()
Definition cryptglue.c:337
void mutt_body_free(struct Body **ptr)
Free a Body.
Definition body.c:58
int mutt_env_to_intl(struct Envelope *env, const char **tag, char **err)
Convert an Envelope's Address fields to Punycode format.
Definition envelope.c:354
void mutt_env_free(struct Envelope **ptr)
Free an Envelope.
Definition envelope.c:125
struct Envelope * mutt_env_new(void)
Create a new Envelope.
Definition envelope.c:45
void mutt_env_set_subject(struct Envelope *env, const char *subj)
Set both subject and real_subj to subj.
Definition envelope.c:68
#define mutt_error(...)
Definition logging2.h:93
void mutt_list_copy_tail(struct ListHead *dst, const struct ListHead *src)
Copy a list into another list.
Definition list.c:275
struct Body * mutt_remove_multipart(struct Body *b)
Extract the multipart body if it exists.
Definition multipart.c:126
char * mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition string.c:282
void mutt_param_delete(struct ParameterList *pl, const char *attribute)
Delete a matching Parameter.
Definition parameter.c:143
void mutt_param_set(struct ParameterList *pl, const char *attribute, const char *value)
Set a Parameter.
Definition parameter.c:111
enum QuadOption query_quadoption(const char *prompt, struct ConfigSubset *sub, const char *name)
Ask the user a quad-question.
Definition question.c:377
struct Address * mutt_default_from(struct ConfigSubset *sub)
Get a default 'from' Address.
Definition send.c:1393
void mutt_prepare_envelope(struct Envelope *env, bool final, struct ConfigSubset *sub)
Prepare an email header.
Definition sendlib.c:779
An email address.
Definition address.h:35
struct Buffer * mailbox
Mailbox and host address.
Definition address.h:37
The body of an email.
Definition body.h:36
struct Envelope * mime_headers
Memory hole protected headers.
Definition body.h:76
struct Body * body
List of MIME parts.
Definition email.h:69
The header of an Email.
Definition envelope.h:57
struct AddressList return_path
Return path for the Email.
Definition envelope.h:58
char *const subject
Email's subject.
Definition envelope.h:70
struct AddressList reply_to
Email's 'reply-to'.
Definition envelope.h:64
char * message_id
Message ID.
Definition envelope.h:73
struct AddressList x_original_to
Email's 'X-Original-to'.
Definition envelope.h:66
struct AddressList mail_followup_to
Email's 'mail-followup-to'.
Definition envelope.h:65
struct ListHead references
message references (in reverse order)
Definition envelope.h:83
struct ListHead in_reply_to
in-reply-to header content
Definition envelope.h:84
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_should_hide_protected_subject()

bool mutt_should_hide_protected_subject ( struct Email * e)

Should NeoMutt hide the protected subject?

Parameters
eEmail to test
Return values
trueThe subject should be protected

Definition at line 1100 of file crypt.c.

1101{
1102 const bool c_crypt_protected_headers_write = cs_subset_bool(NeoMutt->sub, "crypt_protected_headers_write");
1103 const char *const c_crypt_protected_headers_subject =
1104 cs_subset_string(NeoMutt->sub, "crypt_protected_headers_subject");
1105 if (c_crypt_protected_headers_write && (e->security & (SEC_ENCRYPT | SEC_AUTOCRYPT)) &&
1106 !(e->security & SEC_INLINE) && c_crypt_protected_headers_subject)
1107 {
1108 return true;
1109 }
1110
1111 return false;
1112}
#define SEC_INLINE
Email has an inline signature.
Definition lib.h:91
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ crypt_cleanup()

void crypt_cleanup ( void )

Clean up backend.

Definition at line 141 of file cryptglue.c.

142{
143 if (CRYPT_MOD_CALL_CHECK(PGP, cleanup))
144 (CRYPT_MOD_CALL(PGP, cleanup))();
145
146 if (CRYPT_MOD_CALL_CHECK(SMIME, cleanup))
147 (CRYPT_MOD_CALL(SMIME, cleanup))();
148}
#define CRYPT_MOD_CALL_CHECK(identifier, func)
Definition cryptglue.c:79
#define CRYPT_MOD_CALL(identifier, func)
Definition cryptglue.c:85
+ Here is the caller graph for this function:

◆ crypt_has_module_backend()

bool crypt_has_module_backend ( SecurityFlags type)

Is there a crypto backend for a given type?

Parameters
typeCrypto type, see SecurityFlags
Return values
trueBackend is present
falseBackend is not present

Definition at line 170 of file cryptglue.c.

171{
172 if (((WithCrypto & APPLICATION_PGP) != 0) && (type & APPLICATION_PGP) &&
174 {
175 return true;
176 }
177
178 if (((WithCrypto & APPLICATION_SMIME) != 0) && (type & APPLICATION_SMIME) &&
180 {
181 return true;
182 }
183
184 return false;
185}
const struct CryptModuleSpecs * crypto_module_lookup(int identifier)
Lookup a crypto module by name.
Definition crypt_mod.c:68
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ crypt_init()

void crypt_init ( void )

Initialise the crypto backends.

This calls CryptModuleSpecs::init()

Definition at line 93 of file cryptglue.c.

94{
95#ifdef CRYPT_BACKEND_GPGME
96 const bool c_crypt_use_gpgme = cs_subset_bool(NeoMutt->sub, "crypt_use_gpgme");
97#endif
98#ifdef CRYPT_BACKEND_CLASSIC_PGP
99 if (
100#ifdef CRYPT_BACKEND_GPGME
101 (!c_crypt_use_gpgme)
102#else
103 1
104#endif
105 )
107#endif
108
109#ifdef CRYPT_BACKEND_CLASSIC_SMIME
110 if (
111#ifdef CRYPT_BACKEND_GPGME
112 (!c_crypt_use_gpgme)
113#else
114 1
115#endif
116 )
118#endif
119
120#ifdef CRYPT_BACKEND_GPGME
121 if (c_crypt_use_gpgme)
122 {
125 }
126#endif
127
128#if defined(CRYPT_BACKEND_CLASSIC_PGP) || \
129 defined(CRYPT_BACKEND_CLASSIC_SMIME) || defined(CRYPT_BACKEND_GPGME)
130 if (CRYPT_MOD_CALL_CHECK(PGP, init))
131 CRYPT_MOD_CALL(PGP, init)();
132
133 if (CRYPT_MOD_CALL_CHECK(SMIME, init))
134 CRYPT_MOD_CALL(SMIME, init)();
135#endif
136}
void crypto_module_register(const struct CryptModuleSpecs *specs)
Register a new crypto module.
Definition crypt_mod.c:54
const struct CryptModuleSpecs CryptModSmimeGpgme
GPGME SMIME - Implements CryptModuleSpecs -.
const struct CryptModuleSpecs CryptModSmimeClassic
CLI SMIME - Implements CryptModuleSpecs -.
const struct CryptModuleSpecs CryptModPgpGpgme
GPGME PGP - Implements CryptModuleSpecs -.
const struct CryptModuleSpecs CryptModPgpClassic
CLI PGP - Implements CryptModuleSpecs -.
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ crypt_invoke_message()

void crypt_invoke_message ( SecurityFlags type)

Display an informative message.

Parameters
typeCrypto type, see SecurityFlags

Show a message that a backend will be invoked.

Definition at line 156 of file cryptglue.c.

157{
158 if (((WithCrypto & APPLICATION_PGP) != 0) && (type & APPLICATION_PGP))
159 mutt_message(_("Invoking PGP..."));
160 else if (((WithCrypto & APPLICATION_SMIME) != 0) && (type & APPLICATION_SMIME))
161 mutt_message(_("Invoking S/MIME..."));
162}
+ Here is the caller graph for this function:

◆ crypt_pgp_check_traditional()

bool crypt_pgp_check_traditional ( FILE * fp,
struct Body * b,
bool just_one )

Wrapper for CryptModuleSpecs::pgp_check_traditional()

Definition at line 282 of file cryptglue.c.

283{
284 if (CRYPT_MOD_CALL_CHECK(PGP, pgp_check_traditional))
285 return CRYPT_MOD_CALL(PGP, pgp_check_traditional)(fp, b, just_one);
286
287 return false;
288}
+ Here is the caller graph for this function:

◆ crypt_pgp_decrypt_mime()

int crypt_pgp_decrypt_mime ( FILE * fp_in,
FILE ** fp_out,
struct Body * b,
struct Body ** b_dec )

Wrapper for CryptModuleSpecs::decrypt_mime()

Definition at line 210 of file cryptglue.c.

211{
212#ifdef USE_AUTOCRYPT
213 const bool c_autocrypt = cs_subset_bool(NeoMutt->sub, "autocrypt");
214 if (c_autocrypt)
215 {
216 OptAutocryptGpgme = true;
217 int result = pgp_gpgme_decrypt_mime(fp_in, fp_out, b, b_dec);
218 OptAutocryptGpgme = false;
219 if (result == 0)
220 {
221 b->is_autocrypt = true;
222 return result;
223 }
224 }
225#endif
226
227 if (CRYPT_MOD_CALL_CHECK(PGP, decrypt_mime))
228 return CRYPT_MOD_CALL(PGP, decrypt_mime)(fp_in, fp_out, b, b_dec);
229
230 return -1;
231}
bool OptAutocryptGpgme
(pseudo) use Autocrypt context inside ncrypt/crypt_gpgme.c
Definition globals.c:55
int pgp_gpgme_decrypt_mime(FILE *fp_in, FILE **fp_out, struct Body *b, struct Body **b_dec)
Decrypt an encrypted MIME part - Implements CryptModuleSpecs::decrypt_mime() -.
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ crypt_pgp_extract_key_from_attachment()

void crypt_pgp_extract_key_from_attachment ( FILE * fp,
struct Body * b )

Wrapper for CryptModuleSpecs::pgp_extract_key_from_attachment()

Definition at line 394 of file cryptglue.c.

395{
396 if (CRYPT_MOD_CALL_CHECK(PGP, pgp_extract_key_from_attachment))
397 CRYPT_MOD_CALL(PGP, pgp_extract_key_from_attachment)(fp, b);
398}
+ Here is the caller graph for this function:

◆ crypt_pgp_invoke_getkeys()

void crypt_pgp_invoke_getkeys ( struct Address * addr)

Wrapper for CryptModuleSpecs::pgp_invoke_getkeys()

Definition at line 273 of file cryptglue.c.

274{
275 if (CRYPT_MOD_CALL_CHECK(PGP, pgp_invoke_getkeys))
276 CRYPT_MOD_CALL(PGP, pgp_invoke_getkeys)(addr);
277}
+ Here is the caller graph for this function:

◆ crypt_pgp_make_key_attachment()

struct Body * crypt_pgp_make_key_attachment ( void )

Wrapper for CryptModuleSpecs::pgp_make_key_attachment()

Definition at line 304 of file cryptglue.c.

305{
306 if (CRYPT_MOD_CALL_CHECK(PGP, pgp_make_key_attachment))
307 return CRYPT_MOD_CALL(PGP, pgp_make_key_attachment)();
308
309 return NULL;
310}
+ Here is the caller graph for this function:

◆ crypt_pgp_send_menu()

SecurityFlags crypt_pgp_send_menu ( struct Email * e)

Wrapper for CryptModuleSpecs::send_menu()

Definition at line 383 of file cryptglue.c.

384{
385 if (CRYPT_MOD_CALL_CHECK(PGP, send_menu))
386 return CRYPT_MOD_CALL(PGP, send_menu)(e);
387
388 return 0;
389}
+ Here is the caller graph for this function:

◆ crypt_smime_decrypt_mime()

int crypt_smime_decrypt_mime ( FILE * fp_in,
FILE ** fp_out,
struct Body * b,
struct Body ** b_dec )

Wrapper for CryptModuleSpecs::decrypt_mime()

Definition at line 432 of file cryptglue.c.

433{
434 if (CRYPT_MOD_CALL_CHECK(SMIME, decrypt_mime))
435 return CRYPT_MOD_CALL(SMIME, decrypt_mime)(fp_in, fp_out, b, b_dec);
436
437 return -1;
438}
+ Here is the caller graph for this function:

◆ crypt_smime_getkeys()

void crypt_smime_getkeys ( struct Envelope * env)

Wrapper for CryptModuleSpecs::smime_getkeys()

Definition at line 454 of file cryptglue.c.

455{
456 if (CRYPT_MOD_CALL_CHECK(SMIME, smime_getkeys))
457 CRYPT_MOD_CALL(SMIME, smime_getkeys)(env);
458}
+ Here is the caller graph for this function:

◆ crypt_smime_send_menu()

SecurityFlags crypt_smime_send_menu ( struct Email * e)

Wrapper for CryptModuleSpecs::send_menu()

Definition at line 527 of file cryptglue.c.

528{
529 if (CRYPT_MOD_CALL_CHECK(SMIME, send_menu))
530 return CRYPT_MOD_CALL(SMIME, send_menu)(e);
531
532 return 0;
533}
+ Here is the caller graph for this function:

◆ crypt_smime_verify_sender()

int crypt_smime_verify_sender ( struct Email * e,
struct Message * msg )

Wrapper for CryptModuleSpecs::smime_verify_sender()

Definition at line 463 of file cryptglue.c.

464{
465 if (CRYPT_MOD_CALL_CHECK(SMIME, smime_verify_sender))
466 return CRYPT_MOD_CALL(SMIME, smime_verify_sender)(e, msg);
467
468 return 1;
469}
+ Here is the caller graph for this function:

◆ crypto_module_cleanup()

void crypto_module_cleanup ( void )

Clean up the crypto modules.

Definition at line 84 of file crypt_mod.c.

85{
86 struct CryptModule *np = NULL, *tmp = NULL;
87 STAILQ_FOREACH_SAFE(np, &CryptModules, entries, tmp)
88 {
90 FREE(&np);
91 }
92}
static struct CryptModuleList CryptModules
Linked list of crypto modules, e.g. CryptModSmimeClassic, CryptModPgpGpgme.
Definition crypt_mod.c:48
#define STAILQ_REMOVE(head, elm, type, field)
Definition queue.h:441
#define STAILQ_FOREACH_SAFE(var, head, field, tvar)
Definition queue.h:400
A crypto plugin module.
Definition crypt_mod.c:41
+ Here is the caller graph for this function:

◆ mutt_gpgme_select_secret_key()

int mutt_gpgme_select_secret_key ( struct Buffer * keyid)

Select a private Autocrypt key for a new account.

Parameters
keyidAutocrypt Key id
Return values
0Success
-1Error

Unfortunately, the internal ncrypt/crypt_gpgme.c functions use CryptKeyInfo, and so aren't exportable.

This function queries all private keys, provides the crypt_select_keys() menu, and returns the selected key fingerprint in keyid.

Definition at line 3683 of file crypt_gpgme.c.

3684{
3685 int rc = -1;
3686 gpgme_error_t err = GPG_ERR_NO_ERROR;
3687 gpgme_key_t key = NULL;
3688 gpgme_user_id_t uid = NULL;
3689 struct CryptKeyInfo *results = NULL, *k = NULL;
3690 struct CryptKeyInfo **kend = NULL;
3691 struct CryptKeyInfo *choice = NULL;
3692
3693 gpgme_ctx_t ctx = create_gpgme_context(false);
3694
3695 /* list all secret keys */
3696 if (gpgme_op_keylist_start(ctx, NULL, 1))
3697 goto cleanup;
3698
3699 kend = &results;
3700
3701 while ((err = gpgme_op_keylist_next(ctx, &key)) == GPG_ERR_NO_ERROR)
3702 {
3704
3709
3710 if (key->revoked)
3712 if (key->expired)
3714 if (key->disabled)
3716
3717 int idx;
3718 for (idx = 0, uid = key->uids; uid; idx++, uid = uid->next)
3719 {
3720 k = MUTT_MEM_CALLOC(1, struct CryptKeyInfo);
3721 k->kobj = key;
3722 gpgme_key_ref(k->kobj);
3723 k->idx = idx;
3724 k->uid = uid->uid;
3725 k->flags = flags;
3726 if (uid->revoked)
3727 k->flags |= KEYFLAG_REVOKED;
3728 k->validity = uid->validity;
3729 *kend = k;
3730 kend = &k->next;
3731 }
3732 gpgme_key_unref(key);
3733 }
3734 if (gpg_err_code(err) != GPG_ERR_EOF)
3735 mutt_error(_("gpgme_op_keylist_next failed: %s"), gpgme_strerror(err));
3736 gpgme_op_keylist_end(ctx);
3737
3738 if (!results)
3739 {
3740 /* L10N: mutt_gpgme_select_secret_key() tries to list all secret keys to choose
3741 from. This error is displayed if no results were found. */
3742 mutt_error(_("No secret keys found"));
3743 goto cleanup;
3744 }
3745
3746 choice = dlg_gpgme(results, NULL, "*", APPLICATION_PGP, NULL);
3747 if (!(choice && choice->kobj && choice->kobj->subkeys && choice->kobj->subkeys->fpr))
3748 goto cleanup;
3749 buf_strcpy(keyid, choice->kobj->subkeys->fpr);
3750
3751 rc = 0;
3752
3753cleanup:
3754 crypt_key_free(&choice);
3755 crypt_key_free(&results);
3756 gpgme_release(ctx);
3757 return rc;
3758}
size_t buf_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition buffer.c:395
gpgme_ctx_t create_gpgme_context(bool for_smime)
Create a new GPGME context.
unsigned int key_check_cap(gpgme_key_t key, enum KeyCap cap)
Check the capabilities of a key.
static void crypt_key_free(struct CryptKeyInfo **keylist)
Release all the keys in a list.
@ KEY_CAP_CAN_ENCRYPT
Key can be used for encryption.
Definition crypt_gpgme.h:77
@ KEY_CAP_CAN_SIGN
Key can be used for signing.
Definition crypt_gpgme.h:78
struct CryptKeyInfo * dlg_gpgme(struct CryptKeyInfo *keys, struct Address *p, const char *s, unsigned int app, bool *forced_valid)
Get the user to select a key -.
Definition dlg_gpgme.c:194
#define MUTT_MEM_CALLOC(n, type)
Definition memory.h:47
#define KEYFLAG_EXPIRED
Key is expired.
Definition lib.h:137
uint16_t KeyFlags
Flags describing PGP/SMIME keys, e.g. KEYFLAG_CANSIGN.
Definition lib.h:131
#define KEYFLAG_CANENCRYPT
Key is suitable for encryption.
Definition lib.h:134
#define KEYFLAG_NO_FLAGS
No flags are set.
Definition lib.h:132
#define KEYFLAG_DISABLED
Key is marked disabled.
Definition lib.h:139
#define KEYFLAG_REVOKED
Key is revoked.
Definition lib.h:138
#define KEYFLAG_CANSIGN
Key is suitable for signing.
Definition lib.h:133
A stored PGP key.
Definition crypt_gpgme.h:44
KeyFlags flags
global and per uid flags (for convenience)
Definition crypt_gpgme.h:49
int idx
and the user ID at this index
Definition crypt_gpgme.h:47
struct CryptKeyInfo * next
Linked list.
Definition crypt_gpgme.h:45
const char * uid
and for convenience point to this user ID
Definition crypt_gpgme.h:48
gpgme_key_t kobj
Definition crypt_gpgme.h:46
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_gpgme_print_version()

const char * mutt_gpgme_print_version ( void )

Get version of GPGME.

Return values
ptrGPGME version string

Definition at line 4161 of file crypt_gpgme.c.

4162{
4163 return GPGME_VERSION;
4164}
+ Here is the caller graph for this function: