NeoMutt  2019-12-07-60-g0cfa53
Teaching an old dog new tricks
DOXYGEN
crypt.c File Reference

Signing/encryption multiplexor. More...

#include "config.h"
#include <locale.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include "mutt/mutt.h"
#include "address/lib.h"
#include "config/lib.h"
#include "email/lib.h"
#include "gui/lib.h"
#include "mutt.h"
#include "crypt.h"
#include "alias.h"
#include "copy.h"
#include "cryptglue.h"
#include "globals.h"
#include "handler.h"
#include "mutt_parse.h"
#include "muttlib.h"
#include "ncrypt.h"
#include "options.h"
#include "send.h"
#include "sendlib.h"
#include "state.h"
#include "autocrypt/autocrypt.h"
+ Include dependency graph for crypt.c:

Go to the source code of this file.

Functions

void crypt_current_time (struct State *s, const char *app_name)
 Print the current time. More...
 
void crypt_forget_passphrase (void)
 Forget a passphrase and display a message. More...
 
bool crypt_valid_passphrase (SecurityFlags flags)
 Check that we have a usable passphrase, ask if not. More...
 
int mutt_protect (struct Email *e, char *keylist, bool postpone)
 Encrypt and/or sign a message. More...
 
SecurityFlags mutt_is_multipart_signed (struct Body *b)
 Is a message signed? More...
 
SecurityFlags mutt_is_multipart_encrypted (struct Body *b)
 Does the message have encrypted parts? More...
 
int mutt_is_valid_multipart_pgp_encrypted (struct Body *b)
 Is this a valid multi-part encrypted message? More...
 
SecurityFlags mutt_is_malformed_multipart_pgp_encrypted (struct Body *b)
 Check for malformed layout. More...
 
SecurityFlags mutt_is_application_pgp (struct Body *m)
 Does the message use PGP? More...
 
SecurityFlags mutt_is_application_smime (struct Body *m)
 Does the message use S/MIME? More...
 
SecurityFlags crypt_query (struct Body *m)
 Check out the type of encryption used. More...
 
int crypt_write_signed (struct Body *a, struct State *s, const char *tempfile)
 Write the message body/part. More...
 
void crypt_convert_to_7bit (struct Body *a)
 Convert an email to 7bit encoding. More...
 
void crypt_extract_keys_from_messages (struct Mailbox *m, struct EmailList *el)
 Extract keys from 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...
 
static void crypt_fetch_signatures (struct Body ***signatures, struct Body *a, int *n)
 Create an array of an emails parts. More...
 
bool mutt_should_hide_protected_subject (struct Email *e)
 Should NeoMutt hide the protected subject? More...
 
int mutt_protected_headers_handler (struct Body *a, struct State *s)
 Process a protected header - Implements handler_t. More...
 
int mutt_signed_handler (struct Body *a, struct State *s)
 Verify a "multipart/signed" body - Implements handler_t. More...
 
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. More...
 
bool crypt_is_numerical_keyid (const char *s)
 Is this a numerical keyid. More...
 

Variables

bool C_CryptTimestamp
 Config: Add a timestamp to PGP or SMIME output to prevent spoofing. More...
 
unsigned char C_PgpEncryptSelf
 Deprecated, see C_PgpSelfEncrypt. More...
 
unsigned char C_PgpMimeAuto
 Config: Prompt the user to use MIME if inline PGP fails. More...
 
bool C_PgpRetainableSigs
 Config: Create nested multipart/signed or encrypted messages. More...
 
bool C_PgpSelfEncrypt
 Config: Encrypted messages will also be encrypted to C_PgpDefaultKey too. More...
 
