NeoMutt  2021-10-29-220-g2b1eec
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 74 of file lib.h.

◆ SEC_ENCRYPT

#define SEC_ENCRYPT   (1 << 0)

Email is encrypted.

Definition at line 75 of file lib.h.

◆ SEC_SIGN

#define SEC_SIGN   (1 << 1)

Email is signed.

Definition at line 76 of file lib.h.

◆ SEC_GOODSIGN

#define SEC_GOODSIGN   (1 << 2)

Email has a valid signature.

Definition at line 77 of file lib.h.

◆ SEC_BADSIGN

#define SEC_BADSIGN   (1 << 3)

Email has a bad signature.

Definition at line 78 of file lib.h.

◆ SEC_PARTSIGN

#define SEC_PARTSIGN   (1 << 4)

Not all parts of the email is signed.

Definition at line 79 of file lib.h.

◆ SEC_SIGNOPAQUE

#define SEC_SIGNOPAQUE   (1 << 5)

Email has an opaque signature (encrypted)

Definition at line 80 of file lib.h.

◆ SEC_KEYBLOCK

#define SEC_KEYBLOCK   (1 << 6)

Email has a key attached.

Definition at line 81 of file lib.h.

◆ SEC_INLINE

#define SEC_INLINE   (1 << 7)

Email has an inline signature.

Definition at line 82 of file lib.h.

◆ SEC_OPPENCRYPT

#define SEC_OPPENCRYPT   (1 << 8)

Opportunistic encrypt mode.

Definition at line 83 of file lib.h.

◆ SEC_AUTOCRYPT

#define SEC_AUTOCRYPT   (1 << 9)

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

Definition at line 84 of file lib.h.

◆ SEC_AUTOCRYPT_OVERRIDE

#define SEC_AUTOCRYPT_OVERRIDE   (1 << 10)

(Autocrypt) Indicates manual set/unset of encryption

Definition at line 85 of file lib.h.

◆ APPLICATION_PGP

#define APPLICATION_PGP   (1 << 11)

Use PGP to encrypt/sign.

Definition at line 87 of file lib.h.

◆ APPLICATION_SMIME

#define APPLICATION_SMIME   (1 << 12)

Use SMIME to encrypt/sign.

Definition at line 88 of file lib.h.

◆ PGP_TRADITIONAL_CHECKED

#define PGP_TRADITIONAL_CHECKED   (1 << 13)

Email has a traditional (inline) signature.

Definition at line 89 of file lib.h.

◆ SEC_ALL_FLAGS

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

Definition at line 91 of file lib.h.

◆ PGP_ENCRYPT

#define PGP_ENCRYPT   (APPLICATION_PGP | SEC_ENCRYPT)

Definition at line 93 of file lib.h.

◆ PGP_SIGN

#define PGP_SIGN   (APPLICATION_PGP | SEC_SIGN)

Definition at line 94 of file lib.h.

◆ PGP_GOODSIGN

#define PGP_GOODSIGN   (APPLICATION_PGP | SEC_GOODSIGN)

Definition at line 95 of file lib.h.

◆ PGP_KEY

#define PGP_KEY   (APPLICATION_PGP | SEC_KEYBLOCK)

Definition at line 96 of file lib.h.

◆ PGP_INLINE

#define PGP_INLINE   (APPLICATION_PGP | SEC_INLINE)

Definition at line 97 of file lib.h.

◆ SMIME_ENCRYPT

#define SMIME_ENCRYPT   (APPLICATION_SMIME | SEC_ENCRYPT)

Definition at line 99 of file lib.h.

◆ SMIME_SIGN

#define SMIME_SIGN   (APPLICATION_SMIME | SEC_SIGN)

Definition at line 100 of file lib.h.

◆ SMIME_GOODSIGN

#define SMIME_GOODSIGN   (APPLICATION_SMIME | SEC_GOODSIGN)

Definition at line 101 of file lib.h.

◆ SMIME_BADSIGN

#define SMIME_BADSIGN   (APPLICATION_SMIME | SEC_BADSIGN)

Definition at line 102 of file lib.h.

◆ SMIME_OPAQUE

#define SMIME_OPAQUE   (APPLICATION_SMIME | SEC_SIGNOPAQUE)

Definition at line 103 of file lib.h.

◆ WithCrypto

#define WithCrypto   (APPLICATION_PGP | APPLICATION_SMIME)

Definition at line 113 of file lib.h.

◆ KEYFLAG_NO_FLAGS

#define KEYFLAG_NO_FLAGS   0

No flags are set.

Definition at line 123 of file lib.h.

◆ KEYFLAG_CANSIGN

#define KEYFLAG_CANSIGN   (1 << 0)

Key is suitable for signing.

Definition at line 124 of file lib.h.

◆ KEYFLAG_CANENCRYPT

#define KEYFLAG_CANENCRYPT   (1 << 1)

Key is suitable for encryption.

Definition at line 125 of file lib.h.

◆ KEYFLAG_ISX509

#define KEYFLAG_ISX509   (1 << 2)

Key is an X.509 key.

Definition at line 126 of file lib.h.

◆ KEYFLAG_SECRET

#define KEYFLAG_SECRET   (1 << 7)

Key is a secret key.

Definition at line 127 of file lib.h.

◆ KEYFLAG_EXPIRED

#define KEYFLAG_EXPIRED   (1 << 8)

Key is expired.

Definition at line 128 of file lib.h.

◆ KEYFLAG_REVOKED

#define KEYFLAG_REVOKED   (1 << 9)

Key is revoked.

