NeoMutt  2018-07-16 +2481-68dcde
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/mutt.h"
42 #include "crypt_mod.h"
43 #include "curs_lib.h"
44 #include "globals.h"
45 #include "ncrypt.h"
46 #include "options.h"
47 #ifdef USE_AUTOCRYPT
48 #include "autocrypt/autocrypt.h"
49 #endif
50 
51 struct Address;
52 struct AddressList;
53 struct Body;
54 struct Envelope;
55 struct Email;
56 struct State;
57 
58 /* These Config Variables are only used in ncrypt/cryptglue.c */
59 bool C_CryptUseGpgme;
60 
61 #ifdef CRYPT_BACKEND_CLASSIC_PGP
63 #endif
64 
65 #ifdef CRYPT_BACKEND_CLASSIC_SMIME
67 #endif
68 
69 #ifdef CRYPT_BACKEND_GPGME
70 #include "ncrypt/crypt_gpgme.h"
73 #endif
74 
75 /* If the crypto module identifier by IDENTIFIER has been registered,
76  * call its function FUNC. Do nothing else. This may be used as an
77  * expression. */
78 #define CRYPT_MOD_CALL_CHECK(identifier, func) \
79  (crypto_module_lookup(APPLICATION_##identifier) && \
80  (crypto_module_lookup(APPLICATION_##identifier))->func)
81 
82 /* Call the function FUNC in the crypto module identified by
83  * IDENTIFIER. This may be used as an expression. */
84 #define CRYPT_MOD_CALL(identifier, func) \
85  (*(crypto_module_lookup(APPLICATION_##identifier))->func)
86 
92 void crypt_init(void)
93 {
94 #ifdef CRYPT_BACKEND_CLASSIC_PGP
95  if (
96 #ifdef CRYPT_BACKEND_GPGME
98 #else
99  1
100 #endif
101  )
103 #endif
104 
105 #ifdef CRYPT_BACKEND_CLASSIC_SMIME
106  if (
107 #ifdef CRYPT_BACKEND_GPGME
108  (!C_CryptUseGpgme)
109 #else
110  1
111 #endif
112  )
114 #endif
115 
116  if (C_CryptUseGpgme)
117  {
118 #ifdef CRYPT_BACKEND_GPGME
121 #else
122  mutt_message(_("\"crypt_use_gpgme\" set"
123  " but not built with GPGME support"));
124  if (mutt_any_key_to_continue(NULL) == -1)
125  mutt_exit(1);
126 #endif
127  }
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 
146 {
147  if (((WithCrypto & APPLICATION_PGP) != 0) && (type & APPLICATION_PGP))
148  mutt_message(_("Invoking PGP..."));
149  else if (((WithCrypto & APPLICATION_SMIME) != 0) && (type & APPLICATION_SMIME))
150  mutt_message(_("Invoking S/MIME..."));
151 }
152 
160 {
161  if (((WithCrypto & APPLICATION_PGP) != 0) && (type & APPLICATION_PGP) &&
162  crypto_module_lookup(APPLICATION_PGP))
163  {
164  return true;
165  }
166 
167  if (((WithCrypto & APPLICATION_SMIME) != 0) && (type & APPLICATION_SMIME) &&
168  crypto_module_lookup(APPLICATION_SMIME))
169  {
170  return true;
171  }
172 
173  return false;
174 }
175 
180 {
183 }
184 
189 {
191  return CRYPT_MOD_CALL(PGP, valid_passphrase)();
192 
193  return false;
194 }
195 
199 int crypt_pgp_decrypt_mime(FILE *fp_in, FILE **fp_out, struct Body *b, struct Body **cur)
200 {
201 #ifdef USE_AUTOCRYPT
202  if (C_Autocrypt)
203  {
204  OptAutocryptGpgme = true;
205  int result = pgp_gpgme_decrypt_mime(fp_in, fp_out, b, cur);
206  OptAutocryptGpgme = false;
207  if (result == 0)
208  {
209  b->is_autocrypt = true;
210  return result;
211  }
212  }
213 #endif
214 
216  return CRYPT_MOD_CALL(PGP, decrypt_mime)(fp_in, fp_out, b, cur);
217 
218  return -1;
219 }
220 
226 int crypt_pgp_application_handler(struct Body *m, struct State *s)
227 {
229  return CRYPT_MOD_CALL(PGP, application_handler)(m, s);
230 
231  return -1;
232 }
233 
239 int crypt_pgp_encrypted_handler(struct Body *a, struct State *s)
240 {
241 #ifdef USE_AUTOCRYPT
242  if (C_Autocrypt)
243  {
244  OptAutocryptGpgme = true;
245  int result = pgp_gpgme_encrypted_handler(a, s);
246  OptAutocryptGpgme = false;
247  if (result == 0)
248  {
249  a->is_autocrypt = true;
250  return result;
251  }
252  }
253 #endif
254 
256  return CRYPT_MOD_CALL(PGP, encrypted_handler)(a, s);
257 
258  return -1;
259 }
260 
265 {
268 }
269 
273 int crypt_pgp_check_traditional(FILE *fp, struct Body *b, bool just_one)
274 {
276  return CRYPT_MOD_CALL(PGP, pgp_check_traditional)(fp, b, just_one);
277 
278  return 0;
279 }
280 
284 struct Body *crypt_pgp_traditional_encryptsign(struct Body *a, int flags, char *keylist)
285 {
286  if (CRYPT_MOD_CALL_CHECK(PGP, pgp_traditional_encryptsign))
287  return CRYPT_MOD_CALL(PGP, pgp_traditional_encryptsign)(a, flags, keylist);
288 
289  return NULL;
290 }
291 
296 {
297  if (CRYPT_MOD_CALL_CHECK(PGP, pgp_make_key_attachment))
298  return CRYPT_MOD_CALL(PGP, pgp_make_key_attachment)();
299 
300  return NULL;
301 }
302 
306 char *crypt_pgp_find_keys(struct AddressList *addrlist, bool oppenc_mode)
307 {
309  return CRYPT_MOD_CALL(PGP, find_keys)(addrlist, oppenc_mode);
310 
311  return NULL;
312 }
313 
317 struct Body *crypt_pgp_sign_message(struct Body *a)
318 {
320  return CRYPT_MOD_CALL(PGP, sign_message)(a);
321 
322  return NULL;
323 }
324 
328 struct Body *crypt_pgp_encrypt_message(struct Email *e, struct Body *a, char *keylist, int sign)
329 {
330 #ifdef USE_AUTOCRYPT
331  if (e->security & SEC_AUTOCRYPT)
332  {
334  return NULL;
335 
336  OptAutocryptGpgme = true;
337  struct Body *result = pgp_gpgme_encrypt_message(a, keylist, sign);
338  OptAutocryptGpgme = false;
339 
340  return result;
341  }
342 #endif
343 
344  if (CRYPT_MOD_CALL_CHECK(PGP, pgp_encrypt_message))
345  return CRYPT_MOD_CALL(PGP, pgp_encrypt_message)(a, keylist, sign);
346 
347  return NULL;
348 }
349 
353 void crypt_pgp_invoke_import(const char *fname)
354 {
355  if (CRYPT_MOD_CALL_CHECK(PGP, pgp_invoke_import))
356  CRYPT_MOD_CALL(PGP, pgp_invoke_import)(fname);
357 }
358 
362 int crypt_pgp_verify_one(struct Body *sigbdy, struct State *s, const char *tempf)
363 {
365  return CRYPT_MOD_CALL(PGP, verify_one)(sigbdy, s, tempf);
366 
367  return -1;
368 }
369 
374 {
375  if (CRYPT_MOD_CALL_CHECK(PGP, send_menu))
376  return CRYPT_MOD_CALL(PGP, send_menu)(e);
377 
378  return 0;
379 }
380 
384 void crypt_pgp_extract_key_from_attachment(FILE *fp, struct Body *top)
385 {
386  if (CRYPT_MOD_CALL_CHECK(PGP, pgp_extract_key_from_attachment))
387  CRYPT_MOD_CALL(PGP, pgp_extract_key_from_attachment)(fp, top);
388 }
389 
393 void crypt_pgp_set_sender(const char *sender)
394 {
395  if (CRYPT_MOD_CALL_CHECK(PGP, set_sender))
396  CRYPT_MOD_CALL(PGP, set_sender)(sender);
397 }
398 
403 {
404  if (CRYPT_MOD_CALL_CHECK(SMIME, void_passphrase))
405  CRYPT_MOD_CALL(SMIME, void_passphrase)();
406 }
407 
412 {
413  if (CRYPT_MOD_CALL_CHECK(SMIME, valid_passphrase))
414  return CRYPT_MOD_CALL(SMIME, valid_passphrase)();
415 
416  return false;
417 }
418 
422 int crypt_smime_decrypt_mime(FILE *fp_in, FILE **fp_out, struct Body *b, struct Body **cur)
423 {
424  if (CRYPT_MOD_CALL_CHECK(SMIME, decrypt_mime))
425  return CRYPT_MOD_CALL(SMIME, decrypt_mime)(fp_in, fp_out, b, cur);
426 
427  return -1;
428 }
429 
435 int crypt_smime_application_handler(struct Body *m, struct State *s)
436 {
437  if (CRYPT_MOD_CALL_CHECK(SMIME, application_handler))
438  return CRYPT_MOD_CALL(SMIME, application_handler)(m, s);
439 
440  return -1;
441 }
442 
446 void crypt_smime_encrypted_handler(struct Body *a, struct State *s)
447 {
448  if (CRYPT_MOD_CALL_CHECK(SMIME, encrypted_handler))
449  CRYPT_MOD_CALL(SMIME, encrypted_handler)(a, s);
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 Mailbox *m, struct Email *e)
465 {
466  if (CRYPT_MOD_CALL_CHECK(SMIME, smime_verify_sender))
467  return CRYPT_MOD_CALL(SMIME, smime_verify_sender)(m, e);
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 
487 {
489  return CRYPT_MOD_CALL(SMIME, sign_message)(a);
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(char *infile, 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 }
#define SEC_AUTOCRYPT
Message will be, or was Autocrypt encrypt+signed.
Definition: ncrypt.h:131
WHERE bool C_Autocrypt
Config: Enables the Autocrypt feature.
Definition: globals.h:205
The envelope/body of an email.
Definition: email.h:39
int(* encrypted_handler)(struct Body *m, struct State *s)
Manage a PGP or S/MIME encrypted MIME part.
Definition: crypt_mod.h:89
char * crypt_smime_find_keys(struct AddressList *addrlist, bool oppenc_mode)
Wrapper for CryptModuleSpecs::find_keys()
Definition: cryptglue.c:475
struct CryptModuleSpecs CryptModPgpGpgme
GPGME PGP - Implements CryptModuleSpecs.
Wrapper for PGP/SMIME calls to GPGME.
GUI miscellaneous curses (window drawing) routines.
static struct Body * sign_message(struct Body *a, bool use_smime)
Sign a message.
Definition: crypt_gpgme.c:1398
int crypt_pgp_application_handler(struct Body *m, struct State *s)
Wrapper for CryptModuleSpecs::application_handler()
Definition: cryptglue.c:226
#define mutt_message(...)
Definition: logging.h:83
void crypt_pgp_void_passphrase(void)
Wrapper for CryptModuleSpecs::void_passphrase()
Definition: cryptglue.c:179
bool crypt_smime_valid_passphrase(void)
Wrapper for CryptModuleSpecs::valid_passphrase()
Definition: cryptglue.c:411
bool C_CryptUseGpgme
Config: Use GPGME crypto backend.
Definition: cryptglue.c:56
int(* application_handler)(struct Body *m, struct State *s)
Manage the MIME type "application/pgp" or "application/smime".
Definition: crypt_mod.h:81
void(* void_passphrase)(void)
Forget the cached passphrase.
Definition: crypt_mod.h:54
int(* pgp_check_traditional)(FILE *fp, struct Body *b, bool just_one)
Look for inline (non-MIME) PGP content.
Definition: crypt_mod.h:154
void crypt_pgp_set_sender(const char *sender)
Wrapper for CryptModuleSpecs::set_sender()
Definition: cryptglue.c:393
#define _(a)
Definition: message.h:28
bool is_autocrypt
Flag autocrypt-decrypted messages for replying.
Definition: body.h:85
An email address.
Definition: address.h:34
WHERE bool OptAutocryptGpgme
(pseudo) use Autocrypt context inside ncrypt/crypt_gpgme.c
Definition: options.h:32
#define CRYPT_MOD_CALL(identifier, func)
Definition: cryptglue.c:84
static char * find_keys(struct AddressList *addrlist, unsigned int app, bool oppenc_mode)
Find keys of the recipients of the message.
Definition: crypt_gpgme.c:5169
int crypt_smime_verify_sender(struct Mailbox *m, struct Email *e)
Wrapper for CryptModuleSpecs::smime_verify_sender()
Definition: cryptglue.c:464
void crypto_module_register(struct CryptModuleSpecs *specs)
Register a new crypto module.
Definition: crypt_mod.c:51
int crypt_smime_application_handler(struct Body *m, struct State *s)
Wrapper for CryptModuleSpecs::application_handler()
Definition: cryptglue.c:435
The body of an email.
Definition: body.h:34
Hundreds of global variables to back the user variables.
struct CryptModuleSpecs CryptModSmimeClassic
CLI SMIME - Implements CryptModuleSpecs.
struct Body * crypt_smime_sign_message(struct Body *a)
Wrapper for CryptModuleSpecs::sign_message()
Definition: cryptglue.c:486
void crypt_smime_set_sender(const char *sender)
Wrapper for CryptModuleSpecs::set_sender()
Definition: cryptglue.c:539
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:2351
struct CryptModuleSpecs CryptModPgpClassic
CLI PGP - Implements CryptModuleSpecs.
int crypt_smime_send_menu(struct Email *e)
Wrapper for CryptModuleSpecs::send_menu()
Definition: cryptglue.c:528
int pgp_gpgme_encrypted_handler(struct Body *a, struct State *s)
Implements CryptModuleSpecs::encrypted_handler()
Definition: crypt_gpgme.c:3197
int crypt_pgp_encrypted_handler(struct Body *a, struct State *s)
Wrapper for CryptModuleSpecs::encrypted_handler()
Definition: cryptglue.c:239
int(* decrypt_mime)(FILE *fp_in, FILE **fp_out, struct Body *b, struct Body **cur)
Decrypt an encrypted MIME part.
Definition: crypt_mod.h:73
void crypt_smime_void_passphrase(void)
Wrapper for CryptModuleSpecs::void_passphrase()
Definition: cryptglue.c:402
void crypt_pgp_extract_key_from_attachment(FILE *fp, struct Body *top)
Wrapper for CryptModuleSpecs::pgp_extract_key_from_attachment()
Definition: cryptglue.c:384
int mutt_autocrypt_set_sign_as_default_key(struct Email *e)
Set the Autocrypt default key for signing.
Definition: autocrypt.c:675
void crypt_invoke_message(SecurityFlags type)
Display an informative message.
Definition: cryptglue.c:145
#define CRYPT_MOD_CALL_CHECK(identifier, func)
Definition: cryptglue.c:78
void crypt_pgp_invoke_import(const char *fname)
Wrapper for CryptModuleSpecs::pgp_invoke_import()
Definition: cryptglue.c:353
A mailbox.
Definition: mailbox.h:92
Crypto API.
Definition: crypt_mod.h:43
void crypt_smime_encrypted_handler(struct Body *a, struct State *s)
Wrapper for CryptModuleSpecs::encrypted_handler()
Definition: cryptglue.c:446
void crypt_smime_getkeys(struct Envelope *env)
Wrapper for CryptModuleSpecs::smime_getkeys()
Definition: cryptglue.c:455
void crypt_pgp_invoke_getkeys(struct Address *addr)
Wrapper for CryptModuleSpecs::pgp_invoke_getkeys()
Definition: cryptglue.c:264
int crypt_pgp_send_menu(struct Email *e)
Wrapper for CryptModuleSpecs::send_menu()
Definition: cryptglue.c:373
struct Body * crypt_pgp_traditional_encryptsign(struct Body *a, int flags, char *keylist)
Wrapper for CryptModuleSpecs::pgp_traditional_encryptsign()
Definition: cryptglue.c:284
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:422
struct Body * crypt_pgp_sign_message(struct Body *a)
Wrapper for CryptModuleSpecs::sign_message()
Definition: cryptglue.c:317
API for encryption/signing of emails.
void crypt_init(void)
Initialise the crypto backends.
Definition: cryptglue.c:92
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/ncrypt.h pgplib.h, smime.h
Definition: email.h:41
bool(* valid_passphrase)(void)
Ensure we have a valid passphrase.
Definition: crypt_mod.h:63
struct CryptModuleSpecs * crypto_module_lookup(int identifier)
Lookup a crypto module by name.
Definition: crypt_mod.c:65
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: ncrypt.h:134
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:2040
void mutt_exit(int code)
Leave NeoMutt NOW.
Definition: main.c:210
bool crypt_has_module_backend(SecurityFlags type)
Is there a crypto backend for a given type?
Definition: cryptglue.c:159
int crypt_pgp_check_traditional(FILE *fp, struct Body *b, bool just_one)
Wrapper for CryptModuleSpecs::pgp_check_traditional()
Definition: cryptglue.c:273
int mutt_any_key_to_continue(const char *s)
Prompt the user to &#39;press any key&#39; and wait.
Definition: curs_lib.c:532
struct Body * crypt_smime_build_smime_entity(struct Body *a, char *certlist)
Wrapper for CryptModuleSpecs::smime_build_smime_entity()
Definition: cryptglue.c:497
struct Body * crypt_pgp_make_key_attachment(void)
Wrapper for CryptModuleSpecs::pgp_make_key_attachment()
Definition: cryptglue.c:295
char * crypt_pgp_find_keys(struct AddressList *addrlist, bool oppenc_mode)
Wrapper for CryptModuleSpecs::find_keys()
Definition: cryptglue.c:306
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:199
Autocrypt end-to-end encryption.
int crypt_smime_verify_one(struct Body *sigbdy, struct State *s, const char *tempf)
Wrapper for CryptModuleSpecs::verify_one()
Definition: cryptglue.c:517
Keep track when processing files.
Definition: state.h:44
struct Body * crypt_pgp_encrypt_message(struct Email *e, struct Body *a, char *keylist, int sign)
Wrapper for CryptModuleSpecs::pgp_encrypt_message()
Definition: cryptglue.c:328
Handling of global boolean variables.
void crypt_smime_invoke_import(char *infile, char *mailbox)
Wrapper for CryptModuleSpecs::smime_invoke_import()
Definition: cryptglue.c:508
uint16_t SecurityFlags
Flags, e.g. SEC_ENCRYPT.
Definition: ncrypt.h:120
struct Body * pgp_gpgme_encrypt_message(struct Body *a, char *keylist, bool sign)
Implements CryptModuleSpecs::pgp_encrypt_message()
Definition: crypt_gpgme.c:1535
#define WithCrypto
Definition: ncrypt.h:160
void(* pgp_invoke_getkeys)(struct Address *addr)
Run a command to download a PGP key.
Definition: crypt_mod.h:168
void(* init)(void)
Initialise the crypto module.
Definition: crypt_mod.h:50
bool crypt_pgp_valid_passphrase(void)
Wrapper for CryptModuleSpecs::valid_passphrase()
Definition: cryptglue.c:188
struct CryptModuleSpecs CryptModSmimeGpgme
GPGME SMIME - Implements CryptModuleSpecs.
Register crypto modules.
The header of an Email.
Definition: envelope.h:54
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: ncrypt.h:135
int crypt_pgp_verify_one(struct Body *sigbdy, struct State *s, const char *tempf)
Wrapper for CryptModuleSpecs::verify_one()
Definition: cryptglue.c:362