bool C_PgpStrictEnc
 Config: Encode PGP signed messages with quoted-printable (don't unset) More...
 
unsigned char C_SmimeEncryptSelf
 Deprecated, see C_SmimeSelfEncrypt. More...
 
bool C_SmimeSelfEncrypt
 Config: Encrypted messages will also be encrypt to C_SmimeDefaultKey too. More...
 

Detailed Description

Signing/encryption multiplexor.

Authors
  • Michael R. Elkins
  • Thomas Roessler
  • Thomas Roessler
  • Oliver Ehli
  • 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 crypt.c.

Function Documentation

◆ crypt_current_time()

void crypt_current_time ( struct State s,
const char *  app_name 
)

Print the current time.

Parameters
sState to use
app_nameApp name, e.g. "PGP"

print the current time to avoid spoofing of the signature output

Definition at line 82 of file crypt.c.

83 {
84  char p[256], tmp[256];
85 
86  if (!WithCrypto)
87  return;
88 
89  if (C_CryptTimestamp)
90  {
91  mutt_date_localtime_format(p, sizeof(p), _(" (current time: %c)"), MUTT_DATE_NOW);
92  }
93  else
94  *p = '\0';
95 
96  snprintf(tmp, sizeof(tmp), _("[-- %s output follows%s --]\n"), NONULL(app_name), p);
97  state_attach_puts(s, tmp);
98 }
#define NONULL(x)
Definition: string2.h:37
size_t mutt_date_localtime_format(char *buf, size_t buflen, const char *format, time_t t)
Format localtime.
Definition: date.c:774
#define _(a)
Definition: message.h:28
#define MUTT_DATE_NOW
Constant representing the &#39;current time&#39;, see: mutt_date_gmtime(), mutt_date_localtime() ...
Definition: date.h:37
bool C_CryptTimestamp
Config: Add a timestamp to PGP or SMIME output to prevent spoofing.
Definition: crypt.c:63
void state_attach_puts(struct State *s, const char *t)
Write a string to the state.
Definition: state.c:70
#define WithCrypto
Definition: ncrypt.h:160
+ 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 103 of file crypt.c.

104 {
107 
110 
111  if (WithCrypto)
112  {
113  /* L10N: Due to the implementation details (e.g. some passwords are managed
114  by gpg-agent) we can't know whether we forgot zero, 1, 12, ...
115  passwords. So in English we use "Passphrases". Your language might
116  have other means to express this. */
117  mutt_message(_("Passphrases forgotten"));
118  }
119 }
#define mutt_message(...)
Definition: logging.h:83
void crypt_pgp_void_passphrase(void)
Wrapper for CryptModuleSpecs::void_passphrase()
Definition: cryptglue.c:183
#define _(a)
Definition: message.h:28
void crypt_smime_void_passphrase(void)
Wrapper for CryptModuleSpecs::void_passphrase()
Definition: cryptglue.c:407
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: ncrypt.h:134
#define WithCrypto
Definition: ncrypt.h:160
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: ncrypt.h:135
+ 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 145 of file crypt.c.

146 {
147  bool rc = false;
148 
149 #ifndef DEBUG
150  disable_coredumps();
151 #endif
152 
153  if (((WithCrypto & APPLICATION_PGP) != 0) && (flags & APPLICATION_PGP))
155 
156  if (((WithCrypto & APPLICATION_SMIME) != 0) && (flags & APPLICATION_SMIME))
158 
159  return rc;
160 }
bool crypt_smime_valid_passphrase(void)
Wrapper for CryptModuleSpecs::valid_passphrase()
Definition: cryptglue.c:416
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: ncrypt.h:134
#define WithCrypto
Definition: ncrypt.h:160
bool crypt_pgp_valid_passphrase(void)
Wrapper for CryptModuleSpecs::valid_passphrase()
Definition: cryptglue.c:192
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: ncrypt.h:135
+ 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 170 of file crypt.c.

171 {
172  struct Body *pbody = NULL, *tmp_pbody = NULL;
173  struct Body *tmp_smime_pbody = NULL;
174  struct Body *tmp_pgp_pbody = NULL;
175  bool has_retainable_sig = false;
176 
177  if (!WithCrypto)
178  return -1;
179 
180  int security = e->security;
181  int sign = security & (SEC_AUTOCRYPT | SEC_SIGN);
182  if (postpone)
183  {
184  sign = SEC_NO_FLAGS;
185  security &= ~SEC_SIGN;
186  }
187 
188  if (!(security & (SEC_ENCRYPT | SEC_AUTOCRYPT)) && !sign)
189  return 0;
190 
191  if (sign && !(security & SEC_AUTOCRYPT) && !crypt_valid_passphrase(security))
192  return -1;
193 
194  if (((WithCrypto & APPLICATION_PGP) != 0) && !(security & SEC_AUTOCRYPT) &&
195  ((security & PGP_INLINE) == PGP_INLINE))
196  {
197  if ((e->content->type != TYPE_TEXT) ||
198  (mutt_str_strcasecmp(e->content->subtype, "plain") != 0))
199  {
201  _("Inline PGP can't be used with attachments. "
202  "Revert to PGP/MIME?")) != MUTT_YES)
203  {
204  mutt_error(
205  _("Mail not sent: inline PGP can't be used with attachments"));
206  return -1;
207  }
208  }
209  else if (mutt_str_strcasecmp("flowed", mutt_param_get(&e->content->parameter, "format")) == 0)
210  {
212  _("Inline PGP can't be used with format=flowed. "
213  "Revert to PGP/MIME?"))) != MUTT_YES)
214  {
215  mutt_error(
216  _("Mail not sent: inline PGP can't be used with format=flowed"));
217  return -1;
218  }
219  }
220  else
221  {
222  /* they really want to send it inline... go for it */
223  if (!isendwin())
224  {
225  mutt_endwin();
226  puts(_("Invoking PGP..."));
227  }
228  pbody = crypt_pgp_traditional_encryptsign(e->content, security, keylist);
229  if (pbody)
230  {
231  e->content = pbody;
232  return 0;
233  }
234 
235  /* otherwise inline won't work...ask for revert */
236  if (query_quadoption(
238  _("Message can't be sent inline. Revert to using PGP/MIME?")) != MUTT_YES)
239  {
240  mutt_error(_("Mail not sent"));
241  return -1;
242  }
243  }
244 
245  /* go ahead with PGP/MIME */
246  }
247 
248  if (!isendwin())
249  mutt_endwin();
250 
252  tmp_smime_pbody = e->content;
253  if (WithCrypto & APPLICATION_PGP)
254  tmp_pgp_pbody = e->content;
255 
256  if (C_CryptUsePka && sign)
257  {
258  /* Set sender (necessary for e.g. PKA). */
259  const char *mailbox = NULL;
260  struct Address *from = TAILQ_FIRST(&e->env->from);
261  bool free_from = false;
262 
263  if (!from)
264  {
265  free_from = true;
266  from = mutt_default_from();
267  }
268 
269  mailbox = from->mailbox;
270  if (!mailbox && C_EnvelopeFromAddress)
271  mailbox = C_EnvelopeFromAddress->mailbox;
272 
273  if (((WithCrypto & APPLICATION_SMIME) != 0) && (security & APPLICATION_SMIME))
274  crypt_smime_set_sender(mailbox);
275  else if (((WithCrypto & APPLICATION_PGP) != 0) && (security & APPLICATION_PGP))
276  crypt_pgp_set_sender(mailbox);
277 
278  if (free_from)
279  mutt_addr_free(&from);
280  }
281 
283  {
284  struct Envelope *protected_headers = mutt_env_new();
285  mutt_str_replace(&protected_headers->subject, e->env->subject);
286  /* Note: if other headers get added, such as to, cc, then a call to
287  * mutt_env_to_intl() will need to be added here too. */
288  mutt_prepare_envelope(protected_headers, 0);
289 
291  e->content->mime_headers = protected_headers;
292  }
293 
294  /* A note about e->content->mime_headers. If postpone or send
295  * fails, the mime_headers is cleared out before returning to the
296  * compose menu. So despite the "robustness" code above and in the
297  * gen_gossip_list function below, mime_headers will not be set when
298  * entering mutt_protect().
299  *
300  * This is important to note because the user could toggle
301  * $crypt_protected_headers_write or $autocrypt off back in the
302  * compose menu. We don't want mutt_write_rfc822_header() to write
303  * stale data from one option if the other is set.
304  */
305 #ifdef USE_AUTOCRYPT
306  if (C_Autocrypt && !postpone && (security & SEC_AUTOCRYPT))
307  {
309  }
310 #endif
311 
312  if (sign)
313  {
314  if (((WithCrypto & APPLICATION_SMIME) != 0) && (security & APPLICATION_SMIME))
315  {
316  tmp_pbody = crypt_smime_sign_message(e->content, &e->env->from);
317  if (!tmp_pbody)
318  goto bail;
319  pbody = tmp_pbody;
320  tmp_smime_pbody = tmp_pbody;
321  }
322 
323  if (((WithCrypto & APPLICATION_PGP) != 0) && (security & APPLICATION_PGP) &&
324  (!(security & (SEC_ENCRYPT | SEC_AUTOCRYPT)) || C_PgpRetainableSigs))
325  {
326  tmp_pbody = crypt_pgp_sign_message(e->content, &e->env->from);
327  if (!tmp_pbody)
328  goto bail;
329 
330  has_retainable_sig = true;
331  sign = SEC_NO_FLAGS;
332  pbody = tmp_pbody;
333  tmp_pgp_pbody = tmp_pbody;
334  }
335 
336  if ((WithCrypto != 0) && (security & APPLICATION_SMIME) && (security & APPLICATION_PGP))
337  {
338  /* here comes the draft ;-) */
339  }
340  }
341 
342  if (security & (SEC_ENCRYPT | SEC_AUTOCRYPT))
343  {
344  if (((WithCrypto & APPLICATION_SMIME) != 0) && (security & APPLICATION_SMIME))
345  {
346  tmp_pbody = crypt_smime_build_smime_entity(tmp_smime_pbody, keylist);
347  if (!tmp_pbody)
348  {
349  /* signed ? free it! */
350  goto bail;
351  }
352  /* free tmp_body if messages was signed AND encrypted ... */
353  if ((tmp_smime_pbody != e->content) && (tmp_smime_pbody != tmp_pbody))
354  {
355  /* detach and don't delete e->content,
356  * which tmp_smime_pbody->parts after signing. */
357  tmp_smime_pbody->parts = tmp_smime_pbody->parts->next;
358  e->content->next = NULL;
359  mutt_body_free(&tmp_smime_pbody);
360  }
361  pbody = tmp_pbody;
362  }
363 
364  if (((WithCrypto & APPLICATION_PGP) != 0) && (security & APPLICATION_PGP))
365  {
366  pbody = crypt_pgp_encrypt_message(e, tmp_pgp_pbody, keylist, sign, &e->env->from);
367  if (!pbody)
368  {
369  /* did we perform a retainable signature? */
370  if (has_retainable_sig)
371  {
372  /* remove the outer multipart layer */
373  tmp_pgp_pbody = mutt_remove_multipart(tmp_pgp_pbody);
374  /* get rid of the signature */
375  mutt_body_free(&tmp_pgp_pbody->next);
376  }
377 
378  goto bail;
379  }
380 
381  /* destroy temporary signature envelope when doing retainable
382  * signatures.
383 
384  */
385  if (has_retainable_sig)
386  {
387  tmp_pgp_pbody = mutt_remove_multipart(tmp_pgp_pbody);
388  mutt_body_free(&tmp_pgp_pbody->next);
389  }
390  }
391  }
392 
393  if (pbody)
394  {
395  e->content = pbody;
396  return 0;
397  }
398 
399 bail:
401  return -1;
402 }
#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:198
struct Envelope * mime_headers
Memory hole protected headers.
Definition: body.h:63
struct Body * mutt_remove_multipart(struct Body *b)
Extract the multipart body if it exists.
Definition: sendlib.c:1772
#define PGP_INLINE
Definition: ncrypt.h:144
#define TAILQ_FIRST(head)
Definition: queue.h:716
enum QuadOption query_quadoption(enum QuadOption opt, const char *prompt)
Ask the user a quad-question.
Definition: init.c:3360
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:40
#define SEC_NO_FLAGS
No flags are set.
Definition: ncrypt.h:121
struct Body * content
List of MIME parts.
Definition: email.h:90
WHERE bool C_CryptUsePka
Config: Use GPGME to use PKA (lookup PGP keys using DNS)
Definition: globals.h:264
WHERE bool C_CryptProtectedHeadersWrite
Config: Generate protected header (Memory Hole) for signed and encrypted emails.
Definition: globals.h:272
void crypt_pgp_set_sender(const char *sender)
Wrapper for CryptModuleSpecs::set_sender()
Definition: cryptglue.c:398
#define _(a)
Definition: message.h:28
struct Body * next
next attachment in the list
Definition: body.h:53
An email address.
Definition: address.h:34
char * mailbox
Mailbox and host address.
Definition: address.h:37
#define SEC_ENCRYPT
Email is encrypted.
Definition: ncrypt.h:122
void mutt_addr_free(struct Address **ptr)
Free a single Address.
Definition: address.c:440
The body of an email.
Definition: body.h:34
void mutt_prepare_envelope(struct Envelope *env, bool final)
Prepare an email header.
Definition: sendlib.c:3001
void crypt_smime_set_sender(const char *sender)
Wrapper for CryptModuleSpecs::set_sender()
Definition: cryptglue.c:535
struct Body * crypt_smime_sign_message(struct Body *a, const struct AddressList *from)
Wrapper for CryptModuleSpecs::sign_message()
Definition: cryptglue.c:482
bool crypt_valid_passphrase(SecurityFlags flags)
Check that we have a usable passphrase, ask if not.
Definition: crypt.c:145
struct AddressList from
Email&#39;s &#39;From&#39; list.
Definition: envelope.h:57
bool C_PgpRetainableSigs
Config: Create nested multipart/signed or encrypted messages.
Definition: crypt.c:69
struct Envelope * env
Envelope information.
Definition: email.h:89
struct Envelope * mutt_env_new(void)
Create a new Envelope.
Definition: envelope.c:42
char * subtype
content-type subtype
Definition: body.h:37
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:332
#define SEC_SIGN
Email is signed.
Definition: ncrypt.h:123
struct Address * mutt_default_from(void)
Get a default &#39;from&#39; Address.
Definition: send.c:1334
void mutt_endwin(void)
Shutdown curses/slang.
Definition: curs_lib.c:545
Type: &#39;text/*&#39;.
Definition: mime.h:38
void mutt_env_free(struct Envelope **ptr)
Free an Envelope.
Definition: envelope.c:96
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:54
struct Body * crypt_pgp_traditional_encryptsign(struct Body *a, int flags, char *keylist)
Wrapper for CryptModuleSpecs::pgp_traditional_encryptsign()
Definition: cryptglue.c:288
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:39
void mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:453
unsigned int type
content-type primary type
Definition: body.h:65
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: ncrypt.h:134
unsigned char C_PgpMimeAuto
Config: Prompt the user to use MIME if inline PGP fails.
Definition: crypt.c:68
struct Body * crypt_smime_build_smime_entity(struct Body *a, char *certlist)
Wrapper for CryptModuleSpecs::smime_build_smime_entity()
Definition: cryptglue.c:493
char * subject
Email&#39;s subject.
Definition: envelope.h:66
int mutt_autocrypt_generate_gossip_list(struct Email *e)
Create the gossip list headers.
Definition: autocrypt.c:797
#define mutt_error(...)
Definition: logging.h:84
WHERE struct Address * C_EnvelopeFromAddress
Config: Manually set the sender for outgoing messages.
Definition: globals.h:93
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:628
struct Body * crypt_pgp_sign_message(struct Body *a, const struct AddressList *from)
Wrapper for CryptModuleSpecs::sign_message()
Definition: cryptglue.c:321
char * mutt_param_get(const struct ParameterList *pl, const char *s)
Find a matching Parameter.
Definition: parameter.c:84
void mutt_body_free(struct Body **ptr)
Free a Body.
Definition: body.c:57
struct ParameterList parameter
parameters of the content-type
Definition: body.h:39
#define WithCrypto
Definition: ncrypt.h:160
The header of an Email.
Definition: envelope.h:54
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: ncrypt.h:135
+ 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 410 of file crypt.c.