Definition at line 129 of file lib.h.

◆ KEYFLAG_DISABLED

#define KEYFLAG_DISABLED   (1 << 10)

Key is marked disabled.

Definition at line 130 of file lib.h.

◆ KEYFLAG_SUBKEY

#define KEYFLAG_SUBKEY   (1 << 11)

Key is a subkey.

Definition at line 131 of file lib.h.

◆ KEYFLAG_CRITICAL

#define KEYFLAG_CRITICAL   (1 << 12)

Key is marked critical.

Definition at line 132 of file lib.h.

◆ KEYFLAG_PREFER_ENCRYPTION

#define KEYFLAG_PREFER_ENCRYPTION   (1 << 13)

Key's owner prefers encryption.

Definition at line 133 of file lib.h.

◆ KEYFLAG_PREFER_SIGNING

#define KEYFLAG_PREFER_SIGNING   (1 << 14)

Key's owner prefers signing.

Definition at line 134 of file lib.h.

◆ KEYFLAG_CANTUSE

#define KEYFLAG_CANTUSE   (KEYFLAG_DISABLED | KEYFLAG_REVOKED | KEYFLAG_EXPIRED)

Definition at line 136 of file lib.h.

◆ KEYFLAG_RESTRICTIONS

#define KEYFLAG_RESTRICTIONS   (KEYFLAG_CANTUSE | KEYFLAG_CRITICAL)

Definition at line 137 of file lib.h.

◆ KEYFLAG_ABILITIES

Definition at line 139 of file lib.h.

Typedef Documentation

◆ SecurityFlags

typedef uint16_t SecurityFlags

Flags, e.g. SEC_ENCRYPT.

Definition at line 73 of file lib.h.

◆ KeyFlags

typedef uint16_t KeyFlags

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

Definition at line 122 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 856 of file crypt.c.

857 {
858  if (!WithCrypto)
859  return;
860 
861  struct Buffer *tempfname = mutt_buffer_pool_get();
862  mutt_buffer_mktemp(tempfname);
863  FILE *fp_out = mutt_file_fopen(mutt_buffer_string(tempfname), "w");
864  if (!fp_out)
865  {
866  mutt_perror(mutt_buffer_string(tempfname));
867  goto cleanup;
868  }
869 
871  OptDontHandlePgpKeys = true;
872 
873  struct EmailNode *en = NULL;
874  STAILQ_FOREACH(en, el, entries)
875  {
876  struct Email *e = en->email;
877  struct Message *msg = mx_msg_open(m, e->msgno);
878  if (!msg)
879  {
880  continue;
881  }
882  mutt_parse_mime_message(e, msg->fp);
884  {
885  mx_msg_close(m, &msg);
886  mutt_file_fclose(&fp_out);
887  break;
888  }
889 
890  if (((WithCrypto & APPLICATION_PGP) != 0) && (e->security & APPLICATION_PGP))
891  {
893  fflush(fp_out);
894 
895  mutt_endwin();
896  puts(_("Trying to extract PGP keys...\n"));
898  }
899 
900  if (((WithCrypto & APPLICATION_SMIME) != 0) && (e->security & APPLICATION_SMIME))
901  {
902  const bool encrypt = e->security & SEC_ENCRYPT;
903  mutt_copy_message(fp_out, e, msg,
906  CH_NO_FLAGS, 0);
907  fflush(fp_out);
908 
909  char *mbox = NULL;
910  if (!TAILQ_EMPTY(&e->env->from))
911  {
913  mbox = TAILQ_FIRST(&e->env->from)->mailbox;
914  }
915  else if (!TAILQ_EMPTY(&e->env->sender))
916  {
918  mbox = TAILQ_FIRST(&e->env->sender)->mailbox;
919  }
920  if (mbox)
921  {
922  mutt_endwin();
923  puts(_("Trying to extract S/MIME certificates..."));
925  }
926  }
927  mx_msg_close(m, &msg);
928 
929  rewind(fp_out);
930  }
931 
932  mutt_file_fclose(&fp_out);
933  if (isendwin())
935 
937 
939  OptDontHandlePgpKeys = false;
940 
941 cleanup:
942  mutt_buffer_pool_release(&tempfname);
943 }
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:593
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:877
#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:135
void crypt_pgp_invoke_import(const char *fname)
Wrapper for CryptModuleSpecs::pgp_invoke_import()
Definition: cryptglue.c:365
void crypt_smime_invoke_import(const char *infile, const char *mailbox)
Wrapper for CryptModuleSpecs::smime_invoke_import()
Definition: cryptglue.c:509
int mutt_any_key_to_continue(const char *s)
Prompt the user to 'press any key' and wait.
Definition: curs_lib.c:427
void mutt_endwin(void)
Shutdown curses.
Definition: curs_lib.c:394
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:593
void mutt_file_unlink(const char *s)
Delete a file, carefully.
Definition: file.c:195
#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:1192
struct Message * mx_msg_open(struct Mailbox *m, int msgno)
Return a stream pointer for a message.
Definition: mx.c:1146
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: lib.h:87
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: lib.h:88
#define SEC_ENCRYPT
Email is encrypted.
Definition: lib.h:75
#define WithCrypto
Definition: lib.h:113
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:131
struct Email * email
Email in the list.
Definition: email.h:132
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:61
struct AddressList from
Email's 'From' list.
Definition: envelope.h:57
A local copy of an email.
Definition: mxapi.h:42
FILE * fp
pointer to the message data
Definition: mxapi.h:43
+ 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 93 of file crypt.c.

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

