NeoMutt  2024-12-12-14-g7b49f7
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
pgpkey.c File Reference

PGP key management routines. More...

#include "config.h"
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.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 "mutt.h"
#include "pgpkey.h"
#include "lib.h"
#include "editor/lib.h"
#include "history/lib.h"
#include "send/lib.h"
#include "crypt.h"
#include "globals.h"
#include "gnupgparse.h"
#include "mutt_logging.h"
#include "pgpinvoke.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.
 
#define PGP_KV_VALID   (1 << 0)
 PGP Key ID is valid.
 
#define PGP_KV_ADDR   (1 << 1)
 PGP Key address is valid.
 
#define PGP_KV_STRING   (1 << 2)
 PGP Key name string is valid.
 
#define PGP_KV_STRONGID   (1 << 3)
 PGP Key is strong.
 
#define PGP_KV_MATCH   (PGP_KV_ADDR | PGP_KV_STRING)
 

Typedefs

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

Functions

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

Variables

static struct PgpCacheIdDefaults = NULL
 Cache of GPGME keys.
 

Detailed Description

PGP key management routines.

Authors
  • Thomas Roessler
  • Pietro Cerutti
  • Richard Russon
  • Anna Figueiredo Gomes
  • Alejandro Colomar

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 78 of file pgpkey.c.

◆ PGP_KV_VALID

#define PGP_KV_VALID   (1 << 0)

PGP Key ID is valid.

Definition at line 79 of file pgpkey.c.

◆ PGP_KV_ADDR

#define PGP_KV_ADDR   (1 << 1)

PGP Key address is valid.

Definition at line 80 of file pgpkey.c.

◆ PGP_KV_STRING

#define PGP_KV_STRING   (1 << 2)

PGP Key name string is valid.

Definition at line 81 of file pgpkey.c.

◆ PGP_KV_STRONGID

#define PGP_KV_STRONGID   (1 << 3)

PGP Key is strong.

Definition at line 82 of file pgpkey.c.

◆ PGP_KV_MATCH

#define PGP_KV_MATCH   (PGP_KV_ADDR | PGP_KV_STRING)

Definition at line 85 of file pgpkey.c.

Typedef Documentation

◆ PgpKeyValidFlags

typedef uint8_t PgpKeyValidFlags

Flags for valid Pgp Key fields, e.g. PGP_KV_VALID.

Definition at line 77 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 92 of file pgpkey.c.

93{
94 if (key->flags & KEYFLAG_SUBKEY && key->parent)
95 return key->parent;
96 return key;
97}
#define KEYFLAG_SUBKEY
Key is a subkey.
Definition: lib.h:140
KeyFlags flags
Definition: pgplib.h:53
struct PgpKeyInfo * parent
Definition: pgplib.h:58
+ 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
trueKey is valid

Definition at line 104 of file pgpkey.c.

105{
106 struct PgpKeyInfo *pk = pgp_principal_key(k);
107 if (k->flags & KEYFLAG_CANTUSE)
108 return false;
109 if (pk->flags & KEYFLAG_CANTUSE)
110 return false;
111
112 return true;
113}
#define KEYFLAG_CANTUSE
Definition: lib.h:145
struct PgpKeyInfo * pgp_principal_key(struct PgpKeyInfo *key)
Get the main (parent) PGP key.
Definition: pgpkey.c:92
Information about a PGP key.
Definition: pgplib.h:49
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ pgp_keys_are_valid()

bool pgp_keys_are_valid ( struct PgpKeyInfo keys)

Are all these PGP keys valid?

Parameters
keysSet of keys to examine
Return values
trueAll keys are valid

Definition at line 120 of file pgpkey.c.

121{
122 for (struct PgpKeyInfo *k = keys; k != NULL; k = k->next)
123 {
124 if (!pgp_key_is_valid(k))
125 return false;
126 }
127
128 return true;
129}
bool pgp_key_is_valid(struct PgpKeyInfo *k)
Is a PGP key valid?
Definition: pgpkey.c:104
struct PgpKeyInfo * next
Definition: pgplib.h:59
+ 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
trueKey is strong

Definition at line 136 of file pgpkey.c.

137{
138 if ((uid->trust & 3) < 3)
139 return false;
140 /* else */
141 return true;
142}
short trust
Definition: pgplib.h:38
+ 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
trueKey is valid

Definition at line 149 of file pgpkey.c.

150{
151 if (!pgp_key_is_valid(uid->parent))
152 return false;
153 if (uid->flags & KEYFLAG_CANTUSE)
154 return false;
155 /* else */
156 return true;
157}
struct PgpKeyInfo * parent
Parent key.
Definition: pgplib.h:40
int flags
Definition: pgplib.h:39
+ 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 166 of file pgpkey.c.