411 {
412  if (!b || (b->type != TYPE_MULTIPART) || !b->subtype ||
413  (mutt_str_strcasecmp(b->subtype, "signed") != 0))
414  {
415  return SEC_NO_FLAGS;
416  }
417 
418  char *p = mutt_param_get(&b->parameter, "protocol");
419  if (!p)
420  return SEC_NO_FLAGS;
421 
422  if (!(mutt_str_strcasecmp(p, "multipart/mixed") != 0))
423  return SEC_SIGN;
424 
425  if (((WithCrypto & APPLICATION_PGP) != 0) &&
426  !(mutt_str_strcasecmp(p, "application/pgp-signature") != 0))
427  {
428  return PGP_SIGN;
429  }
430 
431  if (((WithCrypto & APPLICATION_SMIME) != 0) &&
432  !(mutt_str_strcasecmp(p, "application/x-pkcs7-signature") != 0))
433  {
434  return SMIME_SIGN;
435  }
436  if (((WithCrypto & APPLICATION_SMIME) != 0) &&
437  !(mutt_str_strcasecmp(p, "application/pkcs7-signature") != 0))
438  {
439  return SMIME_SIGN;
440  }
441 
442  return SEC_NO_FLAGS;
443 }
#define SEC_NO_FLAGS
No flags are set.
Definition: ncrypt.h:121
#define SMIME_SIGN
Definition: ncrypt.h:147
#define PGP_SIGN
Definition: ncrypt.h:141
char * subtype
content-type subtype
Definition: body.h:37
#define SEC_SIGN
Email is signed.
Definition: ncrypt.h:123
unsigned int type
content-type primary type
Definition: body.h:65
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: ncrypt.h:134
Type: &#39;multipart/*&#39;.
Definition: mime.h:37
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:628
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:39
#define WithCrypto
Definition: ncrypt.h:160
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: ncrypt.h:135
+ 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 451 of file crypt.c.

452 {
453  if ((WithCrypto & APPLICATION_PGP) == 0)
454  return SEC_NO_FLAGS;
455 
456  char *p = NULL;
457 
458  if (!b || (b->type != TYPE_MULTIPART) || !b->subtype ||
459  (mutt_str_strcasecmp(b->subtype, "encrypted") != 0) ||
460  !(p = mutt_param_get(&b->parameter, "protocol")) ||
461  (mutt_str_strcasecmp(p, "application/pgp-encrypted") != 0))
462  {
463  return SEC_NO_FLAGS;
464  }
465 
466  return PGP_ENCRYPT;
467 }
#define SEC_NO_FLAGS
No flags are set.
Definition: ncrypt.h:121
char * subtype
content-type subtype
Definition: body.h:37
unsigned int type
content-type primary type
Definition: body.h:65
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: ncrypt.h:134
Type: &#39;multipart/*&#39;.
Definition: mime.h:37
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:628
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:39
#define WithCrypto
Definition: ncrypt.h:160
#define PGP_ENCRYPT
Definition: ncrypt.h:140
+ 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 475 of file crypt.c.

476 {
478  return 0;
479 
480  b = b->parts;
481  if (!b || (b->type != TYPE_APPLICATION) || !b->subtype ||
482  (mutt_str_strcasecmp(b->subtype, "pgp-encrypted") != 0))
483  {
484  return 0;
485  }
486 
487  b = b->next;
488  if (!b || (b->type != TYPE_APPLICATION) || !b->subtype ||
489  (mutt_str_strcasecmp(b->subtype, "octet-stream") != 0))
490  {
491  return 0;
492  }
493 
494  return PGP_ENCRYPT;
495 }
#define SEC_NO_FLAGS
No flags are set.
Definition: ncrypt.h:121
struct Body * next
next attachment in the list
Definition: body.h:53
SecurityFlags mutt_is_multipart_encrypted(struct Body *b)
Does the message have encrypted parts?
Definition: crypt.c:451
char * subtype
content-type subtype
Definition: body.h:37
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:54
unsigned int type
content-type primary type
Definition: body.h:65
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:628
Type: &#39;application/*&#39;.
Definition: mime.h:33
#define PGP_ENCRYPT
Definition: ncrypt.h:140
+ 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 512 of file crypt.c.

513 {
514  if (!(WithCrypto & APPLICATION_PGP))
515  return SEC_NO_FLAGS;
516 
517  if (!b || (b->type != TYPE_MULTIPART) || !b->subtype ||
518  (mutt_str_strcasecmp(b->subtype, "mixed") != 0))
519  {
520  return SEC_NO_FLAGS;
521  }
522 
523  b = b->parts;
524  if (!b || (b->type != TYPE_TEXT) || !b->subtype ||
525  (mutt_str_strcasecmp(b->subtype, "plain") != 0) || (b->length != 0))
526  {
527  return SEC_NO_FLAGS;
528  }
529 
530  b = b->next;
531  if (!b || (b->type != TYPE_APPLICATION) || !b->subtype ||
532  (mutt_str_strcasecmp(b->subtype, "pgp-encrypted") != 0))
533  {
534  return SEC_NO_FLAGS;
535  }
536 
537  b = b->next;
538  if (!b || (b->type != TYPE_APPLICATION) || !b->subtype ||
539  (mutt_str_strcasecmp(b->subtype, "octet-stream") != 0))
540  {
541  return SEC_NO_FLAGS;
542  }
543 
544  b = b->next;
545  if (b)
546  return SEC_NO_FLAGS;
547 
548  return PGP_ENCRYPT;
549 }
#define SEC_NO_FLAGS
No flags are set.
Definition: ncrypt.h:121
struct Body * next
next attachment in the list
Definition: body.h:53
char * subtype
content-type subtype
Definition: body.h:37
LOFF_T length
length (in bytes) of attachment
Definition: body.h:45
Type: &#39;text/*&#39;.
Definition: mime.h:38
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:54
unsigned int type
content-type primary type
Definition: body.h:65
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: ncrypt.h:134
Type: &#39;multipart/*&#39;.
Definition: mime.h:37
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:628
#define WithCrypto
Definition: ncrypt.h:160
Type: &#39;application/*&#39;.
Definition: mime.h:33
#define PGP_ENCRYPT
Definition: ncrypt.h:140
+ 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 m)

Does the message use PGP?

Parameters
mBody of email
Return values
>0Message uses PGP, e.g. PGP_ENCRYPT
0Message doesn't use PGP, (SEC_NO_FLAGS)

Definition at line 557 of file crypt.c.