960 {
961  if (!WithCrypto)
962  return 0;
963 
964  struct AddressList addrlist = TAILQ_HEAD_INITIALIZER(addrlist);
965  const char *fqdn = mutt_fqdn(true, NeoMutt->sub);
966  const char *self_encrypt = NULL;
967 
968  /* Do a quick check to make sure that we can find all of the encryption
969  * keys if the user has requested this service. */
970 
971  *keylist = NULL;
972 
973 #ifdef USE_AUTOCRYPT
974  if (!oppenc_mode && (e->security & SEC_AUTOCRYPT))
975  {
977  return -1;
978  return 0;
979  }
980 #endif
981 
983  OptPgpCheckTrust = true;
984 
985  mutt_addrlist_copy(&addrlist, &e->env->to, false);
986  mutt_addrlist_copy(&addrlist, &e->env->cc, false);
987  mutt_addrlist_copy(&addrlist, &e->env->bcc, false);
988  mutt_addrlist_qualify(&addrlist, fqdn);
989  mutt_addrlist_dedupe(&addrlist);
990 
991  if (oppenc_mode || (e->security & SEC_ENCRYPT))
992  {
993  if (((WithCrypto & APPLICATION_PGP) != 0) && (e->security & APPLICATION_PGP))
994  {
995  *keylist = crypt_pgp_find_keys(&addrlist, oppenc_mode);
996  if (!*keylist)
997  {
998  mutt_addrlist_clear(&addrlist);
999  return -1;
1000  }
1001  OptPgpCheckTrust = false;
1002  const bool c_pgp_self_encrypt =
1003  cs_subset_bool(NeoMutt->sub, "pgp_self_encrypt");
1004  const char *const c_pgp_default_key =
1005  cs_subset_string(NeoMutt->sub, "pgp_default_key");
1006  const enum QuadOption c_pgp_encrypt_self =
1007  cs_subset_quad(NeoMutt->sub, "pgp_encrypt_self");
1008  if (c_pgp_self_encrypt || (c_pgp_encrypt_self == MUTT_YES))
1009  self_encrypt = c_pgp_default_key;
1010  }
1011  if (((WithCrypto & APPLICATION_SMIME) != 0) && (e->security & APPLICATION_SMIME))
1012  {
1013  *keylist = crypt_smime_find_keys(&addrlist, oppenc_mode);
1014  if (!*keylist)
1015  {
1016  mutt_addrlist_clear(&addrlist);
1017  return -1;
1018  }
1019  const bool c_smime_self_encrypt =
1020  cs_subset_bool(NeoMutt->sub, "smime_self_encrypt");
1021  const char *const c_smime_default_key =
1022  cs_subset_string(NeoMutt->sub, "smime_default_key");
1023  const enum QuadOption c_smime_encrypt_self =
1024  cs_subset_quad(NeoMutt->sub, "smime_encrypt_self");
1025  if (c_smime_self_encrypt || (c_smime_encrypt_self == MUTT_YES))
1026  self_encrypt = c_smime_default_key;
1027  }
1028  }
1029 
1030  if (!oppenc_mode && self_encrypt)
1031  {
1032  const size_t keylist_size = mutt_str_len(*keylist);
1033  mutt_mem_realloc(keylist, keylist_size + mutt_str_len(self_encrypt) + 2);
1034  sprintf(*keylist + keylist_size, " %s", self_encrypt);
1035  }
1036 
1037  mutt_addrlist_clear(&addrlist);
1038 
1039  return 0;
1040 }
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:158
enum AutocryptRec mutt_autocrypt_ui_recommendation(struct Email *e, char **keylist)
Get the recommended action for an Email.
Definition: autocrypt.c:570
char * crypt_smime_find_keys(struct AddressList *addrlist, bool oppenc_mode)
Wrapper for CryptModuleSpecs::find_keys()
Definition: cryptglue.c:476
char * crypt_pgp_find_keys(struct AddressList *addrlist, bool oppenc_mode)
Wrapper for CryptModuleSpecs::find_keys()
Definition: cryptglue.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
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:317
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
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:475
#define SEC_AUTOCRYPT
(Autocrypt) Message will be, or was Autocrypt encrypt+signed
Definition: lib.h:84
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:1195
struct AddressList to
Email's 'To' list.
Definition: envelope.h:58
struct AddressList cc
Email's 'Cc' list.
Definition: envelope.h:59
struct AddressList bcc
Email's 'Bcc' list.
Definition: envelope.h:60
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 1049 of file crypt.c.

1050 {
1051  if (!WithCrypto)
1052  return;
1053 
1054  const bool c_crypt_opportunistic_encrypt =
1055  cs_subset_bool(NeoMutt->sub, "crypt_opportunistic_encrypt");
1056  if (!(c_crypt_opportunistic_encrypt && (e->security & SEC_OPPENCRYPT)))
1057  return;
1058 
1059  char *pgpkeylist = NULL;
1060 
1061  crypt_get_keys(e, &pgpkeylist, 1);
1062  if (pgpkeylist)
1063  {
1064  e->security |= SEC_ENCRYPT;
1065  FREE(&pgpkeylist);
1066  }
1067  else
1068  {
1069  e->security &= ~SEC_ENCRYPT;
1070  }
1071 }
int crypt_get_keys(struct Email *e, char **keylist, bool oppenc_mode)
Check we have all the keys we need.
Definition: crypt.c:959
#define FREE(x)
Definition: memory.h:40
#define SEC_OPPENCRYPT
Opportunistic encrypt mode.
Definition: lib.h:83
+ 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 692 of file crypt.c.

