NeoMutt  2020-08-07-1-gab41a1
Teaching an old dog new tricks
DOXYGEN
pgpkey.c
Go to the documentation of this file.
1 
31 #include "config.h"
32 #include <ctype.h>
33 #include <locale.h>
34 #include <stdbool.h>
35 #include <stdint.h>
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <sys/stat.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 "gui/lib.h"
48 #include "mutt.h"
49 #include "pgpkey.h"
50 #include "lib.h"
51 #include "send/lib.h"
52 #include "crypt.h"
53 #include "format_flags.h"
54 #include "gnupgparse.h"
55 #include "keymap.h"
56 #include "mutt_globals.h"
57 #include "mutt_logging.h"
58 #include "mutt_menu.h"
59 #include "muttlib.h"
60 #include "opcodes.h"
61 #include "options.h"
62 #include "pager.h"
63 #include "pgpinvoke.h"
64 #include "protos.h"
65 #ifdef CRYPT_BACKEND_CLASSIC_PGP
66 #include "pgp.h"
67 #include "pgplib.h"
68 #endif
69 
73 struct PgpCache
74 {
75  char *what;
76  char *dflt;
77  struct PgpCache *next;
78 };
79 
80 static struct PgpCache *id_defaults = NULL;
81 
82 // clang-format off
83 typedef uint8_t PgpKeyValidFlags;
84 #define PGP_KV_NO_FLAGS 0
85 #define PGP_KV_VALID (1 << 0)
86 #define PGP_KV_ADDR (1 << 1)
87 #define PGP_KV_STRING (1 << 2)
88 #define PGP_KV_STRONGID (1 << 3)
89 // clang-format on
90 
91 #define PGP_KV_MATCH (PGP_KV_ADDR | PGP_KV_STRING)
92 
99 {
100  if (key->flags & KEYFLAG_SUBKEY && key->parent)
101  return key->parent;
102  return key;
103 }
104 
111 {
112  struct PgpKeyInfo *pk = pgp_principal_key(k);
113  if (k->flags & KEYFLAG_CANTUSE)
114  return false;
115  if (pk->flags & KEYFLAG_CANTUSE)
116  return false;
117 
118  return true;
119 }
120 
126 bool pgp_id_is_strong(struct PgpUid *uid)
127 {
128  if ((uid->trust & 3) < 3)
129  return false;
130  /* else */
131  return true;
132 }
133 
139 bool pgp_id_is_valid(struct PgpUid *uid)
140 {
141  if (!pgp_key_is_valid(uid->parent))
142  return false;
143  if (uid->flags & KEYFLAG_CANTUSE)
144  return false;
145  /* else */
146  return true;
147 }
148 
157  struct Address *u_addr, struct PgpUid *uid)
158 {
160 
161  if (pgp_id_is_valid(uid))
162  flags |= PGP_KV_VALID;
163 
164  if (pgp_id_is_strong(uid))
165  flags |= PGP_KV_STRONGID;
166 
167  if (addr->mailbox && u_addr->mailbox && mutt_istr_equal(addr->mailbox, u_addr->mailbox))
168  {
169  flags |= PGP_KV_ADDR;
170  }
171 
172  if (addr->personal && u_addr->personal &&
173  mutt_istr_equal(addr->personal, u_addr->personal))
174  {
175  flags |= PGP_KV_STRING;
176  }
177 
178  return flags;
179 }
180 
189 struct PgpKeyInfo *pgp_ask_for_key(char *tag, char *whatfor, KeyFlags abilities,
190  enum PgpRing keyring)
191 {
192  struct PgpKeyInfo *key = NULL;
193  char resp[128];
194  struct PgpCache *l = NULL;
195 
197 
198  resp[0] = '\0';
199  if (whatfor)
200  {
201  for (l = id_defaults; l; l = l->next)
202  {
203  if (mutt_istr_equal(whatfor, l->what))
204  {
205  mutt_str_copy(resp, l->dflt, sizeof(resp));
206  break;
207  }
208  }
209  }
210 
211  while (true)
212  {
213  resp[0] = '\0';
214  if (mutt_get_field(tag, resp, sizeof(resp), MUTT_COMP_NO_FLAGS) != 0)
215  return NULL;
216 
217  if (whatfor)
218  {
219  if (l)
220  mutt_str_replace(&l->dflt, resp);
221  else
222  {
223  l = mutt_mem_malloc(sizeof(struct PgpCache));
224  l->next = id_defaults;
225  id_defaults = l;
226  l->what = mutt_str_dup(whatfor);
227  l->dflt = mutt_str_dup(resp);
228  }
229  }
230 
231  key = pgp_getkeybystr(resp, abilities, keyring);
232  if (key)
233  return key;
234 
235  mutt_error(_("No matching keys found for \"%s\""), resp);
236  }
237  /* not reached */
238 }
239 
244 {
245  struct Body *att = NULL;
246  char buf[1024];
247  char tmp[256];
248  struct stat sb;
249  pid_t pid;
250  OptPgpCheckTrust = false;
251  struct Buffer *tempf = NULL;
252 
253  struct PgpKeyInfo *key = pgp_ask_for_key(_("Please enter the key ID: "), NULL,
255 
256  if (!key)
257  return NULL;
258 
259  snprintf(tmp, sizeof(tmp), "0x%s", pgp_fpr_or_lkeyid(pgp_principal_key(key)));
260  pgp_key_free(&key);
261 
262  tempf = mutt_buffer_pool_get();
263  mutt_buffer_mktemp(tempf);
264  FILE *fp_tmp = mutt_file_fopen(mutt_b2s(tempf), "w");
265  if (!fp_tmp)
266  {
267  mutt_perror(_("Can't create temporary file"));
268  goto cleanup;
269  }
270 
271  FILE *fp_null = fopen("/dev/null", "w");
272  if (!fp_null)
273  {
274  mutt_perror(_("Can't open /dev/null"));
275  mutt_file_fclose(&fp_tmp);
276  unlink(mutt_b2s(tempf));
277  goto cleanup;
278  }
279 
280  mutt_message(_("Invoking PGP..."));
281 
282  pid = pgp_invoke_export(NULL, NULL, NULL, -1, fileno(fp_tmp), fileno(fp_null), tmp);
283  if (pid == -1)
284  {
285  mutt_perror(_("Can't create filter"));
286  unlink(mutt_b2s(tempf));
287  mutt_file_fclose(&fp_tmp);
288  mutt_file_fclose(&fp_null);
289  goto cleanup;
290  }
291 
292  filter_wait(pid);
293 
294  mutt_file_fclose(&fp_tmp);
295  mutt_file_fclose(&fp_null);
296 
297  att = mutt_body_new();
298  att->filename = mutt_buffer_strdup(tempf);
299  att->unlink = true;
300  att->use_disp = false;
301  att->type = TYPE_APPLICATION;
302  att->subtype = mutt_str_dup("pgp-keys");
303  snprintf(buf, sizeof(buf), _("PGP Key %s"), tmp);
304  att->description = mutt_str_dup(buf);
306 
307  stat(mutt_b2s(tempf), &sb);
308  att->length = sb.st_size;
309 
310 cleanup:
311  mutt_buffer_pool_release(&tempf);
312  return att;
313 }
314 
323 static void pgp_add_string_to_hints(const char *str, struct ListHead *hints)
324 {
325  char *scratch = mutt_str_dup(str);
326  if (!scratch)
327  return;
328 
329  for (char *t = strtok(scratch, " ,.:\"()<>\n"); t;
330  t = strtok(NULL, " ,.:\"()<>\n"))
331  {
332  if (strlen(t) > 3)
334  }
335 
336  FREE(&scratch);
337 }
338 
344 static struct PgpKeyInfo **pgp_get_lastp(struct PgpKeyInfo *p)
345 {
346  for (; p; p = p->next)
347  if (!p->next)
348  return &p->next;
349 
350  return NULL;
351 }
352 
361 struct PgpKeyInfo *pgp_getkeybyaddr(struct Address *a, KeyFlags abilities,
362  enum PgpRing keyring, bool oppenc_mode)
363 {
364  if (!a)
365  return NULL;
366 
367  struct ListHead hints = STAILQ_HEAD_INITIALIZER(hints);
368 
369  bool multi = false;
370 
371  struct PgpKeyInfo *keys = NULL, *k = NULL, *kn = NULL;
372  struct PgpKeyInfo *the_strong_valid_key = NULL;
373  struct PgpKeyInfo *a_valid_addrmatch_key = NULL;
374  struct PgpKeyInfo *matches = NULL;
375  struct PgpKeyInfo **last = &matches;
376  struct PgpUid *q = NULL;
377 
378  if (a->mailbox)
379  pgp_add_string_to_hints(a->mailbox, &hints);
380  if (a->personal)
381  pgp_add_string_to_hints(a->personal, &hints);
382 
383  if (!oppenc_mode)
384  mutt_message(_("Looking for keys matching \"%s\"..."), a->mailbox);
385  keys = pgp_get_candidates(keyring, &hints);
386 
387  mutt_list_free(&hints);
388 
389  if (!keys)
390  return NULL;
391 
392  mutt_debug(LL_DEBUG5, "looking for %s <%s>\n", a->personal, a->mailbox);
393 
394  for (k = keys; k; k = kn)
395  {
396  kn = k->next;
397 
398  mutt_debug(LL_DEBUG5, " looking at key: %s\n", pgp_keyid(k));
399 
400  if (abilities && !(k->flags & abilities))
401  {
402  mutt_debug(LL_DEBUG3, " insufficient abilities: Has %x, want %x\n", k->flags, abilities);
403  continue;
404  }
405 
406  bool match = false; /* any match */
407 
408  for (q = k->address; q; q = q->next)
409  {
410  struct AddressList al = TAILQ_HEAD_INITIALIZER(al);
411  mutt_addrlist_parse(&al, NONULL(q->addr));
412  struct Address *qa = NULL;
413  TAILQ_FOREACH(qa, &al, entries)
414  {
415  PgpKeyValidFlags validity = pgp_id_matches_addr(a, qa, q);
416 
417  if (validity & PGP_KV_MATCH) /* something matches */
418  match = true;
419 
420  if ((validity & PGP_KV_VALID) && (validity & PGP_KV_ADDR))
421  {
422  if (validity & PGP_KV_STRONGID)
423  {
424  if (the_strong_valid_key && (the_strong_valid_key != k))
425  multi = true;
426  the_strong_valid_key = k;
427  }
428  else
429  {
430  a_valid_addrmatch_key = k;
431  }
432  }
433  }
434 
435  mutt_addrlist_clear(&al);
436  }
437 
438  if (match)
439  {
440  *last = pgp_principal_key(k);
441  kn = pgp_remove_key(&keys, *last);
442  last = pgp_get_lastp(k);
443  }
444  }
445 
446  pgp_key_free(&keys);
447 
448  if (matches)
449  {
450  if (oppenc_mode)
451  {
452  if (the_strong_valid_key)
453  {
454  pgp_remove_key(&matches, the_strong_valid_key);
455  k = the_strong_valid_key;
456  }
457  else if (a_valid_addrmatch_key && !C_CryptOpportunisticEncryptStrongKeys)
458  {
459  pgp_remove_key(&matches, a_valid_addrmatch_key);
460  k = a_valid_addrmatch_key;
461  }
462  else
463  k = NULL;
464  }
465  else if (the_strong_valid_key && !multi)
466  {
467  /* There was precisely one strong match on a valid ID.
468  * Proceed without asking the user. */
469  pgp_remove_key(&matches, the_strong_valid_key);
470  k = the_strong_valid_key;
471  }
472  else
473  {
474  /* Else: Ask the user. */
475  k = dlg_select_pgp_key(matches, a, NULL);
476  if (k)
477  pgp_remove_key(&matches, k);
478  }
479 
480  pgp_key_free(&matches);
481 
482  return k;
483  }
484 
485  return NULL;
486 }
487 
495 struct PgpKeyInfo *pgp_getkeybystr(const char *cp, KeyFlags abilities, enum PgpRing keyring)
496 {
497  struct ListHead hints = STAILQ_HEAD_INITIALIZER(hints);
498  struct PgpKeyInfo *keys = NULL;
499  struct PgpKeyInfo *matches = NULL;
500  struct PgpKeyInfo **last = &matches;
501  struct PgpKeyInfo *k = NULL, *kn = NULL;
502  struct PgpUid *a = NULL;
503  size_t l;
504  const char *ps = NULL, *pl = NULL, *pfcopy = NULL, *phint = NULL;
505 
506  char *p = strdup(cp); // mutt_str_dup converts "" into NULL, see #1809
507  l = mutt_str_len(p);
508  if ((l > 0) && (p[l - 1] == '!'))
509  p[l - 1] = 0;
510 
511  mutt_message(_("Looking for keys matching \"%s\"..."), p);
512 
513  pfcopy = crypt_get_fingerprint_or_id(p, &phint, &pl, &ps);
514  pgp_add_string_to_hints(phint, &hints);
515  keys = pgp_get_candidates(keyring, &hints);
516  mutt_list_free(&hints);
517 
518  for (k = keys; k; k = kn)
519  {
520  kn = k->next;
521  if (abilities && !(k->flags & abilities))
522  continue;
523 
524  /* This shouldn't happen, but keys without any addresses aren't selectable
525  * in dlg_select_pgp_key(). */
526  if (!k->address)
527  continue;
528 
529  bool match = false;
530 
531  mutt_debug(LL_DEBUG5, "matching \"%s\" against key %s:\n", p, pgp_long_keyid(k));
532 
533  if ((*p == '\0') || (pfcopy && mutt_istr_equal(pfcopy, k->fingerprint)) ||
534  (pl && mutt_istr_equal(pl, pgp_long_keyid(k))) ||
535  (ps && mutt_istr_equal(ps, pgp_short_keyid(k))))
536  {
537  mutt_debug(LL_DEBUG5, "\t\tmatch #1\n");
538  match = true;
539  }
540  else
541  {
542  for (a = k->address; a; a = a->next)
543  {
544  mutt_debug(LL_DEBUG5, "matching \"%s\" against key %s, \"%s\":\n", p,
545  pgp_long_keyid(k), NONULL(a->addr));
546  if (mutt_istr_find(a->addr, p))
547  {
548  mutt_debug(LL_DEBUG5, "\t\tmatch #2\n");
549  match = true;
550  break;
551  }
552  }
553  }
554 
555  if (match)
556  {
557  *last = pgp_principal_key(k);
558  kn = pgp_remove_key(&keys, *last);
559  last = pgp_get_lastp(k);
560  }
561  }
562 
563  pgp_key_free(&keys);
564 
565  if (matches)
566  {
567  k = dlg_select_pgp_key(matches, NULL, p);
568  if (k)
569  pgp_remove_key(&matches, k);
570  pgp_key_free(&matches);
571  }
572  else
573  {
574  k = NULL;
575  }
576 
577  FREE(&pfcopy);
578  FREE(&p);
579  return k;
580 }
Convenience wrapper for the gui 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:1258
struct PgpKeyInfo * next
Definition: pgplib.h:57
#define mutt_buffer_mktemp(buf)
Definition: muttlib.h:77
struct PgpCache * next
Definition: pgpkey.c:77
char * filename
when sending a message, this is the file to which this structure refers
Definition: body.h:46
Manage keymappings.
#define NONULL(x)
Definition: string2.h:37
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
#define mutt_perror(...)
Definition: logging.h:85
void mutt_update_encoding(struct Body *a, struct ConfigSubset *sub)
Update the encoding type.
Definition: sendlib.c:903
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:718
PGP key management routines.
struct PgpUid * next
Definition: pgplib.h:40
Structs that make up an email.
int mutt_addrlist_parse(struct AddressList *al, const char *s)
Parse a list of email addresses.
Definition: address.c:458
Convenience wrapper for the send headers.
#define mutt_message(...)
Definition: logging.h:83
void mutt_addrlist_clear(struct AddressList *al)
Unlink and free all Address in an AddressList.
Definition: address.c:1468
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:323
char * pgp_keyid(struct PgpKeyInfo *k)
Get the ID of the main (parent) key.
Definition: pgp.c:191
NeoMutt Logging.
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
char * mutt_buffer_strdup(struct Buffer *buf)
Copy a Buffer&#39;s string.
Definition: buffer.c:432
#define KEYFLAG_SUBKEY
Key is a subkey.
Definition: lib.h:141
String manipulation buffer.
Definition: buffer.h:33
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:375
#define _(a)
Definition: message.h:28
uint8_t PgpKeyValidFlags
Pgp Key valid fields, e.g. PGP_KV_VALID.
Definition: pgpkey.c:83
An email address.
Definition: address.h:34
PGP User ID.
Definition: pgplib.h:34
char * mailbox
Mailbox and host address.
Definition: address.h:37
KeyFlags flags
Definition: pgplib.h:51
bool pgp_key_is_valid(struct PgpKeyInfo *k)
Is a PGP key valid?
Definition: pgpkey.c:110
bool C_CryptOpportunisticEncryptStrongKeys
Config: Enable encryption only when strong a key is available.
Definition: config.c:42
Wrapper around calls to external PGP program.
struct Body * pgp_class_make_key_attachment(void)
Implements CryptModuleSpecs::pgp_make_key_attachment()
Definition: pgpkey.c:243
Shared constants/structs that are private to libconn.
Flags to control mutt_expando_format()
All user-callable functions.
Container for Accounts, Notifications.
Definition: neomutt.h:36
struct PgpKeyInfo * pgp_principal_key(struct PgpKeyInfo *key)
Get the main (parent) PGP key.
Definition: pgpkey.c:98
void mutt_list_free(struct ListHead *h)
Free a List AND its strings.
Definition: list.c:122
#define mutt_get_field(field, buf, buflen, complete)
Definition: curs_lib.h:91
The body of an email.
Definition: body.h:34
Convenience wrapper for the config headers.
struct PgpKeyInfo * pgp_get_candidates(enum PgpRing keyring, struct ListHead *hints)
Find PGP keys matching a list of hints.
Definition: gnupgparse.c:412
char * addr
Definition: pgplib.h:36
Email Address Handling.
struct Body * mutt_body_new(void)
Create a new Body.
Definition: body.c:43
Some miscellaneous functions.
Parse the output of CLI PGP programinclude "pgpkey.h".
Information about a PGP key.
Definition: pgplib.h:46
Many unsorted constants and some structs.
char * pgp_short_keyid(struct PgpKeyInfo *k)
Get a key&#39;s short id.
Definition: pgp.c:165
#define MUTT_COMP_NO_FLAGS
No flags are set.
Definition: mutt.h:56
short trust
Definition: pgplib.h:37
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
Convenience wrapper for the core headers.
#define PGP_KV_ADDR
PGP Key address is valid.
Definition: pgpkey.c:86
void pgp_key_free(struct PgpKeyInfo **kpp)
Free a PGP key info.
Definition: pgplib.c:199
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:113
PgpRing
PGP ring type.
Definition: pgpkey.h:37
#define KEYFLAG_CANTUSE
Definition: lib.h:146
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:888
struct PgpKeyInfo * pgp_getkeybyaddr(struct Address *a, KeyFlags abilities, enum PgpRing keyring, bool oppenc_mode)
Find a PGP key by address.
Definition: pgpkey.c:361
char * subtype
content-type subtype
Definition: body.h:37
struct ListNode * mutt_list_insert_tail(struct ListHead *h, char *s)
Append a string to the end of a List.
Definition: list.c:64
struct PgpKeyInfo * dlg_select_pgp_key(struct PgpKeyInfo *keys, struct Address *p, const char *s)
Let the user select a key to use.
Definition: dlgpgp.c:469
#define mutt_b2s(buf)
Definition: buffer.h:41
#define PGP_KV_VALID
PGP Key ID is valid.
Definition: pgpkey.c:85
Prototypes for many functions.
#define PGP_KV_STRING
PGP Key name string is valid.
Definition: pgpkey.c:87
Signing/encryption multiplexor.
LOFF_T length
length (in bytes) of attachment
Definition: body.h:45
#define KEYFLAG_NO_FLAGS
No flags are set.
Definition: lib.h:133
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
Definition: memory.c:90
char * what
Definition: pgpkey.c:75
List of cached PGP keys.
Definition: pgpkey.c:73
uint16_t KeyFlags
Flags describing PGP/SMIME keys, e.g. KEYFLAG_CANSIGN.
Definition: lib.h:132
static struct PgpKeyInfo ** pgp_get_lastp(struct PgpKeyInfo *p)
Get the last PGP key in a list.
Definition: pgpkey.c:344
struct PgpUid * address
Definition: pgplib.h:50
Public keys.
Definition: pgpkey.h:39
#define PGP_KV_NO_FLAGS
No flags are set.
Definition: pgpkey.c:84
struct PgpKeyInfo * pgp_remove_key(struct PgpKeyInfo **klist, struct PgpKeyInfo *key)
Remove a PGP key from a list.
Definition: pgplib.c:167
GUI present the user with a selectable list.
WHERE bool OptPgpCheckTrust
(pseudo) used by dlg_select_pgp_key()
Definition: options.h:49
struct PgpKeyInfo * parent
Definition: pgplib.h:39
char * description
content-description
Definition: body.h:40
unsigned int type
content-type primary type, ContentType
Definition: body.h:65
PGP sign, encrypt, check routines.
char * pgp_fpr_or_lkeyid(struct PgpKeyInfo *k)
Get the fingerprint or long keyid.
Definition: pgp.c:221
char * personal
Real name of address.
Definition: address.h:36
GUI display a file/email/help in a viewport with paging.
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:636
const char * mutt_istr_find(const char *haystack, const char *needle)
Find first occurrence of string (ignoring case)
Definition: string.c:661
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:721
bool use_disp
Content-Disposition uses filename= ?
Definition: body.h:68
#define PGP_KV_STRONGID
PGP Key is strong.
Definition: pgpkey.c:88
char * mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:451
bool pgp_id_is_valid(struct PgpUid *uid)
Is a PGP key valid.
Definition: pgpkey.c:139
struct PgpKeyInfo * pgp_getkeybystr(const char *cp, KeyFlags abilities, enum PgpRing keyring)
Find a PGP key by string.
Definition: pgpkey.c:495
#define mutt_error(...)
Definition: logging.h:84
bool unlink
If true, filename should be unlink()ed before free()ing this structure.
Definition: body.h:69
Misc PGP helper routines.
#define FREE(x)
Definition: memory.h:40
static struct PgpCache * id_defaults
Definition: pgpkey.c:80
struct PgpKeyInfo * parent
Definition: pgplib.h:56
struct PgpKeyInfo * pgp_ask_for_key(char *tag, char *whatfor, KeyFlags abilities, enum PgpRing keyring)
Ask the user for a PGP key.
Definition: pgpkey.c:189
#define STAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:321
bool pgp_id_is_strong(struct PgpUid *uid)
Is a PGP key strong?
Definition: pgpkey.c:126
Hundreds of global variables to back the user variables.
Handling of global boolean variables.
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
#define PGP_KV_MATCH
Definition: pgpkey.c:91
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
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:156
Log at debug level 5.
Definition: logging.h:44
Convenience wrapper for the library headers.
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:588
int filter_wait(pid_t pid)
Wait for the exit of a process and return its status.
Definition: filter.c:217
#define TAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:630
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&#39;s keyring.
Definition: pgpinvoke.c:475
char * dflt
Definition: pgpkey.c:76
char * fingerprint
Definition: pgplib.h:49
Type: &#39;application/*&#39;.
Definition: mime.h:33
Log at debug level 3.
Definition: logging.h:42
int flags
Definition: pgplib.h:38
char * pgp_long_keyid(struct PgpKeyInfo *k)
Get a key&#39;s long id.
Definition: pgp.c:153