558 {
560  char *p = NULL;
561 
562  if (m->type == TYPE_APPLICATION)
563  {
564  if ((mutt_str_strcasecmp(m->subtype, "pgp") == 0) ||
565  (mutt_str_strcasecmp(m->subtype, "x-pgp-message") == 0))
566  {
567  p = mutt_param_get(&m->parameter, "x-action");
568  if (p && ((mutt_str_strcasecmp(p, "sign") == 0) ||
569  (mutt_str_strcasecmp(p, "signclear") == 0)))
570  {
571  t |= PGP_SIGN;
572  }
573 
574  p = mutt_param_get(&m->parameter, "format");
575  if (p && (mutt_str_strcasecmp(p, "keys-only") == 0))
576  {
577  t |= PGP_KEY;
578  }
579 
580  if (t == SEC_NO_FLAGS)
581  t |= PGP_ENCRYPT; /* not necessarily correct, but... */
582  }
583 
584  if (mutt_str_strcasecmp(m->subtype, "pgp-signed") == 0)
585  t |= PGP_SIGN;
586 
587  if (mutt_str_strcasecmp(m->subtype, "pgp-keys") == 0)
588  t |= PGP_KEY;
589  }
590  else if ((m->type == TYPE_TEXT) && (mutt_str_strcasecmp("plain", m->subtype) == 0))
591  {
592  if (((p = mutt_param_get(&m->parameter, "x-mutt-action")) ||
593  (p = mutt_param_get(&m->parameter, "x-action")) ||
594  (p = mutt_param_get(&m->parameter, "action"))) &&
595  mutt_str_startswith(p, "pgp-sign", CASE_IGNORE))
596  {
597  t |= PGP_SIGN;
598  }
599  else if (p && mutt_str_startswith(p, "pgp-encrypt", CASE_IGNORE))
600  t |= PGP_ENCRYPT;
601  else if (p && mutt_str_startswith(p, "pgp-keys", CASE_IGNORE))
602  t |= PGP_KEY;
603  }
604  if (t)
605  t |= PGP_INLINE;
606 
607  return t;
608 }
#define PGP_INLINE
Definition: ncrypt.h:144
#define SEC_NO_FLAGS
No flags are set.
Definition: ncrypt.h:121
#define PGP_SIGN
Definition: ncrypt.h:141
char * subtype
content-type subtype
Definition: body.h:37
#define PGP_KEY
Definition: ncrypt.h:143
Type: &#39;text/*&#39;.
Definition: mime.h:38
Ignore case when comparing strings.
Definition: string2.h:68
unsigned int type
content-type primary type
Definition: body.h:65
size_t mutt_str_startswith(const char *str, const char *prefix, enum CaseSensitivity cs)
Check whether a string starts with a prefix.
Definition: string.c:168
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:628
char * mutt_param_get(const struct ParameterList *pl, const char *s)
Find a matching Parameter.
Definition: parameter.c:84
uint16_t SecurityFlags
Flags, e.g. SEC_ENCRYPT.
Definition: ncrypt.h:120
struct ParameterList parameter
parameters of the content-type
Definition: body.h:39
Type: &#39;application/*&#39;.
Definition: mime.h:33
#define PGP_ENCRYPT
Definition: ncrypt.h:140
+ 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 m)

Does the message use S/MIME?

Parameters
mBody of email
Return values
>0Message uses S/MIME, e.g. SMIME_ENCRYPT
0Message doesn't use S/MIME, (SEC_NO_FLAGS)

Definition at line 616 of file crypt.c.

617 {
618  if (!m)
619  return SEC_NO_FLAGS;
620 
621  if (((m->type & TYPE_APPLICATION) == 0) || !m->subtype)
622  return SEC_NO_FLAGS;
623 
624  char *t = NULL;
625  bool complain = false;
626  /* S/MIME MIME types don't need x- anymore, see RFC2311 */
627  if ((mutt_str_strcasecmp(m->subtype, "x-pkcs7-mime") == 0) ||
628  (mutt_str_strcasecmp(m->subtype, "pkcs7-mime") == 0))
629  {
630  t = mutt_param_get(&m->parameter, "smime-type");
631  if (t)
632  {
633  if (mutt_str_strcasecmp(t, "enveloped-data") == 0)
634  return SMIME_ENCRYPT;
635  if (mutt_str_strcasecmp(t, "signed-data") == 0)
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_str_strcasecmp(m->description, "S/MIME Encrypted Message") == 0)
643  return SMIME_ENCRYPT;
644  complain = true;
645  }
646  else if (mutt_str_strcasecmp(m->subtype, "octet-stream") != 0)
647  return SEC_NO_FLAGS;
648 
649  t = mutt_param_get(&m->parameter, "name");
650 
651  if (!t)
652  t = m->d_filename;
653  if (!t)
654  t = m->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_strlen(t) - 4;
668  if ((len > 0) && (*(t + len) == '.'))
669  {
670  len++;
671  if (mutt_str_strcasecmp((t + len), "p7m") == 0)
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_str_strcasecmp((t + len), "p7s") == 0)
678  return SMIME_SIGN | SMIME_OPAQUE;
679  }
680 
681  return SEC_NO_FLAGS;
682 }
char * filename
when sending a message, this is the file to which this structure refers
Definition: body.h:46
#define mutt_message(...)
Definition: logging.h:83
#define SEC_NO_FLAGS
No flags are set.
Definition: ncrypt.h:121
#define _(a)
Definition: message.h:28
#define SMIME_SIGN
Definition: ncrypt.h:147
size_t mutt_str_strlen(const char *a)
Calculate the length of a string, safely.
Definition: string.c:666
#define SMIME_OPAQUE
Definition: ncrypt.h:150
char * subtype
content-type subtype
Definition: body.h:37
char * description
content-description
Definition: body.h:40
unsigned int type
content-type primary type
Definition: body.h:65
#define SMIME_ENCRYPT
Definition: ncrypt.h:146
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:628
char * mutt_param_get(const struct ParameterList *pl, const char *s)
Find a matching Parameter.
Definition: parameter.c:84
char * d_filename
filename to be used for the content-disposition header.
Definition: body.h:47
struct ParameterList parameter
parameters of the content-type
Definition: body.h:39
Type: &#39;application/*&#39;.
Definition: mime.h:33
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ crypt_query()

SecurityFlags crypt_query ( struct Body m)

Check out the type of encryption used.

Parameters
mBody 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 || !m)
695  return SEC_NO_FLAGS;
696 
698 
699  if (m->type == TYPE_APPLICATION)
700  {
702  rc |= mutt_is_application_pgp(m);
703 
705  {
706  rc |= mutt_is_application_smime(m);
707  if (rc && m->goodsig)
708  rc |= SEC_GOODSIGN;
709  if (rc && m->badsig)
710  rc |= SEC_BADSIGN;
711  }
712  }
713  else if (((WithCrypto & APPLICATION_PGP) != 0) && (m->type == TYPE_TEXT))
714  {
715  rc |= mutt_is_application_pgp(m);
716  if (rc && m->goodsig)
717  rc |= SEC_GOODSIGN;
718  }
719 
720  if (m->type == TYPE_MULTIPART)
721  {
723  rc |= mutt_is_multipart_signed(m);
725 
726  if (rc && m->goodsig)
727  rc |= SEC_GOODSIGN;
728 #ifdef USE_AUTOCRYPT
729  if (rc && m->is_autocrypt)
730  rc |= SEC_AUTOCRYPT;
731 #endif
732  }
733 
734  if ((m->type == TYPE_MULTIPART) || (m->type == TYPE_MESSAGE))
735  {
736  SecurityFlags u = m->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 (struct Body *b = m->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 }
#define SEC_AUTOCRYPT
Message will be, or was Autocrypt encrypt+signed.
Definition: ncrypt.h:131
#define SEC_NO_FLAGS
No flags are set.
Definition: ncrypt.h:121
bool is_autocrypt
Flag autocrypt-decrypted messages for replying.
Definition: body.h:79
struct Body * next
next attachment in the list
Definition: body.h:53
#define SEC_PARTSIGN
Not all parts of the email is signed.
Definition: ncrypt.h:126
The body of an email.
Definition: body.h:34
#define SEC_BADSIGN
Email has a bad signature.
Definition: ncrypt.h:125
#define SEC_ALL_FLAGS
Definition: ncrypt.h:138
SecurityFlags mutt_is_multipart_encrypted(struct Body *b)
Does the message have encrypted parts?
Definition: crypt.c:451
#define SEC_GOODSIGN
Email has a valid signature.
Definition: ncrypt.h:124
bool badsig
Bad cryptographic signature (needed to check encrypted s/mime-signatures)
Definition: body.h:77
SecurityFlags mutt_is_multipart_signed(struct Body *b)
Is a message signed?
Definition: crypt.c:410
bool goodsig
Good cryptographic signature.
Definition: body.h:75
SecurityFlags mutt_is_application_pgp(struct Body *m)
Does the message use PGP?
Definition: crypt.c:557
Type: &#39;text/*&#39;.
Definition: mime.h:38
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:54
SecurityFlags mutt_is_malformed_multipart_pgp_encrypted(struct Body *b)
Check for malformed layout.
Definition: crypt.c:512
SecurityFlags mutt_is_application_smime(struct Body *m)
Does the message use S/MIME?
Definition: crypt.c:616
unsigned int type
content-type primary type
Definition: body.h:65
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: ncrypt.h:134
Type: &#39;message/*&#39;.
Definition: mime.h:35
Type: &#39;multipart/*&#39;.
Definition: mime.h:37
uint16_t SecurityFlags
Flags, e.g. SEC_ENCRYPT.
Definition: ncrypt.h:120
#define WithCrypto
Definition: ncrypt.h:160
SecurityFlags crypt_query(struct Body *m)
Check out the type of encryption used.
Definition: crypt.c:692
Type: &#39;application/*&#39;.
Definition: mime.h:33
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: ncrypt.h:135
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ crypt_write_signed()

int crypt_write_signed ( struct Body a,
struct State s,
const char *  tempfile 
)

Write the message body/part.

Parameters
aBody to write
sState to use
tempfileFile to write to
Return values
0Success
-1Error

Body/part A described by state S to the given TEMPFILE.

Definition at line 764 of file crypt.c.

765 {
766  if (!WithCrypto)
767  return -1;
768 
769  FILE *fp = mutt_file_fopen(tempfile, "w");
770  if (!fp)
771  {
772  mutt_perror(tempfile);
773  return -1;
774  }
775 
776  fseeko(s->fp_in, a->hdr_offset, SEEK_SET);
777  size_t bytes = a->length + a->offset - a->hdr_offset;
778  bool hadcr = false;
779  while (bytes > 0)
780  {
781  const int c = fgetc(s->fp_in);
782  if (c == EOF)
783  break;
784 
785  bytes--;
786 
787  if (c == '\r')
788  hadcr = true;
789  else
790  {
791  if ((c == '\n') && !hadcr)
792  fputc('\r', fp);
793 
794  hadcr = false;
795  }
796 
797  fputc(c, fp);
798  }
799  mutt_file_fclose(&fp);
800 
801  return 0;
802 }
#define mutt_perror(...)
Definition: logging.h:85
LOFF_T offset
offset where the actual data begins
Definition: body.h:44
FILE * fp_in
File to read from.
Definition: state.h:46
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:152
LOFF_T length
length (in bytes) of attachment
Definition: body.h:45
long hdr_offset
Offset in stream where the headers begin.
Definition: body.h:42
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:585
#define WithCrypto
Definition: ncrypt.h:160
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ crypt_convert_to_7bit()

void crypt_convert_to_7bit ( struct Body a)

Convert an email to 7bit encoding.

Parameters
aBody of email to convert

Definition at line 808 of file crypt.c.

809 {
810  if (!WithCrypto)
811  return;
812 
813  while (a)
814  {
815  if (a->type == TYPE_MULTIPART)
816  {
817  if (a->encoding != ENC_7BIT)
818  {
819  a->encoding = ENC_7BIT;
821  }
822  else if (((WithCrypto & APPLICATION_PGP) != 0) && C_PgpStrictEnc)
824  }
825  else if ((a->type == TYPE_MESSAGE) &&
826  (mutt_str_strcasecmp(a->subtype, "delivery-status") != 0))
827  {
828  if (a->encoding != ENC_7BIT)
829  mutt_message_to_7bit(a, NULL);
830  }
831  else if (a->encoding == ENC_8BIT)
833  else if (a->encoding == ENC_BINARY)
834  a->encoding = ENC_BASE64;
835  else if (a->content && (a->encoding != ENC_BASE64) &&
836  (a->content->from || (a->content->space && C_PgpStrictEnc)))
837  {
839  }
840  a = a->next;
841  }
842 }
void mutt_message_to_7bit(struct Body *a, FILE *fp)
Convert an email&#39;s MIME parts to 7-bit.
Definition: sendlib.c:1303
struct Content * content
Detailed info about the content of the attachment.
Definition: body.h:51
7-bit text
Definition: mime.h:49
void crypt_convert_to_7bit(struct Body *a)
Convert an email to 7bit encoding.
Definition: crypt.c:808
struct Body * next
next attachment in the list
Definition: body.h:53
8-bit text
Definition: mime.h:50
bool C_PgpStrictEnc
Config: Encode PGP signed messages with quoted-printable (don&#39;t unset)
Definition: crypt.c:71
unsigned int encoding
content-transfer-encoding
Definition: body.h:66
Base-64 encoded text.
Definition: mime.h:52
char * subtype
content-type subtype
Definition: body.h:37
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:54
unsigned int type
content-type primary type
Definition: body.h:65
bool from
Has a line beginning with "From "?
Definition: content.h:43
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: ncrypt.h:134
Type: &#39;message/*&#39;.
Definition: mime.h:35
Type: &#39;multipart/*&#39;.
Definition: mime.h:37
Binary.
Definition: mime.h:53
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:628
Quoted-printable text.
Definition: mime.h:51
bool space
Whitespace at the end of lines?
Definition: content.h:41
#define WithCrypto
Definition: ncrypt.h:160
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ 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 851 of file crypt.c.

852 {
853  if (!WithCrypto)
854  return;
855 
856  struct Buffer *tempfname = mutt_buffer_pool_get();
857  mutt_buffer_mktemp(tempfname);
858  FILE *fp_out = mutt_file_fopen(mutt_b2s(tempfname), "w");
859  if (!fp_out)
860  {
861  mutt_perror(mutt_b2s(tempfname));
862  goto cleanup;
863  }
864 
866  OptDontHandlePgpKeys = true;
867 
868  struct EmailNode *en = NULL;
869  STAILQ_FOREACH(en, el, entries)
870  {
871  struct Email *e = en->email;
872 
875  {
876  mutt_file_fclose(&fp_out);
877  break;
878  }
879 
880  if (((WithCrypto & APPLICATION_PGP) != 0) && (e->security & APPLICATION_PGP))
881  {
883  fflush(fp_out);
884 
885  mutt_endwin();
886  puts(_("Trying to extract PGP keys...\n"));
887  crypt_pgp_invoke_import(mutt_b2s(tempfname));
888  }
889 
890  if (((WithCrypto & APPLICATION_SMIME) != 0) && (e->security & APPLICATION_SMIME))
891  {
892  if (e->security & SEC_ENCRYPT)
893  {
895  CH_NO_FLAGS, 0);
896  }
897  else
899  fflush(fp_out);
900 
901  char *mbox = NULL;
902  if (!TAILQ_EMPTY(&e->env->from))
903  {
905  mbox = TAILQ_FIRST(&e->env->from)->mailbox;
906  }
907  else if (!TAILQ_EMPTY(&e->env->sender))
908  {
910  mbox = TAILQ_FIRST(&e->env->sender)->mailbox;
911  }
912  if (mbox)
913  {
914  mutt_endwin();
915  puts(_("Trying to extract S/MIME certificates..."));
916  crypt_smime_invoke_import(mutt_b2s(tempfname), mbox);
917  }
918  }
919 
920  rewind(fp_out);
921  }
922 
923  mutt_file_fclose(&fp_out);
924  if (isendwin())
926 
927  mutt_file_unlink(mutt_b2s(tempfname));
928 
929  if (WithCrypto & APPLICATION_PGP)
930  OptDontHandlePgpKeys = false;
931 
932 cleanup:
933  mutt_buffer_pool_release(&tempfname);
934 }
#define MUTT_CM_DECODE_CRYPT
Definition: copy.h:47
#define mutt_buffer_mktemp(buf)
Definition: muttlib.h:78
void mutt_expand_aliases(struct AddressList *al)
Expand aliases in a List of Addresses.
Definition: alias.c:303
The envelope/body of an email.
Definition: email.h:37
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
#define TAILQ_FIRST(head)
Definition: queue.h:716
#define mutt_perror(...)
Definition: logging.h:85
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
void mutt_file_unlink(const char *s)
Delete a file, carefully.
Definition: file.c:194
String manipulation buffer.
Definition: buffer.h:33
void mutt_parse_mime_message(struct Mailbox *m, struct Email *e)
Parse a MIME email.
Definition: mutt_parse.c:49
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:810
#define _(a)
Definition: message.h:28
#define SEC_ENCRYPT
Email is encrypted.
Definition: ncrypt.h:122
#define MUTT_CM_NO_FLAGS
No flags are set.
Definition: copy.h:34
bool crypt_valid_passphrase(SecurityFlags flags)
Check that we have a usable passphrase, ask if not.
Definition: crypt.c:145
struct AddressList from
Email&#39;s &#39;From&#39; list.
Definition: envelope.h:57
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:152
struct Envelope * env
Envelope information.
Definition: email.h:89
WHERE bool OptDontHandlePgpKeys
(pseudo) used to extract PGP keys
Definition: options.h:34
#define mutt_b2s(buf)
Definition: buffer.h:41
void mutt_endwin(void)
Shutdown curses/slang.
Definition: curs_lib.c:545
void crypt_pgp_invoke_import(const char *fname)
Wrapper for CryptModuleSpecs::pgp_invoke_import()
Definition: cryptglue.c:358
#define CH_NO_FLAGS
No flags are set.
Definition: copy.h:50
#define MUTT_CM_DECODE
Decode the message body into text/plain.
Definition: copy.h:37
#define MUTT_CM_CHARCONV
Perform character set conversions.
Definition: copy.h:41
#define STAILQ_FOREACH(var, head, field)
Definition: queue.h:349
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:39
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: ncrypt.h:134
#define MUTT_CM_DECODE_SMIME
Used for decoding S/MIME messages.
Definition: copy.h:45
int mutt_any_key_to_continue(const char *s)
Prompt the user to &#39;press any key&#39; and wait.
Definition: curs_lib.c:578
void crypt_smime_invoke_import(const char *infile, const char *mailbox)
Wrapper for CryptModuleSpecs::smime_invoke_import()
Definition: cryptglue.c:504
struct Email * email
Email in the list.
Definition: email.h:116
struct AddressList sender
Email&#39;s sender.
Definition: envelope.h:61
List of Emails.
Definition: email.h:114
#define TAILQ_EMPTY(head)
Definition: queue.h:714
#define MUTT_CM_NOHEADER
Don&#39;t copy the message header.
Definition: copy.h:35
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:585
#define WithCrypto
Definition: ncrypt.h:160
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: ncrypt.h:135
+ 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 950 of file crypt.c.

951 {
952  if (!WithCrypto)
953  return 0;
954 
955  struct AddressList addrlist = TAILQ_HEAD_INITIALIZER(addrlist);
956  const char *fqdn = mutt_fqdn(true);
957  char *self_encrypt = NULL;
958 
959  /* Do a quick check to make sure that we can find all of the encryption
960  * keys if the user has requested this service. */
961 
962  *keylist = NULL;
963 
964 #ifdef USE_AUTOCRYPT
965  if (!oppenc_mode && (e->security & SEC_AUTOCRYPT))
966  {
968  return -1;
969  return 0;
970  }
971 #endif
972 
974  OptPgpCheckTrust = true;
975 
976  mutt_addrlist_copy(&addrlist, &e->env->to, false);
977  mutt_addrlist_copy(&addrlist, &e->env->cc, false);
978  mutt_addrlist_copy(&addrlist, &e->env->bcc, false);
979  mutt_addrlist_qualify(&addrlist, fqdn);
980  mutt_addrlist_dedupe(&addrlist);
981 
982  if (oppenc_mode || (e->security & SEC_ENCRYPT))
983  {
984  if (((WithCrypto & APPLICATION_PGP) != 0) && (e->security & APPLICATION_PGP))
985  {
986  *keylist = crypt_pgp_find_keys(&addrlist, oppenc_mode);
987  if (!*keylist)
988  {
989  mutt_addrlist_clear(&addrlist);
990  return -1;
991  }
992  OptPgpCheckTrust = false;
994  self_encrypt = C_PgpDefaultKey;
995  }
996  if (((WithCrypto & APPLICATION_SMIME) != 0) && (e->security & APPLICATION_SMIME))
997  {
998  *keylist = crypt_smime_find_keys(&addrlist, oppenc_mode);
999  if (!*keylist)
1000  {
1001  mutt_addrlist_clear(&addrlist);
1002  return -1;
1003  }
1005  self_encrypt = C_SmimeDefaultKey;
1006  }
1007  }
1008 
1009  if (!oppenc_mode && self_encrypt)
1010  {
1011  const size_t keylist_size = mutt_str_strlen(*keylist);
1012  mutt_mem_realloc(keylist, keylist_size + mutt_str_strlen(self_encrypt) + 2);
1013  sprintf(*keylist + keylist_size, " %s", self_encrypt);
1014  }
1015 
1016  mutt_addrlist_clear(&addrlist);
1017 
1018  return 0;
1019 }
#define SEC_AUTOCRYPT
Message will be, or was Autocrypt encrypt+signed.
Definition: ncrypt.h:131
char * crypt_smime_find_keys(struct AddressList *addrlist, bool oppenc_mode)
Wrapper for CryptModuleSpecs::find_keys()
Definition: cryptglue.c:471
WHERE char * C_SmimeDefaultKey
Config: Default key for SMIME operations.
Definition: globals.h:163
User answered &#39;Yes&#39;, or assume &#39;Yes&#39;.
Definition: quad.h:40
struct AddressList bcc
Email&#39;s &#39;Bcc&#39; list.
Definition: envelope.h:60
void mutt_addrlist_clear(struct AddressList *al)
Unlink and free all Address in an AddressList.
Definition: address.c:1382
void mutt_addrlist_copy(struct AddressList *dst, const struct AddressList *src, bool prune)
Copy a list of addresses into another list.
Definition: address.c:728
size_t mutt_str_strlen(const char *a)
Calculate the length of a string, safely.
Definition: string.c:666
#define SEC_ENCRYPT
Email is encrypted.
Definition: ncrypt.h:122
bool C_PgpSelfEncrypt
Config: Encrypted messages will also be encrypted to C_PgpDefaultKey too.
Definition: crypt.c:70
void mutt_addrlist_dedupe(struct AddressList *al)
Remove duplicate addresses.
Definition: address.c:1319
unsigned char C_PgpEncryptSelf
Deprecated, see C_PgpSelfEncrypt.
Definition: crypt.c:67
struct Envelope * env
Envelope information.
Definition: email.h:89
struct AddressList cc
Email&#39;s &#39;Cc&#39; list.
Definition: envelope.h:59
void mutt_mem_realloc(void *ptr, size_t size)
Resize a block of memory on the heap.
Definition: memory.c:114
bool C_SmimeSelfEncrypt
Config: Encrypted messages will also be encrypt to C_SmimeDefaultKey too.
Definition: crypt.c:73
Do no use Autocrypt.
Definition: autocrypt.h:104
unsigned char C_SmimeEncryptSelf
Deprecated, see C_SmimeSelfEncrypt.
Definition: crypt.c:72
WHERE bool OptPgpCheckTrust
(pseudo) used by pgp_select_key()
Definition: options.h:47
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:39
const char * mutt_fqdn(bool may_hide_host)
Get the Fully-Qualified Domain Name.
Definition: sendlib.c:2531
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: ncrypt.h:134
void mutt_addrlist_qualify(struct AddressList *al, const char *host)
Expand local names in an Address list using a hostname.
Definition: address.c:641
char * crypt_pgp_find_keys(struct AddressList *addrlist, bool oppenc_mode)
Wrapper for CryptModuleSpecs::find_keys()
Definition: cryptglue.c:310
enum AutocryptRec mutt_autocrypt_ui_recommendation(struct Email *e, char **keylist)
Get the recommended action for an Email.
Definition: autocrypt.c:561
WHERE char * C_PgpDefaultKey
Config: Default key to use for PGP operations.
Definition: globals.h:159
struct AddressList to
Email&#39;s &#39;To&#39; list.
Definition: envelope.h:58
#define TAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:630
#define WithCrypto
Definition: ncrypt.h:160
#define APPLICATION_SMIME
Use SMIME to encrypt/sign.
Definition: ncrypt.h:135
+ 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 1028 of file crypt.c.

1029 {
1030  if (!WithCrypto)
1031  return;
1032 
1034  return;
1035 
1036  char *pgpkeylist = NULL;
1037 
1038  crypt_get_keys(e, &pgpkeylist, 1);
1039  if (pgpkeylist)
1040  {
1041  e->security |= SEC_ENCRYPT;
1042  FREE(&pgpkeylist);
1043  }
1044  else
1045  {
1046  e->security &= ~SEC_ENCRYPT;
1047  }
1048 }
int crypt_get_keys(struct Email *e, char **keylist, bool oppenc_mode)
Check we have all the keys we need.
Definition: crypt.c:950
#define SEC_ENCRYPT
Email is encrypted.
Definition: ncrypt.h:122
WHERE bool C_CryptOpportunisticEncrypt
Config: Enable encryption when the recipient&#39;s key is available.
Definition: globals.h:269
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:39
#define SEC_OPPENCRYPT
Opportunistic encrypt mode.
Definition: ncrypt.h:130
#define FREE(x)
Definition: memory.h:40
#define WithCrypto
Definition: ncrypt.h:160
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ crypt_fetch_signatures()

static void crypt_fetch_signatures ( struct Body ***  signatures,
struct Body a,
int *  n 
)
static

Create an array of an emails parts.

Parameters
[out]signaturesArray of Body parts
[in]aBody part to examine
[out]nCumulative count of parts

Definition at line 1056 of file crypt.c.

1057 {
1058  if (!WithCrypto)
1059  return;
1060 
1061  for (; a; a = a->next)
1062  {
1063  if (a->type == TYPE_MULTIPART)
1064  crypt_fetch_signatures(signatures, a->parts, n);
1065  else
1066  {
1067  if ((*n % 5) == 0)
1068  mutt_mem_realloc(signatures, (*n + 6) * sizeof(struct Body **));
1069 
1070  (*signatures)[(*n)++] = a;
1071  }
1072  }
1073 }
struct Body * next
next attachment in the list
Definition: body.h:53
The body of an email.
Definition: body.h:34
void mutt_mem_realloc(void *ptr, size_t size)
Resize a block of memory on the heap.
Definition: memory.c:114
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:54
static void crypt_fetch_signatures(struct Body ***signatures, struct Body *a, int *n)
Create an array of an emails parts.
Definition: crypt.c:1056
unsigned int type
content-type primary type
Definition: body.h:65
Type: &#39;multipart/*&#39;.
Definition: mime.h:37
#define WithCrypto
Definition: ncrypt.h:160
+ 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
boolTrue if the subject should be protected

Definition at line 1080 of file crypt.c.

1081 {
1084  {
1085  return true;
1086  }
1087 
1088  return false;
1089 }
#define SEC_AUTOCRYPT
Message will be, or was Autocrypt encrypt+signed.
Definition: ncrypt.h:131
WHERE char * C_CryptProtectedHeadersSubject
Config: Use this as the subject for encrypted emails.
Definition: globals.h:105
WHERE bool C_CryptProtectedHeadersWrite
Config: Generate protected header (Memory Hole) for signed and encrypted emails.
Definition: globals.h:272
#define SEC_INLINE
Email has an inline signature.
Definition: ncrypt.h:129
#define SEC_ENCRYPT
Email is encrypted.
Definition: ncrypt.h:122
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:39
+ Here is the caller graph for this function:

◆ mutt_protected_headers_handler()

int mutt_protected_headers_handler ( struct Body a,
struct State s 
)

Process a protected header - Implements handler_t.

Definition at line 1094 of file crypt.c.

1095 {
1097  {
1098  if (a->mime_headers->subject)
1099  {
1100  const bool display = (s->flags & MUTT_DISPLAY);
1101 
1102  if (display && C_Weed && mutt_matches_ignore("subject"))
1103  return 0;
1104 
1106  int wraplen = display ? mutt_window_wrap_cols(s->wraplen, C_Wrap) : 0;
1107 
1108  mutt_write_one_header(s->fp_out, "Subject", a->mime_headers->subject,
1109  s->prefix, wraplen, display ? CH_DISPLAY : CH_NO_FLAGS);
1110  state_puts(s, "\n");
1111  }
1112  }
1113 
1114  return 0;
1115 }
bool mutt_matches_ignore(const char *s)
Does the string match the ignore list.
Definition: parse.c:309
#define MUTT_DISPLAY
Output is displayed to the user.
Definition: state.h:32
struct Envelope * mime_headers
Memory hole protected headers.
Definition: body.h:63
#define state_puts(STATE, STR)
Definition: state.h:55
char * prefix
String to add to the beginning of each output line.
Definition: state.h:48
WHERE short C_Wrap
Config: Width to wrap text in the pager.
Definition: globals.h:152
FILE * fp_out
File to write to.
Definition: state.h:47
StateFlags flags
Flags, e.g. MUTT_DISPLAY.
Definition: state.h:49
int wraplen
Width to wrap lines to (when flags & MUTT_DISPLAY)
Definition: state.h:50
#define CH_NO_FLAGS
No flags are set.
Definition: copy.h:50
#define CH_DISPLAY
Display result to user.
Definition: copy.h:69
int mutt_window_wrap_cols(int width, short wrap)
Calculate the wrap column for a given screen width.
Definition: mutt_window.c:383
void state_mark_protected_header(struct State *s)
Write a unique marker around protected headers.
Definition: state.c:56
WHERE bool C_CryptProtectedHeadersRead
Config: Display protected headers (Memory Hole) in the pager.
Definition: globals.h:270
char * subject
Email&#39;s subject.
Definition: envelope.h:66
int mutt_write_one_header(FILE *fp, const char *tag, const char *value, const char *pfx, int wraplen, CopyHeaderFlags chflags)
Write one header line to a file.
Definition: sendlib.c:2154
bool C_Weed
Config: Filter headers when displaying/forwarding/printing/replying.
Definition: email_globals.c:40
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ mutt_signed_handler()

int mutt_signed_handler ( struct Body a,
struct State s 
)

Verify a "multipart/signed" body - Implements handler_t.

Definition at line 1120 of file crypt.c.

1121 {
1122  if (!WithCrypto)
1123  return -1;
1124 
1125  bool inconsistent = false;
1126  struct Body *b = a;
1127  struct Body **signatures = NULL;
1128  int sigcnt = 0;
1129  int rc = 0;
1130  struct Buffer *tempfile = NULL;
1131 
1132  a = a->parts;
1133  SecurityFlags signed_type = mutt_is_multipart_signed(b);
1134  if (signed_type == SEC_NO_FLAGS)
1135  {
1136  /* A null protocol value is already checked for in mutt_body_handler() */
1137  state_printf(s,
1138  _("[-- Error: "
1139  "Unknown multipart/signed protocol %s --]\n\n"),
1140  mutt_param_get(&b->parameter, "protocol"));
1141  return mutt_body_handler(a, s);
1142  }
1143 
1144  if (!(a && a->next))
1145  inconsistent = true;
1146  else
1147  {
1148  switch (signed_type)
1149  {
1150  case SEC_SIGN:
1151  if ((a->next->type != TYPE_MULTIPART) ||
1152  (mutt_str_strcasecmp(a->next->subtype, "mixed") != 0))
1153  {
1154  inconsistent = true;
1155  }
1156  break;
1157  case PGP_SIGN:
1158  if ((a->next->type != TYPE_APPLICATION) ||
1159  (mutt_str_strcasecmp(a->next->subtype, "pgp-signature") != 0))
1160  {
1161  inconsistent = true;
1162  }
1163  break;
1164  case SMIME_SIGN:
1165  if ((a->next->type != TYPE_APPLICATION) ||
1166  ((mutt_str_strcasecmp(a->next->subtype, "x-pkcs7-signature") != 0) &&
1167  (mutt_str_strcasecmp(a->next->subtype, "pkcs7-signature") != 0)))
1168  {
1169  inconsistent = true;
1170  }
1171  break;
1172  default:
1173  inconsistent = true;
1174  }
1175  }
1176  if (inconsistent)
1177  {
1178  state_attach_puts(s, _("[-- Error: Missing or bad-format multipart/signed "
1179  "signature --]\n\n"));
1180  return mutt_body_handler(a, s);
1181  }
1182 
1183  if (s->flags & MUTT_DISPLAY)
1184  {
1185  crypt_fetch_signatures(&signatures, a->next, &sigcnt);
1186 
1187  if (sigcnt != 0)
1188  {
1189  tempfile = mutt_buffer_pool_get();
1190  mutt_buffer_mktemp(tempfile);
1191  bool goodsig = true;
1192  if (crypt_write_signed(a, s, mutt_b2s(tempfile)) == 0)
1193  {
1194  for (int i = 0; i < sigcnt; i++)
1195  {
1196  if (((WithCrypto & APPLICATION_PGP) != 0) &&
1197  (signatures[i]->type == TYPE_APPLICATION) &&
1198  (mutt_str_strcasecmp(signatures[i]->subtype, "pgp-signature") == 0))
1199  {
1200  if (crypt_pgp_verify_one(signatures[i], s, mutt_b2s(tempfile)) != 0)
1201  goodsig = false;
1202 
1203  continue;
1204  }
1205 
1206  if (((WithCrypto & APPLICATION_SMIME) != 0) &&
1207  (signatures[i]->type == TYPE_APPLICATION) &&
1208  ((mutt_str_strcasecmp(signatures[i]->subtype,
1209  "x-pkcs7-signature") == 0) ||
1210  (mutt_str_strcasecmp(signatures[i]->subtype,
1211  "pkcs7-signature") == 0)))
1212  {
1213  if (crypt_smime_verify_one(signatures[i], s, mutt_b2s(tempfile)) != 0)
1214  goodsig = false;
1215 
1216  continue;
1217  }
1218 
1219  state_printf(s,
1220  _("[-- Warning: "
1221  "We can't verify %s/%s signatures. --]\n\n"),
1222  TYPE(signatures[i]), signatures[i]->subtype);
1223  }
1224  }
1225 
1226  mutt_file_unlink(mutt_b2s(tempfile));
1227  mutt_buffer_pool_release(&tempfile);
1228 
1229  b->goodsig = goodsig;
1230  b->badsig = !goodsig;
1231 
1232  /* Now display the signed body */
1233  state_attach_puts(s, _("[-- The following data is signed --]\n\n"));
1234 
1236 
1237  FREE(&signatures);
1238  }
1239  else
1241  _("[-- Warning: Can't find any signatures. --]\n\n"));
1242  }
1243 
1244  rc = mutt_body_handler(a, s);
1245 
1246  if ((s->flags & MUTT_DISPLAY) && (sigcnt != 0))
1247  state_attach_puts(s, _("\n[-- End of signed data --]\n"));
1248 
1249  return rc;
1250 }
int mutt_protected_headers_handler(struct Body *a, struct State *s)
Process a protected header - Implements handler_t.
Definition: crypt.c:1094
int state_printf(struct State *s, const char *fmt,...)
Write a formatted string to the State.
Definition: state.c:153
#define mutt_buffer_mktemp(buf)
Definition: muttlib.h:78
#define MUTT_DISPLAY
Output is displayed to the user.
Definition: state.h:32
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
#define SEC_NO_FLAGS
No flags are set.
Definition: ncrypt.h:121
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
void mutt_file_unlink(const char *s)
Delete a file, carefully.
Definition: file.c:194
String manipulation buffer.
Definition: buffer.h:33
#define _(a)
Definition: message.h:28
struct Body * next
next attachment in the list
Definition: body.h:53
#define SMIME_SIGN
Definition: ncrypt.h:147
int crypt_write_signed(struct Body *a, struct State *s, const char *tempfile)
Write the message body/part.
Definition: crypt.c:764
The body of an email.
Definition: body.h:34
StateFlags flags
Flags, e.g. MUTT_DISPLAY.
Definition: state.h:49
bool badsig
Bad cryptographic signature (needed to check encrypted s/mime-signatures)
Definition: body.h:77
SecurityFlags mutt_is_multipart_signed(struct Body *b)
Is a message signed?
Definition: crypt.c:410
#define PGP_SIGN
Definition: ncrypt.h:141
char * subtype
content-type subtype
Definition: body.h:37
#define mutt_b2s(buf)
Definition: buffer.h:41
bool goodsig
Good cryptographic signature.
Definition: body.h:75
#define SEC_SIGN
Email is signed.
Definition: ncrypt.h:123
struct Body * parts
parts of a multipart or message/rfc822
Definition: body.h:54
static void crypt_fetch_signatures(struct Body ***signatures, struct Body *a, int *n)
Create an array of an emails parts.
Definition: crypt.c:1056
unsigned int type
content-type primary type
Definition: body.h:65
#define APPLICATION_PGP
Use PGP to encrypt/sign.
Definition: ncrypt.h:134
void state_attach_puts(struct State *s, const char *t)
Write a string to the state.
Definition: state.c:70
#define TYPE(body)
Definition: mime.h:83
Type: &#39;multipart/*&#39;.
Definition: mime.h:37
int mutt_str_strcasecmp(const char *a, const char *b)
Compare two strings ignoring case, safely.
Definition: string.c:628
#define FREE(x)
Definition: memory.h:40
char * mutt_param_get(const struct ParameterList *pl, const char *s)
Find a matching Parameter.
Definition: parameter.c:84
int crypt_smime_verify_one(struct Body *sigbdy, struct State *s, const char *tempf)
Wrapper for CryptModuleSpecs::verify_one()
Definition: cryptglue.c:513
int mutt_body_handler(struct Body *b, struct State *s)
Handler for the Body of an email.
Definition: handler.c:1551
uint16_t SecurityFlags
Flags, e.g. SEC_ENCRYPT.
Definition: ncrypt.h:120
struct ParameterList parameter
parameters of the content-type
Definition: body.h:39
#define WithCrypto
Definition: ncrypt.h:160
Type: &#39;application/*&#39;.
Definition: mime.h:33
#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:367
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ 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.

Parameters
[in]pString to examine
[out]pphintStart of string to be passed to pgp_add_string_to_hints() or crypt_add_string_to_hints()
[out]pplStart of long key ID if detected, else NULL
[out]ppsStart of short key ID if detected, else NULL
Return values
ptrCopy of fingerprint, if any, stripped of all spaces. Must be FREE'd by caller
NULLOtherwise

Obtain pointers to fingerprint or short or long key ID, if any.

Upon return, at most one of return, *ppl and *pps pointers is non-NULL, indicating the longest fingerprint or ID found, if any.

Definition at line 1266 of file crypt.c.

1268 {
1269  const char *ps = NULL, *pl = NULL, *phint = NULL;
1270  char *pfcopy = NULL, *s1 = NULL, *s2 = NULL;
1271  char c;
1272  int isid;
1273  size_t hexdigits;
1274 
1275  /* User input may be partial name, fingerprint or short or long key ID,
1276  * independent of C_PgpLongIds.
1277  * Fingerprint without spaces is 40 hex digits (SHA-1) or 32 hex digits (MD5).
1278  * Strip leading "0x" for key ID detection and prepare pl and ps to indicate
1279  * if an ID was found and to simplify logic in the key loop's inner
1280  * condition of the caller. */
1281 
1282  char *pf = mutt_str_skip_whitespace(p);
1283  if (mutt_str_startswith(pf, "0x", CASE_IGNORE))
1284  pf += 2;
1285 
1286  /* Check if a fingerprint is given, must be hex digits only, blanks
1287  * separating groups of 4 hex digits are allowed. Also pre-check for ID. */
1288  isid = 2; /* unknown */
1289  hexdigits = 0;
1290  s1 = pf;
1291  do
1292  {
1293  c = *(s1++);
1294  if ((('0' <= c) && (c <= '9')) || (('A' <= c) && (c <= 'F')) ||
1295  (('a' <= c) && (c <= 'f')))
1296  {
1297  hexdigits++;
1298  if (isid == 2)
1299  isid = 1; /* it is an ID so far */
1300  }
1301  else if (c)
1302  {
1303  isid = 0; /* not an ID */
1304  if ((c == ' ') && ((hexdigits % 4) == 0))
1305  ; /* skip blank before or after 4 hex digits */
1306  else
1307  break; /* any other character or position */
1308  }
1309  } while (c);
1310 
1311  /* If at end of input, check for correct fingerprint length and copy if. */
1312  pfcopy = (!c && ((hexdigits == 40) || (hexdigits == 32)) ? mutt_str_strdup(pf) : NULL);
1313 
1314  if (pfcopy)
1315  {
1316  /* Use pfcopy to strip all spaces from fingerprint and as hint. */
1317  s1 = pfcopy;
1318  s2 = pfcopy;
1319  do
1320  {
1321  *(s1++) = *(s2 = mutt_str_skip_whitespace(s2));
1322  } while (*(s2++));
1323 
1324  phint = pfcopy;
1325  ps = NULL;
1326  pl = NULL;
1327  }
1328  else
1329  {
1330  phint = p;
1331  ps = NULL;
1332  pl = NULL;
1333  if (isid == 1)
1334  {
1335  if (mutt_str_strlen(pf) == 16)
1336  pl = pf; /* long key ID */
1337  else if (mutt_str_strlen(pf) == 8)
1338  ps = pf; /* short key ID */
1339  }
1340  }
1341 
1342  *pphint = phint;
1343  *ppl = pl;
1344  *pps = ps;
1345  return pfcopy;
1346 }
char * mutt_str_skip_whitespace(const char *p)
Find the first non-whitespace character in a string.
Definition: string.c:720
size_t mutt_str_strlen(const char *a)
Calculate the length of a string, safely.
Definition: string.c:666
Ignore case when comparing strings.
Definition: string2.h:68
size_t mutt_str_startswith(const char *str, const char *prefix, enum CaseSensitivity cs)
Check whether a string starts with a prefix.
Definition: string.c:168
char * mutt_str_strdup(const char *str)
Copy a string, safely.
Definition: string.c:380
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ crypt_is_numerical_keyid()

bool crypt_is_numerical_keyid ( const char *  s)

Is this a numerical keyid.

Parameters
sKey to test
Return values
trueIf keyid is numeric

Check if a crypt-hook value is a key id.

Definition at line 1355 of file crypt.c.

1356 {
1357  /* or should we require the "0x"? */
1358  if (strncmp(s, "0x", 2) == 0)
1359  s += 2;
1360  if (strlen(s) % 8)
1361  return false;
1362  while (*s)
1363  if (!strchr("0123456789ABCDEFabcdef", *s++))
1364  return false;
1365 
1366  return true;
1367 }
+ Here is the caller graph for this function:

Variable Documentation

◆ C_CryptTimestamp

bool C_CryptTimestamp

Config: Add a timestamp to PGP or SMIME output to prevent spoofing.

Definition at line 63 of file crypt.c.

◆ C_PgpEncryptSelf

unsigned char C_PgpEncryptSelf

Deprecated, see C_PgpSelfEncrypt.

Definition at line 67 of file crypt.c.

◆ C_PgpMimeAuto

unsigned char C_PgpMimeAuto

Config: Prompt the user to use MIME if inline PGP fails.

Definition at line 68 of file crypt.c.

◆ C_PgpRetainableSigs

bool C_PgpRetainableSigs

Config: Create nested multipart/signed or encrypted messages.

Definition at line 69 of file crypt.c.

◆ C_PgpSelfEncrypt

bool C_PgpSelfEncrypt

Config: Encrypted messages will also be encrypted to C_PgpDefaultKey too.

Definition at line 70 of file crypt.c.

◆ C_PgpStrictEnc

bool C_PgpStrictEnc

Config: Encode PGP signed messages with quoted-printable (don't unset)

Definition at line 71 of file crypt.c.

◆ C_SmimeEncryptSelf

unsigned char C_SmimeEncryptSelf

Deprecated, see C_SmimeSelfEncrypt.

Definition at line 72 of file crypt.c.

◆ C_SmimeSelfEncrypt

bool C_SmimeSelfEncrypt

Config: Encrypted messages will also be encrypt to C_SmimeDefaultKey too.

Definition at line 73 of file crypt.c.