NeoMutt  2020-06-26-250-g349c94
Teaching an old dog new tricks
DOXYGEN
pgpkey.c File Reference

PGP key management routines. More...

#include "config.h"
#include <ctype.h>
#include <locale.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#include "private.h"
#include "mutt/lib.h"
#include "address/lib.h"
#include "config/lib.h"
#include "email/lib.h"
#include "core/lib.h"
#include "gui/lib.h"
#include "mutt.h"
#include "pgpkey.h"
#include "lib.h"
#include "crypt.h"
#include "format_flags.h"
#include "gnupgparse.h"
#include "keymap.h"
#include "mutt_globals.h"
#include "mutt_logging.h"
#include "mutt_menu.h"
#include "muttlib.h"
#include "opcodes.h"
#include "options.h"
#include "pager.h"
#include "pgpinvoke.h"
#include "protos.h"
#include "send/lib.h"
#include "pgp.h"
#include "pgplib.h"
+ Include dependency graph for pgpkey.c:

Go to the source code of this file.

Data Structures

struct  PgpCache
 List of cached PGP keys. More...
 

Macros

#define PGP_KV_NO_FLAGS   0
 No flags are set. More...
 
#define PGP_KV_VALID   (1 << 0)
 PGP Key ID is valid. More...
 
#define PGP_KV_ADDR   (1 << 1)
 PGP Key address is valid. More...
 
#define PGP_KV_STRING   (1 << 2)
 PGP Key name string is valid. More...
 
#define PGP_KV_STRONGID   (1 << 3)
 PGP Key is strong. More...
 
#define PGP_KV_MATCH   (PGP_KV_ADDR | PGP_KV_STRING)
 

Typedefs

typedef uint8_t PgpKeyValidFlags
 Pgp Key valid fields, e.g. PGP_KV_VALID. More...
 

Functions

struct PgpKeyInfopgp_principal_key (struct PgpKeyInfo *key)
 Get the main (parent) PGP key. More...
 
bool pgp_key_is_valid (struct PgpKeyInfo *k)
 Is a PGP key valid? More...
 
bool pgp_id_is_strong (struct PgpUid *uid)
 Is a PGP key strong? More...
 
bool pgp_id_is_valid (struct PgpUid *uid)
 Is a PGP key valid. More...
 
static PgpKeyValidFlags pgp_id_matches_addr (struct Address *addr, struct Address *u_addr, struct PgpUid *uid)
 Does the key ID match the address. More...
 
struct PgpKeyInfopgp_ask_for_key (char *tag, char *whatfor, KeyFlags abilities, enum PgpRing keyring)
 Ask the user for a PGP key. More...
 
struct Bodypgp_class_make_key_attachment (void)
 Implements CryptModuleSpecs::pgp_make_key_attachment() More...
 
static void pgp_add_string_to_hints (const char *str, struct ListHead *hints)
 Split a string and add the parts to a List. More...
 
static struct PgpKeyInfo ** pgp_get_lastp (struct PgpKeyInfo *p)
 Get the last PGP key in a list. More...
 
struct PgpKeyInfopgp_getkeybyaddr (struct Address *a, KeyFlags abilities, enum PgpRing keyring, bool oppenc_mode)
 Find a PGP key by address. More...
 
struct PgpKeyInfopgp_getkeybystr (const char *cp, KeyFlags abilities, enum PgpRing keyring)
 Find a PGP key by string. More...
 

Variables

static struct PgpCacheid_defaults = NULL
 

Detailed Description

PGP key management routines.

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

Macro Definition Documentation

◆ PGP_KV_NO_FLAGS

#define PGP_KV_NO_FLAGS   0

No flags are set.

Definition at line 84 of file pgpkey.c.

◆ PGP_KV_VALID

#define PGP_KV_VALID   (1 << 0)

PGP Key ID is valid.

Definition at line 85 of file pgpkey.c.

◆ PGP_KV_ADDR

#define PGP_KV_ADDR   (1 << 1)

PGP Key address is valid.

Definition at line 86 of file pgpkey.c.

◆ PGP_KV_STRING

#define PGP_KV_STRING   (1 << 2)

PGP Key name string is valid.

