NeoMutt  2025-12-11-435-g4ac674
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 "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 77 of file pgpkey.c.

◆ PGP_KV_VALID

#define PGP_KV_VALID   (1 << 0)

PGP Key ID is valid.

Definition at line 78 of file pgpkey.c.

◆ PGP_KV_ADDR

#define PGP_KV_ADDR   (1 << 1)

PGP Key address is valid.

Definition at line 79 of file pgpkey.c.

◆ PGP_KV_STRING

#define PGP_KV_STRING   (1 << 2)

PGP Key name string is valid.

Definition at line 80 of file pgpkey.c.

◆ PGP_KV_STRONGID

#define PGP_KV_STRONGID   (1 << 3)

PGP Key is strong.

Definition at line 81 of file pgpkey.c.

◆ PGP_KV_MATCH

#define PGP_KV_MATCH   (PGP_KV_ADDR | PGP_KV_STRING)

Definition at line 84 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 76 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 91 of file pgpkey.c.

92{
93 if (key->flags & KEYFLAG_SUBKEY && key->parent)
94 return key->parent;
95 return key;
96}
#define KEYFLAG_SUBKEY
Key is a subkey.
Definition lib.h:142
KeyFlags flags
Key flags.
Definition pgplib.h:53
struct PgpKeyInfo * parent
Parent key.
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 103 of file pgpkey.c.

104{
105 struct PgpKeyInfo *pk = pgp_principal_key(k);
106 if (k->flags & KEYFLAG_CANTUSE)
107 return false;
108 if (pk->flags & KEYFLAG_CANTUSE)
109 return false;
110
111 return true;
112}
#define KEYFLAG_CANTUSE
Definition lib.h:147
struct PgpKeyInfo * pgp_principal_key(struct PgpKeyInfo *key)
Get the main (parent) PGP key.
Definition pgpkey.c:91
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 119 of file pgpkey.c.

120{
121 for (struct PgpKeyInfo *k = keys; k != NULL; k = k->next)
122 {
123 if (!pgp_key_is_valid(k))
124 return false;
125 }
126
127 return true;
128}
bool pgp_key_is_valid(struct PgpKeyInfo *k)
Is a PGP key valid?
Definition pgpkey.c:103
struct PgpKeyInfo * next
Linked list.
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 135 of file pgpkey.c.

136{
137 if ((uid->trust & 3) < 3)
138 return false;
139 /* else */
140 return true;
141}
short trust
Trust level.
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 148 of file pgpkey.c.

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

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

200{
201 struct PgpKeyInfo *key = NULL;
202 struct PgpCache *l = NULL;
203 struct Buffer *resp = buf_pool_get();
204
206
207 if (whatfor)
208 {
209 for (l = IdDefaults; l; l = l->next)
210 {
211 if (mutt_istr_equal(whatfor, l->what))
212 {
213 buf_strcpy(resp, l->dflt);
214 break;
215 }
216 }
217 }
218
219 while (true)
220 {
221 buf_reset(resp);
222 if (mw_get_field(tag, resp, MUTT_COMP_NO_FLAGS, HC_OTHER, NULL, NULL) != 0)
223 {
224 goto done;
225 }
226
227 if (whatfor)
228 {
229 if (l)
230 {
231 mutt_str_replace(&l->dflt, buf_string(resp));
232 }
233 else
234 {
235 l = MUTT_MEM_MALLOC(1, struct PgpCache);
236 l->next = IdDefaults;
237 IdDefaults = l;
238 l->what = mutt_str_dup(whatfor);
239 l->dflt = buf_strdup(resp);
240 }
241 }
242
243 key = pgp_getkeybystr(buf_string(resp), abilities, keyring);
244 if (key)
245 goto done;
246
247 mutt_error(_("No matching keys found for \"%s\""), buf_string(resp));
248 }
249
250done:
251 buf_pool_release(&resp);
252 return key;
253}
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
static struct CryptCache * IdDefaults
Cache of GPGME keys.
Definition crypt_gpgme.c:92
#define MUTT_COMP_NO_FLAGS
No flags are set.
Definition wdata.h:42
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:270
#define mutt_error(...)
Definition logging2.h:94
@ HC_OTHER
Miscellaneous strings.
Definition lib.h:60
#define MUTT_MEM_MALLOC(n, type)
Definition memory.h:53
#define _(a)
Definition message.h:28
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition string.c:674
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition string.c:257
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)
struct PgpKeyInfo * pgp_getkeybystr(const char *cp, KeyFlags abilities, enum PgpRing keyring)
Find a PGP key by string.
Definition pgpkey.c:513
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
String manipulation buffer.
Definition buffer.h:36
List of cached PGP keys.
Definition pgpkey.c:66
char * dflt
Default key ID.
Definition pgpkey.c:68
struct PgpCache * next
Linked list.
Definition pgpkey.c:69
char * what
Cached key identifier.
Definition pgpkey.c:67
+ 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 337 of file pgpkey.c.

338{
339 char *scratch = mutt_str_dup(str);
340 if (!scratch)
341 return;
342
343 for (char *t = strtok(scratch, " ,.:\"()<>\n"); t; t = strtok(NULL, " ,.:\"()<>\n"))
344 {
345 if (strlen(t) > 3)
347 }
348
349 FREE(&scratch);
350}
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)
Free memory and set the pointer to NULL.
Definition memory.h:68
+ 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 357 of file pgpkey.c.

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

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

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