168{
170
171 if (pgp_id_is_valid(uid))
172 flags |= PGP_KV_VALID;
173
174 if (pgp_id_is_strong(uid))
175 flags |= PGP_KV_STRONGID;
176
177 if (addr->mailbox && u_addr->mailbox && buf_istr_equal(addr->mailbox, u_addr->mailbox))
178 {
179 flags |= PGP_KV_ADDR;
180 }
181
182 if (addr->personal && u_addr->personal &&
183 buf_istr_equal(addr->personal, u_addr->personal))
184 {
185 flags |= PGP_KV_STRING;
186 }
187
188 return flags;
189}
bool buf_istr_equal(const struct Buffer *a, const struct Buffer *b)
Return if two buffers are equal, case insensitive.
Definition: buffer.c:697
bool pgp_id_is_valid(struct PgpUid *uid)
Is a PGP key valid.
Definition: pgpkey.c:149
#define PGP_KV_NO_FLAGS
No flags are set.
Definition: pgpkey.c:78
#define PGP_KV_STRONGID
PGP Key is strong.
Definition: pgpkey.c:82
#define PGP_KV_VALID
PGP Key ID is valid.
Definition: pgpkey.c:79
#define PGP_KV_STRING
PGP Key name string is valid.
Definition: pgpkey.c:81
#define PGP_KV_ADDR
PGP Key address is valid.
Definition: pgpkey.c:80
bool pgp_id_is_strong(struct PgpUid *uid)
Is a PGP key strong?
Definition: pgpkey.c:136
uint8_t PgpKeyValidFlags
Flags for valid Pgp Key fields, e.g. PGP_KV_VALID.
Definition: pgpkey.c:77
struct Buffer * personal
Real name of address.
Definition: address.h:37
struct Buffer * mailbox
Mailbox and host address.
Definition: address.h:38
+ 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,
const 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 199 of file pgpkey.c.

201{
202 struct PgpKeyInfo *key = NULL;
203 struct PgpCache *l = NULL;
204 struct Buffer *resp = buf_pool_get();
205
207
208 if (whatfor)
209 {
210 for (l = IdDefaults; l; l = l->next)
211 {
212 if (mutt_istr_equal(whatfor, l->what))
213 {
214 buf_strcpy(resp, l->dflt);
215 break;
216 }
217 }
218 }
219
220 while (true)
221 {
222 buf_reset(resp);
223 if (mw_get_field(tag, resp, MUTT_COMP_NO_FLAGS, HC_OTHER, NULL, NULL) != 0)
224 {
225 goto done;
226 }
227
228 if (whatfor)
229 {
230 if (l)
231 {
232 mutt_str_replace(&l->dflt, buf_string(resp));
233 }
234 else
235 {
236 l = MUTT_MEM_MALLOC(1, struct PgpCache);
237 l->next = IdDefaults;
238 IdDefaults = l;
239 l->what = mutt_str_dup(whatfor);
240 l->dflt = buf_strdup(resp);
241 }
242 }
243
244 key = pgp_getkeybystr(buf_string(resp), abilities, keyring);
245 if (key)
246 goto done;
247
248 mutt_error(_("No matching keys found for \"%s\""), buf_string(resp));
249 }
250
251done:
252 buf_pool_release(&resp);
253 return key;
254}
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
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:274
#define mutt_error(...)
Definition: logging2.h:92
@ HC_OTHER
Miscellaneous strings.
Definition: lib.h:58
#define MUTT_MEM_MALLOC(n, type)
Definition: memory.h:41
#define _(a)
Definition: message.h:28
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:672
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:253
char * mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:280
#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:74
static struct PgpCache * IdDefaults
Cache of GPGME keys.
Definition: pgpkey.c:74
struct PgpKeyInfo * pgp_getkeybystr(const char *cp, KeyFlags abilities, enum PgpRing keyring)
Find a PGP key by string.
Definition: pgpkey.c:514
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:82
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition: pool.c:96
String manipulation buffer.
Definition: buffer.h:36
List of cached PGP keys.
Definition: pgpkey.c:67
char * dflt
Definition: pgpkey.c:69
struct PgpCache * next
Linked list.
Definition: pgpkey.c:70
char * what
Definition: pgpkey.c:68
+ Here is the call graph for this function:
+ Here is the caller 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 338 of file pgpkey.c.

339{
340 char *scratch = mutt_str_dup(str);
341 if (!scratch)
342 return;
343
344 for (char *t = strtok(scratch, " ,.:\"()<>\n"); t; t = strtok(NULL, " ,.:\"()<>\n"))
345 {
346 if (strlen(t) > 3)
348 }
349
350 FREE(&scratch);
351}
struct ListNode * mutt_list_insert_tail(struct ListHead *h, char *s)
Append a string to the end of a List.
Definition: list.c:65
#define FREE(x)
Definition: memory.h:55
+ 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 358 of file pgpkey.c.

359{
360 for (; p; p = p->next)
361 if (!p->next)
362 return &p->next;
363
364 return NULL;
365}
+ 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 375 of file pgpkey.c.

377{
378 if (!a)
379 return NULL;
380
381 struct ListHead hints = STAILQ_HEAD_INITIALIZER(hints);
382
383 bool multi = false;
384
385 struct PgpKeyInfo *keys = NULL, *k = NULL, *kn = NULL;
386 struct PgpKeyInfo *the_strong_valid_key = NULL;
387 struct PgpKeyInfo *a_valid_addrmatch_key = NULL;
388 struct PgpKeyInfo *matches = NULL;
389 struct PgpKeyInfo **last = &matches;
390 struct PgpUid *q = NULL;
391
392 if (a->mailbox)
394 if (a->personal)
396
397 if (!oppenc_mode)
398 mutt_message(_("Looking for keys matching \"%s\"..."), buf_string(a->mailbox));
399 keys = pgp_get_candidates(keyring, &hints);
400
401 mutt_list_free(&hints);
402
403 if (!keys)
404 return NULL;
405
406 mutt_debug(LL_DEBUG5, "looking for %s <%s>\n", buf_string(a->personal),
407 buf_string(a->mailbox));
408
409 for (k = keys; k; k = kn)
410 {
411 kn = k->next;
412
413 mutt_debug(LL_DEBUG5, " looking at key: %s\n", pgp_keyid(k));
414
415 if (abilities && !(k->flags & abilities))
416 {
417 mutt_debug(LL_DEBUG3, " insufficient abilities: Has %x, want %x\n", k->flags, abilities);
418 continue;
419 }
420
421 bool match = false; /* any match */
422
423 for (q = k->address; q; q = q->next)
424 {
425 struct AddressList al = TAILQ_HEAD_INITIALIZER(al);
427 struct Address *qa = NULL;
428 TAILQ_FOREACH(qa, &al, entries)
429 {
430 PgpKeyValidFlags validity = pgp_id_matches_addr(a, qa, q);
431
432 if (validity & PGP_KV_MATCH) /* something matches */
433 match = true;
434
435 if ((validity & PGP_KV_VALID) && (validity & PGP_KV_ADDR))
436 {
437 if (validity & PGP_KV_STRONGID)
438 {
439 if (the_strong_valid_key && (the_strong_valid_key != k))
440 multi = true;
441 the_strong_valid_key = k;
442 }
443 else
444 {
445 a_valid_addrmatch_key = k;
446 }
447 }
448 }
449
451 }
452
453 if (match)
454 {
455 *last = pgp_principal_key(k);
456 kn = pgp_remove_key(&keys, *last);
457 last = pgp_get_lastp(k);
458 }
459 }
460
461 pgp_key_free(&keys);
462
463 if (matches)
464 {
465 if (oppenc_mode || !isatty(STDIN_FILENO))
466 {
467 const bool c_crypt_opportunistic_encrypt_strong_keys =
468 cs_subset_bool(NeoMutt->sub, "crypt_opportunistic_encrypt_strong_keys");
469 if (the_strong_valid_key)
470 {
471 pgp_remove_key(&matches, the_strong_valid_key);
472 k = the_strong_valid_key;
473 }
474 else if (a_valid_addrmatch_key && !c_crypt_opportunistic_encrypt_strong_keys)
475 {
476 pgp_remove_key(&matches, a_valid_addrmatch_key);
477 k = a_valid_addrmatch_key;
478 }
479 else
480 {
481 k = NULL;
482 }
483 }
484 else if (the_strong_valid_key && !multi)
485 {
486 /* There was precisely one strong match on a valid ID.
487 * Proceed without asking the user. */
488 pgp_remove_key(&matches, the_strong_valid_key);
489 k = the_strong_valid_key;
490 }
491 else
492 {
493 /* Else: Ask the user. */
494 k = dlg_pgp(matches, a, NULL);
495 if (k)
496 pgp_remove_key(&matches, k);
497 }
498
499 pgp_key_free(&matches);
500
501 return k;
502 }
503
504 return NULL;
505}
void mutt_addrlist_clear(struct AddressList *al)
Unlink and free all Address in an AddressList.
Definition: address.c:1460
int mutt_addrlist_parse(struct AddressList *al, const char *s)
Parse a list of email addresses.
Definition: address.c:480
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:47
struct PgpKeyInfo * pgp_get_candidates(enum PgpRing keyring, struct ListHead *hints)
Find PGP keys matching a list of hints.
Definition: gnupgparse.c:419
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
#define mutt_message(...)
Definition: logging2.h:91
#define mutt_debug(LEVEL,...)
Definition: logging2.h:89
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:45
@ LL_DEBUG5
Log at debug level 5.
Definition: logging2.h:47
char * pgp_keyid(struct PgpKeyInfo *k)
Get the ID of the main (parent) key.
Definition: pgp.c:204
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:338
#define PGP_KV_MATCH
Definition: pgpkey.c:85
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:166
static struct PgpKeyInfo ** pgp_get_lastp(struct PgpKeyInfo *p)
Get the last PGP key in a list.
Definition: pgpkey.c:358
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
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:743
#define STAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:324
#define TAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:655
#define NONULL(x)
Definition: string2.h:37
An email address.
Definition: address.h:36
Container for Accounts, Notifications.
Definition: neomutt.h:42
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:46
PGP User ID.
Definition: pgplib.h:36
char * addr
Definition: pgplib.h:37
struct PgpUid * next
Linked list.
Definition: pgplib.h:41
+ 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 514 of file pgpkey.c.

515{
516 struct ListHead hints = STAILQ_HEAD_INITIALIZER(hints);
517 struct PgpKeyInfo *keys = NULL;
518 struct PgpKeyInfo *matches = NULL;
519 struct PgpKeyInfo **last = &matches;
520 struct PgpKeyInfo *k = NULL, *kn = NULL;
521 struct PgpUid *a = NULL;
522 size_t l;
523 const char *ps = NULL, *pl = NULL, *pfcopy = NULL, *phint = NULL;
524
525 char *p = strdup(cp); // mutt_str_dup converts "" into NULL, see #1809
526 l = mutt_str_len(p);
527 if ((l > 0) && (p[l - 1] == '!'))
528 p[l - 1] = 0;
529
530 mutt_message(_("Looking for keys matching \"%s\"..."), p);
531
532 pfcopy = crypt_get_fingerprint_or_id(p, &phint, &pl, &ps);
533 pgp_add_string_to_hints(phint, &hints);
534 keys = pgp_get_candidates(keyring, &hints);
535 mutt_list_free(&hints);
536
537 for (k = keys; k; k = kn)
538 {
539 kn = k->next;
540 if (abilities && !(k->flags & abilities))
541 continue;
542
543 /* This shouldn't happen, but keys without any addresses aren't selectable
544 * in dlg_pgp(). */
545 if (!k->address)
546 continue;
547
548 bool match = false;
549
550 mutt_debug(LL_DEBUG5, "matching \"%s\" against key %s:\n", p, pgp_long_keyid(k));
551
552 if ((*p == '\0') || (pfcopy && mutt_istr_equal(pfcopy, k->fingerprint)) ||
553 (pl && mutt_istr_equal(pl, pgp_long_keyid(k))) ||
554 (ps && mutt_istr_equal(ps, pgp_short_keyid(k))))
555 {
556 mutt_debug(LL_DEBUG5, " match #1\n");
557 match = true;
558 }
559 else
560 {
561 for (a = k->address; a; a = a->next)
562 {
563 mutt_debug(LL_DEBUG5, "matching \"%s\" against key %s, \"%s\":\n", p,
564 pgp_long_keyid(k), NONULL(a->addr));
565 if (mutt_istr_find(a->addr, p))
566 {
567 mutt_debug(LL_DEBUG5, " match #2\n");
568 match = true;
569 break;
570 }
571 }
572 }
573
574 if (match)
575 {
576 *last = pgp_principal_key(k);
577 kn = pgp_remove_key(&keys, *last);
578 last = pgp_get_lastp(k);
579 }
580 }
581
582 pgp_key_free(&keys);
583
584 k = NULL;
585 if (matches)
586 {
587 if (isatty(STDIN_FILENO))
588 {
589 k = dlg_pgp(matches, NULL, p);
590 if (k)
591 pgp_remove_key(&matches, k);
592 pgp_key_free(&matches);
593 }
594 else if (pgp_keys_are_valid(matches))
595 {
596 k = matches;
597 }
598 else
599 {
600 mutt_error(_("A key can't be used: expired/disabled/revoked"));
601 }
602 }
603
604 FREE(&pfcopy);
605 FREE(&p);
606 return k;
607}
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:1385
const char * mutt_istr_find(const char *haystack, const char *needle)
Find first occurrence of string (ignoring case)
Definition: string.c:521
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:496
char * pgp_long_keyid(struct PgpKeyInfo *k)
Get a key's long id.
Definition: pgp.c:165
char * pgp_short_keyid(struct PgpKeyInfo *k)
Get a key's short id.
Definition: pgp.c:177
bool pgp_keys_are_valid(struct PgpKeyInfo *keys)
Are all these PGP keys valid?
Definition: pgpkey.c:120
struct PgpUid * address
Definition: pgplib.h:52
char * fingerprint
Definition: pgplib.h:51
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ IdDefaults

struct PgpCache* IdDefaults = NULL
static

Cache of GPGME keys.

Definition at line 74 of file pgpkey.c.