Definition at line 87 of file pgpkey.c.

◆ PGP_KV_STRONGID

#define PGP_KV_STRONGID   (1 << 3)

PGP Key is strong.

Definition at line 88 of file pgpkey.c.

◆ PGP_KV_MATCH

#define PGP_KV_MATCH   (PGP_KV_ADDR | PGP_KV_STRING)

Definition at line 91 of file pgpkey.c.

Typedef Documentation

◆ PgpKeyValidFlags

typedef uint8_t PgpKeyValidFlags

Pgp Key valid fields, e.g. PGP_KV_VALID.

Definition at line 83 of file pgpkey.c.

Function Documentation

◆ pgp_principal_key()

struct PgpKeyInfo* pgp_principal_key ( struct PgpKeyInfo key)

Get the main (parent) PGP key.

Parameters
keyKey to start with
Return values
ptrPGP Key

Definition at line 98 of file pgpkey.c.

99 {
100  if (key->flags & KEYFLAG_SUBKEY && key->parent)
101  return key->parent;
102  return key;
103 }
#define KEYFLAG_SUBKEY
Key is a subkey.
Definition: lib.h:141
KeyFlags flags
Definition: pgplib.h:51
struct PgpKeyInfo * parent
Definition: pgplib.h:56
+ Here is the caller graph for this function:

◆ pgp_key_is_valid()

bool pgp_key_is_valid ( struct PgpKeyInfo k)

Is a PGP key valid?

Parameters
kKey to examine
Return values
trueIf key is valid

Definition at line 110 of file pgpkey.c.

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 }
KeyFlags flags
Definition: pgplib.h:51
struct PgpKeyInfo * pgp_principal_key(struct PgpKeyInfo *key)
Get the main (parent) PGP key.
Definition: pgpkey.c:98
Information about a PGP key.
Definition: pgplib.h:46
#define KEYFLAG_CANTUSE
Definition: lib.h:146
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ pgp_id_is_strong()

bool pgp_id_is_strong ( struct PgpUid uid)

Is a PGP key strong?

Parameters
uidUID of a PGP key
Return values
trueIf key is strong

Definition at line 126 of file pgpkey.c.

127 {
128  if ((uid->trust & 3) < 3)
129  return false;
130  /* else */
131  return true;
132 }
short trust
Definition: pgplib.h:37
+ Here is the caller graph for this function:

◆ pgp_id_is_valid()

bool pgp_id_is_valid ( struct PgpUid uid)

Is a PGP key valid.

Parameters
uidUID of a PGP key
Return values
trueIf key is valid

Definition at line 139 of file pgpkey.c.

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 }
bool pgp_key_is_valid(struct PgpKeyInfo *k)
Is a PGP key valid?
Definition: pgpkey.c:110
#define KEYFLAG_CANTUSE
Definition: lib.h:146
struct PgpKeyInfo * parent
Definition: pgplib.h:39
int flags
Definition: pgplib.h:38
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ pgp_id_matches_addr()

static PgpKeyValidFlags pgp_id_matches_addr ( struct Address addr,
struct Address u_addr,
struct PgpUid uid 
)
static

Does the key ID match the address.

Parameters
addrFirst email address
u_addrSecond email address
uidUID of PGP key
Return values
numFlags, e.g. PGP_KV_VALID

Definition at line 156 of file pgpkey.c.

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 }
uint8_t PgpKeyValidFlags
Pgp Key valid fields, e.g. PGP_KV_VALID.
Definition: pgpkey.c:83
char * mailbox
Mailbox and host address.
Definition: address.h:37
KeyFlags flags
Definition: pgplib.h:51
#define PGP_KV_ADDR
PGP Key address is valid.
Definition: pgpkey.c:86
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:888
#define PGP_KV_VALID
PGP Key ID is valid.
Definition: pgpkey.c:85
#define PGP_KV_STRING
PGP Key name string is valid.
Definition: pgpkey.c:87
#define PGP_KV_NO_FLAGS
No flags are set.
Definition: pgpkey.c:84
char * personal
Real name of address.
Definition: address.h:36
#define PGP_KV_STRONGID
PGP Key is strong.
Definition: pgpkey.c:88
bool pgp_id_is_valid(struct PgpUid *uid)
Is a PGP key valid.
Definition: pgpkey.c:139
bool pgp_id_is_strong(struct PgpUid *uid)
Is a PGP key strong?
Definition: pgpkey.c:126
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ pgp_ask_for_key()

struct PgpKeyInfo* pgp_ask_for_key ( char *  tag,
char *  whatfor,
KeyFlags  abilities,
enum PgpRing  keyring 
)

Ask the user for a PGP key.

Parameters
tagPrompt for the user
whatforUse for key, e.g. "signing"
abilitiesAbilities to match, see KeyFlags
keyringPGP keyring to use
Return values
ptrSelected PGP key

Definition at line 189 of file pgpkey.c.

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 }
struct PgpCache * next
Definition: pgpkey.c:77
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:375
#define _(a)
Definition: message.h:28
#define mutt_get_field(field, buf, buflen, complete)
Definition: curs_lib.h:91
Information about a PGP key.
Definition: pgplib.h:46
#define MUTT_COMP_NO_FLAGS
No flags are set.
Definition: mutt.h:56
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:113
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:888
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
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
char * mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:451
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
static struct PgpCache * id_defaults
Definition: pgpkey.c:80
char * dflt
Definition: pgpkey.c:76
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ pgp_class_make_key_attachment()

struct Body* pgp_class_make_key_attachment ( void  )

Implements CryptModuleSpecs::pgp_make_key_attachment()

Definition at line 243 of file pgpkey.c.

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 }
#define mutt_buffer_mktemp(buf)
Definition: muttlib.h:77
char * filename
when sending a message, this is the file to which this structure refers
Definition: body.h:46
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 mutt_message(...)
Definition: logging.h:83
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
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
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
The body of an email.
Definition: body.h:34
struct Body * mutt_body_new(void)
Create a new Body.
Definition: body.c:43
Information about a PGP key.
Definition: pgplib.h:46
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:153
void pgp_key_free(struct PgpKeyInfo **kpp)
Free a PGP key info.
Definition: pgplib.c:199
char * subtype
content-type subtype
Definition: body.h:37
#define mutt_b2s(buf)
Definition: buffer.h:41
LOFF_T length
length (in bytes) of attachment
Definition: body.h:45
#define KEYFLAG_NO_FLAGS
No flags are set.
Definition: lib.h:133
Public keys.
Definition: pgpkey.h:39
WHERE bool OptPgpCheckTrust
(pseudo) used by pgp_select_key()
Definition: options.h:49
char * description
content-description
Definition: body.h:40
unsigned int type
content-type primary type, ContentType
Definition: body.h:65
char * pgp_fpr_or_lkeyid(struct PgpKeyInfo *k)
Get the fingerprint or long keyid.
Definition: pgp.c:221
bool use_disp
Content-Disposition uses filename= ?
Definition: body.h:68
bool unlink
If true, filename should be unlink()ed before free()ing this structure.
Definition: body.h:69
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
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
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
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
Type: &#39;application/*&#39;.
Definition: mime.h:33
+ Here is the call graph for this function:

◆ pgp_add_string_to_hints()

static void pgp_add_string_to_hints ( const char *  str,
struct ListHead *  hints 
)
static

Split a string and add the parts to a List.

Parameters
[in]strString to parse
[out]hintsList of string parts

The string str is split by whitespace and punctuation and the parts added to hints.

Definition at line 323 of file pgpkey.c.

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 }
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:375
struct ListNode * mutt_list_insert_tail(struct ListHead *h, char *s)
Append a string to the end of a List.
Definition: list.c:64
#define FREE(x)
Definition: memory.h:40
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ pgp_get_lastp()

static struct PgpKeyInfo** pgp_get_lastp ( struct PgpKeyInfo p)
static

Get the last PGP key in a list.

Parameters
pList of PGP keys
Return values
ptrLast PGP key in list

Definition at line 344 of file pgpkey.c.

345 {
346  for (; p; p = p->next)
347  if (!p->next)
348  return &p->next;
349 
350  return NULL;
351 }
struct PgpKeyInfo * next
Definition: pgplib.h:57
+ Here is the caller graph for this function:

◆ pgp_getkeybyaddr()

struct PgpKeyInfo* pgp_getkeybyaddr ( struct Address a,
KeyFlags  abilities,
enum PgpRing  keyring,
bool  oppenc_mode 
)

Find a PGP key by address.

Parameters
aEmail address to match
abilitiesAbilities to match, see KeyFlags
keyringPGP keyring to use
oppenc_modeIf true, use opportunistic encryption
Return values
ptrMatching PGP key

Definition at line 361 of file pgpkey.c.

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 = pgp_select_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 }
#define NONULL(x)
Definition: string2.h:37
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:718
struct PgpUid * next
Definition: pgplib.h:40
int mutt_addrlist_parse(struct AddressList *al, const char *s)
Parse a list of email addresses.
Definition: address.c:458
#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:1461
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
struct PgpKeyInfo * pgp_select_key(struct PgpKeyInfo *keys, struct Address *p, const char *s)
Let the user select a key to use.
Definition: dlgpgp.c:469
char * pgp_keyid(struct PgpKeyInfo *k)
Get the ID of the main (parent) key.
Definition: pgp.c:191
#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
bool C_CryptOpportunisticEncryptStrongKeys
Config: Enable encryption only when strong a key is available.
Definition: config.c:42
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
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
Information about a PGP key.
Definition: pgplib.h:46
#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
#define PGP_KV_VALID
PGP Key ID is valid.
Definition: pgpkey.c:85
static struct PgpKeyInfo ** pgp_get_lastp(struct PgpKeyInfo *p)
Get the last PGP key in a list.
Definition: pgpkey.c:344
struct PgpKeyInfo * pgp_remove_key(struct PgpKeyInfo **klist, struct PgpKeyInfo *key)
Remove a PGP key from a list.
Definition: pgplib.c:167
char * personal
Real name of address.
Definition: address.h:36
#define PGP_KV_STRONGID
PGP Key is strong.
Definition: pgpkey.c:88
#define STAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:321
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
#define PGP_KV_MATCH
Definition: pgpkey.c:91
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
#define TAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:630
Log at debug level 3.
Definition: logging.h:42
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ pgp_getkeybystr()

struct PgpKeyInfo* pgp_getkeybystr ( const char *  cp,
KeyFlags  abilities,
enum PgpRing  keyring 
)

Find a PGP key by string.

Parameters
cpString to match, can be empty but cannot be NULL
abilitiesAbilities to match, see KeyFlags
keyringPGP keyring to use
Return values
ptrMatching PGP key

Definition at line 495 of file pgpkey.c.

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 pgp_select_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 = pgp_select_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 }
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:1256
struct PgpKeyInfo * next
Definition: pgplib.h:57
#define NONULL(x)
Definition: string2.h:37
struct PgpUid * next
Definition: pgplib.h:40
#define mutt_message(...)
Definition: logging.h:83
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
struct PgpKeyInfo * pgp_select_key(struct PgpKeyInfo *keys, struct Address *p, const char *s)
Let the user select a key to use.
Definition: dlgpgp.c:469
#define _(a)
Definition: message.h:28
PGP User ID.
Definition: pgplib.h:34
KeyFlags flags
Definition: pgplib.h:51
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
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
Information about a PGP key.
Definition: pgplib.h:46
char * pgp_short_keyid(struct PgpKeyInfo *k)
Get a key&#39;s short id.
Definition: pgp.c:165
void pgp_key_free(struct PgpKeyInfo **kpp)
Free a PGP key info.
Definition: pgplib.c:199
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:888
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
struct PgpKeyInfo * pgp_remove_key(struct PgpKeyInfo **klist, struct PgpKeyInfo *key)
Remove a PGP key from a list.
Definition: pgplib.c:167
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
#define FREE(x)
Definition: memory.h:40
#define STAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:321
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
Log at debug level 5.
Definition: logging.h:44
char * fingerprint
Definition: pgplib.h:49
char * pgp_long_keyid(struct PgpKeyInfo *k)
Get a key&#39;s long id.
Definition: pgp.c:153
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ id_defaults

struct PgpCache* id_defaults = NULL
static

Definition at line 80 of file pgpkey.c.