693 {
694  if (!WithCrypto || !b)
695  return SEC_NO_FLAGS;
696 
698 
699  if (b->type == TYPE_APPLICATION)
700  {
702  rc |= mutt_is_application_pgp(b);
703 
705  {
706  rc |= mutt_is_application_smime(b);
707  if (rc && b->goodsig)
708  rc |= SEC_GOODSIGN;
709  if (rc && b->badsig)
710  rc |= SEC_BADSIGN;
711  }
712  }
713  else if (((WithCrypto & APPLICATION_PGP) != 0) && (b->type == TYPE_TEXT))
714  {
715  rc |= mutt_is_application_pgp(b);
716  if (rc && b->goodsig)
717  rc |= SEC_GOODSIGN;
718  }
719 
720  if (b->type == TYPE_MULTIPART)
721  {
723  rc |= mutt_is_multipart_signed(b);
725 
726  if (rc && b->goodsig)
727  rc |= SEC_GOODSIGN;
728 #ifdef USE_AUTOCRYPT
729  if (rc && b->is_autocrypt)
730  rc |= SEC_AUTOCRYPT;
731 #endif
732  }
733 
734  if ((b->type == TYPE_MULTIPART) || (b->type == TYPE_MESSAGE))
735  {
736  SecurityFlags u = b->parts ? SEC_ALL_FLAGS : SEC_NO_FLAGS; /* Bits set in all parts */
737  SecurityFlags w = SEC_NO_FLAGS; /* Bits set in any part */
738 
739  for (b = b->parts; b; b = b->next)
740  {
741  const SecurityFlags v = crypt_query(b);
742  u &= v;
743  w |= v;
744  }
745  rc |= u | (w & ~SEC_GOODSIGN);
746 
747  if ((w & SEC_GOODSIGN) && !(u & SEC_GOODSIGN))
748  rc |= SEC_PARTSIGN;
749  }
750 
751  return rc;
752 }
SecurityFlags mutt_is_application_pgp(struct Body *b)
Does the message use PGP?
Definition: crypt.c:559
SecurityFlags mutt_is_multipart_signed(struct Body *b)
Is a message signed?
Definition: crypt.c:414
SecurityFlags mutt_is_application_smime(struct Body *b)
Does the message use S/MIME?
Definition: crypt.c:617
SecurityFlags mutt_is_multipart_encrypted(struct Body *b)
Does the message have encrypted parts?
Definition: crypt.c:454
SecurityFlags mutt_is_malformed_multipart_pgp_encrypted(struct Body *b)
Check for malformed layout.
Definition: crypt.c:515
SecurityFlags crypt_query(struct Body *b)
Check out the type of encryption used.
Definition: crypt.c:692
@ 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:71
#define SEC_ALL_FLAGS
Definition: lib.h:91
#define SEC_GOODSIGN
Email has a valid signature.
Definition: lib.h:77
#define SEC_BADSIGN
Email has a bad signature.
Definition: lib.h:78
#define SEC_NO_FLAGS
No flags are set.
Definition: lib.h:74
#define SEC_PARTSIGN
Not all parts of the email is signed.
Definition: lib.h:79
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:71
bool badsig
Bad cryptographic signature (needed to check encrypted s/mime-signatures)
Definition: body.h:42
bool is_autocrypt
Flag autocrypt-decrypted messages for replying.
Definition: body.h:49
struct Body * next
next attachment in the list
Definition: body.h:70
bool goodsig
Good cryptographic signature.
Definition: body.h:44
unsigned int type
content-type primary type, ContentType
Definition: body.h:39
+ 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 135 of file crypt.c.

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

560 {
562  char *p = NULL;
563 
564  if (b->type == TYPE_APPLICATION)
565  {
566  if (mutt_istr_equal(b->subtype, "pgp") ||
567  mutt_istr_equal(b->subtype, "x-pgp-message"))
568  {
569  p = mutt_param_get(&b->parameter, "x-action");
570  if (p && (mutt_istr_equal(p, "sign") || mutt_istr_equal(p, "signclear")))
571  {
572  t |= PGP_SIGN;
573  }
574 
575  p = mutt_param_get(&b->parameter, "format");
576  if (p && mutt_istr_equal(p, "keys-only"))
577  {
578  t |= PGP_KEY;
579  }
580 
581  if (t == SEC_NO_FLAGS)
582  t |= PGP_ENCRYPT; /* not necessarily correct, but... */
583  }
584 
585  if (mutt_istr_equal(b->subtype, "pgp-signed"))
586  t |= PGP_SIGN;
587 
588  if (mutt_istr_equal(b->subtype, "pgp-keys"))
589  t |= PGP_KEY;
590  }
591  else if ((b->type == TYPE_TEXT) && mutt_istr_equal("plain", b->subtype))
592  {
593  if (((p = mutt_param_get(&b->parameter, "x-mutt-action")) ||
594  (p = mutt_param_get(&b->parameter, "x-action")) ||
595  (p = mutt_param_get(&b->parameter, "action"))) &&
596  mutt_istr_startswith(p, "pgp-sign"))
597  {
598  t |= PGP_SIGN;
599  }
600  else if (p && mutt_istr_startswith(p, "pgp-encrypt"))
601  t |= PGP_ENCRYPT;
602  else if (p && mutt_istr_startswith(p, "pgp-keys"))
603  t |= PGP_KEY;
604  }
605  if (t)
606  t |= PGP_INLINE;
607 
608  return t;
609 }
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:727
size_t mutt_istr_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix, ignoring case.
Definition: string.c:170
#define PGP_SIGN
Definition: lib.h:94
#define PGP_ENCRYPT
Definition: lib.h:93
#define PGP_INLINE
Definition: lib.h:97
#define PGP_KEY
Definition: lib.h:96
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:61
char * subtype
content-type subtype
Definition: body.h:59
+ 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 617 of file crypt.c.

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

