NeoMutt  2022-04-29-249-gaae397
Teaching an old dog new tricks
DOXYGEN
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. More...
 
#define SEC_ENCRYPT   (1 << 0)
 Email is encrypted. More...
 
#define SEC_SIGN   (1 << 1)
 Email is signed. More...
 
#define SEC_GOODSIGN   (1 << 2)
 Email has a valid signature. More...
 
#define SEC_BADSIGN   (1 << 3)
 Email has a bad signature. More...
 
#define SEC_PARTSIGN   (1 << 4)
 Not all parts of the email is signed. More...
 
#define SEC_SIGNOPAQUE   (1 << 5)
 Email has an opaque signature (encrypted) More...
 
#define SEC_KEYBLOCK   (1 << 6)
 Email has a key attached. More...
 
#define SEC_INLINE   (1 << 7)
 Email has an inline signature. More...
 
#define SEC_OPPENCRYPT   (1 << 8)
 Opportunistic encrypt mode. More...
 
#define SEC_AUTOCRYPT   (1 << 9)
 (Autocrypt) Message will be, or was Autocrypt encrypt+signed More...
 
#define SEC_AUTOCRYPT_OVERRIDE   (1 << 10)
 (Autocrypt) Indicates manual set/unset of encryption More...
 
#define APPLICATION_PGP   (1 << 11)
 Use PGP to encrypt/sign. More...
 
#define APPLICATION_SMIME   (1 << 12)
 Use SMIME to encrypt/sign. More...
 
#define PGP_TRADITIONAL_CHECKED   (1 << 13)
 Email has a traditional (inline) signature. More...
 
#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. More...
 
#define KEYFLAG_CANSIGN   (1 << 0)
 Key is suitable for signing. More...
 
#define KEYFLAG_CANENCRYPT   (1 << 1)
 Key is suitable for encryption. More...
 
#define KEYFLAG_ISX509   (1 << 2)
 Key is an X.509 key. More...
 
#define KEYFLAG_SECRET   (1 << 7)
 Key is a secret key. More...
 
#define KEYFLAG_EXPIRED   (1 << 8)
 Key is expired. More...
 
#define KEYFLAG_REVOKED   (1 << 9)
 Key is revoked. More...
 
#define KEYFLAG_DISABLED   (1 << 10)
 Key is marked disabled. More...
 
#define KEYFLAG_SUBKEY   (1 << 11)
 Key is a subkey. More...
 
#define KEYFLAG_CRITICAL   (1 << 12)
 Key is marked critical. More...
 
#define KEYFLAG_PREFER_ENCRYPTION   (1 << 13)
 Key's owner prefers encryption. More...
 
#define KEYFLAG_PREFER_SIGNING   (1 << 14)
 Key's owner prefers signing. More...
 
#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. More...
 
typedef uint16_t KeyFlags
 Flags describing PGP/SMIME keys, e.g. KEYFLAG_CANSIGN. More...
 

Functions

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

Detailed Description

API for encryption/signing of emails.

Authors
  • Werner Koch
  • g10code GmbH
  • 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 77 of file lib.h.

◆ SEC_ENCRYPT

#define SEC_ENCRYPT   (1 << 0)

Email is encrypted.

Definition at line 78 of file lib.h.

◆ SEC_SIGN

#define SEC_SIGN   (1 << 1)

Email is signed.

Definition at line 79 of file lib.h.

◆ SEC_GOODSIGN

#define SEC_GOODSIGN   (1 << 2)

Email has a valid signature.

Definition at line 80 of file lib.h.

◆ SEC_BADSIGN

#define SEC_BADSIGN   (1 << 3)

Email has a bad signature.

Definition at line 81 of file lib.h.

◆ SEC_PARTSIGN

#define SEC_PARTSIGN   (1 << 4)

Not all parts of the email is signed.

Definition at line 82 of file lib.h.

◆ SEC_SIGNOPAQUE

#define SEC_SIGNOPAQUE   (1 << 5)

Email has an opaque signature (encrypted)

Definition at line 83 of file lib.h.

◆ SEC_KEYBLOCK

#define SEC_KEYBLOCK   (1 << 6)

Email has a key attached.

Definition at line 84 of file lib.h.

◆ SEC_INLINE

#define SEC_INLINE   (1 << 7)

Email has an inline signature.

Definition at line 85 of file lib.h.

◆ SEC_OPPENCRYPT

#define SEC_OPPENCRYPT   (1 << 8)

Opportunistic encrypt mode.

Definition at line 86 of file lib.h.

◆ SEC_AUTOCRYPT

#define SEC_AUTOCRYPT   (1 << 9)

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

Definition at line 87 of file lib.h.

◆ SEC_AUTOCRYPT_OVERRIDE

#define SEC_AUTOCRYPT_OVERRIDE   (1 << 10)

(Autocrypt) Indicates manual set/unset of encryption

Definition at line 88 of file lib.h.

◆ APPLICATION_PGP

#define APPLICATION_PGP   (1 << 11)

Use PGP to encrypt/sign.

Definition at line 90 of file lib.h.

◆ APPLICATION_SMIME

#define APPLICATION_SMIME   (1 << 12)

Use SMIME to encrypt/sign.

Definition at line 91 of file lib.h.

◆ PGP_TRADITIONAL_CHECKED

#define PGP_TRADITIONAL_CHECKED   (1 << 13)

Email has a traditional (inline) signature.

Definition at line 92 of file lib.h.

◆ SEC_ALL_FLAGS

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

Definition at line 94 of file lib.h.

◆ PGP_ENCRYPT

#define PGP_ENCRYPT   (APPLICATION_PGP | SEC_ENCRYPT)

Definition at line 96 of file lib.h.

◆ PGP_SIGN

#define PGP_SIGN   (APPLICATION_PGP | SEC_SIGN)

Definition at line 97 of file lib.h.

◆ PGP_GOODSIGN

#define PGP_GOODSIGN   (APPLICATION_PGP | SEC_GOODSIGN)

Definition at line 98 of file lib.h.

◆ PGP_KEY

#define PGP_KEY   (APPLICATION_PGP | SEC_KEYBLOCK)

Definition at line 99 of file lib.h.

◆ PGP_INLINE

#define PGP_INLINE   (APPLICATION_PGP | SEC_INLINE)

Definition at line 100 of file lib.h.

◆ SMIME_ENCRYPT

#define SMIME_ENCRYPT   (APPLICATION_SMIME | SEC_ENCRYPT)

Definition at line 102 of file lib.h.

◆ SMIME_SIGN

#define SMIME_SIGN   (APPLICATION_SMIME | SEC_SIGN)

Definition at line 103 of file lib.h.

◆ SMIME_GOODSIGN

#define SMIME_GOODSIGN   (APPLICATION_SMIME | SEC_GOODSIGN)

Definition at line 104 of file lib.h.

◆ SMIME_BADSIGN

#define SMIME_BADSIGN   (APPLICATION_SMIME | SEC_BADSIGN)

Definition at line 105 of file lib.h.

◆ SMIME_OPAQUE

#define SMIME_OPAQUE   (APPLICATION_SMIME | SEC_SIGNOPAQUE)

Definition at line 106 of file lib.h.

◆ WithCrypto

#define WithCrypto   (APPLICATION_PGP | APPLICATION_SMIME)

Definition at line 116 of file lib.h.

◆ KEYFLAG_NO_FLAGS

#define KEYFLAG_NO_FLAGS   0

No flags are set.

Definition at line 126 of file lib.h.

◆ KEYFLAG_CANSIGN

#define KEYFLAG_CANSIGN   (1 << 0)

Key is suitable for signing.

Definition at line 127 of file lib.h.

◆ KEYFLAG_CANENCRYPT

#define KEYFLAG_CANENCRYPT   (1 << 1)

Key is suitable for encryption.

Definition at line 128 of file lib.h.

◆ KEYFLAG_ISX509

#define KEYFLAG_ISX509   (1 << 2)

Key is an X.509 key.

Definition at line 129 of file lib.h.

◆ KEYFLAG_SECRET

#define KEYFLAG_SECRET   (1 << 7)

Key is a secret key.

Definition at line 130 of file lib.h.

◆ KEYFLAG_EXPIRED

#define KEYFLAG_EXPIRED   (1 << 8)

Key is expired.

Definition at line 131 of file lib.h.

◆ KEYFLAG_REVOKED

#define KEYFLAG_REVOKED   (1 << 9)

Key is revoked.

Definition at line 132 of file lib.h.

◆ KEYFLAG_DISABLED

#define KEYFLAG_DISABLED   (1 << 10)

Key is marked disabled.

Definition at line 133 of file lib.h.

◆ KEYFLAG_SUBKEY

#define KEYFLAG_SUBKEY   (1 << 11)

Key is a subkey.

Definition at line 134 of file lib.h.

◆ KEYFLAG_CRITICAL

#define KEYFLAG_CRITICAL   (1 << 12)

Key is marked critical.

Definition at line 135 of file lib.h.

◆ KEYFLAG_PREFER_ENCRYPTION

#define KEYFLAG_PREFER_ENCRYPTION   (1 << 13)

Key's owner prefers encryption.

Definition at line 136 of file lib.h.

◆ KEYFLAG_PREFER_SIGNING

#define KEYFLAG_PREFER_SIGNING   (1 << 14)

Key's owner prefers signing.

Definition at line 137 of file lib.h.

◆ KEYFLAG_CANTUSE

#define KEYFLAG_CANTUSE   (KEYFLAG_DISABLED | KEYFLAG_REVOKED | KEYFLAG_EXPIRED)

Definition at line 139 of file lib.h.

◆ KEYFLAG_RESTRICTIONS

#define KEYFLAG_RESTRICTIONS   (KEYFLAG_CANTUSE | KEYFLAG_CRITICAL)

Definition at line 140 of file lib.h.

◆ KEYFLAG_ABILITIES

Definition at line 142 of file lib.h.

Typedef Documentation

◆ SecurityFlags

typedef uint16_t SecurityFlags

Flags, e.g. SEC_ENCRYPT.

Definition at line 76 of file lib.h.

◆ KeyFlags

typedef uint16_t KeyFlags

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

Definition at line 125 of file lib.h.

Function Documentation

◆ crypt_extract_keys_from_messages()

void crypt_extract_keys_from_messages ( struct Mailbox m,
struct EmailList *  el 
)

Extract keys from a message.

Parameters
mMailbox
elList of Emails to process

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

Definition at line 838 of file crypt.c.

839{
840 if (!WithCrypto)
841 return;
842
843 struct Buffer *tempfname = mutt_buffer_pool_get();
844 mutt_buffer_mktemp(tempfname);
845 FILE *fp_out = mutt_file_fopen(mutt_buffer_string(tempfname), "w");
846 if (!fp_out)
847 {
849 goto cleanup;
850 }
851
854
855 struct EmailNode *en = NULL;
856 STAILQ_FOREACH(en, el, entries)
857 {
858 struct Email *e = en->email;
859 struct Message *msg = mx_msg_open(m, e->msgno);
860 if (!msg)
861 {
862 continue;
863 }
866 {
867 mx_msg_close(m, &msg);
868 mutt_file_fclose(&fp_out);
869 break;
870 }
871
872 if (((WithCrypto & APPLICATION_PGP) != 0) && (e->security & APPLICATION_PGP))
873 {
875 fflush(fp_out);
876
877 mutt_endwin();
878 puts(_("Trying to extract PGP keys...\n"));
880 }
881
883 {
884 const bool encrypt = e->security & SEC_ENCRYPT;
885 mutt_copy_message(fp_out, e, msg,
888 CH_NO_FLAGS, 0);
889 fflush(fp_out);
890
891 char *mbox = NULL;
892 if (!TAILQ_EMPTY(&e->env->from))
893 {
895 mbox = TAILQ_FIRST(&e->env->from)->mailbox;
896 }
897 else if (!TAILQ_EMPTY(&e->env->sender))
898 {
900 mbox = TAILQ_FIRST(&e->env->sender)->mailbox;
901 }
902 if (mbox)
903 {
904 mutt_endwin();
905 puts(_("Trying to extract S/MIME certificates..."));
907 }
908 }
909 mx_msg_close(m, &msg);
910
911 rewind(fp_out);
912 }
913
914 mutt_file_fclose(&fp_out);
915 if (isendwin())
917
919
921 OptDontHandlePgpKeys = false;
922
923cleanup:
924 mutt_buffer_pool_release(&tempfname);
925}
void mutt_expand_aliases(struct AddressList *al)
Expand aliases in a List of Addresses.
Definition: alias.c:298
void mutt_parse_mime_message(struct Email *e, FILE *fp)
Parse a MIME email.
Definition: attachments.c:591
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:77
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:864
#define MUTT_CM_DECODE
Decode the message body into text/plain.
Definition: copy.h:38
#define MUTT_CM_CHARCONV
Perform character set conversions.
Definition: copy.h:42
#define MUTT_CM_DECODE_SMIME
Used for decoding S/MIME messages.
Definition: copy.h:46
#define MUTT_CM_NO_FLAGS
No flags are set.
Definition: copy.h:35
#define MUTT_CM_DECODE_CRYPT
Definition: copy.h:48
#define MUTT_CM_NOHEADER
Don't copy the message header.
Definition: copy.h:36
#define CH_NO_FLAGS
No flags are set.
Definition: copy.h:51
bool crypt_valid_passphrase(SecurityFlags flags)
Check that we have a usable passphrase, ask if not.
Definition: crypt.c:134
void crypt_pgp_invoke_import(const char *fname)
Wrapper for CryptModuleSpecs::pgp_invoke_import()
Definition: cryptglue.c:364
void crypt_smime_invoke_import(const char *infile, const char *mailbox)
Wrapper for CryptModuleSpecs::smime_invoke_import()
Definition: cryptglue.c:508
int mutt_any_key_to_continue(const char *s)
Prompt the user to 'press any key' and wait.
Definition: curs_lib.c:387
void mutt_endwin(void)
Shutdown curses.
Definition: curs_lib.c:354
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:618
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:152
void mutt_file_unlink(const char *s)
Delete a file, carefully.
Definition: file.c:194
#define mutt_perror(...)
Definition: logging.h:88
#define _(a)
Definition: message.h:28
#define mutt_buffer_mktemp(buf)
Definition: muttlib.h:74
int mx_msg_close(struct Mailbox *m, struct Message **msg)
Close a message.
Definition: mx.c:1193
struct Message * mx_msg_open(struct Mailbox *m, int msgno)
Return a stream pointer for a message.
Definition: mx.c:1147
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: lib.h:90
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: lib.h:91
#define SEC_ENCRYPT
Email is encrypted.
Definition: lib.h:78
#define WithCrypto
Definition: lib.h:116
bool OptDontHandlePgpKeys
(pseudo) used to extract PGP keys
Definition: options.h:41
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:352
#define TAILQ_FIRST(head)
Definition: queue.h:723
#define TAILQ_EMPTY(head)
Definition: queue.h:721
String manipulation buffer.
Definition: buffer.h:34
List of Emails.
Definition: email.h:132
struct Email * email
Email in the list.
Definition: email.h:133
The envelope/body of an email.
Definition: email.h:37
struct Envelope * env
Envelope information.
Definition: email.h:66
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/lib.h pgplib....
Definition: email.h:41
int msgno
Number displayed to the user.
Definition: email.h:111
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: mxapi.h:43
FILE * fp
pointer to the message data
Definition: mxapi.h:44
+ 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 92 of file crypt.c.

93{
96
99
100 if (WithCrypto)
101 {
102 /* L10N: Due to the implementation details (e.g. some passwords are managed
103 by gpg-agent) we can't know whether we forgot zero, 1, 12, ...
104 passwords. So in English we use "Passphrases". Your language might
105 have other means to express this. */
106 mutt_message(_("Passphrases forgotten"));
107 }
108}
void crypt_smime_void_passphrase(void)
Wrapper for CryptModuleSpecs::void_passphrase()
Definition: cryptglue.c:413
void crypt_pgp_void_passphrase(void)
Wrapper for CryptModuleSpecs::void_passphrase()
Definition: cryptglue.c:191
#define mutt_message(...)
Definition: logging.h:86
+ 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 941 of file crypt.c.

942{
943 if (!WithCrypto)
944 return 0;
945
946 struct AddressList addrlist = TAILQ_HEAD_INITIALIZER(addrlist);
947 const char *fqdn = mutt_fqdn(true, NeoMutt->sub);
948 const char *self_encrypt = NULL;
949
950 /* Do a quick check to make sure that we can find all of the encryption
951 * keys if the user has requested this service. */
952
953 *keylist = NULL;
954
955#ifdef USE_AUTOCRYPT
956 if (!oppenc_mode && (e->security & SEC_AUTOCRYPT))
957 {
959 return -1;
960 return 0;
961 }
962#endif
963
965 OptPgpCheckTrust = true;
966
967 mutt_addrlist_copy(&addrlist, &e->env->to, false);
968 mutt_addrlist_copy(&addrlist, &e->env->cc, false);
969 mutt_addrlist_copy(&addrlist, &e->env->bcc, false);
970 mutt_addrlist_qualify(&addrlist, fqdn);
971 mutt_addrlist_dedupe(&addrlist);
972
973 if (oppenc_mode || (e->security & SEC_ENCRYPT))
974 {
975 if (((WithCrypto & APPLICATION_PGP) != 0) && (e->security & APPLICATION_PGP))
976 {
977 *keylist = crypt_pgp_find_keys(&addrlist, oppenc_mode);
978 if (!*keylist)
979 {
980 mutt_addrlist_clear(&addrlist);
981 return -1;
982 }
983 OptPgpCheckTrust = false;
984 const bool c_pgp_self_encrypt = cs_subset_bool(NeoMutt->sub, "pgp_self_encrypt");
985 const char *const c_pgp_default_key = cs_subset_string(NeoMutt->sub, "pgp_default_key");
986 const enum QuadOption c_pgp_encrypt_self = cs_subset_quad(NeoMutt->sub, "pgp_encrypt_self");
987 if (c_pgp_self_encrypt || (c_pgp_encrypt_self == MUTT_YES))
988 self_encrypt = c_pgp_default_key;
989 }
991 {
992 *keylist = crypt_smime_find_keys(&addrlist, oppenc_mode);
993 if (!*keylist)
994 {
995 mutt_addrlist_clear(&addrlist);
996 return -1;
997 }
998 const bool c_smime_self_encrypt = cs_subset_bool(NeoMutt->sub, "smime_self_encrypt");
999 const char *const c_smime_default_key = cs_subset_string(NeoMutt->sub, "smime_default_key");
1000 const enum QuadOption c_smime_encrypt_self = cs_subset_quad(NeoMutt->sub, "smime_encrypt_self");
1001 if (c_smime_self_encrypt || (c_smime_encrypt_self == MUTT_YES))
1002 self_encrypt = c_smime_default_key;
1003 }
1004 }
1005
1006 if (!oppenc_mode && self_encrypt)
1007 {
1008 const size_t keylist_size = mutt_str_len(*keylist);
1009 mutt_mem_realloc(keylist, keylist_size + mutt_str_len(self_encrypt) + 2);
1010 sprintf(*keylist + keylist_size, " %s", self_encrypt);
1011 }
1012
1013 mutt_addrlist_clear(&addrlist);
1014
1015 return 0;
1016}
void mutt_addrlist_copy(struct AddressList *dst, const struct AddressList *src, bool prune)
Copy a list of addresses into another list.
Definition: address.c:737
void mutt_addrlist_qualify(struct AddressList *al, const char *host)
Expand local names in an Address list using a hostname.
Definition: address.c:650
void mutt_addrlist_clear(struct AddressList *al)
Unlink and free all Address in an AddressList.
Definition: address.c:1470
void mutt_addrlist_dedupe(struct AddressList *al)
Remove duplicate addresses.
Definition: address.c:1407
@ AUTOCRYPT_REC_NO
Do no use Autocrypt.
Definition: lib.h:159
enum AutocryptRec mutt_autocrypt_ui_recommendation(const struct Email *e, char **keylist)
Get the recommended action for an Email.
Definition: autocrypt.c:567
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:317
enum QuadOption cs_subset_quad(const struct ConfigSubset *sub, const char *name)
Get a quad-value config item by name.
Definition: helpers.c:218
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
char * crypt_smime_find_keys(struct AddressList *addrlist, bool oppenc_mode)
Wrapper for CryptModuleSpecs::find_keys()
Definition: cryptglue.c:475
char * crypt_pgp_find_keys(struct AddressList *addrlist, bool oppenc_mode)
Wrapper for CryptModuleSpecs::find_keys()
Definition: cryptglue.c:316
void mutt_mem_realloc(void *ptr, size_t size)
Resize a block of memory on the heap.
Definition: memory.c:114
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:567
#define SEC_AUTOCRYPT
(Autocrypt) Message will be, or was Autocrypt encrypt+signed
Definition: lib.h:87
bool OptPgpCheckTrust
(pseudo) used by dlg_select_pgp_key()
Definition: options.h:54
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:637
const char * mutt_fqdn(bool may_hide_host, const struct ConfigSubset *sub)
Get the Fully-Qualified Domain Name.
Definition: sendlib.c:698
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:37
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
+ 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 1025 of file crypt.c.

1026{
1027 if (!WithCrypto)
1028 return;
1029
1030 const bool c_crypt_opportunistic_encrypt = cs_subset_bool(NeoMutt->sub, "crypt_opportunistic_encrypt");
1031 if (!(c_crypt_opportunistic_encrypt && (e->security & SEC_OPPENCRYPT)))
1032 return;
1033
1034 char *pgpkeylist = NULL;
1035
1036 crypt_get_keys(e, &pgpkeylist, 1);
1037 if (pgpkeylist)
1038 {
1039 e->security |= SEC_ENCRYPT;
1040 FREE(&pgpkeylist);
1041 }
1042 else
1043 {
1044 e->security &= ~SEC_ENCRYPT;
1045 }
1046}
int crypt_get_keys(struct Email *e, char **keylist, bool oppenc_mode)
Check we have all the keys we need.
Definition: crypt.c:941
#define FREE(x)
Definition: memory.h:43
#define SEC_OPPENCRYPT
Opportunistic encrypt mode.
Definition: lib.h:86
+ 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 675 of file crypt.c.

676{
677 if (!WithCrypto || !b)
678 return SEC_NO_FLAGS;
679
681
682 if (b->type == TYPE_APPLICATION)
683 {
686
688 {
690 if (rc && b->goodsig)
691 rc |= SEC_GOODSIGN;
692 if (rc && b->badsig)
693 rc |= SEC_BADSIGN;
694 }
695 }
696 else if (((WithCrypto & APPLICATION_PGP) != 0) && (b->type == TYPE_TEXT))
697 {
699 if (rc && b->goodsig)
700 rc |= SEC_GOODSIGN;
701 }
702
703 if (b->type == TYPE_MULTIPART)
704 {
708
709 if (rc && b->goodsig)
710 rc |= SEC_GOODSIGN;
711#ifdef USE_AUTOCRYPT
712 if (rc && b->is_autocrypt)
713 rc |= SEC_AUTOCRYPT;
714#endif
715 }
716
717 if ((b->type == TYPE_MULTIPART) || (b->type == TYPE_MESSAGE))
718 {
719 SecurityFlags u = b->parts ? SEC_ALL_FLAGS : SEC_NO_FLAGS; /* Bits set in all parts */
720 SecurityFlags w = SEC_NO_FLAGS; /* Bits set in any part */
721
722 for (b = b->parts; b; b = b->next)
723 {
724 const SecurityFlags v = crypt_query(b);
725 u &= v;
726 w |= v;
727 }
728 rc |= u | (w & ~SEC_GOODSIGN);
729
730 if ((w & SEC_GOODSIGN) && !(u & SEC_GOODSIGN))
731 rc |= SEC_PARTSIGN;
732 }
733
734 return rc;
735}
SecurityFlags mutt_is_application_pgp(struct Body *b)
Does the message use PGP?
Definition: crypt.c:544
SecurityFlags mutt_is_multipart_signed(struct Body *b)
Is a message signed?
Definition: crypt.c:402
SecurityFlags mutt_is_application_smime(struct Body *b)
Does the message use S/MIME?
Definition: crypt.c:601
SecurityFlags mutt_is_multipart_encrypted(struct Body *b)
Does the message have encrypted parts?
Definition: crypt.c:439
SecurityFlags mutt_is_malformed_multipart_pgp_encrypted(struct Body *b)
Check for malformed layout.
Definition: crypt.c:500
SecurityFlags crypt_query(struct Body *b)
Check out the type of encryption used.
Definition: crypt.c:675
@ 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:76
#define SEC_ALL_FLAGS
Definition: lib.h:94
#define SEC_GOODSIGN
Email has a valid signature.
Definition: lib.h:80
#define SEC_BADSIGN
Email has a bad signature.
Definition: lib.h:81
#define SEC_NO_FLAGS
No flags are set.
Definition: lib.h:77
#define SEC_PARTSIGN
Not all parts of the email is signed.
Definition: lib.h:82
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:72
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:71
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 134 of file crypt.c.

135{
136 bool rc = false;
137
138#ifndef DEBUG
139 disable_coredumps();
140#endif
141
142 if (((WithCrypto & APPLICATION_PGP) != 0) && (flags & APPLICATION_PGP))
144
145 if (((WithCrypto & APPLICATION_SMIME) != 0) && (flags & APPLICATION_SMIME))
147
148 return rc;
149}
bool crypt_smime_valid_passphrase(void)
Wrapper for CryptModuleSpecs::valid_passphrase()
Definition: cryptglue.c:422
bool crypt_pgp_valid_passphrase(void)
Wrapper for CryptModuleSpecs::valid_passphrase()
Definition: cryptglue.c:200
+ 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 ( 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 544 of file crypt.c.

545{
547 char *p = NULL;
548
549 if (b->type == TYPE_APPLICATION)
550 {
551 if (mutt_istr_equal(b->subtype, "pgp") || mutt_istr_equal(b->subtype, "x-pgp-message"))
552 {
553 p = mutt_param_get(&b->parameter, "x-action");
554 if (p && (mutt_istr_equal(p, "sign") || mutt_istr_equal(p, "signclear")))
555 {
556 t |= PGP_SIGN;
557 }
558
559 p = mutt_param_get(&b->parameter, "format");
560 if (p && mutt_istr_equal(p, "keys-only"))
561 {
562 t |= PGP_KEY;
563 }
564
565 if (t == SEC_NO_FLAGS)
566 t |= PGP_ENCRYPT; /* not necessarily correct, but... */
567 }
568
569 if (mutt_istr_equal(b->subtype, "pgp-signed"))
570 t |= PGP_SIGN;
571
572 if (mutt_istr_equal(b->subtype, "pgp-keys"))
573 t |= PGP_KEY;
574 }
575 else if ((b->type == TYPE_TEXT) && mutt_istr_equal("plain", b->subtype))
576 {
577 if (((p = mutt_param_get(&b->parameter, "x-mutt-action")) ||
578 (p = mutt_param_get(&b->parameter, "x-action")) ||
579 (p = mutt_param_get(&b->parameter, "action"))) &&
580 mutt_istr_startswith(p, "pgp-sign"))
581 {
582 t |= PGP_SIGN;
583 }
584 else if (p && mutt_istr_startswith(p, "pgp-encrypt"))
585 t |= PGP_ENCRYPT;
586 else if (p && mutt_istr_startswith(p, "pgp-keys"))
587 t |= PGP_KEY;
588 }
589 if (t)
590 t |= PGP_INLINE;
591
592 return t;
593}
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:819
size_t mutt_istr_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix, ignoring case.
Definition: string.c:239
#define PGP_SIGN
Definition: lib.h:97
#define PGP_ENCRYPT
Definition: lib.h:96
#define PGP_INLINE
Definition: lib.h:100
#define PGP_KEY
Definition: lib.h:99
char * mutt_param_get(const struct ParameterList *pl, const char *s)
Find a matching Parameter.
Definition: parameter.c:84
struct ParameterList parameter
Parameters of the content-type.
Definition: body.h:62
char * subtype
content-type subtype
Definition: body.h:60
+ 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 601 of file crypt.c.

602{
603 if (!b)
604 return SEC_NO_FLAGS;
605
606 if (((b->type & TYPE_APPLICATION) == 0) || !b->subtype)
607 return SEC_NO_FLAGS;
608
609 char *t = NULL;
610 bool complain = false;
611 /* S/MIME MIME types don't need x- anymore, see RFC2311 */
612 if (mutt_istr_equal(b->subtype, "x-pkcs7-mime") || mutt_istr_equal(b->subtype, "pkcs7-mime"))
613 {
614 t = mutt_param_get(&b->parameter, "smime-type");
615 if (t)
616 {
617 if (mutt_istr_equal(t, "enveloped-data"))
618 return SMIME_ENCRYPT;
619 if (mutt_istr_equal(t, "signed-data"))
620 return SMIME_SIGN | SMIME_OPAQUE;
621 return SEC_NO_FLAGS;
622 }
623 /* Netscape 4.7 uses
624 * Content-Description: S/MIME Encrypted Message
625 * instead of Content-Type parameter */
626 if (mutt_istr_equal(b->description, "S/MIME Encrypted Message"))
627 return SMIME_ENCRYPT;
628 complain = true;
629 }
630 else if (!mutt_istr_equal(b->subtype, "octet-stream"))
631 return SEC_NO_FLAGS;
632
633 t = mutt_param_get(&b->parameter, "name");
634
635 if (!t)
636 t = b->d_filename;
637 if (!t)
638 t = b->filename;
639 if (!t)
640 {
641 if (complain)
642 {
643 mutt_message(_("S/MIME messages with no hints on content are unsupported"));
644 }
645 return SEC_NO_FLAGS;
646 }
647
648 /* no .p7c, .p10 support yet. */
649
650 int len = mutt_str_len(t) - 4;
651 if ((len > 0) && (*(t + len) == '.'))
652 {
653 len++;
654 if (mutt_istr_equal((t + len), "p7m"))
655 {
656 /* Not sure if this is the correct thing to do, but
657 * it's required for compatibility with Outlook */
658 return SMIME_SIGN | SMIME_OPAQUE;
659 }
660 else if (mutt_istr_equal((t + len), "p7s"))
661 return SMIME_SIGN | SMIME_OPAQUE;
662 }
663
664 return SEC_NO_FLAGS;
665}
#define SMIME_SIGN
Definition: lib.h:103
#define SMIME_OPAQUE
Definition: lib.h:106
#define SMIME_ENCRYPT
Definition: lib.h:102
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:58
+ 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 500 of file crypt.c.

501{
503 return SEC_NO_FLAGS;
504
505 if (!b || (b->type != TYPE_MULTIPART) || !b->subtype || !mutt_istr_equal(b->subtype, "mixed"))
506 {
507 return SEC_NO_FLAGS;
508 }
509
510 b = b->parts;
511 if (!b || (b->type != TYPE_TEXT) || !b->subtype ||
512 !mutt_istr_equal(b->subtype, "plain") || (b->length != 0))
513 {
514 return SEC_NO_FLAGS;
515 }
516
517 b = b->next;
518 if (!b || (b->type != TYPE_APPLICATION) || !b->subtype ||
519 !mutt_istr_equal(b->subtype, "pgp-encrypted"))
520 {
521 return SEC_NO_FLAGS;
522 }
523
524 b = b->next;
525 if (!b || (b->type != TYPE_APPLICATION) || !b->subtype ||
526 !mutt_istr_equal(b->subtype, "octet-stream"))
527 {
528 return SEC_NO_FLAGS;
529 }
530
531 b = b->next;
532 if (b)
533 return SEC_NO_FLAGS;
534
535 return PGP_ENCRYPT;
536}
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 439 of file crypt.c.

440{
441 if ((WithCrypto & APPLICATION_PGP) == 0)
442 return SEC_NO_FLAGS;
443
444 char *p = NULL;
445
446 if (!b || (b->type != TYPE_MULTIPART) || !b->subtype ||
447 !mutt_istr_equal(b->subtype, "encrypted") ||
448 !(p = mutt_param_get(&b->parameter, "protocol")) ||
449 !mutt_istr_equal(p, "application/pgp-encrypted"))
450 {
451 return SEC_NO_FLAGS;
452 }
453
454 return PGP_ENCRYPT;
455}
+ 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 402 of file crypt.c.

403{
404 if (!b || (b->type != TYPE_MULTIPART) || !b->subtype || !mutt_istr_equal(b->subtype, "signed"))
405 {
406 return SEC_NO_FLAGS;
407 }
408
409 char *p = mutt_param_get(&b->parameter, "protocol");
410 if (!p)
411 return SEC_NO_FLAGS;
412
413 if (mutt_istr_equal(p, "multipart/mixed"))
414 return SEC_SIGN;
415
416 if (((WithCrypto & APPLICATION_PGP) != 0) && mutt_istr_equal(p, "application/pgp-signature"))
417 {
418 return PGP_SIGN;
419 }
420
421 if (((WithCrypto & APPLICATION_SMIME) != 0) && mutt_istr_equal(p, "application/x-pkcs7-signature"))
422 {
423 return SMIME_SIGN;
424 }
425 if (((WithCrypto & APPLICATION_SMIME) != 0) && mutt_istr_equal(p, "application/pkcs7-signature"))
426 {
427 return SMIME_SIGN;
428 }
429
430 return SEC_NO_FLAGS;
431}
#define SEC_SIGN
Email is signed.
Definition: lib.h:79
+ 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 463 of file crypt.c.

464{
466 return 0;
467
468 b = b->parts;
469 if (!b || (b->type != TYPE_APPLICATION) || !b->subtype ||
470 !mutt_istr_equal(b->subtype, "pgp-encrypted"))
471 {
472 return 0;
473 }
474
475 b = b->next;
476 if (!b || (b->type != TYPE_APPLICATION) || !b->subtype ||
477 !mutt_istr_equal(b->subtype, "octet-stream"))
478 {
479 return 0;
480 }
481
482 return PGP_ENCRYPT;
483}
+ 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 159 of file crypt.c.

160{
161 struct Body *pbody = NULL, *tmp_pbody = NULL;
162 struct Body *tmp_smime_pbody = NULL;
163 struct Body *tmp_pgp_pbody = NULL;
164 bool has_retainable_sig = false;
165
166 if (!WithCrypto)
167 return -1;
168
169 SecurityFlags security = e->security;
170 int sign = security & (SEC_AUTOCRYPT | SEC_SIGN);
171 if (postpone)
172 {
173 sign = SEC_NO_FLAGS;
174 security &= ~SEC_SIGN;
175 }
176
177 if (!(security & (SEC_ENCRYPT | SEC_AUTOCRYPT)) && !sign)
178 return 0;
179
180 if (sign && !(security & SEC_AUTOCRYPT) && !crypt_valid_passphrase(security))
181 return -1;
182
183 if (((WithCrypto & APPLICATION_PGP) != 0) && !(security & SEC_AUTOCRYPT) &&
184 ((security & PGP_INLINE) == PGP_INLINE))
185 {
186 const enum QuadOption c_pgp_mime_auto = cs_subset_quad(NeoMutt->sub, "pgp_mime_auto");
187 if ((e->body->type != TYPE_TEXT) || !mutt_istr_equal(e->body->subtype, "plain"))
188 {
189 if (query_quadoption(c_pgp_mime_auto, _("Inline PGP can't be used with attachments. Revert to PGP/MIME?")) !=
190 MUTT_YES)
191 {
192 mutt_error(_("Mail not sent: inline PGP can't be used with attachments"));
193 return -1;
194 }
195 }
196 else if (mutt_istr_equal("flowed", mutt_param_get(&e->body->parameter, "format")))
197 {
198 if ((query_quadoption(c_pgp_mime_auto, _("Inline PGP can't be used with format=flowed. Revert to PGP/MIME?"))) !=
199 MUTT_YES)
200 {
201 mutt_error(_("Mail not sent: inline PGP can't be used with format=flowed"));
202 return -1;
203 }
204 }
205 else
206 {
207 /* they really want to send it inline... go for it */
208 if (!isendwin())
209 {
210 mutt_endwin();
211 puts(_("Invoking PGP..."));
212 }
213 pbody = crypt_pgp_traditional_encryptsign(e->body, security, keylist);
214 if (pbody)
215 {
216 e->body = pbody;
217 return 0;
218 }
219
220 /* otherwise inline won't work...ask for revert */
221 if (query_quadoption(c_pgp_mime_auto,
222 _("Message can't be sent inline. Revert to using PGP/MIME?")) != MUTT_YES)
223 {
224 mutt_error(_("Mail not sent"));
225 return -1;
226 }
227 }
228
229 /* go ahead with PGP/MIME */
230 }
231
232 if (!isendwin())
233 mutt_endwin();
234
236 tmp_smime_pbody = e->body;
238 tmp_pgp_pbody = e->body;
239
240#ifdef CRYPT_BACKEND_GPGME
241 const bool c_crypt_use_pka = cs_subset_bool(NeoMutt->sub, "crypt_use_pka");
242 if (sign && c_crypt_use_pka)
243#else
244 if (sign)
245#endif
246 {
247 /* Set sender (necessary for e.g. PKA). */
248 const char *mailbox = NULL;
249 struct Address *from = TAILQ_FIRST(&e->env->from);
250 bool free_from = false;
251
252 if (!from)
253 {
254 free_from = true;
256 }
257
258 mailbox = from->mailbox;
259 const struct Address *c_envelope_from_address = cs_subset_address(NeoMutt->sub, "envelope_from_address");
260 if (!mailbox && c_envelope_from_address)
261 mailbox = c_envelope_from_address->mailbox;
262
263 if (((WithCrypto & APPLICATION_SMIME) != 0) && (security & APPLICATION_SMIME))
265 else if (((WithCrypto & APPLICATION_PGP) != 0) && (security & APPLICATION_PGP))
267
268 if (free_from)
269 mutt_addr_free(&from);
270 }
271
272 const bool c_crypt_protected_headers_write = cs_subset_bool(NeoMutt->sub, "crypt_protected_headers_write");
273 if (c_crypt_protected_headers_write)
274 {
275 struct Envelope *protected_headers = mutt_env_new();
276 mutt_str_replace(&protected_headers->subject, e->env->subject);
277 /* Note: if other headers get added, such as to, cc, then a call to
278 * mutt_env_to_intl() will need to be added here too. */
279 mutt_prepare_envelope(protected_headers, 0, NeoMutt->sub);
280
282 e->body->mime_headers = protected_headers;
283 mutt_param_set(&e->body->parameter, "protected-headers", "v1");
284 }
285
286#ifdef USE_AUTOCRYPT
287 /* A note about e->body->mime_headers. If postpone or send
288 * fails, the mime_headers is cleared out before returning to the
289 * compose menu. So despite the "robustness" code above and in the
290 * gen_gossip_list function below, mime_headers will not be set when
291 * entering mutt_protect().
292 *
293 * This is important to note because the user could toggle
294 * $crypt_protected_headers_write or $autocrypt off back in the
295 * compose menu. We don't want mutt_write_rfc822_header() to write
296 * stale data from one option if the other is set.
297 */
298 const bool c_autocrypt = cs_subset_bool(NeoMutt->sub, "autocrypt");
299 if (c_autocrypt && !postpone && (security & SEC_AUTOCRYPT))
300 {
302 }
303#endif
304
305 if (sign)
306 {
307 if (((WithCrypto & APPLICATION_SMIME) != 0) && (security & APPLICATION_SMIME))
308 {
309 tmp_pbody = crypt_smime_sign_message(e->body, &e->env->from);
310 if (!tmp_pbody)
311 goto bail;
312 pbody = tmp_pbody;
313 tmp_smime_pbody = tmp_pbody;
314 }
315
316 const bool c_pgp_retainable_sigs = cs_subset_bool(NeoMutt->sub, "pgp_retainable_sigs");
317 if (((WithCrypto & APPLICATION_PGP) != 0) && (security & APPLICATION_PGP) &&
318 (!(security & (SEC_ENCRYPT | SEC_AUTOCRYPT)) || c_pgp_retainable_sigs))
319 {
320 tmp_pbody = crypt_pgp_sign_message(e->body, &e->env->from);
321 if (!tmp_pbody)
322 goto bail;
323
324 has_retainable_sig = true;
325 sign = SEC_NO_FLAGS;
326 pbody = tmp_pbody;
327 tmp_pgp_pbody = tmp_pbody;
328 }
329
330 if ((WithCrypto != 0) && (security & APPLICATION_SMIME) && (security & APPLICATION_PGP))
331 {
332 /* here comes the draft ;-) */
333 }
334 }
335
336 if (security & (SEC_ENCRYPT | SEC_AUTOCRYPT))
337 {
338 if (((WithCrypto & APPLICATION_SMIME) != 0) && (security & APPLICATION_SMIME))
339 {
340 tmp_pbody = crypt_smime_build_smime_entity(tmp_smime_pbody, keylist);
341 if (!tmp_pbody)
342 {
343 /* signed ? free it! */
344 goto bail;
345 }
346 /* free tmp_body if messages was signed AND encrypted ... */
347 if ((tmp_smime_pbody != e->body) && (tmp_smime_pbody != tmp_pbody))
348 {
349 /* detach and don't delete e->body,
350 * which tmp_smime_pbody->parts after signing. */
351 tmp_smime_pbody->parts = tmp_smime_pbody->parts->next;
352 e->body->next = NULL;
353 mutt_body_free(&tmp_smime_pbody);
354 }
355 pbody = tmp_pbody;
356 }
357
358 if (((WithCrypto & APPLICATION_PGP) != 0) && (security & APPLICATION_PGP))
359 {
360 pbody = crypt_pgp_encrypt_message(e, tmp_pgp_pbody, keylist, sign, &e->env->from);
361 if (!pbody)
362 {
363 /* did we perform a retainable signature? */
364 if (has_retainable_sig)
365 {
366 /* remove the outer multipart layer */
367 tmp_pgp_pbody = mutt_remove_multipart(tmp_pgp_pbody);
368 /* get rid of the signature */
369 mutt_body_free(&tmp_pgp_pbody->next);
370 }
371
372 goto bail;
373 }
374
375 // destroy temporary signature envelope when doing retainable signatures.
376 if (has_retainable_sig)
377 {
378 tmp_pgp_pbody = mutt_remove_multipart(tmp_pgp_pbody);
379 mutt_body_free(&tmp_pgp_pbody->next);
380 }
381 }
382 }
383
384 if (pbody)
385 {
386 e->body = pbody;
387 return 0;
388 }
389
390bail:
392 mutt_param_delete(&e->body->parameter, "protected-headers");
393 return -1;
394}
void mutt_addr_free(struct Address **ptr)
Free a single Address.
Definition: address.c:440
int mutt_autocrypt_generate_gossip_list(struct Email *e)
Create the gossip list headers.
Definition: autocrypt.c:828
const struct Address * cs_subset_address(const struct ConfigSubset *sub, const char *name)
Get an Address config item by name.
Definition: helpers.c:49
struct Body * crypt_pgp_sign_message(struct Body *a, const struct AddressList *from)
Wrapper for CryptModuleSpecs::sign_message()
Definition: cryptglue.c:327
struct Body * crypt_smime_build_smime_entity(struct Body *a, char *certlist)
Wrapper for CryptModuleSpecs::smime_build_smime_entity()
Definition: cryptglue.c:497
void crypt_pgp_set_sender(const char *sender)
Wrapper for CryptModuleSpecs::set_sender()
Definition: cryptglue.c:404
void crypt_smime_set_sender(const char *sender)
Wrapper for CryptModuleSpecs::set_sender()
Definition: cryptglue.c:539
struct Body * crypt_pgp_encrypt_message(struct Email *e, struct Body *a, char *keylist, int sign, const struct AddressList *from)
Wrapper for CryptModuleSpecs::pgp_encrypt_message()
Definition: cryptglue.c:338
struct Body * crypt_pgp_traditional_encryptsign(struct Body *a, SecurityFlags flags, char *keylist)
Wrapper for CryptModuleSpecs::pgp_traditional_encryptsign()
Definition: cryptglue.c:294
struct Body * crypt_smime_sign_message(struct Body *a, const struct AddressList *from)
Wrapper for CryptModuleSpecs::sign_message()
Definition: cryptglue.c:486
void mutt_body_free(struct Body **ptr)
Free a Body.
Definition: body.c:57
void mutt_env_free(struct Envelope **ptr)
Free an Envelope.
Definition: envelope.c:97
struct Envelope * mutt_env_new(void)
Create a new Envelope.
Definition: envelope.c:43
#define mutt_error(...)
Definition: logging.h:87
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:326
void mutt_param_delete(struct ParameterList *pl, const char *attribute)
Delete a matching Parameter.
Definition: parameter.c:142
void mutt_param_set(struct ParameterList *pl, const char *attribute, const char *value)
Set a Parameter.
Definition: parameter.c:110
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: question.c:386
struct Address * mutt_default_from(struct ConfigSubset *sub)
Get a default 'from' Address.
Definition: send.c:1459
void mutt_prepare_envelope(struct Envelope *env, bool final, struct ConfigSubset *sub)
Prepare an email header.
Definition: sendlib.c:754
An email address.
Definition: address.h:36
char * mailbox
Mailbox and host address.
Definition: address.h:38
The body of an email.
Definition: body.h:36
struct Envelope * mime_headers
Memory hole protected headers.
Definition: body.h:75
struct Body * body
List of MIME parts.
Definition: email.h:67
The header of an Email.
Definition: envelope.h:57
char * subject
Email's subject.
Definition: envelope.h:70
+ 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 1078 of file crypt.c.

1079{
1080 const bool c_crypt_protected_headers_write = cs_subset_bool(NeoMutt->sub, "crypt_protected_headers_write");
1081 const char *const c_crypt_protected_headers_subject =
1082 cs_subset_string(NeoMutt->sub, "crypt_protected_headers_subject");
1083 if (c_crypt_protected_headers_write && (e->security & (SEC_ENCRYPT | SEC_AUTOCRYPT)) &&
1084 !(e->security & SEC_INLINE) && c_crypt_protected_headers_subject)
1085 {
1086 return true;
1087 }
1088
1089 return false;
1090}
#define SEC_INLINE
Email has an inline signature.
Definition: lib.h:85
+ 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 142 of file cryptglue.c.

143{
144 if (CRYPT_MOD_CALL_CHECK(PGP, cleanup))
145 (CRYPT_MOD_CALL(PGP, cleanup))();
146
147 if (CRYPT_MOD_CALL_CHECK(SMIME, cleanup))
148 (CRYPT_MOD_CALL(SMIME, cleanup))();
149}
#define CRYPT_MOD_CALL_CHECK(identifier, func)
Definition: cryptglue.c:80
#define CRYPT_MOD_CALL(identifier, func)
Definition: cryptglue.c:86
+ 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 171 of file cryptglue.c.

172{
173 if (((WithCrypto & APPLICATION_PGP) != 0) && (type & APPLICATION_PGP) &&
175 {
176 return true;
177 }
178
179 if (((WithCrypto & APPLICATION_SMIME) != 0) && (type & APPLICATION_SMIME) &&
181 {
182 return true;
183 }
184
185 return false;
186}
struct CryptModuleSpecs * crypto_module_lookup(int identifier)
Lookup a crypto module by name.
Definition: crypt_mod.c:65
+ 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 94 of file cryptglue.c.

95{
96#ifdef CRYPT_BACKEND_GPGME
97 const bool c_crypt_use_gpgme = cs_subset_bool(NeoMutt->sub, "crypt_use_gpgme");
98#endif
99#ifdef CRYPT_BACKEND_CLASSIC_PGP
100 if (
101#ifdef CRYPT_BACKEND_GPGME
102 (!c_crypt_use_gpgme)
103#else
104 1
105#endif
106 )
108#endif
109
110#ifdef CRYPT_BACKEND_CLASSIC_SMIME
111 if (
112#ifdef CRYPT_BACKEND_GPGME
113 (!c_crypt_use_gpgme)
114#else
115 1
116#endif
117 )
119#endif
120
121#ifdef CRYPT_BACKEND_GPGME
122 if (c_crypt_use_gpgme)
123 {
126 }
127#endif
128
129#if defined(CRYPT_BACKEND_CLASSIC_PGP) || \
130 defined(CRYPT_BACKEND_CLASSIC_SMIME) || defined(CRYPT_BACKEND_GPGME)
131 if (CRYPT_MOD_CALL_CHECK(PGP, init))
132 CRYPT_MOD_CALL(PGP, init)();
133
134 if (CRYPT_MOD_CALL_CHECK(SMIME, init))
135 CRYPT_MOD_CALL(SMIME, init)();
136#endif
137}
void crypto_module_register(struct CryptModuleSpecs *specs)
Register a new crypto module.
Definition: crypt_mod.c:51
struct CryptModuleSpecs CryptModPgpGpgme
GPGME PGP - Implements CryptModuleSpecs.
struct CryptModuleSpecs CryptModPgpClassic
CLI PGP - Implements CryptModuleSpecs.
struct CryptModuleSpecs CryptModSmimeGpgme
GPGME SMIME - Implements CryptModuleSpecs.
struct CryptModuleSpecs CryptModSmimeClassic
CLI SMIME - 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 157 of file cryptglue.c.

158{
159 if (((WithCrypto & APPLICATION_PGP) != 0) && (type & APPLICATION_PGP))
160 mutt_message(_("Invoking PGP..."));
161 else if (((WithCrypto & APPLICATION_SMIME) != 0) && (type & APPLICATION_SMIME))
162 mutt_message(_("Invoking S/MIME..."));
163}
+ 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 283 of file cryptglue.c.

284{
285 if (CRYPT_MOD_CALL_CHECK(PGP, pgp_check_traditional))
286 return CRYPT_MOD_CALL(PGP, pgp_check_traditional)(fp, b, just_one);
287
288 return false;
289}
+ 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 **  cur 
)

Wrapper for CryptModuleSpecs::decrypt_mime()

Definition at line 211 of file cryptglue.c.

212{
213#ifdef USE_AUTOCRYPT
214 const bool c_autocrypt = cs_subset_bool(NeoMutt->sub, "autocrypt");
215 if (c_autocrypt)
216 {
217 OptAutocryptGpgme = true;
218 int result = pgp_gpgme_decrypt_mime(fp_in, fp_out, b, cur);
219 OptAutocryptGpgme = false;
220 if (result == 0)
221 {
222 b->is_autocrypt = true;
223 return result;
224 }
225 }
226#endif
227
228 if (CRYPT_MOD_CALL_CHECK(PGP, decrypt_mime))
229 return CRYPT_MOD_CALL(PGP, decrypt_mime)(fp_in, fp_out, b, cur);
230
231 return -1;
232}
int pgp_gpgme_decrypt_mime(FILE *fp_in, FILE **fp_out, struct Body *b, struct Body **cur)
Implements CryptModuleSpecs::decrypt_mime() -.
Definition: crypt_gpgme.c:1846
bool OptAutocryptGpgme
(pseudo) use Autocrypt context inside ncrypt/crypt_gpgme.c
Definition: options.h:39
+ 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 top 
)

Wrapper for CryptModuleSpecs::pgp_extract_key_from_attachment()

Definition at line 395 of file cryptglue.c.

396{
397 if (CRYPT_MOD_CALL_CHECK(PGP, pgp_extract_key_from_attachment))
398 CRYPT_MOD_CALL(PGP, pgp_extract_key_from_attachment)(fp, top);
399}
+ 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 274 of file cryptglue.c.

275{
276 if (CRYPT_MOD_CALL_CHECK(PGP, pgp_invoke_getkeys))
277 CRYPT_MOD_CALL(PGP, pgp_invoke_getkeys)(addr);
278}
+ 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 305 of file cryptglue.c.

306{
307 if (CRYPT_MOD_CALL_CHECK(PGP, pgp_make_key_attachment))
308 return CRYPT_MOD_CALL(PGP, pgp_make_key_attachment)();
309
310 return NULL;
311}
+ 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 384 of file cryptglue.c.

385{
386 if (CRYPT_MOD_CALL_CHECK(PGP, send_menu))
387 return CRYPT_MOD_CALL(PGP, send_menu)(e);
388
389 return 0;
390}
+ 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 **  cur 
)

Wrapper for CryptModuleSpecs::decrypt_mime()

Definition at line 433 of file cryptglue.c.

434{
435 if (CRYPT_MOD_CALL_CHECK(SMIME, decrypt_mime))
436 return CRYPT_MOD_CALL(SMIME, decrypt_mime)(fp_in, fp_out, b, cur);
437
438 return -1;
439}
+ 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 455 of file cryptglue.c.

456{
457 if (CRYPT_MOD_CALL_CHECK(SMIME, smime_getkeys))
458 CRYPT_MOD_CALL(SMIME, smime_getkeys)(env);
459}
+ 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 528 of file cryptglue.c.

529{
530 if (CRYPT_MOD_CALL_CHECK(SMIME, send_menu))
531 return CRYPT_MOD_CALL(SMIME, send_menu)(e);
532
533 return 0;
534}
+ 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 464 of file cryptglue.c.

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

◆ crypto_module_free()

void crypto_module_free ( void  )

Clean up the crypto modules.

Definition at line 81 of file crypt_mod.c.

82{
83 struct CryptModule *np = NULL, *tmp = NULL;
84 STAILQ_FOREACH_SAFE(np, &CryptModules, entries, tmp)
85 {
87 FREE(&np);
88 }
89}
static struct CryptModuleList CryptModules
Definition: crypt_mod.c:45
#define STAILQ_REMOVE(head, elm, type, field)
Definition: queue.h:402
#define STAILQ_FOREACH_SAFE(var, head, field, tvar)
Definition: queue.h:362
A crypto plugin module.
Definition: crypt_mod.c:39
+ 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 3549 of file crypt_gpgme.c.

3550{
3551 int rc = -1;
3552 gpgme_error_t err;
3553 gpgme_key_t key = NULL;
3554 gpgme_user_id_t uid = NULL;
3555 struct CryptKeyInfo *results = NULL, *k = NULL;
3556 struct CryptKeyInfo **kend = NULL;
3557 struct CryptKeyInfo *choice = NULL;
3558
3559 gpgme_ctx_t ctx = create_gpgme_context(false);
3560
3561 /* list all secret keys */
3562 if (gpgme_op_keylist_start(ctx, NULL, 1))
3563 goto cleanup;
3564
3565 kend = &results;
3566
3567 while (!(err = gpgme_op_keylist_next(ctx, &key)))
3568 {
3570
3575
3576 if (key->revoked)
3578 if (key->expired)
3580 if (key->disabled)
3582
3583 int idx;
3584 for (idx = 0, uid = key->uids; uid; idx++, uid = uid->next)
3585 {
3586 k = mutt_mem_calloc(1, sizeof(*k));
3587 k->kobj = key;
3588 gpgme_key_ref(k->kobj);
3589 k->idx = idx;
3590 k->uid = uid->uid;
3591 k->flags = flags;
3592 if (uid->revoked)
3593 k->flags |= KEYFLAG_REVOKED;
3594 k->validity = uid->validity;
3595 *kend = k;
3596 kend = &k->next;
3597 }
3598 gpgme_key_unref(key);
3599 }
3600 if (gpg_err_code(err) != GPG_ERR_EOF)
3601 mutt_error(_("gpgme_op_keylist_next failed: %s"), gpgme_strerror(err));
3602 gpgme_op_keylist_end(ctx);
3603
3604 if (!results)
3605 {
3606 /* L10N: mutt_gpgme_select_secret_key() tries to list all secret keys to choose
3607 from. This error is displayed if no results were found. */
3608 mutt_error(_("No secret keys found"));
3609 goto cleanup;
3610 }
3611
3612 choice = dlg_select_gpgme_key(results, NULL, "*", APPLICATION_PGP, NULL);
3613 if (!(choice && choice->kobj && choice->kobj->subkeys && choice->kobj->subkeys->fpr))
3614 goto cleanup;
3615 mutt_buffer_strcpy(keyid, choice->kobj->subkeys->fpr);
3616
3617 rc = 0;
3618
3619cleanup:
3620 crypt_key_free(&choice);
3621 crypt_key_free(&results);
3622 gpgme_release(ctx);
3623 return rc;
3624}
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:327
gpgme_ctx_t create_gpgme_context(bool for_smime)
Create a new GPGME context.
Definition: crypt_gpgme.c:362
unsigned int key_check_cap(gpgme_key_t key, enum KeyCap cap)
Check the capabilities of a key.
Definition: crypt_gpgme.c:2837
static void crypt_key_free(struct CryptKeyInfo **keylist)
Release all the keys in a list.
Definition: crypt_gpgme.c:253
@ KEY_CAP_CAN_ENCRYPT
Key can be used for encryption.
Definition: crypt_gpgme.h:76
@ KEY_CAP_CAN_SIGN
Key can be used for signing.
Definition: crypt_gpgme.h:77
struct CryptKeyInfo * dlg_select_gpgme_key(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:665
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
#define KEYFLAG_EXPIRED
Key is expired.
Definition: lib.h:131
uint16_t KeyFlags
Flags describing PGP/SMIME keys, e.g. KEYFLAG_CANSIGN.
Definition: lib.h:125
#define KEYFLAG_CANENCRYPT
Key is suitable for encryption.
Definition: lib.h:128
#define KEYFLAG_NO_FLAGS
No flags are set.
Definition: lib.h:126
#define KEYFLAG_DISABLED
Key is marked disabled.
Definition: lib.h:133
#define KEYFLAG_REVOKED
Key is revoked.
Definition: lib.h:132
#define KEYFLAG_CANSIGN
Key is suitable for signing.
Definition: lib.h:127
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 4024 of file crypt_gpgme.c.

4025{
4026 return GPGME_VERSION;
4027}
+ Here is the caller graph for this function: