NeoMutt  2025-12-11-872-g385a04
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
pgpkey.c
Go to the documentation of this file.
1
26
32
33#include "config.h"
34#include <stdbool.h>
35#include <stdint.h>
36#include <stdio.h>
37#include <string.h>
38#include <sys/stat.h>
39#include <sys/types.h>
40#include <unistd.h>
41#include "private.h"
42#include "mutt/lib.h"
43#include "address/lib.h"
44#include "config/lib.h"
45#include "email/lib.h"
46#include "core/lib.h"
47#include "pgpkey.h"
48#include "lib.h"
49#include "editor/lib.h"
50#include "history/lib.h"
51#include "send/lib.h"
52#include "crypt.h"
53#include "globals.h"
54#include "gnupgparse.h"
55#include "module_data.h"
56#include "mutt_logging.h"
57#include "pgpinvoke.h"
58#ifdef CRYPT_BACKEND_CLASSIC_PGP
59#include "pgp.h"
60#include "pgplib.h"
61#endif
62
67{
68 char *what;
69 char *dflt;
70 struct PgpCache *next;
71};
72
77{
78 // clang-format off
80 PGP_KV_VALID = 1U << 0,
81 PGP_KV_ADDR = 1U << 1,
82 PGP_KV_STRING = 1U << 2,
83 PGP_KV_STRONGID = 1U << 3,
84 // clang-format on
85};
86typedef uint8_t PgpKeyValidFlags;
87
88#define PGP_KV_MATCH (PGP_KV_ADDR | PGP_KV_STRING)
89
96{
97 if (key->flags & KEYFLAG_SUBKEY && key->parent)
98 return key->parent;
99 return key;
100}
101
108{
109 struct PgpKeyInfo *pk = pgp_principal_key(k);
110 if (k->flags & KEYFLAG_CANTUSE)
111 return false;
112 if (pk->flags & KEYFLAG_CANTUSE)
113 return false;
114
115 return true;
116}
117
124{
125 for (struct PgpKeyInfo *k = keys; k != NULL; k = k->next)
126 {
127 if (!pgp_key_is_valid(k))
128 return false;
129 }
130
131 return true;
132}
133
139bool pgp_id_is_strong(struct PgpUid *uid)
140{
141 if ((uid->trust & 3) < 3)
142 return false;
143 /* else */
144 return true;
145}
146
152bool pgp_id_is_valid(struct PgpUid *uid)
153{
154 if (!pgp_key_is_valid(uid->parent))
155 return false;
156 if (uid->flags & KEYFLAG_CANTUSE)
157 return false;
158 /* else */
159 return true;
160}
161
170 struct Address *u_addr, struct PgpUid *uid)
171{
173
174 if (pgp_id_is_valid(uid))
176
177 if (pgp_id_is_strong(uid))
179
180 if (addr->mailbox && u_addr->mailbox && buf_istr_equal(addr->mailbox, u_addr->mailbox))
181 {
183 }
184
185 if (addr->personal && u_addr->personal &&
186 buf_istr_equal(addr->personal, u_addr->personal))
187 {
189 }
190
191 return flags;
192}
193
202struct PgpKeyInfo *pgp_ask_for_key(char *tag, const char *whatfor,
203 KeyFlags abilities, enum PgpRing keyring)
204{
206 struct PgpKeyInfo *key = NULL;
207 struct PgpCache *l = NULL;
208 struct Buffer *resp = buf_pool_get();
209
211
212 if (whatfor)
213 {
214 for (l = (struct PgpCache *) mod_data->pgp_id_defaults; l; l = l->next)
215 {
216 if (mutt_istr_equal(whatfor, l->what))
217 {
218 buf_strcpy(resp, l->dflt);
219 break;
220 }
221 }
222 }
223
224 while (true)
225 {
226 buf_reset(resp);
227 if (mw_get_field(tag, resp, MUTT_COMP_NONE, HC_OTHER, NULL, NULL) != 0)
228 {
229 goto done;
230 }
231
232 if (whatfor)
233 {
234 if (l)
235 {
236 mutt_str_replace(&l->dflt, buf_string(resp));
237 }
238 else
239 {
240 l = MUTT_MEM_MALLOC(1, struct PgpCache);
241 l->next = (struct PgpCache *) mod_data->pgp_id_defaults;
242 mod_data->pgp_id_defaults = l;
243 l->what = mutt_str_dup(whatfor);
244 l->dflt = buf_strdup(resp);
245 }
246 }
247
248 key = pgp_getkeybystr(buf_string(resp), abilities, keyring);
249 if (key)
250 goto done;
251
252 mutt_error(_("No matching keys found for \"%s\""), buf_string(resp));
253 }
254
255done:
256 buf_pool_release(&resp);
257 return key;
258}
259
264{
265 struct Body *att = NULL;
266 char buf[1024] = { 0 };
267 char tmp[256] = { 0 };
268 struct stat st = { 0 };
269 pid_t pid;
270 OptPgpCheckTrust = false;
271
272 struct PgpKeyInfo *key = pgp_ask_for_key(_("Please enter the key ID: "), NULL,
274
275 if (!key)
276 return NULL;
277
278 snprintf(tmp, sizeof(tmp), "0x%s", pgp_fpr_or_lkeyid(pgp_principal_key(key)));
279 pgp_key_free(&key);
280
281 struct Buffer *tempfile = buf_pool_get();
282 buf_mktemp(tempfile);
283 FILE *fp_tmp = mutt_file_fopen(buf_string(tempfile), "w");
284 if (!fp_tmp)
285 {
286 mutt_perror(_("Can't create temporary file"));
287 goto cleanup;
288 }
289
290 FILE *fp_null = mutt_file_fopen("/dev/null", "w");
291 if (!fp_null)
292 {
293 mutt_perror(_("Can't open /dev/null"));
294 mutt_file_fclose(&fp_tmp);
295 unlink(buf_string(tempfile));
296 goto cleanup;
297 }
298
299 mutt_message(_("Invoking PGP..."));
300
301 pid = pgp_invoke_export(NULL, NULL, NULL, -1, fileno(fp_tmp), fileno(fp_null), tmp);
302 if (pid == -1)
303 {
304 mutt_perror(_("Can't create filter"));
305 unlink(buf_string(tempfile));
306 mutt_file_fclose(&fp_tmp);
307 mutt_file_fclose(&fp_null);
308 goto cleanup;
309 }
310
311 filter_wait(pid);
312
313 mutt_file_fclose(&fp_tmp);
314 mutt_file_fclose(&fp_null);
315
316 att = mutt_body_new();
317 att->filename = buf_strdup(tempfile);
318 att->unlink = true;
319 att->use_disp = false;
320 att->type = TYPE_APPLICATION;
321 att->subtype = mutt_str_dup("pgp-keys");
322 snprintf(buf, sizeof(buf), _("PGP Key %s"), tmp);
323 att->description = mutt_str_dup(buf);
325
326 stat(buf_string(tempfile), &st);
327 att->length = st.st_size;
328
329cleanup:
330 buf_pool_release(&tempfile);
331 return att;
332}
333
342static void pgp_add_string_to_hints(const char *str, struct ListHead *hints)
343{
344 char *scratch = mutt_str_dup(str);
345 if (!scratch)
346 return;
347
348 for (char *t = strtok(scratch, " ,.:\"()<>\n"); t; t = strtok(NULL, " ,.:\"()<>\n"))
349 {
350 if (strlen(t) > 3)
352 }
353
354 FREE(&scratch);
355}
356
362static struct PgpKeyInfo **pgp_get_lastp(struct PgpKeyInfo *p)
363{
364 for (; p; p = p->next)
365 if (!p->next)
366 return &p->next;
367
368 return NULL;
369}
370
379struct PgpKeyInfo *pgp_getkeybyaddr(struct Address *a, KeyFlags abilities,
380 enum PgpRing keyring, bool oppenc_mode)
381{
382 if (!a)
383 return NULL;
384
385 struct ListHead hints = STAILQ_HEAD_INITIALIZER(hints);
386
387 bool multi = false;
388
389 struct PgpKeyInfo *keys = NULL, *k = NULL, *kn = NULL;
390 struct PgpKeyInfo *the_strong_valid_key = NULL;
391 struct PgpKeyInfo *a_valid_addrmatch_key = NULL;
392 struct PgpKeyInfo *matches = NULL;
393 struct PgpKeyInfo **last = &matches;
394 struct PgpUid *q = NULL;
395
396 if (a->mailbox)
398 if (a->personal)
400
401 if (!oppenc_mode)
402 mutt_message(_("Looking for keys matching \"%s\"..."), buf_string(a->mailbox));
403 keys = pgp_get_candidates(keyring, &hints);
404
405 mutt_list_free(&hints);
406
407 if (!keys)
408 return NULL;
409
410 mutt_debug(LL_DEBUG5, "looking for %s <%s>\n", buf_string(a->personal),
411 buf_string(a->mailbox));
412
413 for (k = keys; k; k = kn)
414 {
415 kn = k->next;
416
417 mutt_debug(LL_DEBUG5, " looking at key: %s\n", pgp_keyid(k));
418
419 if (abilities && !(k->flags & abilities))
420 {
421 mutt_debug(LL_DEBUG3, " insufficient abilities: Has %x, want %x\n", k->flags, abilities);
422 continue;
423 }
424
425 bool match = false; /* any match */
426
427 for (q = k->address; q; q = q->next)
428 {
429 struct AddressList al = TAILQ_HEAD_INITIALIZER(al);
431 struct Address *qa = NULL;
432 TAILQ_FOREACH(qa, &al, entries)
433 {
434 PgpKeyValidFlags validity = pgp_id_matches_addr(a, qa, q);
435
436 if (validity & PGP_KV_MATCH) /* something matches */
437 match = true;
438
439 if ((validity & PGP_KV_VALID) && (validity & PGP_KV_ADDR))
440 {
441 if (validity & PGP_KV_STRONGID)
442 {
443 if (the_strong_valid_key && (the_strong_valid_key != k))
444 multi = true;
445 the_strong_valid_key = k;
446 }
447 else
448 {
449 a_valid_addrmatch_key = k;
450 }
451 }
452 }
453
455 }
456
457 if (match)
458 {
459 *last = pgp_principal_key(k);
460 kn = pgp_remove_key(&keys, *last);
461 last = pgp_get_lastp(k);
462 }
463 }
464
465 pgp_key_free(&keys);
466
467 if (matches)
468 {
469 if (oppenc_mode || !isatty(STDIN_FILENO))
470 {
471 const bool c_crypt_opportunistic_encrypt_strong_keys =
472 cs_subset_bool(NeoMutt->sub, "crypt_opportunistic_encrypt_strong_keys");
473 if (the_strong_valid_key)
474 {
475 pgp_remove_key(&matches, the_strong_valid_key);
476 k = the_strong_valid_key;
477 }
478 else if (a_valid_addrmatch_key && !c_crypt_opportunistic_encrypt_strong_keys)
479 {
480 pgp_remove_key(&matches, a_valid_addrmatch_key);
481 k = a_valid_addrmatch_key;
482 }
483 else
484 {
485 k = NULL;
486 }
487 }
488 else if (the_strong_valid_key && !multi)
489 {
490 /* There was precisely one strong match on a valid ID.
491 * Proceed without asking the user. */
492 pgp_remove_key(&matches, the_strong_valid_key);
493 k = the_strong_valid_key;
494 }
495 else
496 {
497 /* Else: Ask the user. */
498 k = dlg_pgp(matches, a, NULL);
499 if (k)
500 pgp_remove_key(&matches, k);
501 }
502
503 pgp_key_free(&matches);
504
505 return k;
506 }
507
508 return NULL;
509}
510
518struct PgpKeyInfo *pgp_getkeybystr(const char *cp, KeyFlags abilities, enum PgpRing keyring)
519{
520 struct ListHead hints = STAILQ_HEAD_INITIALIZER(hints);
521 struct PgpKeyInfo *keys = NULL;
522 struct PgpKeyInfo *matches = NULL;
523 struct PgpKeyInfo **last = &matches;
524 struct PgpKeyInfo *k = NULL, *kn = NULL;
525 struct PgpUid *a = NULL;
526 size_t l;
527 const char *ps = NULL, *pl = NULL, *pfcopy = NULL, *phint = NULL;
528
529 char *p = strdup(cp); // mutt_str_dup converts "" into NULL, see #1809
530 l = mutt_str_len(p);
531 if ((l > 0) && (p[l - 1] == '!'))
532 p[l - 1] = 0;
533
534 mutt_message(_("Looking for keys matching \"%s\"..."), p);
535
536 pfcopy = crypt_get_fingerprint_or_id(p, &phint, &pl, &ps);
537 pgp_add_string_to_hints(phint, &hints);
538 keys = pgp_get_candidates(keyring, &hints);
539 mutt_list_free(&hints);
540
541 for (k = keys; k; k = kn)
542 {
543 kn = k->next;
544 if (abilities && !(k->flags & abilities))
545 continue;
546
547 /* This shouldn't happen, but keys without any addresses aren't selectable
548 * in dlg_pgp(). */
549 if (!k->address)
550 continue;
551
552 bool match = false;
553
554 mutt_debug(LL_DEBUG5, "matching \"%s\" against key %s:\n", p, pgp_long_keyid(k));
555
556 if ((*p == '\0') || (pfcopy && mutt_istr_equal(pfcopy, k->fingerprint)) ||
557 (pl && mutt_istr_equal(pl, pgp_long_keyid(k))) ||
558 (ps && mutt_istr_equal(ps, pgp_short_keyid(k))))
559 {
560 mutt_debug(LL_DEBUG5, " match #1\n");
561 match = true;
562 }
563 else
564 {
565 for (a = k->address; a; a = a->next)
566 {
567 mutt_debug(LL_DEBUG5, "matching \"%s\" against key %s, \"%s\":\n", p,
568 pgp_long_keyid(k), NONULL(a->addr));
569 if (mutt_istr_find(a->addr, p))
570 {
571 mutt_debug(LL_DEBUG5, " match #2\n");
572 match = true;
573 break;
574 }
575 }
576 }
577
578 if (match)
579 {
580 *last = pgp_principal_key(k);
581 kn = pgp_remove_key(&keys, *last);
582 last = pgp_get_lastp(k);
583 }
584 }
585
586 pgp_key_free(&keys);
587
588 k = NULL;
589 if (matches)
590 {
591 if (isatty(STDIN_FILENO))
592 {
593 k = dlg_pgp(matches, NULL, p);
594 if (k)
595 pgp_remove_key(&matches, k);
596 pgp_key_free(&matches);
597 }
598 else if (pgp_keys_are_valid(matches))
599 {
600 k = matches;
601 }
602 else
603 {
604 mutt_error(_("A key can't be used: expired/disabled/revoked"));
605 }
606 }
607
608 FREE(&pfcopy);
609 FREE(&p);
610 return k;
611}
612
617void pgp_id_defaults_cleanup(struct PgpCache **pgp_id_defaults)
618{
619 struct PgpCache *l = *pgp_id_defaults;
620 while (l)
621 {
622 struct PgpCache *next = l->next;
623 FREE(&l->what);
624 FREE(&l->dflt);
625 FREE(&l);
626 l = next;
627 }
628 *pgp_id_defaults = NULL;
629}
void mutt_addrlist_clear(struct AddressList *al)
Unlink and free all Address in an AddressList.
Definition address.c:1469
int mutt_addrlist_parse(struct AddressList *al, const char *s)
Parse a list of email addresses.
Definition address.c:480
Email Address Handling.
bool buf_istr_equal(const struct Buffer *a, const struct Buffer *b)
Return if two buffers are equal, case insensitive.
Definition buffer.c:695
void buf_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition buffer.c:76
size_t buf_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition buffer.c:395
char * buf_strdup(const struct Buffer *buf)
Copy a Buffer's string.
Definition buffer.c:571
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition buffer.h:96
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition helpers.c:47
Convenience wrapper for the config headers.
Convenience wrapper for the core headers.
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:1395
Signing/encryption multiplexor.
Edit a string.
@ MUTT_COMP_NONE
No flags are set.
Definition wdata.h:46
struct Body * mutt_body_new(void)
Create a new Body.
Definition body.c:44
Structs that make up an email.
#define mutt_file_fclose(FP)
Definition file.h:144
#define mutt_file_fopen(PATH, MODE)
Definition file.h:143
bool OptPgpCheckTrust
(pseudo) used by dlg_pgp()
Definition globals.c:55
Global variables.
struct PgpKeyInfo * pgp_get_candidates(enum PgpRing keyring, struct ListHead *hints)
Find PGP keys matching a list of hints.
Definition gnupgparse.c:417
Parse the output of CLI PGP programinclude "pgpkey.h".
struct Body * pgp_class_make_key_attachment(void)
Generate a public key attachment - Implements CryptModuleSpecs::pgp_make_key_attachment() -.
Definition pgpkey.c:263
struct PgpKeyInfo * dlg_pgp(struct PgpKeyInfo *keys, struct Address *p, const char *s)
Let the user select a key to use -.
Definition dlg_pgp.c:192
int mw_get_field(const char *prompt, struct Buffer *buf, CompletionFlags complete, enum HistoryClass hclass, const struct CompleteOps *comp_api, void *cdata)
Ask the user for a string -.
Definition window.c:467
#define mutt_error(...)
Definition logging2.h:94
#define mutt_message(...)
Definition logging2.h:93
#define mutt_debug(LEVEL,...)
Definition logging2.h:91
#define mutt_perror(...)
Definition logging2.h:95
Read/write command history from/to a file.
@ HC_OTHER
Miscellaneous strings.
Definition lib.h:61
struct ListNode * mutt_list_insert_tail(struct ListHead *h, char *s)
Append a string to the end of a List.
Definition list.c:65
void mutt_list_free(struct ListHead *h)
Free a List AND its strings.
Definition list.c:123
@ LL_DEBUG3
Log at debug level 3.
Definition logging2.h:47
@ LL_DEBUG5
Log at debug level 5.
Definition logging2.h:49
#define FREE(x)
Free memory and set the pointer to NULL.
Definition memory.h:68
#define MUTT_MEM_MALLOC(n, type)
Definition memory.h:53
@ TYPE_APPLICATION
Type: 'application/*'.
Definition mime.h:33
@ MODULE_ID_NCRYPT
ModuleNcrypt, Ncrypt
Definition module_api.h:80
int filter_wait(pid_t pid)
Wait for the exit of a process and return its status.
Definition filter.c:228
Convenience wrapper for the library headers.
#define _(a)
Definition message.h:28
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition string.c:677
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition string.c:257
const char * mutt_istr_find(const char *haystack, const char *needle)
Find first occurrence of string (ignoring case)
Definition string.c:528
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition string.c:503
char * mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition string.c:284
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
NeoMutt Logging.
API for encryption/signing of emails.
uint16_t KeyFlags
Definition lib.h:159
#define KEYFLAG_CANTUSE
Definition lib.h:161
@ KEYFLAG_NONE
No flags are set.
Definition lib.h:146
@ KEYFLAG_SUBKEY
Key is a subkey.
Definition lib.h:154
Ncrypt private Module data.
Shared constants/structs that are private to libconn.
void * neomutt_get_module_data(struct NeoMutt *n, enum ModuleId id)
Get the private data for a Module.
Definition neomutt.c:663
char * pgp_long_keyid(struct PgpKeyInfo *k)
Get a key's long id.
Definition pgp.c:162
char * pgp_keyid(struct PgpKeyInfo *k)
Get the ID of the main (parent) key.
Definition pgp.c:201
char * pgp_fpr_or_lkeyid(struct PgpKeyInfo *k)
Get the fingerprint or long keyid.
Definition pgp.c:231
char * pgp_short_keyid(struct PgpKeyInfo *k)
Get a key's short id.
Definition pgp.c:174
PGP sign, encrypt, check routines.
pid_t pgp_invoke_export(FILE **fp_pgp_in, FILE **fp_pgp_out, FILE **fp_pgp_err, int fd_pgp_in, int fd_pgp_out, int fd_pgp_err, const char *uids)
Use PGP to export a key from the user's keyring.
Definition pgpinvoke.c:374
Wrapper around calls to external PGP program.
void pgp_id_defaults_cleanup(struct PgpCache **pgp_id_defaults)
Free the PGP IdDefaults cache.
Definition pgpkey.c:617
bool pgp_id_is_valid(struct PgpUid *uid)
Is a PGP key valid.
Definition pgpkey.c:152
static void pgp_add_string_to_hints(const char *str, struct ListHead *hints)
Split a string and add the parts to a List.
Definition pgpkey.c:342
#define PGP_KV_MATCH
Definition pgpkey.c:88
static PgpKeyValidFlags pgp_id_matches_addr(struct Address *addr, struct Address *u_addr, struct PgpUid *uid)
Does the key ID match the address.
Definition pgpkey.c:169
struct PgpKeyInfo * pgp_ask_for_key(char *tag, const char *whatfor, KeyFlags abilities, enum PgpRing keyring)
Ask the user for a PGP key.
Definition pgpkey.c:202
bool pgp_keys_are_valid(struct PgpKeyInfo *keys)
Are all these PGP keys valid?
Definition pgpkey.c:123
static struct PgpKeyInfo ** pgp_get_lastp(struct PgpKeyInfo *p)
Get the last PGP key in a list.
Definition pgpkey.c:362
PgpKeyValidFlag
Flags for valid Pgp Key fields.
Definition pgpkey.c:77
@ PGP_KV_NONE
No flags are set.
Definition pgpkey.c:79
@ PGP_KV_STRING
PGP Key name string is valid.
Definition pgpkey.c:82
@ PGP_KV_ADDR
PGP Key address is valid.
Definition pgpkey.c:81
@ PGP_KV_VALID
PGP Key ID is valid.
Definition pgpkey.c:80
@ PGP_KV_STRONGID
PGP Key is strong.
Definition pgpkey.c:83
bool pgp_id_is_strong(struct PgpUid *uid)
Is a PGP key strong?
Definition pgpkey.c:139
struct PgpKeyInfo * pgp_getkeybyaddr(struct Address *a, KeyFlags abilities, enum PgpRing keyring, bool oppenc_mode)
Find a PGP key by address.
Definition pgpkey.c:379
bool pgp_key_is_valid(struct PgpKeyInfo *k)
Is a PGP key valid?
Definition pgpkey.c:107
struct PgpKeyInfo * pgp_getkeybystr(const char *cp, KeyFlags abilities, enum PgpRing keyring)
Find a PGP key by string.
Definition pgpkey.c:518
uint8_t PgpKeyValidFlags
Definition pgpkey.c:86
struct PgpKeyInfo * pgp_principal_key(struct PgpKeyInfo *key)
Get the main (parent) PGP key.
Definition pgpkey.c:95
PGP key management routines.
PgpRing
PGP ring type.
Definition pgpkey.h:39
@ PGP_PUBRING
Public keys.
Definition pgpkey.h:40
void pgp_key_free(struct PgpKeyInfo **kpp)
Free a PGP key info.
Definition pgplib.c:201
struct PgpKeyInfo * pgp_remove_key(struct PgpKeyInfo **klist, struct PgpKeyInfo *key)
Remove a PGP key from a list.
Definition pgplib.c:169
Misc PGP helper routines.
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition pool.c:91
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition pool.c:111
#define TAILQ_FOREACH(var, head, field)
Definition queue.h:782
#define STAILQ_HEAD_INITIALIZER(head)
Definition queue.h:324
#define TAILQ_HEAD_INITIALIZER(head)
Definition queue.h:694
Convenience wrapper for the send headers.
void mutt_update_encoding(struct Body *b, struct ConfigSubset *sub)
Update the encoding type.
Definition sendlib.c:421
#define NONULL(x)
Definition string2.h:44
An email address.
Definition address.h:35
struct Buffer * personal
Real name of address.
Definition address.h:36
struct Buffer * mailbox
Mailbox and host address.
Definition address.h:37
The body of an email.
Definition body.h:36
bool unlink
If true, filename should be unlink()ed before free()ing this structure.
Definition body.h:68
LOFF_T length
length (in bytes) of attachment
Definition body.h:53
bool use_disp
Content-Disposition uses filename= ?
Definition body.h:47
char * description
content-description
Definition body.h:55
char * subtype
content-type subtype
Definition body.h:61
unsigned int type
content-type primary type, ContentType
Definition body.h:40
char * filename
When sending a message, this is the file to which this structure refers.
Definition body.h:59
String manipulation buffer.
Definition buffer.h:36
Ncrypt private Module data.
Definition module_data.h:38
struct PgpCache * pgp_id_defaults
PGP IdDefaults cache.
Definition module_data.h:52
Container for Accounts, Notifications.
Definition neomutt.h:41
struct ConfigSubset * sub
Inherited config items.
Definition neomutt.h:49
List of cached PGP keys.
Definition pgpkey.c:67
char * dflt
Default key ID.
Definition pgpkey.c:69
struct PgpCache * next
Linked list.
Definition pgpkey.c:70
char * what
Cached key identifier.
Definition pgpkey.c:68
Information about a PGP key.
Definition pgplib.h:49
KeyFlags flags
Key flags.
Definition pgplib.h:53
struct PgpKeyInfo * next
Linked list.
Definition pgplib.h:59
struct PgpUid * address
User IDs.
Definition pgplib.h:52
char * fingerprint
Key fingerprint.
Definition pgplib.h:51
struct PgpKeyInfo * parent
Parent key.
Definition pgplib.h:58
PGP User ID.
Definition pgplib.h:36
short trust
Trust level.
Definition pgplib.h:38
struct PgpKeyInfo * parent
Parent key.
Definition pgplib.h:40
int flags
Flags for this UID.
Definition pgplib.h:39
char * addr
Email address.
Definition pgplib.h:37
struct PgpUid * next
Linked list.
Definition pgplib.h:41
#define buf_mktemp(buf)
Definition tmp.h:33