NeoMutt  2021-02-05-89-gabe350
Teaching an old dog new tricks
DOXYGEN
crypt.c
Go to the documentation of this file.
1 
35 #include "config.h"
36 #include <locale.h>
37 #include <stdbool.h>
38 #include <stdio.h>
39 #include <string.h>
40 #include "private.h"
41 #include "mutt/lib.h"
42 #include "address/lib.h"
43 #include "config/lib.h"
44 #include "email/lib.h"
45 #include "core/lib.h"
46 #include "alias/lib.h"
47 #include "gui/lib.h"
48 #include "mutt.h"
49 #include "crypt.h"
50 #include "ncrypt/lib.h"
51 #include "send/lib.h"
52 #include "context.h"
53 #include "copy.h"
54 #include "cryptglue.h"
55 #include "handler.h"
56 #include "mutt_globals.h"
57 #include "mutt_parse.h"
58 #include "muttlib.h"
59 #include "options.h"
60 #include "state.h"
61 #ifdef USE_AUTOCRYPT
62 #include "autocrypt/lib.h"
63 #endif
64 
72 void crypt_current_time(struct State *s, const char *app_name)
73 {
74  char p[256], tmp[256];
75 
76  if (!WithCrypto)
77  return;
78 
79  if (C_CryptTimestamp)
80  {
81  mutt_date_localtime_format(p, sizeof(p), _(" (current time: %c)"), MUTT_DATE_NOW);
82  }
83  else
84  *p = '\0';
85 
86  snprintf(tmp, sizeof(tmp), _("[-- %s output follows%s --]\n"), NONULL(app_name), p);
87  state_attach_puts(s, tmp);
88 }
89 
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 }
110 
111 #ifndef DEBUG
112 #include <sys/resource.h>
116 static void disable_coredumps(void)
117 {
118  struct rlimit rl = { 0, 0 };
119  static bool done = false;
120 
121  if (!done)
122  {
123  setrlimit(RLIMIT_CORE, &rl);
124  done = true;
125  }
126 }
127 #endif
128 
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 }
151 
160 int mutt_protect(struct Email *e, char *keylist, bool postpone)
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  if ((e->body->type != TYPE_TEXT) ||
188  !mutt_istr_equal(e->body->subtype, "plain"))
189  {
191  _("Inline PGP can't be used with attachments. "
192  "Revert to PGP/MIME?")) != MUTT_YES)
193  {
194  mutt_error(
195  _("Mail not sent: inline PGP can't be used with attachments"));
196  return -1;
197  }
198  }
199  else if (mutt_istr_equal("flowed",
200  mutt_param_get(&e->body->parameter, "format")))
201  {
203  _("Inline PGP can't be used with format=flowed. "
204  "Revert to PGP/MIME?"))) != MUTT_YES)
205  {
206  mutt_error(
207  _("Mail not sent: inline PGP can't be used with format=flowed"));
208  return -1;
209  }
210  }
211  else
212  {
213  /* they really want to send it inline... go for it */
214  if (!isendwin())
215  {
216  mutt_endwin();
217  puts(_("Invoking PGP..."));
218  }
219  pbody = crypt_pgp_traditional_encryptsign(e->body, security, keylist);
220  if (pbody)
221  {
222  e->body = pbody;
223  return 0;
224  }
225 
226  /* otherwise inline won't work...ask for revert */
227  if (query_quadoption(
229  _("Message can't be sent inline. Revert to using PGP/MIME?")) != MUTT_YES)
230  {
231  mutt_error(_("Mail not sent"));
232  return -1;
233  }
234  }
235 
236  /* go ahead with PGP/MIME */
237  }
238 
239  if (!isendwin())
240  mutt_endwin();
241 
243  tmp_smime_pbody = e->body;
245  tmp_pgp_pbody = e->body;
246 
247 #ifdef CRYPT_BACKEND_GPGME
248  if (sign && C_CryptUsePka)
249 #else
250  if (sign)
251 #endif
252  {
253  /* Set sender (necessary for e.g. PKA). */
254  const char *mailbox = NULL;
255  struct Address *from = TAILQ_FIRST(&e->env->from);
256  bool free_from = false;
257 
258  if (!from)
259  {
260  free_from = true;
261  from = mutt_default_from(NeoMutt->sub);
262  }
263 
264  mailbox = from->mailbox;
267 
268  if (((WithCrypto & APPLICATION_SMIME) != 0) && (security & APPLICATION_SMIME))
270  else if (((WithCrypto & APPLICATION_PGP) != 0) && (security & APPLICATION_PGP))
272 
273  if (free_from)
274  mutt_addr_free(&from);
275  }
276 
278  {
279  struct Envelope *protected_headers = mutt_env_new();
280  mutt_str_replace(&protected_headers->subject, e->env->subject);
281  /* Note: if other headers get added, such as to, cc, then a call to
282  * mutt_env_to_intl() will need to be added here too. */
283  mutt_prepare_envelope(protected_headers, 0, NeoMutt->sub);
284 
286  e->body->mime_headers = protected_headers;
287  /* Optional part of the draft RFC, but required by Enigmail */
288  mutt_param_set(&e->body->parameter, "protected-headers", "v1");
289  }
290  else
291  {
292  mutt_param_delete(&e->body->parameter, "protected-headers");
293  }
294 
295 #ifdef USE_AUTOCRYPT
296  /* A note about e->body->mime_headers. If postpone or send
297  * fails, the mime_headers is cleared out before returning to the
298  * compose menu. So despite the "robustness" code above and in the
299  * gen_gossip_list function below, mime_headers will not be set when
300  * entering mutt_protect().
301  *
302  * This is important to note because the user could toggle
303  * $crypt_protected_headers_write or $autocrypt off back in the
304  * compose menu. We don't want mutt_write_rfc822_header() to write
305  * stale data from one option if the other is set.
306  */
307  if (C_Autocrypt && !postpone && (security & SEC_AUTOCRYPT))
308  {
309  struct Mailbox *m = ctx_mailbox(Context);
311  }
312 #endif
313 
314  if (sign)
315  {
316  if (((WithCrypto & APPLICATION_SMIME) != 0) && (security & APPLICATION_SMIME))
317  {
318  tmp_pbody = crypt_smime_sign_message(e->body, &e->env->from);
319  if (!tmp_pbody)
320  goto bail;
321  pbody = tmp_pbody;
322  tmp_smime_pbody = tmp_pbody;
323  }
324 
325  if (((WithCrypto & APPLICATION_PGP) != 0) && (security & APPLICATION_PGP) &&
326  (!(security & (SEC_ENCRYPT | SEC_AUTOCRYPT)) || C_PgpRetainableSigs))
327  {
328  tmp_pbody = crypt_pgp_sign_message(e->body, &e->env->from);
329  if (!tmp_pbody)
330  goto bail;
331 
332  has_retainable_sig = true;
333  sign = SEC_NO_FLAGS;
334  pbody = tmp_pbody;
335  tmp_pgp_pbody = tmp_pbody;
336  }
337 
338  if ((WithCrypto != 0) && (security & APPLICATION_SMIME) && (security & APPLICATION_PGP))
339  {
340  /* here comes the draft ;-) */
341  }
342  }
343 
344  if (security & (SEC_ENCRYPT | SEC_AUTOCRYPT))
345  {
346  if (((WithCrypto & APPLICATION_SMIME) != 0) && (security & APPLICATION_SMIME))
347  {
348  tmp_pbody = crypt_smime_build_smime_entity(tmp_smime_pbody, keylist);
349  if (!tmp_pbody)
350  {
351  /* signed ? free it! */
352  goto bail;
353  }
354  /* free tmp_body if messages was signed AND encrypted ... */
355  if ((tmp_smime_pbody != e->body) && (tmp_smime_pbody != tmp_pbody))
356  {
357  /* detach and don't delete e->body,
358  * which tmp_smime_pbody->parts after signing. */
359  tmp_smime_pbody->parts = tmp_smime_pbody->parts->next;
360  e->body->next = NULL;
361  mutt_body_free(&tmp_smime_pbody);
362  }
363  pbody = tmp_pbody;
364  }
365 
366  if (((WithCrypto & APPLICATION_PGP) != 0) && (security & APPLICATION_PGP))
367  {
368  pbody = crypt_pgp_encrypt_message(e, tmp_pgp_pbody, keylist, sign, &e->env->from);
369  if (!pbody)
370  {
371  /* did we perform a retainable signature? */
372  if (has_retainable_sig)
373  {
374  /* remove the outer multipart layer */
375  tmp_pgp_pbody = mutt_remove_multipart(tmp_pgp_pbody);
376  /* get rid of the signature */
377  mutt_body_free(&tmp_pgp_pbody->next);
378  }
379 
380  goto bail;
381  }
382 
383  // destroy temporary signature envelope when doing retainable signatures.
384  if (has_retainable_sig)
385  {
386  tmp_pgp_pbody = mutt_remove_multipart(tmp_pgp_pbody);
387  mutt_body_free(&tmp_pgp_pbody->next);
388  }
389  }
390  }
391 
392  if (pbody)
393  {
394  e->body = pbody;
395  return 0;
396  }
397 
398 bail:
400  return -1;
401 }
402 
410 {
411  if (!b || (b->type != TYPE_MULTIPART) || !b->subtype || !mutt_istr_equal(b->subtype, "signed"))
412  {
413  return SEC_NO_FLAGS;
414  }
415 
416  char *p = mutt_param_get(&b->parameter, "protocol");
417  if (!p)
418  return SEC_NO_FLAGS;
419 
420  if (mutt_istr_equal(p, "multipart/mixed"))
421  return SEC_SIGN;
422 
423  if (((WithCrypto & APPLICATION_PGP) != 0) &&
424  mutt_istr_equal(p, "application/pgp-signature"))
425  {
426  return PGP_SIGN;
427  }
428 
429  if (((WithCrypto & APPLICATION_SMIME) != 0) &&
430  mutt_istr_equal(p, "application/x-pkcs7-signature"))
431  {
432  return SMIME_SIGN;
433  }
434  if (((WithCrypto & APPLICATION_SMIME) != 0) &&
435  mutt_istr_equal(p, "application/pkcs7-signature"))
436  {
437  return SMIME_SIGN;
438  }
439 
440  return SEC_NO_FLAGS;
441 }
442 
450 {
451  if ((WithCrypto & APPLICATION_PGP) == 0)
452  return SEC_NO_FLAGS;
453 
454  char *p = NULL;
455 
456  if (!b || (b->type != TYPE_MULTIPART) || !b->subtype ||
457  !mutt_istr_equal(b->subtype, "encrypted") ||
458  !(p = mutt_param_get(&b->parameter, "protocol")) ||
459  !mutt_istr_equal(p, "application/pgp-encrypted"))
460  {
461  return SEC_NO_FLAGS;
462  }
463 
464  return PGP_ENCRYPT;
465 }
466 
474 {
476  return 0;
477 
478  b = b->parts;
479  if (!b || (b->type != TYPE_APPLICATION) || !b->subtype ||
480  !mutt_istr_equal(b->subtype, "pgp-encrypted"))
481  {
482  return 0;
483  }
484 
485  b = b->next;
486  if (!b || (b->type != TYPE_APPLICATION) || !b->subtype ||
487  !mutt_istr_equal(b->subtype, "octet-stream"))
488  {
489  return 0;
490  }
491 
492  return PGP_ENCRYPT;
493 }
494 
511 {
512  if (!(WithCrypto & APPLICATION_PGP))
513  return SEC_NO_FLAGS;
514 
515  if (!b || (b->type != TYPE_MULTIPART) || !b->subtype || !mutt_istr_equal(b->subtype, "mixed"))
516  {
517  return SEC_NO_FLAGS;
518  }
519 
520  b = b->parts;
521  if (!b || (b->type != TYPE_TEXT) || !b->subtype ||
522  !mutt_istr_equal(b->subtype, "plain") || (b->length != 0))
523  {
524  return SEC_NO_FLAGS;
525  }
526 
527  b = b->next;
528  if (!b || (b->type != TYPE_APPLICATION) || !b->subtype ||
529  !mutt_istr_equal(b->subtype, "pgp-encrypted"))
530  {
531  return SEC_NO_FLAGS;
532  }
533 
534  b = b->next;
535  if (!b || (b->type != TYPE_APPLICATION) || !b->subtype ||
536  !mutt_istr_equal(b->subtype, "octet-stream"))
537  {
538  return SEC_NO_FLAGS;
539  }
540 
541  b = b->next;
542  if (b)
543  return SEC_NO_FLAGS;
544 
545  return PGP_ENCRYPT;
546 }
547 
555 {
557  char *p = NULL;
558 
559  if (m->type == TYPE_APPLICATION)
560  {
561  if (mutt_istr_equal(m->subtype, "pgp") ||
562  mutt_istr_equal(m->subtype, "x-pgp-message"))
563  {
564  p = mutt_param_get(&m->parameter, "x-action");
565  if (p && (mutt_istr_equal(p, "sign") || mutt_istr_equal(p, "signclear")))
566  {
567  t |= PGP_SIGN;
568  }
569 
570  p = mutt_param_get(&m->parameter, "format");
571  if (p && mutt_istr_equal(p, "keys-only"))
572  {
573  t |= PGP_KEY;
574  }
575 
576  if (t == SEC_NO_FLAGS)
577  t |= PGP_ENCRYPT; /* not necessarily correct, but... */
578  }
579 
580  if (mutt_istr_equal(m->subtype, "pgp-signed"))
581  t |= PGP_SIGN;
582 
583  if (mutt_istr_equal(m->subtype, "pgp-keys"))
584  t |= PGP_KEY;
585  }
586  else if ((m->type == TYPE_TEXT) && mutt_istr_equal("plain", m->subtype))
587  {
588  if (((p = mutt_param_get(&m->parameter, "x-mutt-action")) ||
589  (p = mutt_param_get(&m->parameter, "x-action")) ||
590  (p = mutt_param_get(&m->parameter, "action"))) &&
591  mutt_istr_startswith(p, "pgp-sign"))
592  {
593  t |= PGP_SIGN;
594  }
595  else if (p && mutt_istr_startswith(p, "pgp-encrypt"))
596  t |= PGP_ENCRYPT;
597  else if (p && mutt_istr_startswith(p, "pgp-keys"))
598  t |= PGP_KEY;
599  }
600  if (t)
601  t |= PGP_INLINE;
602 
603  return t;
604 }
605 
613 {
614  if (!m)
615  return SEC_NO_FLAGS;
616 
617  if (((m->type & TYPE_APPLICATION) == 0) || !m->subtype)
618  return SEC_NO_FLAGS;
619 
620  char *t = NULL;
621  bool complain = false;
622  /* S/MIME MIME types don't need x- anymore, see RFC2311 */
623  if (mutt_istr_equal(m->subtype, "x-pkcs7-mime") || mutt_istr_equal(m->subtype, "pkcs7-mime"))
624  {
625  t = mutt_param_get(&m->parameter, "smime-type");
626  if (t)
627  {
628  if (mutt_istr_equal(t, "enveloped-data"))
629  return SMIME_ENCRYPT;
630  if (mutt_istr_equal(t, "signed-data"))
631  return SMIME_SIGN | SMIME_OPAQUE;
632  return SEC_NO_FLAGS;
633  }
634  /* Netscape 4.7 uses
635  * Content-Description: S/MIME Encrypted Message
636  * instead of Content-Type parameter */
637  if (mutt_istr_equal(m->description, "S/MIME Encrypted Message"))
638  return SMIME_ENCRYPT;
639  complain = true;
640  }
641  else if (!mutt_istr_equal(m->subtype, "octet-stream"))
642  return SEC_NO_FLAGS;
643 
644  t = mutt_param_get(&m->parameter, "name");
645 
646  if (!t)
647  t = m->d_filename;
648  if (!t)
649  t = m->filename;
650  if (!t)
651  {
652  if (complain)
653  {
654  mutt_message(
655  _("S/MIME messages with no hints on content are unsupported"));
656  }
657  return SEC_NO_FLAGS;
658  }
659 
660  /* no .p7c, .p10 support yet. */
661 
662  int len = mutt_str_len(t) - 4;
663  if ((len > 0) && (*(t + len) == '.'))
664  {
665  len++;
666  if (mutt_istr_equal((t + len), "p7m"))
667  {
668  /* Not sure if this is the correct thing to do, but
669  * it's required for compatibility with Outlook */
670  return SMIME_SIGN | SMIME_OPAQUE;
671  }
672  else if (mutt_istr_equal((t + len), "p7s"))
673  return SMIME_SIGN | SMIME_OPAQUE;
674  }
675 
676  return SEC_NO_FLAGS;
677 }
678 
688 {
689  if (!WithCrypto || !m)
690  return SEC_NO_FLAGS;
691 
693 
694  if (m->type == TYPE_APPLICATION)
695  {
697  rc |= mutt_is_application_pgp(m);
698 
700  {
701  rc |= mutt_is_application_smime(m);
702  if (rc && m->goodsig)
703  rc |= SEC_GOODSIGN;
704  if (rc && m->badsig)
705  rc |= SEC_BADSIGN;
706  }
707  }
708  else if (((WithCrypto & APPLICATION_PGP) != 0) && (m->type == TYPE_TEXT))
709  {
710  rc |= mutt_is_application_pgp(m);
711  if (rc && m->goodsig)
712  rc |= SEC_GOODSIGN;
713  }
714 
715  if (m->type == TYPE_MULTIPART)
716  {
718  rc |= mutt_is_multipart_signed(m);
720 
721  if (rc && m->goodsig)
722  rc |= SEC_GOODSIGN;
723 #ifdef USE_AUTOCRYPT
724  if (rc && m->is_autocrypt)
725  rc |= SEC_AUTOCRYPT;
726 #endif
727  }
728 
729  if ((m->type == TYPE_MULTIPART) || (m->type == TYPE_MESSAGE))
730  {
731  SecurityFlags u = m->parts ? SEC_ALL_FLAGS : SEC_NO_FLAGS; /* Bits set in all parts */
732  SecurityFlags w = SEC_NO_FLAGS; /* Bits set in any part */
733 
734  for (struct Body *b = m->parts; b; b = b->next)
735  {
736  const SecurityFlags v = crypt_query(b);
737  u &= v;
738  w |= v;
739  }
740  rc |= u | (w & ~SEC_GOODSIGN);
741 
742  if ((w & SEC_GOODSIGN) && !(u & SEC_GOODSIGN))
743  rc |= SEC_PARTSIGN;
744  }
745 
746  return rc;
747 }
748 
759 int crypt_write_signed(struct Body *a, struct State *s, const char *tempfile)
760 {
761  if (!WithCrypto)
762  return -1;
763 
764  FILE *fp = mutt_file_fopen(tempfile, "w");
765  if (!fp)
766  {
767  mutt_perror(tempfile);
768  return -1;
769  }
770 
771  fseeko(s->fp_in, a->hdr_offset, SEEK_SET);
772  size_t bytes = a->length + a->offset - a->hdr_offset;
773  bool hadcr = false;
774  while (bytes > 0)
775  {
776  const int c = fgetc(s->fp_in);
777  if (c == EOF)
778  break;
779 
780  bytes--;
781 
782  if (c == '\r')
783  hadcr = true;
784  else
785  {
786  if ((c == '\n') && !hadcr)
787  fputc('\r', fp);
788 
789  hadcr = false;
790  }
791 
792  fputc(c, fp);
793  }
794  mutt_file_fclose(&fp);
795 
796  return 0;
797 }
798 
804 {
805  if (!WithCrypto)
806  return;
807 
808  while (a)
809  {
810  if (a->type == TYPE_MULTIPART)
811  {
812  if (a->encoding != ENC_7BIT)
813  {
814  a->encoding = ENC_7BIT;
816  }
817  else if (((WithCrypto & APPLICATION_PGP) != 0) && C_PgpStrictEnc)
819  }
820  else if ((a->type == TYPE_MESSAGE) &&
821  !mutt_istr_equal(a->subtype, "delivery-status"))
822  {
823  if (a->encoding != ENC_7BIT)
824  mutt_message_to_7bit(a, NULL, NeoMutt->sub);
825  }
826  else if (a->encoding == ENC_8BIT)
828  else if (a->encoding == ENC_BINARY)
829  a->encoding = ENC_BASE64;
830  else if (a->content && (a->encoding != ENC_BASE64) &&
831  (a->content->from || (a->content->space && C_PgpStrictEnc)))
832  {
834  }
835  a = a->next;
836  }
837 }
838 
846 void crypt_extract_keys_from_messages(struct Mailbox *m, struct EmailList *el)
847 {
848  if (!WithCrypto)
849  return;
850 
851  struct Buffer *tempfname = mutt_buffer_pool_get();
852  mutt_buffer_mktemp(tempfname);
853  FILE *fp_out = mutt_file_fopen(mutt_buffer_string(tempfname), "w");
854  if (!fp_out)
855  {
856  mutt_perror(mutt_buffer_string(tempfname));
857  goto cleanup;
858  }
859 
861  OptDontHandlePgpKeys = true;
862 
863  struct EmailNode *en = NULL;
864  STAILQ_FOREACH(en, el, entries)
865  {
866  struct Email *e = en->email;
867 
870  {
871  mutt_file_fclose(&fp_out);
872  break;
873  }
874 
875  if (((WithCrypto & APPLICATION_PGP) != 0) && (e->security & APPLICATION_PGP))
876  {
878  fflush(fp_out);
879 
880  mutt_endwin();
881  puts(_("Trying to extract PGP keys...\n"));
883  }
884 
885  if (((WithCrypto & APPLICATION_SMIME) != 0) && (e->security & APPLICATION_SMIME))
886  {
887  if (e->security & SEC_ENCRYPT)
888  {
890  CH_NO_FLAGS, 0);
891  }
892  else
894  fflush(fp_out);
895 
896  char *mbox = NULL;
897  if (!TAILQ_EMPTY(&e->env->from))
898  {
900  mbox = TAILQ_FIRST(&e->env->from)->mailbox;
901  }
902  else if (!TAILQ_EMPTY(&e->env->sender))
903  {
905  mbox = TAILQ_FIRST(&e->env->sender)->mailbox;
906  }
907  if (mbox)
908  {
909  mutt_endwin();
910  puts(_("Trying to extract S/MIME certificates..."));
912  }
913  }
914 
915  rewind(fp_out);
916  }
917 
918  mutt_file_fclose(&fp_out);
919  if (isendwin())
921 
923 
925  OptDontHandlePgpKeys = false;
926 
927 cleanup:
928  mutt_buffer_pool_release(&tempfname);
929 }
930 
945 int crypt_get_keys(struct Email *e, char **keylist, bool oppenc_mode)
946 {
947  if (!WithCrypto)
948  return 0;
949 
950  struct AddressList addrlist = TAILQ_HEAD_INITIALIZER(addrlist);
951  const char *fqdn = mutt_fqdn(true, NeoMutt->sub);
952  char *self_encrypt = NULL;
953 
954  /* Do a quick check to make sure that we can find all of the encryption
955  * keys if the user has requested this service. */
956 
957  *keylist = NULL;
958 
959 #ifdef USE_AUTOCRYPT
960  if (!oppenc_mode && (e->security & SEC_AUTOCRYPT))
961  {
962  struct Mailbox *m = ctx_mailbox(Context);
964  return -1;
965  return 0;
966  }
967 #endif
968 
970  OptPgpCheckTrust = true;
971 
972  mutt_addrlist_copy(&addrlist, &e->env->to, false);
973  mutt_addrlist_copy(&addrlist, &e->env->cc, false);
974  mutt_addrlist_copy(&addrlist, &e->env->bcc, false);
975  mutt_addrlist_qualify(&addrlist, fqdn);
976  mutt_addrlist_dedupe(&addrlist);
977 
978  if (oppenc_mode || (e->security & SEC_ENCRYPT))
979  {
980  if (((WithCrypto & APPLICATION_PGP) != 0) && (e->security & APPLICATION_PGP))
981  {
982  *keylist = crypt_pgp_find_keys(&addrlist, oppenc_mode);
983  if (!*keylist)
984  {
985  mutt_addrlist_clear(&addrlist);
986  return -1;
987  }
988  OptPgpCheckTrust = false;
990  self_encrypt = C_PgpDefaultKey;
991  }
992  if (((WithCrypto & APPLICATION_SMIME) != 0) && (e->security & APPLICATION_SMIME))
993  {
994  *keylist = crypt_smime_find_keys(&addrlist, oppenc_mode);
995  if (!*keylist)
996  {
997  mutt_addrlist_clear(&addrlist);
998  return -1;
999  }
1001  self_encrypt = C_SmimeDefaultKey;
1002  }
1003  }
1004 
1005  if (!oppenc_mode && self_encrypt)
1006  {
1007  const size_t keylist_size = mutt_str_len(*keylist);
1008  mutt_mem_realloc(keylist, keylist_size + mutt_str_len(self_encrypt) + 2);
1009  sprintf(*keylist + keylist_size, " %s", self_encrypt);
1010  }
1011 
1012  mutt_addrlist_clear(&addrlist);
1013 
1014  return 0;
1015 }
1016 
1025 {
1026  if (!WithCrypto)
1027  return;
1028 
1030  return;
1031 
1032  char *pgpkeylist = NULL;
1033 
1034  crypt_get_keys(e, &pgpkeylist, 1);
1035  if (pgpkeylist)
1036  {
1037  e->security |= SEC_ENCRYPT;
1038  FREE(&pgpkeylist);
1039  }
1040  else
1041  {
1042  e->security &= ~SEC_ENCRYPT;
1043  }
1044 }
1045 
1052 static void crypt_fetch_signatures(struct Body ***signatures, struct Body *a, int *n)
1053 {
1054  if (!WithCrypto)
1055  return;
1056 
1057  for (; a; a = a->next)
1058  {
1059  if (a->type == TYPE_MULTIPART)
1060  crypt_fetch_signatures(signatures, a->parts, n);
1061  else
1062  {
1063  if ((*n % 5) == 0)
1064  mutt_mem_realloc(signatures, (*n + 6) * sizeof(struct Body **));
1065 
1066  (*signatures)[(*n)++] = a;
1067  }
1068  }
1069 }
1070 
1077 {
1080  {
1081  return true;
1082  }
1083 
1084  return false;
1085 }
1086 
1090 int mutt_protected_headers_handler(struct Body *a, struct State *s)
1091 {
1093  {
1094  if (a->mime_headers->subject)
1095  {
1096  const bool display = (s->flags & MUTT_DISPLAY);
1097 
1098  if (display && C_Weed && mutt_matches_ignore("subject"))
1099  return 0;
1100 
1102  int wraplen = display ? mutt_window_wrap_cols(s->wraplen, C_Wrap) : 0;
1103 
1104  mutt_write_one_header(s->fp_out, "Subject", a->mime_headers->subject, s->prefix,
1105  wraplen, display ? CH_DISPLAY : CH_NO_FLAGS, NeoMutt->sub);
1106  state_puts(s, "\n");
1107  }
1108  }
1109 
1110  return 0;
1111 }
1112 
1116 int mutt_signed_handler(struct Body *a, struct State *s)
1117 {
1118  if (!WithCrypto)
1119  return -1;
1120 
1121  bool inconsistent = false;
1122  struct Body *b = a;
1123  struct Body **signatures = NULL;
1124  int sigcnt = 0;
1125  int rc = 0;
1126  struct Buffer *tempfile = NULL;
1127 
1128  a = a->parts;
1129  SecurityFlags signed_type = mutt_is_multipart_signed(b);
1130  if (signed_type == SEC_NO_FLAGS)
1131  {
1132  /* A null protocol value is already checked for in mutt_body_handler() */
1133  state_printf(s,
1134  _("[-- Error: "
1135  "Unknown multipart/signed protocol %s --]\n\n"),
1136  mutt_param_get(&b->parameter, "protocol"));
1137  return mutt_body_handler(a, s);
1138  }
1139 
1140  if (!(a && a->next))
1141  inconsistent = true;
1142  else
1143  {
1144  switch (signed_type)
1145  {
1146  case SEC_SIGN:
1147  if ((a->next->type != TYPE_MULTIPART) || !mutt_istr_equal(a->next->subtype, "mixed"))
1148  {
1149  inconsistent = true;
1150  }
1151  break;
1152  case PGP_SIGN:
1153  if ((a->next->type != TYPE_APPLICATION) ||
1154  !mutt_istr_equal(a->next->subtype, "pgp-signature"))
1155  {
1156  inconsistent = true;
1157  }
1158  break;
1159  case SMIME_SIGN:
1160  if ((a->next->type != TYPE_APPLICATION) ||
1161  (!mutt_istr_equal(a->next->subtype, "x-pkcs7-signature") &&
1162  !mutt_istr_equal(a->next->subtype, "pkcs7-signature")))
1163  {
1164  inconsistent = true;
1165  }
1166  break;
1167  default:
1168  inconsistent = true;
1169  }
1170  }
1171  if (inconsistent)
1172  {
1173  state_attach_puts(s, _("[-- Error: Missing or bad-format multipart/signed "
1174  "signature --]\n\n"));
1175  return mutt_body_handler(a, s);
1176  }
1177 
1178  if (s->flags & MUTT_DISPLAY)
1179  {
1180  crypt_fetch_signatures(&signatures, a->next, &sigcnt);
1181 
1182  if (sigcnt != 0)
1183  {
1184  tempfile = mutt_buffer_pool_get();
1185  mutt_buffer_mktemp(tempfile);
1186  bool goodsig = true;
1187  if (crypt_write_signed(a, s, mutt_buffer_string(tempfile)) == 0)
1188  {
1189  for (int i = 0; i < sigcnt; i++)
1190  {
1191  if (((WithCrypto & APPLICATION_PGP) != 0) &&
1192  (signatures[i]->type == TYPE_APPLICATION) &&
1193  mutt_istr_equal(signatures[i]->subtype, "pgp-signature"))
1194  {
1195  if (crypt_pgp_verify_one(signatures[i], s, mutt_buffer_string(tempfile)) != 0)
1196  goodsig = false;
1197 
1198  continue;
1199  }
1200 
1201  if (((WithCrypto & APPLICATION_SMIME) != 0) &&
1202  (signatures[i]->type == TYPE_APPLICATION) &&
1203  (mutt_istr_equal(signatures[i]->subtype, "x-pkcs7-signature") ||
1204  mutt_istr_equal(signatures[i]->subtype, "pkcs7-signature")))
1205  {
1206  if (crypt_smime_verify_one(signatures[i], s, mutt_buffer_string(tempfile)) != 0)
1207  goodsig = false;
1208 
1209  continue;
1210  }
1211 
1212  state_printf(s,
1213  _("[-- Warning: "
1214  "We can't verify %s/%s signatures. --]\n\n"),
1215  TYPE(signatures[i]), signatures[i]->subtype);
1216  }
1217  }
1218 
1220  mutt_buffer_pool_release(&tempfile);
1221 
1222  b->goodsig = goodsig;
1223  b->badsig = !goodsig;
1224 
1225  /* Now display the signed body */
1226  state_attach_puts(s, _("[-- The following data is signed --]\n\n"));
1227 
1229 
1230  FREE(&signatures);
1231  }
1232  else
1233  {
1235  _("[-- Warning: Can't find any signatures. --]\n\n"));
1236  }
1237  }
1238 
1239  rc = mutt_body_handler(a, s);
1240 
1241  if ((s->flags & MUTT_DISPLAY) && (sigcnt != 0))
1242  state_attach_puts(s, _("\n[-- End of signed data --]\n"));
1243 
1244  return rc;
1245 }
1246 
1261 const char *crypt_get_fingerprint_or_id(const char *p, const char **pphint,
1262  const char **ppl, const char **pps)
1263 {
1264  const char *ps = NULL, *pl = NULL, *phint = NULL;
1265  char *pfcopy = NULL, *s1 = NULL, *s2 = NULL;
1266  char c;
1267  int isid;
1268  size_t hexdigits;
1269 
1270  /* User input may be partial name, fingerprint or short or long key ID,
1271  * independent of `$pgp_long_ids`.
1272  * Fingerprint without spaces is 40 hex digits (SHA-1) or 32 hex digits (MD5).
1273  * Strip leading "0x" for key ID detection and prepare pl and ps to indicate
1274  * if an ID was found and to simplify logic in the key loop's inner
1275  * condition of the caller. */
1276 
1277  char *pf = mutt_str_skip_whitespace(p);
1278  if (mutt_istr_startswith(pf, "0x"))
1279  pf += 2;
1280 
1281  /* Check if a fingerprint is given, must be hex digits only, blanks
1282  * separating groups of 4 hex digits are allowed. Also pre-check for ID. */
1283  isid = 2; /* unknown */
1284  hexdigits = 0;
1285  s1 = pf;
1286  do
1287  {
1288  c = *(s1++);
1289  if ((('0' <= c) && (c <= '9')) || (('A' <= c) && (c <= 'F')) ||
1290  (('a' <= c) && (c <= 'f')))
1291  {
1292  hexdigits++;
1293  if (isid == 2)
1294  isid = 1; /* it is an ID so far */
1295  }
1296  else if (c)
1297  {
1298  isid = 0; /* not an ID */
1299  if ((c == ' ') && ((hexdigits % 4) == 0))
1300  ; /* skip blank before or after 4 hex digits */
1301  else
1302  break; /* any other character or position */
1303  }
1304  } while (c);
1305 
1306  /* If at end of input, check for correct fingerprint length and copy if. */
1307  pfcopy = (!c && ((hexdigits == 40) || (hexdigits == 32)) ? mutt_str_dup(pf) : NULL);
1308 
1309  if (pfcopy)
1310  {
1311  /* Use pfcopy to strip all spaces from fingerprint and as hint. */
1312  s1 = pfcopy;
1313  s2 = pfcopy;
1314  do
1315  {
1316  *(s1++) = *(s2 = mutt_str_skip_whitespace(s2));
1317  } while (*(s2++));
1318 
1319  phint = pfcopy;
1320  ps = NULL;
1321  pl = NULL;
1322  }
1323  else
1324  {
1325  phint = p;
1326  ps = NULL;
1327  pl = NULL;
1328  if (isid == 1)
1329  {
1330  if (mutt_str_len(pf) == 16)
1331  pl = pf; /* long key ID */
1332  else if (mutt_str_len(pf) == 8)
1333  ps = pf; /* short key ID */
1334  }
1335  }
1336 
1337  *pphint = phint;
1338  *ppl = pl;
1339  *pps = ps;
1340  return pfcopy;
1341 }
1342 
1350 bool crypt_is_numerical_keyid(const char *s)
1351 {
1352  /* or should we require the "0x"? */
1353  if (mutt_strn_equal(s, "0x", 2))
1354  s += 2;
1355  if (strlen(s) % 8)
1356  return false;
1357  while (*s)
1358  if (!strchr("0123456789ABCDEFabcdef", *s++))
1359  return false;
1360 
1361  return true;
1362 }
Body::hdr_offset
long hdr_offset
Offset in stream where the headers begin.
Definition: body.h:42
lib.h
Envelope
The header of an Email.
Definition: envelope.h:54
C_CryptProtectedHeadersSubject
char * C_CryptProtectedHeadersSubject
Config: Use this as the subject for encrypted emails.
Definition: config.c:70
SMIME_SIGN
#define SMIME_SIGN
Definition: lib.h:110
mutt_endwin
void mutt_endwin(void)
Shutdown curses/slang.
Definition: curs_lib.c:572
Envelope::subject
char * subject
Email's subject.
Definition: envelope.h:66
Envelope::bcc
struct AddressList bcc
Email's 'Bcc' list.
Definition: envelope.h:60
ENC_BINARY
@ ENC_BINARY
Binary.
Definition: mime.h:53
ENC_QUOTED_PRINTABLE
@ ENC_QUOTED_PRINTABLE
Quoted-printable text.
Definition: mime.h:51
C_EnvelopeFromAddress
struct Address * C_EnvelopeFromAddress
Config: Manually set the sender for outgoing messages.
Definition: config.c:71
PGP_SIGN
#define PGP_SIGN
Definition: lib.h:104
State::fp_in
FILE * fp_in
File to read from.
Definition: state.h:46
AUTOCRYPT_REC_NO
@ AUTOCRYPT_REC_NO
Do no use Autocrypt.
Definition: lib.h:158
MUTT_CM_CHARCONV
#define MUTT_CM_CHARCONV
Perform character set conversions.
Definition: copy.h:41
_
#define _(a)
Definition: message.h:28
NONULL
#define NONULL(x)
Definition: string2.h:37
Mailbox
A mailbox.
Definition: mailbox.h:81
APPLICATION_SMIME
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: lib.h:98
Body::content
struct Content * content
Detailed info about the content of the attachment.
Definition: body.h:51
mutt_strn_equal
bool mutt_strn_equal(const char *a, const char *b, size_t num)
Check for equality of two strings (to a maximum), safely.
Definition: string.c:593
mutt_addrlist_dedupe
void mutt_addrlist_dedupe(struct AddressList *al)
Remove duplicate addresses.
Definition: address.c:1405
crypt_fetch_signatures
static void crypt_fetch_signatures(struct Body ***signatures, struct Body *a, int *n)
Create an array of an emails parts.
Definition: crypt.c:1052
mutt_addrlist_qualify
void mutt_addrlist_qualify(struct AddressList *al, const char *host)
Expand local names in an Address list using a hostname.
Definition: address.c:650
MUTT_DISPLAY
#define MUTT_DISPLAY
Output is displayed to the user.
Definition: state.h:32
Buffer
String manipulation buffer.
Definition: buffer.h:33
Body::offset
LOFF_T offset
offset where the actual data begins
Definition: body.h:44
ctx_mailbox
struct Mailbox * ctx_mailbox(struct Context *ctx)
wrapper to get the mailbox in a Context, or NULL
Definition: context.c:429
SEC_OPPENCRYPT
#define SEC_OPPENCRYPT
Opportunistic encrypt mode.
Definition: lib.h:93
crypt_smime_void_passphrase
void crypt_smime_void_passphrase(void)
Wrapper for CryptModuleSpecs::void_passphrase()
Definition: cryptglue.c:414
mutt_file_fclose
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
mutt_is_malformed_multipart_pgp_encrypted
SecurityFlags mutt_is_malformed_multipart_pgp_encrypted(struct Body *b)
Check for malformed layout.
Definition: crypt.c:510
Body::next
struct Body * next
next attachment in the list
Definition: body.h:53
MUTT_CM_DECODE_CRYPT
#define MUTT_CM_DECODE_CRYPT
Definition: copy.h:47
Body
The body of an email.
Definition: body.h:34
SMIME_ENCRYPT
#define SMIME_ENCRYPT
Definition: lib.h:109
SEC_ENCRYPT
#define SEC_ENCRYPT
Email is encrypted.
Definition: lib.h:85
Body::is_autocrypt
bool is_autocrypt
Flag autocrypt-decrypted messages for replying.
Definition: body.h:79
crypt_pgp_encrypt_message
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
MUTT_CM_NOHEADER
#define MUTT_CM_NOHEADER
Don't copy the message header.
Definition: copy.h:35
mutt_remove_multipart
struct Body * mutt_remove_multipart(struct Body *b)
Extract the multipart body if it exists.
Definition: multipart.c:126
mutt_window_wrap_cols
int mutt_window_wrap_cols(int width, short wrap)
Calculate the wrap column for a given screen width.
Definition: mutt_window.c:477
SEC_SIGN
#define SEC_SIGN
Email is signed.
Definition: lib.h:86
C_PgpStrictEnc
bool C_PgpStrictEnc
Config: Encode PGP signed messages with quoted-printable (don't unset)
Definition: config.c:77
SMIME_OPAQUE
#define SMIME_OPAQUE
Definition: lib.h:113
PGP_INLINE
#define PGP_INLINE
Definition: lib.h:107
mutt_buffer_mktemp
#define mutt_buffer_mktemp(buf)
Definition: muttlib.h:77
handler.h
mutt_autocrypt_generate_gossip_list
int mutt_autocrypt_generate_gossip_list(struct Mailbox *m, struct Email *e)
Create the gossip list headers.
Definition: autocrypt.c:823
Content::from
bool from
Has a line beginning with "From "?
Definition: content.h:43
TAILQ_EMPTY
#define TAILQ_EMPTY(head)
Definition: queue.h:714
EmailNode::email
struct Email * email
Email in the list.
Definition: email.h:127
mutt_prepare_envelope
void mutt_prepare_envelope(struct Envelope *env, bool final, struct ConfigSubset *sub)
Prepare an email header.
Definition: sendlib.c:1238
crypt_pgp_find_keys
char * crypt_pgp_find_keys(struct AddressList *addrlist, bool oppenc_mode)
Wrapper for CryptModuleSpecs::find_keys()
Definition: cryptglue.c:316
mutt_parse.h
crypt_pgp_invoke_import
void crypt_pgp_invoke_import(const char *fname)
Wrapper for CryptModuleSpecs::pgp_invoke_import()
Definition: cryptglue.c:365
MUTT_YES
@ MUTT_YES
User answered 'Yes', or assume 'Yes'.
Definition: quad.h:40
crypt_smime_build_smime_entity
struct Body * crypt_smime_build_smime_entity(struct Body *a, char *certlist)
Wrapper for CryptModuleSpecs::smime_build_smime_entity()
Definition: cryptglue.c:500
mutt_expand_aliases
void mutt_expand_aliases(struct AddressList *al)
Expand aliases in a List of Addresses.
Definition: alias.c:294
Context
The "current" mailbox.
Definition: context.h:38
mutt_str_dup
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:370
crypt_smime_invoke_import
void crypt_smime_invoke_import(const char *infile, const char *mailbox)
Wrapper for CryptModuleSpecs::smime_invoke_import()
Definition: cryptglue.c:511
mutt_globals.h
mutt_file_fopen
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:589
mutt_file_unlink
void mutt_file_unlink(const char *s)
Delete a file, carefully.
Definition: file.c:195
crypt_convert_to_7bit
void crypt_convert_to_7bit(struct Body *a)
Convert an email to 7bit encoding.
Definition: crypt.c:803
mutt_is_valid_multipart_pgp_encrypted
int mutt_is_valid_multipart_pgp_encrypted(struct Body *b)
Is this a valid multi-part encrypted message?
Definition: crypt.c:473
FREE
#define FREE(x)
Definition: memory.h:40
mutt_should_hide_protected_subject
bool mutt_should_hide_protected_subject(struct Email *e)
Should NeoMutt hide the protected subject?
Definition: crypt.c:1076
C_Autocrypt
bool C_Autocrypt
Config: Enables the Autocrypt feature.
Definition: config.c:37
options.h
EmailNode
List of Emails.
Definition: email.h:125
mutt_perror
#define mutt_perror(...)
Definition: logging.h:85
Body::encoding
unsigned int encoding
content-transfer-encoding, ContentEncoding
Definition: body.h:66
SecurityFlags
uint16_t SecurityFlags
Flags, e.g. SEC_ENCRYPT.
Definition: lib.h:83
State::wraplen
int wraplen
Width to wrap lines to (when flags & MUTT_DISPLAY)
Definition: state.h:50
state_mark_protected_header
void state_mark_protected_header(struct State *s)
Write a unique marker around protected headers.
Definition: state.c:56
copy.h
mutt_buffer_pool_release
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
Content::space
bool space
Whitespace at the end of lines?
Definition: content.h:41
mutt_body_free
void mutt_body_free(struct Body **ptr)
Free a Body.
Definition: body.c:57
crypt_smime_verify_one
int crypt_smime_verify_one(struct Body *sigbdy, struct State *s, const char *tempf)
Wrapper for CryptModuleSpecs::verify_one()
Definition: cryptglue.c:520
Body::subtype
char * subtype
content-type subtype
Definition: body.h:37
STAILQ_FOREACH
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:349
State::fp_out
FILE * fp_out
File to write to.
Definition: state.h:47
state_attach_puts
void state_attach_puts(struct State *s, const char *t)
Write a string to the state.
Definition: state.c:70
C_CryptProtectedHeadersRead
bool C_CryptProtectedHeadersRead
Config: Display protected headers (Memory Hole) in the pager.
Definition: config.c:56
crypt_get_keys
int crypt_get_keys(struct Email *e, char **keylist, bool oppenc_mode)
Check we have all the keys we need.
Definition: crypt.c:945
State::prefix
char * prefix
String to add to the beginning of each output line.
Definition: state.h:48
mutt_parse_mime_message
void mutt_parse_mime_message(struct Mailbox *m, struct Email *e)
Parse a MIME email.
Definition: mutt_parse.c:49
mutt_istr_equal
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:883
MUTT_CM_DECODE_SMIME
#define MUTT_CM_DECODE_SMIME
Used for decoding S/MIME messages.
Definition: copy.h:45
Body::badsig
bool badsig
Bad cryptographic signature (needed to check encrypted s/mime-signatures)
Definition: body.h:77
crypt.h
lib.h
C_CryptUsePka
bool C_CryptUsePka
Config: Use GPGME to use PKA (lookup PGP keys using DNS)
Definition: config.c:51
TAILQ_HEAD_INITIALIZER
#define TAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:630
C_PgpRetainableSigs
bool C_PgpRetainableSigs
Config: Create nested multipart/signed or encrypted messages.
Definition: config.c:75
TAILQ_FIRST
#define TAILQ_FIRST(head)
Definition: queue.h:716
mutt_any_key_to_continue
int mutt_any_key_to_continue(const char *s)
Prompt the user to 'press any key' and wait.
Definition: curs_lib.c:605
mutt_write_one_header
int mutt_write_one_header(FILE *fp, const char *tag, const char *value, const char *pfx, int wraplen, CopyHeaderFlags chflags, struct ConfigSubset *sub)
Write one header line to a file.
Definition: header.c:420
Envelope::cc
struct AddressList cc
Email's 'Cc' list.
Definition: envelope.h:59
query_quadoption
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: curs_lib.c:518
mutt_date_localtime_format
size_t mutt_date_localtime_format(char *buf, size_t buflen, const char *format, time_t t)
Format localtime.
Definition: date.c:680
mutt_env_free
void mutt_env_free(struct Envelope **ptr)
Free an Envelope.
Definition: envelope.c:96
mutt_buffer_pool_get
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
mutt_is_application_pgp
SecurityFlags mutt_is_application_pgp(struct Body *m)
Does the message use PGP?
Definition: crypt.c:554
SEC_ALL_FLAGS
#define SEC_ALL_FLAGS
Definition: lib.h:101
crypt_query
SecurityFlags crypt_query(struct Body *m)
Check out the type of encryption used.
Definition: crypt.c:687
crypt_pgp_valid_passphrase
bool crypt_pgp_valid_passphrase(void)
Wrapper for CryptModuleSpecs::valid_passphrase()
Definition: cryptglue.c:198
Body::goodsig
bool goodsig
Good cryptographic signature.
Definition: body.h:75
C_Wrap
WHERE short C_Wrap
Config: Width to wrap text in the pager.
Definition: mutt_globals.h:116
lib.h
muttlib.h
TYPE
#define TYPE(body)
Definition: mime.h:89
mutt_is_multipart_encrypted
SecurityFlags mutt_is_multipart_encrypted(struct Body *b)
Does the message have encrypted parts?
Definition: crypt.c:449
mutt_protect
int mutt_protect(struct Email *e, char *keylist, bool postpone)
Encrypt and/or sign a message.
Definition: crypt.c:160
Body::length
LOFF_T length
length (in bytes) of attachment
Definition: body.h:45
crypt_pgp_traditional_encryptsign
struct Body * crypt_pgp_traditional_encryptsign(struct Body *a, SecurityFlags flags, char *keylist)
Wrapper for CryptModuleSpecs::pgp_traditional_encryptsign()
Definition: cryptglue.c:294
crypt_pgp_sign_message
struct Body * crypt_pgp_sign_message(struct Body *a, const struct AddressList *from)
Wrapper for CryptModuleSpecs::sign_message()
Definition: cryptglue.c:327
ENC_8BIT
@ ENC_8BIT
8-bit text
Definition: mime.h:50
APPLICATION_PGP
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: lib.h:97
MUTT_CM_NO_FLAGS
#define MUTT_CM_NO_FLAGS
No flags are set.
Definition: copy.h:34
C_CryptOpportunisticEncrypt
bool C_CryptOpportunisticEncrypt
Config: Enable encryption when the recipient's key is available.
Definition: config.c:54
lib.h
lib.h
CH_NO_FLAGS
#define CH_NO_FLAGS
No flags are set.
Definition: copy.h:50
mutt_signed_handler
int mutt_signed_handler(struct Body *a, struct State *s)
Verify a "multipart/signed" body - Implements handler_t.
Definition: crypt.c:1116
OptDontHandlePgpKeys
WHERE bool OptDontHandlePgpKeys
(pseudo) used to extract PGP keys
Definition: options.h:36
C_PgpSelfEncrypt
bool C_PgpSelfEncrypt
Config: Encrypted messages will also be encrypted to $pgp_default_key too.
Definition: config.c:76
C_PgpEncryptSelf
unsigned char C_PgpEncryptSelf
Definition: config.c:73
mutt_addrlist_clear
void mutt_addrlist_clear(struct AddressList *al)
Unlink and free all Address in an AddressList.
Definition: address.c:1468
Body::description
char * description
content-description
Definition: body.h:40
mutt_matches_ignore
bool mutt_matches_ignore(const char *s)
Does the string match the ignore list.
Definition: parse.c:315
crypt_get_fingerprint_or_id
const char * crypt_get_fingerprint_or_id(const char *p, const char **pphint, const char **ppl, const char **pps)
Get the fingerprint or long key ID.
Definition: crypt.c:1261
mutt_param_set
void mutt_param_set(struct ParameterList *pl, const char *attribute, const char *value)
Set a Parameter.
Definition: parameter.c:110
CH_DISPLAY
#define CH_DISPLAY
Display result to user.
Definition: copy.h:69
Envelope::to
struct AddressList to
Email's 'To' list.
Definition: envelope.h:58
C_PgpDefaultKey
char * C_PgpDefaultKey
Config: Default key to use for PGP operations.
Definition: config.c:64
Body::parts
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:54
TYPE_MESSAGE
@ TYPE_MESSAGE
Type: 'message/*'.
Definition: mime.h:35
C_PgpMimeAuto
unsigned char C_PgpMimeAuto
Config: Prompt the user to use MIME if inline PGP fails.
Definition: config.c:74
mutt_mem_realloc
void mutt_mem_realloc(void *ptr, size_t size)
Resize a block of memory on the heap.
Definition: memory.c:114
Email::env
struct Envelope * env
Envelope information.
Definition: email.h:90
crypt_write_signed
int crypt_write_signed(struct Body *a, struct State *s, const char *tempfile)
Write the message body/part.
Definition: crypt.c:759
state_printf
int state_printf(struct State *s, const char *fmt,...)
Write a formatted string to the State.
Definition: state.c:153
mutt_addr_free
void mutt_addr_free(struct Address **ptr)
Free a single Address.
Definition: address.c:440
mutt_str_len
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:631
mutt_buffer_string
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:77
mutt_env_new
struct Envelope * mutt_env_new(void)
Create a new Envelope.
Definition: envelope.c:42
Email::security
SecurityFlags security
bit 0-10: flags, bit 11,12: application, bit 13: traditional pgp See: ncrypt/lib.h pgplib....
Definition: email.h:39
MUTT_DATE_NOW
#define MUTT_DATE_NOW
Constant representing the 'current time', see: mutt_date_gmtime(), mutt_date_localtime()
Definition: date.h:39
crypt_current_time
void crypt_current_time(struct State *s, const char *app_name)
Print the current time.
Definition: crypt.c:72
mutt_str_replace
char * mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:446
crypt_smime_valid_passphrase
bool crypt_smime_valid_passphrase(void)
Wrapper for CryptModuleSpecs::valid_passphrase()
Definition: cryptglue.c:423
WithCrypto
#define WithCrypto
Definition: lib.h:123
SEC_BADSIGN
#define SEC_BADSIGN
Email has a bad signature.
Definition: lib.h:88
crypt_smime_set_sender
void crypt_smime_set_sender(const char *sender)
Wrapper for CryptModuleSpecs::set_sender()
Definition: cryptglue.c:542
mutt_param_delete
void mutt_param_delete(struct ParameterList *pl, const char *attribute)
Delete a matching Parameter.
Definition: parameter.c:142
Address::mailbox
char * mailbox
Mailbox and host address.
Definition: address.h:37
mutt_param_get
char * mutt_param_get(const struct ParameterList *pl, const char *s)
Find a matching Parameter.
Definition: parameter.c:84
lib.h
lib.h
PGP_ENCRYPT
#define PGP_ENCRYPT
Definition: lib.h:103
crypt_forget_passphrase
void crypt_forget_passphrase(void)
Forget a passphrase and display a message.
Definition: crypt.c:93
crypt_smime_sign_message
struct Body * crypt_smime_sign_message(struct Body *a, const struct AddressList *from)
Wrapper for CryptModuleSpecs::sign_message()
Definition: cryptglue.c:489
mutt_str_skip_whitespace
char * mutt_str_skip_whitespace(const char *p)
Find the first non-whitespace character in a string.
Definition: string.c:686
C_Weed
bool C_Weed
Config: Filter headers when displaying/forwarding/printing/replying.
Definition: globals.c:40
OptPgpCheckTrust
WHERE bool OptPgpCheckTrust
(pseudo) used by dlg_select_pgp_key()
Definition: options.h:49
lib.h
crypt_pgp_verify_one
int crypt_pgp_verify_one(struct Body *sigbdy, struct State *s, const char *tempf)
Wrapper for CryptModuleSpecs::verify_one()
Definition: cryptglue.c:374
Envelope::from
struct AddressList from
Email's 'From' list.
Definition: envelope.h:57
TYPE_APPLICATION
@ TYPE_APPLICATION
Type: 'application/*'.
Definition: mime.h:33
State
Keep track when processing files.
Definition: state.h:44
Body::d_filename
char * d_filename
filename to be used for the content-disposition header.
Definition: body.h:47
ENC_BASE64
@ ENC_BASE64
Base-64 encoded text.
Definition: mime.h:52
crypt_is_numerical_keyid
bool crypt_is_numerical_keyid(const char *s)
Is this a numerical keyid.
Definition: crypt.c:1350
C_SmimeSelfEncrypt
bool C_SmimeSelfEncrypt
Config: Encrypted messages will also be encrypt to $smime_default_key too.
Definition: config.c:79
TYPE_TEXT
@ TYPE_TEXT
Type: 'text/*'.
Definition: mime.h:38
mutt_protected_headers_handler
int mutt_protected_headers_handler(struct Body *a, struct State *s)
Process a protected header - Implements handler_t.
Definition: crypt.c:1090
NeoMutt
Container for Accounts, Notifications.
Definition: neomutt.h:36
mutt.h
SEC_INLINE
#define SEC_INLINE
Email has an inline signature.
Definition: lib.h:92
crypt_opportunistic_encrypt
void crypt_opportunistic_encrypt(struct Email *e)
Can all recipients be determined.
Definition: crypt.c:1024
crypt_smime_find_keys
char * crypt_smime_find_keys(struct AddressList *addrlist, bool oppenc_mode)
Wrapper for CryptModuleSpecs::find_keys()
Definition: cryptglue.c:478
PGP_KEY
#define PGP_KEY
Definition: lib.h:106
mutt_istr_startswith
size_t mutt_istr_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix, ignoring case.
Definition: string.c:172
Body::type
unsigned int type
content-type primary type, ContentType
Definition: body.h:65
C_SmimeDefaultKey
char * C_SmimeDefaultKey
Config: Default key for SMIME operations.
Definition: config.c:67
mutt_body_handler
int mutt_body_handler(struct Body *b, struct State *s)
Handler for the Body of an email.
Definition: handler.c:1595
context.h
mutt_default_from
struct Address * mutt_default_from(struct ConfigSubset *sub)
Get a default 'from' Address.
Definition: send.c:1338
MUTT_CM_DECODE
#define MUTT_CM_DECODE
Decode the message body into text/plain.
Definition: copy.h:37
NeoMutt::sub
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
crypt_pgp_void_passphrase
void crypt_pgp_void_passphrase(void)
Wrapper for CryptModuleSpecs::void_passphrase()
Definition: cryptglue.c:189
crypt_extract_keys_from_messages
void crypt_extract_keys_from_messages(struct Mailbox *m, struct EmailList *el)
Extract keys from a message.
Definition: crypt.c:846
Body::parameter
struct ParameterList parameter
parameters of the content-type
Definition: body.h:39
mutt_autocrypt_ui_recommendation
enum AutocryptRec mutt_autocrypt_ui_recommendation(struct Mailbox *m, struct Email *e, char **keylist)
Get the recommended action for an Email.
Definition: autocrypt.c:561
mutt_fqdn
const char * mutt_fqdn(bool may_hide_host, const struct ConfigSubset *sub)
Get the Fully-Qualified Domain Name.
Definition: sendlib.c:1182
lib.h
state.h
State::flags
StateFlags flags
Flags, e.g. MUTT_DISPLAY.
Definition: state.h:49
TYPE_MULTIPART
@ TYPE_MULTIPART
Type: 'multipart/*'.
Definition: mime.h:37
Email
The envelope/body of an email.
Definition: email.h:37
lib.h
C_CryptProtectedHeadersWrite
bool C_CryptProtectedHeadersWrite
Config: Generate protected header (Memory Hole) for signed and encrypted emails.
Definition: config.c:58
mutt_message
#define mutt_message(...)
Definition: logging.h:83
crypt_pgp_set_sender
void crypt_pgp_set_sender(const char *sender)
Wrapper for CryptModuleSpecs::set_sender()
Definition: cryptglue.c:405
C_CryptTimestamp
bool C_CryptTimestamp
Config: Add a timestamp to PGP or SMIME output to prevent spoofing.
Definition: config.c:72
mutt_addrlist_copy
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
mutt_copy_message
int mutt_copy_message(FILE *fp_out, struct Mailbox *m, struct Email *e, CopyMessageFlags cmflags, CopyHeaderFlags chflags, int wraplen)
Copy a message from a Mailbox.
Definition: copy.c:835
crypt_valid_passphrase
bool crypt_valid_passphrase(SecurityFlags flags)
Check that we have a usable passphrase, ask if not.
Definition: crypt.c:135
SEC_NO_FLAGS
#define SEC_NO_FLAGS
No flags are set.
Definition: lib.h:84
mutt_is_multipart_signed
SecurityFlags mutt_is_multipart_signed(struct Body *b)
Is a message signed?
Definition: crypt.c:409
Envelope::sender
struct AddressList sender
Email's sender.
Definition: envelope.h:61
SEC_GOODSIGN
#define SEC_GOODSIGN
Email has a valid signature.
Definition: lib.h:87
private.h
mutt_is_application_smime
SecurityFlags mutt_is_application_smime(struct Body *m)
Does the message use S/MIME?
Definition: crypt.c:612
ENC_7BIT
@ ENC_7BIT
7-bit text
Definition: mime.h:49
mutt_message_to_7bit
void mutt_message_to_7bit(struct Body *a, FILE *fp, struct ConfigSubset *sub)
Convert an email's MIME parts to 7-bit.
Definition: sendlib.c:748
SEC_AUTOCRYPT
#define SEC_AUTOCRYPT
(Autocrypt) Message will be, or was Autocrypt encrypt+signed
Definition: lib.h:94
Address
An email address.
Definition: address.h:34
cryptglue.h
state_puts
#define state_puts(STATE, STR)
Definition: state.h:55
SEC_PARTSIGN
#define SEC_PARTSIGN
Not all parts of the email is signed.
Definition: lib.h:89
Body::mime_headers
struct Envelope * mime_headers
Memory hole protected headers.
Definition: body.h:63
C_SmimeEncryptSelf
unsigned char C_SmimeEncryptSelf
Definition: config.c:78
Body::filename
char * filename
when sending a message, this is the file to which this structure refers
Definition: body.h:46
Email::body
struct Body * body
List of MIME parts.
Definition: email.h:91
mutt_error
#define mutt_error(...)
Definition: logging.h:84