NeoMutt  2022-04-29-81-g9c5a59
Teaching an old dog new tricks
DOXYGEN
cryptglue.c
Go to the documentation of this file.
1 
38 #include "config.h"
39 #include <stdbool.h>
40 #include <stdio.h>
41 #include "mutt/lib.h"
42 #include "core/lib.h"
43 #include "cryptglue.h"
44 #include "lib.h"
45 #include "crypt_mod.h"
46 #ifndef CRYPT_BACKEND_GPGME
47 #include "gui/lib.h"
48 #endif
49 #if defined(CRYPT_BACKEND_GPGME) || defined(USE_AUTOCRYPT)
50 #include "config/lib.h"
51 #endif
52 #ifdef USE_AUTOCRYPT
53 #include "email/lib.h"
54 #include "autocrypt/lib.h"
55 #include "crypt_gpgme.h"
56 #include "options.h"
57 #else
58 struct Envelope;
59 #endif
60 
61 struct Address;
62 struct AddressList;
63 
64 #ifdef CRYPT_BACKEND_CLASSIC_PGP
66 #endif
67 
68 #ifdef CRYPT_BACKEND_CLASSIC_SMIME
70 #endif
71 
72 #ifdef CRYPT_BACKEND_GPGME
75 #endif
76 
77 /* If the crypto module identifier by IDENTIFIER has been registered,
78  * call its function FUNC. Do nothing else. This may be used as an
79  * expression. */
80 #define CRYPT_MOD_CALL_CHECK(identifier, func) \
81  (crypto_module_lookup(APPLICATION_##identifier) && \
82  (crypto_module_lookup(APPLICATION_##identifier))->func)
83 
84 /* Call the function FUNC in the crypto module identified by
85  * IDENTIFIER. This may be used as an expression. */
86 #define CRYPT_MOD_CALL(identifier, func) \
87  (*(crypto_module_lookup(APPLICATION_##identifier))->func)
88 
94 void crypt_init(void)
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 }
138 
142 void crypt_cleanup(void)
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 }
150 
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 }
164 
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 }
187 
192 {
195 }
196 
201 {
203  return CRYPT_MOD_CALL(PGP, valid_passphrase)();
204 
205  return false;
206 }
207 
211 int crypt_pgp_decrypt_mime(FILE *fp_in, FILE **fp_out, struct Body *b, struct Body **cur)
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 
229  return CRYPT_MOD_CALL(PGP, decrypt_mime)(fp_in, fp_out, b, cur);
230 
231  return -1;
232 }
233 
237 int crypt_pgp_application_handler(struct Body *b, struct State *s)
238 {
240  return CRYPT_MOD_CALL(PGP, application_handler)(b, s);
241 
242  return -1;
243 }
244 
248 int crypt_pgp_encrypted_handler(struct Body *b, struct State *s)
249 {
250 #ifdef USE_AUTOCRYPT
251  const bool c_autocrypt = cs_subset_bool(NeoMutt->sub, "autocrypt");
252  if (c_autocrypt)
253  {
254  OptAutocryptGpgme = true;
255  int result = pgp_gpgme_encrypted_handler(b, s);
256  OptAutocryptGpgme = false;
257  if (result == 0)
258  {
259  b->is_autocrypt = true;
260  return result;
261  }
262  }
263 #endif
264 
266  return CRYPT_MOD_CALL(PGP, encrypted_handler)(b, s);
267 
268  return -1;
269 }
270 
275 {
278 }
279 
283 bool crypt_pgp_check_traditional(FILE *fp, struct Body *b, bool just_one)
284 {
286  return CRYPT_MOD_CALL(PGP, pgp_check_traditional)(fp, b, just_one);
287 
288  return false;
289 }
290 
294 struct Body *crypt_pgp_traditional_encryptsign(struct Body *a, SecurityFlags flags, char *keylist)
295 {
296  if (CRYPT_MOD_CALL_CHECK(PGP, pgp_traditional_encryptsign))
297  return CRYPT_MOD_CALL(PGP, pgp_traditional_encryptsign)(a, flags, keylist);
298 
299  return NULL;
300 }
301 
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 }
312 
316 char *crypt_pgp_find_keys(struct AddressList *addrlist, bool oppenc_mode)
317 {
319  return CRYPT_MOD_CALL(PGP, find_keys)(addrlist, oppenc_mode);
320 
321  return NULL;
322 }
323 
327 struct Body *crypt_pgp_sign_message(struct Body *a, const struct AddressList *from)
328 {
330  return CRYPT_MOD_CALL(PGP, sign_message)(a, from);
331 
332  return NULL;
333 }
334 
338 struct Body *crypt_pgp_encrypt_message(struct Email *e, struct Body *a, char *keylist,
339  int sign, const struct AddressList *from)
340 {
341 #ifdef USE_AUTOCRYPT
342  if (e->security & SEC_AUTOCRYPT)
343  {
345  return NULL;
346 
347  OptAutocryptGpgme = true;
348  struct Body *result = pgp_gpgme_encrypt_message(a, keylist, sign, from);
349  OptAutocryptGpgme = false;
350 
351  return result;
352  }
353 #endif
354 
355  if (CRYPT_MOD_CALL_CHECK(PGP, pgp_encrypt_message))
356  return CRYPT_MOD_CALL(PGP, pgp_encrypt_message)(a, keylist, sign, from);
357 
358  return NULL;
359 }
360 
364 void crypt_pgp_invoke_import(const char *fname)
365 {
366  if (CRYPT_MOD_CALL_CHECK(PGP, pgp_invoke_import))
367  CRYPT_MOD_CALL(PGP, pgp_invoke_import)(fname);
368 }
369 
373 int crypt_pgp_verify_one(struct Body *sigbdy, struct State *s, const char *tempf)
374 {
376  return CRYPT_MOD_CALL(PGP, verify_one)(sigbdy, s, tempf);
377 
378  return -1;
379 }
380 
385 {
386  if (CRYPT_MOD_CALL_CHECK(PGP, send_menu))
387  return CRYPT_MOD_CALL(PGP, send_menu)(e);
388 
389  return 0;
390 }
391 
395 void crypt_pgp_extract_key_from_attachment(FILE *fp, struct Body *top)
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 }
400 
404 void crypt_pgp_set_sender(const char *sender)
405 {
406  if (CRYPT_MOD_CALL_CHECK(PGP, set_sender))
407  CRYPT_MOD_CALL(PGP, set_sender)(sender);
408 }
409 
414 {
415  if (CRYPT_MOD_CALL_CHECK(SMIME, void_passphrase))
416  CRYPT_MOD_CALL(SMIME, void_passphrase)();
417 }
418 
423 {
424  if (CRYPT_MOD_CALL_CHECK(SMIME, valid_passphrase))
425  return CRYPT_MOD_CALL(SMIME, valid_passphrase)();
426 
427  return false;
428 }
429 
433 int crypt_smime_decrypt_mime(FILE *fp_in, FILE **fp_out, struct Body *b, struct Body **cur)
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 }
440 
444 int crypt_smime_application_handler(struct Body *b, struct State *s)
445 {
446  if (CRYPT_MOD_CALL_CHECK(SMIME, application_handler))
447  return CRYPT_MOD_CALL(SMIME, application_handler)(b, s);
448 
449  return -1;
450 }
451 
455 void crypt_smime_getkeys(struct Envelope *env)
456 {
457  if (CRYPT_MOD_CALL_CHECK(SMIME, smime_getkeys))
458  CRYPT_MOD_CALL(SMIME, smime_getkeys)(env);
459 }
460 
464 int crypt_smime_verify_sender(struct Email *e, struct Message *msg)
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 }
471 
475 char *crypt_smime_find_keys(struct AddressList *addrlist, bool oppenc_mode)
476 {
477  if (CRYPT_MOD_CALL_CHECK(SMIME, find_keys))
478  return CRYPT_MOD_CALL(SMIME, find_keys)(addrlist, oppenc_mode);
479 
480  return NULL;
481 }
482 
486 struct Body *crypt_smime_sign_message(struct Body *a, const struct AddressList *from)
487 {
489  return CRYPT_MOD_CALL(SMIME, sign_message)(a, from);
490 
491  return NULL;
492 }
493 
497 struct Body *crypt_smime_build_smime_entity(struct Body *a, char *certlist)
498 {
499  if (CRYPT_MOD_CALL_CHECK(SMIME, smime_build_smime_entity))
500  return CRYPT_MOD_CALL(SMIME, smime_build_smime_entity)(a, certlist);
501 
502  return NULL;
503 }
504 
508 void crypt_smime_invoke_import(const char *infile, const char *mailbox)
509 {
510  if (CRYPT_MOD_CALL_CHECK(SMIME, smime_invoke_import))
511  CRYPT_MOD_CALL(SMIME, smime_invoke_import)(infile, mailbox);
512 }
513 
517 int crypt_smime_verify_one(struct Body *sigbdy, struct State *s, const char *tempf)
518 {
519  if (CRYPT_MOD_CALL_CHECK(SMIME, verify_one))
520  return CRYPT_MOD_CALL(SMIME, verify_one)(sigbdy, s, tempf);
521 
522  return -1;
523 }
524 
529 {
530  if (CRYPT_MOD_CALL_CHECK(SMIME, send_menu))
531  return CRYPT_MOD_CALL(SMIME, send_menu)(e);
532 
533  return 0;
534 }
535 
539 void crypt_smime_set_sender(const char *sender)
540 {
541  if (CRYPT_MOD_CALL_CHECK(SMIME, set_sender))
542  CRYPT_MOD_CALL(SMIME, set_sender)(sender);
543 }
Autocrypt end-to-end encryption.
int mutt_autocrypt_set_sign_as_default_key(struct Email *e)
Set the Autocrypt default key for signing.
Definition: autocrypt.c:702
Convenience wrapper for the config headers.
Convenience wrapper for the core headers.
static int verify_one(struct Body *sigbdy, struct State *s, const char *tempfile, bool is_smime)
Do the actual verification step.
Definition: crypt_gpgme.c:1901
static char * find_keys(const struct AddressList *addrlist, unsigned int app, bool oppenc_mode)
Find keys of the recipients of the message.
Definition: crypt_gpgme.c:3817
static struct Body * sign_message(struct Body *a, const struct AddressList *from, bool use_smime)
Sign a message.
Definition: crypt_gpgme.c:1262
Wrapper for PGP/SMIME calls to GPGME.
void crypto_module_register(struct CryptModuleSpecs *specs)
Register a new crypto module.
Definition: crypt_mod.c:51
struct CryptModuleSpecs * crypto_module_lookup(int identifier)
Lookup a crypto module by name.
Definition: crypt_mod.c:65
Register crypto modules.
bool crypt_has_module_backend(SecurityFlags type)
Is there a crypto backend for a given type?
Definition: cryptglue.c:171
void crypt_invoke_message(SecurityFlags type)
Display an informative message.
Definition: cryptglue.c:157
struct Body * crypt_pgp_traditional_encryptsign(struct Body *a, SecurityFlags flags, char *keylist)
Wrapper for CryptModuleSpecs::pgp_traditional_encryptsign()
Definition: cryptglue.c:294
struct CryptModuleSpecs CryptModPgpGpgme
GPGME PGP - Implements CryptModuleSpecs.
struct CryptModuleSpecs CryptModPgpClassic
CLI PGP - Implements CryptModuleSpecs.
struct Body * crypt_smime_build_smime_entity(struct Body *a, char *certlist)
Wrapper for CryptModuleSpecs::smime_build_smime_entity()
Definition: cryptglue.c:497
int crypt_smime_decrypt_mime(FILE *fp_in, FILE **fp_out, struct Body *b, struct Body **cur)
Wrapper for CryptModuleSpecs::decrypt_mime()
Definition: cryptglue.c:433
void crypt_cleanup(void)
Clean up backend.
Definition: cryptglue.c:142
void crypt_smime_getkeys(struct Envelope *env)
Wrapper for CryptModuleSpecs::smime_getkeys()
Definition: cryptglue.c:455
char * crypt_smime_find_keys(struct AddressList *addrlist, bool oppenc_mode)
Wrapper for CryptModuleSpecs::find_keys()
Definition: cryptglue.c:475
bool crypt_pgp_check_traditional(FILE *fp, struct Body *b, bool just_one)
Wrapper for CryptModuleSpecs::pgp_check_traditional()
Definition: cryptglue.c:283
#define CRYPT_MOD_CALL_CHECK(identifier, func)
Definition: cryptglue.c:80
SecurityFlags crypt_smime_send_menu(struct Email *e)
Wrapper for CryptModuleSpecs::send_menu()
Definition: cryptglue.c:528
SecurityFlags crypt_pgp_send_menu(struct Email *e)
Wrapper for CryptModuleSpecs::send_menu()
Definition: cryptglue.c:384
void crypt_pgp_invoke_getkeys(struct Address *addr)
Wrapper for CryptModuleSpecs::pgp_invoke_getkeys()
Definition: cryptglue.c:274
int crypt_smime_verify_one(struct Body *sigbdy, struct State *s, const char *tempf)
Wrapper for CryptModuleSpecs::verify_one()
Definition: cryptglue.c:517
bool crypt_smime_valid_passphrase(void)
Wrapper for CryptModuleSpecs::valid_passphrase()
Definition: cryptglue.c:422
void crypt_pgp_invoke_import(const char *fname)
Wrapper for CryptModuleSpecs::pgp_invoke_import()
Definition: cryptglue.c:364
void crypt_smime_void_passphrase(void)
Wrapper for CryptModuleSpecs::void_passphrase()
Definition: cryptglue.c:413
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_smime_sign_message(struct Body *a, const struct AddressList *from)
Wrapper for CryptModuleSpecs::sign_message()
Definition: cryptglue.c:486
struct CryptModuleSpecs CryptModSmimeGpgme
GPGME SMIME - Implements CryptModuleSpecs.
int crypt_pgp_verify_one(struct Body *sigbdy, struct State *s, const char *tempf)
Wrapper for CryptModuleSpecs::verify_one()
Definition: cryptglue.c:373
void crypt_smime_invoke_import(const char *infile, const char *mailbox)
Wrapper for CryptModuleSpecs::smime_invoke_import()
Definition: cryptglue.c:508
int crypt_smime_verify_sender(struct Email *e, struct Message *msg)
Wrapper for CryptModuleSpecs::smime_verify_sender()
Definition: cryptglue.c:464
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
int crypt_pgp_decrypt_mime(FILE *fp_in, FILE **fp_out, struct Body *b, struct Body **cur)
Wrapper for CryptModuleSpecs::decrypt_mime()
Definition: cryptglue.c:211
void crypt_init(void)
Initialise the crypto backends.
Definition: cryptglue.c:94
void crypt_pgp_void_passphrase(void)
Wrapper for CryptModuleSpecs::void_passphrase()
Definition: cryptglue.c:191
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_pgp_make_key_attachment(void)
Wrapper for CryptModuleSpecs::pgp_make_key_attachment()
Definition: cryptglue.c:305
#define CRYPT_MOD_CALL(identifier, func)
Definition: cryptglue.c:86
char * crypt_pgp_find_keys(struct AddressList *addrlist, bool oppenc_mode)
Wrapper for CryptModuleSpecs::find_keys()
Definition: cryptglue.c:316
bool crypt_pgp_valid_passphrase(void)
Wrapper for CryptModuleSpecs::valid_passphrase()
Definition: cryptglue.c:200
struct CryptModuleSpecs CryptModSmimeClassic
CLI SMIME - Implements CryptModuleSpecs.
void crypt_pgp_extract_key_from_attachment(FILE *fp, struct Body *top)
Wrapper for CryptModuleSpecs::pgp_extract_key_from_attachment()
Definition: cryptglue.c:395
Wrapper around crypto functions.
Structs that make up an email.
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:2210
int pgp_gpgme_encrypted_handler(struct Body *a, struct State *s)
Implements CryptModuleSpecs::encrypted_handler() -.
Definition: crypt_gpgme.c:3067
struct Body * pgp_gpgme_encrypt_message(struct Body *a, char *keylist, bool sign, const struct AddressList *from)
Implements CryptModuleSpecs::pgp_encrypt_message() -.
Definition: crypt_gpgme.c:1399
int crypt_pgp_encrypted_handler(struct Body *b, struct State *s)
Wrapper for CryptModuleSpecs::encrypted_handler() - Implements handler_t -.
Definition: cryptglue.c:248
int crypt_smime_application_handler(struct Body *b, struct State *s)
Wrapper for CryptModuleSpecs::application_handler() - Implements handler_t -.
Definition: cryptglue.c:444
int crypt_pgp_application_handler(struct Body *b, struct State *s)
Wrapper for CryptModuleSpecs::application_handler() - Implements handler_t -.
Definition: cryptglue.c:237
#define mutt_message(...)
Definition: logging.h:86
Convenience wrapper for the gui headers.
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
Convenience wrapper for the library headers.
#define _(a)
Definition: message.h:28
#define SEC_AUTOCRYPT
(Autocrypt) Message will be, or was Autocrypt encrypt+signed
Definition: lib.h:87
uint16_t SecurityFlags
Flags, e.g. SEC_ENCRYPT.
Definition: lib.h:74
#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 WithCrypto
Definition: lib.h:116
Handling of global boolean variables.
bool OptAutocryptGpgme
(pseudo) use Autocrypt context inside ncrypt/crypt_gpgme.c
Definition: options.h:39
Key value store.
An email address.
Definition: address.h:36
The body of an email.
Definition: body.h:36
bool is_autocrypt
Flag autocrypt-decrypted messages for replying.
Definition: body.h:50
int(* encrypted_handler)(struct Body *m, struct State *s)
Definition: crypt_mod.h:123
int(* decrypt_mime)(FILE *fp_in, FILE **fp_out, struct Body *b, struct Body **cur)
Definition: crypt_mod.h:99
void(* init)(void)
Definition: crypt_mod.h:56
bool(* valid_passphrase)(void)
Definition: crypt_mod.h:85
void(* cleanup)(void)
Definition: crypt_mod.h:64
int(* application_handler)(struct Body *m, struct State *s)
Definition: crypt_mod.h:111
bool(* pgp_check_traditional)(FILE *fp, struct Body *b, bool just_one)
Definition: crypt_mod.h:221
void(* void_passphrase)(void)
Definition: crypt_mod.h:72
void(* pgp_invoke_getkeys)(struct Address *addr)
Definition: crypt_mod.h:243
The envelope/body of an email.
Definition: email.h:37
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/lib.h pgplib....
Definition: email.h:41
The header of an Email.
Definition: envelope.h:57
A local copy of an email.
Definition: mxapi.h:43
Container for Accounts, Notifications.
Definition: neomutt.h:37
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
Keep track when processing files.
Definition: state.h:46