516 {
517  if (!(WithCrypto & APPLICATION_PGP))
518  return SEC_NO_FLAGS;
519 
520  if (!b || (b->type != TYPE_MULTIPART) || !b->subtype || !mutt_istr_equal(b->subtype, "mixed"))
521  {
522  return SEC_NO_FLAGS;
523  }
524 
525  b = b->parts;
526  if (!b || (b->type != TYPE_TEXT) || !b->subtype ||
527  !mutt_istr_equal(b->subtype, "plain") || (b->length != 0))
528  {
529  return SEC_NO_FLAGS;
530  }
531 
532  b = b->next;
533  if (!b || (b->type != TYPE_APPLICATION) || !b->subtype ||
534  !mutt_istr_equal(b->subtype, "pgp-encrypted"))
535  {
536  return SEC_NO_FLAGS;
537  }
538 
539  b = b->next;
540  if (!b || (b->type != TYPE_APPLICATION) || !b->subtype ||
541  !mutt_istr_equal(b->subtype, "octet-stream"))
542  {
543  return SEC_NO_FLAGS;
544  }
545 
546  b = b->next;
547  if (b)
548  return SEC_NO_FLAGS;
549 
550  return PGP_ENCRYPT;
551 }
LOFF_T length
length (in bytes) of attachment
Definition: body.h:52
+ 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 454 of file crypt.c.

455 {
456  if ((WithCrypto & APPLICATION_PGP) == 0)
457  return SEC_NO_FLAGS;
458 
459  char *p = NULL;
460 
461  if (!b || (b->type != TYPE_MULTIPART) || !b->subtype ||
462  !mutt_istr_equal(b->subtype, "encrypted") ||
463  !(p = mutt_param_get(&b->parameter, "protocol")) ||
464  !mutt_istr_equal(p, "application/pgp-encrypted"))
465  {
466  return SEC_NO_FLAGS;
467  }
468 
469  return PGP_ENCRYPT;
470 }
+ 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 414 of file crypt.c.

415 {
416  if (!b || (b->type != TYPE_MULTIPART) || !b->subtype || !mutt_istr_equal(b->subtype, "signed"))
417  {
418  return SEC_NO_FLAGS;
419  }
420 
421  char *p = mutt_param_get(&b->parameter, "protocol");
422  if (!p)
423  return SEC_NO_FLAGS;
424 
425  if (mutt_istr_equal(p, "multipart/mixed"))
426  return SEC_SIGN;
427 
428  if (((WithCrypto & APPLICATION_PGP) != 0) &&
429  mutt_istr_equal(p, "application/pgp-signature"))
430  {
431  return PGP_SIGN;
432  }
433 
434  if (((WithCrypto & APPLICATION_SMIME) != 0) &&
435  mutt_istr_equal(p, "application/x-pkcs7-signature"))
436  {
437  return SMIME_SIGN;
438  }
439  if (((WithCrypto & APPLICATION_SMIME) != 0) &&
440  mutt_istr_equal(p, "application/pkcs7-signature"))
441  {
442  return SMIME_SIGN;
443  }
444 
445  return SEC_NO_FLAGS;
446 }
#define SEC_SIGN
Email is signed.
Definition: lib.h:76
+ 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 478 of file crypt.c.

479 {
481  return 0;
482 
483  b = b->parts;
484  if (!b || (b->type != TYPE_APPLICATION) || !b->subtype ||
485  !mutt_istr_equal(b->subtype, "pgp-encrypted"))
486  {
487  return 0;
488  }
489 
490  b = b->next;
491  if (!b || (b->type != TYPE_APPLICATION) || !b->subtype ||
492  !mutt_istr_equal(b->subtype, "octet-stream"))
493  {
494  return 0;
495  }
496 
497  return PGP_ENCRYPT;
498 }
+ 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 160 of file crypt.c.

161 {
162  struct Body *pbody = NULL, *tmp_pbody = NULL;
163  struct Body *tmp_smime_pbody = NULL;
164  struct Body *tmp_pgp_pbody = NULL;
165  bool has_retainable_sig = false;
166 
167  if (!WithCrypto)
168  return -1;
169 
170  SecurityFlags security = e->security;
171  int sign = security & (SEC_AUTOCRYPT | SEC_SIGN);
172  if (postpone)
173  {
174  sign = SEC_NO_FLAGS;
175  security &= ~SEC_SIGN;
176  }
177 
178  if (!(security & (SEC_ENCRYPT | SEC_AUTOCRYPT)) && !sign)
179  return 0;
180 
181  if (sign && !(security & SEC_AUTOCRYPT) && !crypt_valid_passphrase(security))
182  return -1;
183 
184  if (((WithCrypto & APPLICATION_PGP) != 0) && !(security & SEC_AUTOCRYPT) &&
185  ((security & PGP_INLINE) == PGP_INLINE))
186  {
187  const enum QuadOption c_pgp_mime_auto =
188  cs_subset_quad(NeoMutt->sub, "pgp_mime_auto");
189  if ((e->body->type != TYPE_TEXT) ||
190  !mutt_istr_equal(e->body->subtype, "plain"))
191  {
192  if (query_quadoption(c_pgp_mime_auto,
193  _("Inline PGP can't be used with attachments. "
194  "Revert to PGP/MIME?")) != MUTT_YES)
195  {
196  mutt_error(
197  _("Mail not sent: inline PGP can't be used with attachments"));
198  return -1;
199  }
200  }
201  else if (mutt_istr_equal("flowed",
202  mutt_param_get(&e->body->parameter, "format")))
203  {
204  if ((query_quadoption(c_pgp_mime_auto,
205  _("Inline PGP can't be used with format=flowed. "
206  "Revert to PGP/MIME?"))) != MUTT_YES)
207  {
208  mutt_error(
209  _("Mail not sent: inline PGP can't be used with format=flowed"));
210  return -1;
211  }
212  }
213  else
214  {
215  /* they really want to send it inline... go for it */
216  if (!isendwin())
217  {
218  mutt_endwin();
219  puts(_("Invoking PGP..."));
220  }
221  pbody = crypt_pgp_traditional_encryptsign(e->body, security, keylist);
222  if (pbody)
223  {
224  e->body = pbody;
225  return 0;
226  }
227 
228  /* otherwise inline won't work...ask for revert */
229  if (query_quadoption(
230  c_pgp_mime_auto,
231  _("Message can't be sent inline. Revert to using PGP/MIME?")) != MUTT_YES)
232  {
233  mutt_error(_("Mail not sent"));
234  return -1;
235  }
236  }
237 
238  /* go ahead with PGP/MIME */
239  }
240 
241  if (!isendwin())
242  mutt_endwin();
243 
245  tmp_smime_pbody = e->body;
247  tmp_pgp_pbody = e->body;
248 
249 #ifdef CRYPT_BACKEND_GPGME
250  const bool c_crypt_use_pka = cs_subset_bool(NeoMutt->sub, "crypt_use_pka");
251  if (sign && c_crypt_use_pka)
252 #else
253  if (sign)
254 #endif
255  {
256  /* Set sender (necessary for e.g. PKA). */
257  const char *mailbox = NULL;
258  struct Address *from = TAILQ_FIRST(&e->env->from);
259  bool free_from = false;
260 
261  if (!from)
262  {
263  free_from = true;
264  from = mutt_default_from(NeoMutt->sub);
265  }
266 
267  mailbox = from->mailbox;
268  const struct Address *c_envelope_from_address =
269  cs_subset_address(NeoMutt->sub, "envelope_from_address");
270  if (!mailbox && c_envelope_from_address)
271  mailbox = c_envelope_from_address->mailbox;
272 
273  if (((WithCrypto & APPLICATION_SMIME) != 0) && (security & APPLICATION_SMIME))
275  else if (((WithCrypto & APPLICATION_PGP) != 0) && (security & APPLICATION_PGP))
277 
278  if (free_from)
279  mutt_addr_free(&from);
280  }
281 
282  const bool c_crypt_protected_headers_write =
283  cs_subset_bool(NeoMutt->sub, "crypt_protected_headers_write");
284  if (c_crypt_protected_headers_write)
285  {
286  struct Envelope *protected_headers = mutt_env_new();
287  mutt_str_replace(&protected_headers->subject, e->env->subject);
288  /* Note: if other headers get added, such as to, cc, then a call to
289  * mutt_env_to_intl() will need to be added here too. */
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_write_rfc822_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 =
328  cs_subset_bool(NeoMutt->sub, "pgp_retainable_sigs");
329  if (((WithCrypto & APPLICATION_PGP) != 0) && (security & APPLICATION_PGP) &&
330  (!(security & (SEC_ENCRYPT | SEC_AUTOCRYPT)) || c_pgp_retainable_sigs))
331  {
332  tmp_pbody = crypt_pgp_sign_message(e->body, &e->env->from);
333  if (!tmp_pbody)
334  goto bail;
335 
336  has_retainable_sig = true;
337  sign = SEC_NO_FLAGS;
338  pbody = tmp_pbody;
339  tmp_pgp_pbody = tmp_pbody;
340  }
341 
342  if ((WithCrypto != 0) && (security & APPLICATION_SMIME) && (security & APPLICATION_PGP))
343  {
344  /* here comes the draft ;-) */
345  }
346  }
347 
348  if (security & (SEC_ENCRYPT | SEC_AUTOCRYPT))
349  {
350  if (((WithCrypto & APPLICATION_SMIME) != 0) && (security & APPLICATION_SMIME))
351  {
352  tmp_pbody = crypt_smime_build_smime_entity(tmp_smime_pbody, keylist);
353  if (!tmp_pbody)
354  {
355  /* signed ? free it! */
356  goto bail;
357  }
358  /* free tmp_body if messages was signed AND encrypted ... */
359  if ((tmp_smime_pbody != e->body) && (tmp_smime_pbody != tmp_pbody))
360  {
361  /* detach and don't delete e->body,
362  * which tmp_smime_pbody->parts after signing. */
363  tmp_smime_pbody->parts = tmp_smime_pbody->parts->next;
364  e->body->next = NULL;
365  mutt_body_free(&tmp_smime_pbody);
366  }
367  pbody = tmp_pbody;
368  }
369 
370  if (((WithCrypto & APPLICATION_PGP) != 0) && (security & APPLICATION_PGP))
371  {
372  pbody = crypt_pgp_encrypt_message(e, tmp_pgp_pbody, keylist, sign, &e->env->from);
373  if (!pbody)
374  {
375  /* did we perform a retainable signature? */
376  if (has_retainable_sig)
377  {
378  /* remove the outer multipart layer */
379  tmp_pgp_pbody = mutt_remove_multipart(tmp_pgp_pbody);
380  /* get rid of the signature */
381  mutt_body_free(&tmp_pgp_pbody->next);
382  }
383 
384  goto bail;
385  }
386 
387  // destroy temporary signature envelope when doing retainable signatures.
388  if (has_retainable_sig)
389  {
390  tmp_pgp_pbody = mutt_remove_multipart(tmp_pgp_pbody);
391  mutt_body_free(&tmp_pgp_pbody->next);
392  }
393  }
394  }
395 
396  if (pbody)
397  {
398  e->body = pbody;
399  return 0;
400  }
401 
402 bail:
404  mutt_param_delete(&e->body->parameter, "protected-headers");
405  return -1;
406 }
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:831
struct Body * crypt_pgp_traditional_encryptsign(struct Body *a, SecurityFlags flags, char *keylist)
Wrapper for CryptModuleSpecs::pgp_traditional_encryptsign()
Definition: cryptglue.c:295
struct Body * crypt_smime_build_smime_entity(struct Body *a, char *certlist)
Wrapper for CryptModuleSpecs::smime_build_smime_entity()
Definition: cryptglue.c:498
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:339
struct Body * crypt_smime_sign_message(struct Body *a, const struct AddressList *from)
Wrapper for CryptModuleSpecs::sign_message()
Definition: cryptglue.c:487
void crypt_pgp_set_sender(const char *sender)
Wrapper for CryptModuleSpecs::set_sender()
Definition: cryptglue.c:405
void crypt_smime_set_sender(const char *sender)
Wrapper for CryptModuleSpecs::set_sender()
Definition: cryptglue.c:540
struct Body * crypt_pgp_sign_message(struct Body *a, const struct AddressList *from)
Wrapper for CryptModuleSpecs::sign_message()
Definition: cryptglue.c:328
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:96
struct Envelope * mutt_env_new(void)
Create a new Envelope.
Definition: envelope.c:42
#define mutt_error(...)
Definition: logging.h:87
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 * 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:257
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:349
struct Address * mutt_default_from(struct ConfigSubset *sub)
Get a default 'from' Address.
Definition: send.c:1468
void mutt_prepare_envelope(struct Envelope *env, bool final, struct ConfigSubset *sub)
Prepare an email header.
Definition: sendlib.c:1251
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:35
struct Envelope * mime_headers
Memory hole protected headers.
Definition: body.h:74
struct Body * body
List of MIME parts.
Definition: email.h:67
The header of an Email.
Definition: envelope.h:55
char * subject
Email's subject.
Definition: envelope.h:68
+ 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 1103 of file crypt.c.

1104 {
1105  const bool c_crypt_protected_headers_write =
1106  cs_subset_bool(NeoMutt->sub, "crypt_protected_headers_write");
1107  const char *const c_crypt_protected_headers_subject =
1108  cs_subset_string(NeoMutt->sub, "crypt_protected_headers_subject");
1109  if (c_crypt_protected_headers_write && (e->security & (SEC_ENCRYPT | SEC_AUTOCRYPT)) &&
1110  !(e->security & SEC_INLINE) && c_crypt_protected_headers_subject)
1111  {
1112  return true;
1113  }
1114 
1115  return false;
1116 }
#define SEC_INLINE
Email has an inline signature.
Definition: lib.h:82
+ 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 143 of file cryptglue.c.

144 {
145  if (CRYPT_MOD_CALL_CHECK(PGP, cleanup))
146  (CRYPT_MOD_CALL(PGP, cleanup))();
147 
148  if (CRYPT_MOD_CALL_CHECK(SMIME, cleanup))
149  (CRYPT_MOD_CALL(SMIME, cleanup))();
150 }
#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 172 of file cryptglue.c.

173 {
174  if (((WithCrypto & APPLICATION_PGP) != 0) && (type & APPLICATION_PGP) &&
176  {
177  return true;
178  }
179 
180  if (((WithCrypto & APPLICATION_SMIME) != 0) && (type & APPLICATION_SMIME) &&
182  {
183  return true;
184  }
185 
186  return false;
187 }
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 =
98  cs_subset_bool(NeoMutt->sub, "crypt_use_gpgme");
99 #endif
100 #ifdef CRYPT_BACKEND_CLASSIC_PGP
101  if (
102 #ifdef CRYPT_BACKEND_GPGME
103  (!c_crypt_use_gpgme)
104 #else
105  1
106 #endif
107  )
109 #endif
110 
111 #ifdef CRYPT_BACKEND_CLASSIC_SMIME
112  if (
113 #ifdef CRYPT_BACKEND_GPGME
114  (!c_crypt_use_gpgme)
115 #else
116  1
117 #endif
118  )
120 #endif
121 
122 #ifdef CRYPT_BACKEND_GPGME
123  if (c_crypt_use_gpgme)
124  {
127  }
128 #endif
129 
130 #if defined(CRYPT_BACKEND_CLASSIC_PGP) || \
131  defined(CRYPT_BACKEND_CLASSIC_SMIME) || defined(CRYPT_BACKEND_GPGME)
132  if (CRYPT_MOD_CALL_CHECK(PGP, init))
133  CRYPT_MOD_CALL(PGP, init)();
134 
135  if (CRYPT_MOD_CALL_CHECK(SMIME, init))
136  CRYPT_MOD_CALL(SMIME, init)();
137 #endif
138 }
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 158 of file cryptglue.c.

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

285 {
286  if (CRYPT_MOD_CALL_CHECK(PGP, pgp_check_traditional))
287  return CRYPT_MOD_CALL(PGP, pgp_check_traditional)(fp, b, just_one);
288 
289  return false;
290 }
+ 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 212 of file cryptglue.c.

213 {
214 #ifdef USE_AUTOCRYPT
215  const bool c_autocrypt = cs_subset_bool(NeoMutt->sub, "autocrypt");
216  if (c_autocrypt)
217  {
218  OptAutocryptGpgme = true;
219  int result = pgp_gpgme_decrypt_mime(fp_in, fp_out, b, cur);
220  OptAutocryptGpgme = false;
221  if (result == 0)
222  {
223  b->is_autocrypt = true;
224  return result;
225  }
226  }
227 #endif
228 
229  if (CRYPT_MOD_CALL_CHECK(PGP, decrypt_mime))
230  return CRYPT_MOD_CALL(PGP, decrypt_mime)(fp_in, fp_out, b, cur);
231 
232  return -1;
233 }
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:2213
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 396 of file cryptglue.c.

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

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

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

386 {
387  if (CRYPT_MOD_CALL_CHECK(PGP, send_menu))
388  return CRYPT_MOD_CALL(PGP, send_menu)(e);
389 
390  return 0;
391 }
+ 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 434 of file cryptglue.c.

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

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

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

466 {
467  if (CRYPT_MOD_CALL_CHECK(SMIME, smime_verify_sender))
468  return CRYPT_MOD_CALL(SMIME, smime_verify_sender)(e, msg);
469 
470  return 1;
471 }
+ 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  {
86  STAILQ_REMOVE(&CryptModules, np, CryptModule, entries);
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 3989 of file crypt_gpgme.c.

3990 {
3991  int rc = -1, junk;
3992  gpgme_error_t err;
3993  gpgme_key_t key = NULL;
3994  gpgme_user_id_t uid = NULL;
3995  struct CryptKeyInfo *results = NULL, *k = NULL;
3996  struct CryptKeyInfo **kend = NULL;
3997  struct CryptKeyInfo *choice = NULL;
3998 
3999  gpgme_ctx_t ctx = create_gpgme_context(false);
4000 
4001  /* list all secret keys */
4002  if (gpgme_op_keylist_start(ctx, NULL, 1))
4003  goto cleanup;
4004 
4005  kend = &results;
4006 
4007  while (!(err = gpgme_op_keylist_next(ctx, &key)))
4008  {
4010 
4013  if (key_check_cap(key, KEY_CAP_CAN_SIGN))
4015 
4016  if (key->revoked)
4018  if (key->expired)
4020  if (key->disabled)
4022 
4023  int idx;
4024  for (idx = 0, uid = key->uids; uid; idx++, uid = uid->next)
4025  {
4026  k = mutt_mem_calloc(1, sizeof(*k));
4027  k->kobj = key;
4028  gpgme_key_ref(k->kobj);
4029  k->idx = idx;
4030  k->uid = uid->uid;
4031  k->flags = flags;
4032  if (uid->revoked)
4033  k->flags |= KEYFLAG_REVOKED;
4034  k->validity = uid->validity;
4035  *kend = k;
4036  kend = &k->next;
4037  }
4038  gpgme_key_unref(key);
4039  }
4040  if (gpg_err_code(err) != GPG_ERR_EOF)
4041  mutt_error(_("gpgme_op_keylist_next failed: %s"), gpgme_strerror(err));
4042  gpgme_op_keylist_end(ctx);
4043 
4044  if (!results)
4045  {
4046  /* L10N: mutt_gpgme_select_secret_key() tries to list all secret keys to choose
4047  from. This error is displayed if no results were found. */
4048  mutt_error(_("No secret keys found"));
4049  goto cleanup;
4050  }
4051 
4052  choice = dlg_select_gpgme_key(results, NULL, "*", APPLICATION_PGP, &junk);
4053  if (!(choice && choice->kobj && choice->kobj->subkeys && choice->kobj->subkeys->fpr))
4054  goto cleanup;
4055  mutt_buffer_strcpy(keyid, choice->kobj->subkeys->fpr);
4056 
4057  rc = 0;
4058 
4059 cleanup:
4060  crypt_key_free(&choice);
4061  crypt_key_free(&results);
4062  gpgme_release(ctx);
4063  return rc;
4064 }
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:312
gpgme_ctx_t create_gpgme_context(bool for_smime)
Create a new GPGME context.
Definition: crypt_gpgme.c:573
unsigned int key_check_cap(gpgme_key_t key, enum KeyCap cap)
Check the capabilities of a key.
Definition: crypt_gpgme.c:3266
static void crypt_key_free(struct CryptKeyInfo **keylist)
Release all the keys in a list.
Definition: crypt_gpgme.c:464
@ 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, int *forced_valid)
Get the user to select a key.
Definition: dlggpgme.c:1315
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:128
uint16_t KeyFlags
Flags describing PGP/SMIME keys, e.g. KEYFLAG_CANSIGN.
Definition: lib.h:122
#define KEYFLAG_CANENCRYPT
Key is suitable for encryption.
Definition: lib.h:125
#define KEYFLAG_NO_FLAGS
No flags are set.
Definition: lib.h:123
#define KEYFLAG_DISABLED
Key is marked disabled.
Definition: lib.h:130
#define KEYFLAG_REVOKED
Key is revoked.
Definition: lib.h:129
#define KEYFLAG_CANSIGN
Key is suitable for signing.
Definition: lib.h:124
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 4477 of file crypt_gpgme.c.

4478 {
4479  return GPGME_VERSION;
4480 }
+ Here is the caller graph for this function: