NeoMutt  2025-12-11-980-ge38c27
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 "module_data.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_MATCH   (PGP_KV_ADDR | PGP_KV_STRING)
 

Typedefs

typedef uint8_t PgpKeyValidFlags
 

Enumerations

enum  PgpKeyValidFlag {
  PGP_KV_NONE = 0 , PGP_KV_VALID = 1U << 0 , PGP_KV_ADDR = 1U << 1 , PGP_KV_STRING = 1U << 2 ,
  PGP_KV_STRONGID = 1U << 3
}
 Flags for valid Pgp Key fields. More...
 

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.
 
void pgp_id_defaults_cleanup (struct PgpCache **pgp_id_defaults)
 Free the PGP IdDefaults cache.
 

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_MATCH

#define PGP_KV_MATCH   (PGP_KV_ADDR | PGP_KV_STRING)

Definition at line 88 of file pgpkey.c.

Typedef Documentation

◆ PgpKeyValidFlags

typedef uint8_t PgpKeyValidFlags

Definition at line 86 of file pgpkey.c.

Enumeration Type Documentation

◆ PgpKeyValidFlag

Flags for valid Pgp Key fields.

Enumerator
PGP_KV_NONE 

No flags are set.

PGP_KV_VALID 

PGP Key ID is valid.

PGP_KV_ADDR 

PGP Key address is valid.

PGP_KV_STRING 

PGP Key name string is valid.

PGP_KV_STRONGID 

PGP Key is strong.

Definition at line 76 of file pgpkey.c.

77{
78 // clang-format off
79 PGP_KV_NONE = 0,
80 PGP_KV_VALID = 1U << 0,
81 PGP_KV_ADDR = 1U << 1,
82 PGP_KV_STRING = 1U << 2,
83 PGP_KV_STRONGID = 1U << 3,
84 // clang-format on
85};
@ PGP_KV_NONE
No flags are set.
Definition pgpkey.c:79
@ PGP_KV_STRING
PGP Key name string is valid.
Definition pgpkey.c:82
@ PGP_KV_ADDR
PGP Key address is valid.
Definition pgpkey.c:81
@ PGP_KV_VALID
PGP Key ID is valid.
Definition pgpkey.c:80
@ PGP_KV_STRONGID
PGP Key is strong.
Definition pgpkey.c:83

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

96{
97 if (key->flags & KEYFLAG_SUBKEY && key->parent)
98 return key->parent;
99 return key;
100}
@ KEYFLAG_SUBKEY
Key is a subkey.
Definition lib.h:154
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 107 of file pgpkey.c.

108{
109 struct PgpKeyInfo *pk = pgp_principal_key(k);
110 if (k->flags & KEYFLAG_CANTUSE)
111 return false;
112 if (pk->flags & KEYFLAG_CANTUSE)
113 return false;
114
115 return true;
116}
#define KEYFLAG_CANTUSE
Definition lib.h:161
struct PgpKeyInfo * pgp_principal_key(struct PgpKeyInfo *key)
Get the main (parent) PGP key.
Definition pgpkey.c:95
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 123 of file pgpkey.c.

124{
125 for (struct PgpKeyInfo *k = keys; k != NULL; k = k->next)
126 {
127 if (!pgp_key_is_valid(k))
128 return false;
129 }
130
131 return true;
132}
bool pgp_key_is_valid(struct PgpKeyInfo *k)
Is a PGP key valid?
Definition pgpkey.c:107
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 139 of file pgpkey.c.

140{
141 if ((uid->trust & 3) < 3)
142 return false;
143 /* else */
144 return true;
145}
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 152 of file pgpkey.c.

153{
154 if (!pgp_key_is_valid(uid->parent))
155 return false;
156 if (uid->flags & KEYFLAG_CANTUSE)
157 return false;
158 /* else */
159 return true;
160}
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 169 of file pgpkey.c.

171{
173
174 if (pgp_id_is_valid(uid))
175 flags |= PGP_KV_VALID;
176
177 if (pgp_id_is_strong(uid))
178 flags |= PGP_KV_STRONGID;
179
180 if (addr->mailbox && u_addr->mailbox && buf_istr_equal(addr->mailbox, u_addr->mailbox))
181 {
182 flags |= PGP_KV_ADDR;
183 }
184
185 if (addr->personal && u_addr->personal &&
186 buf_istr_equal(addr->personal, u_addr->personal))
187 {
188 flags |= PGP_KV_STRING;
189 }
190
191 return flags;
192}
bool buf_istr_equal(const struct Buffer *a, const struct Buffer *b)
Return if two buffers are equal, case insensitive.
Definition buffer.c:701
bool pgp_id_is_valid(struct PgpUid *uid)
Is a PGP key valid.
Definition pgpkey.c:152
bool pgp_id_is_strong(struct PgpUid *uid)
Is a PGP key strong?
Definition pgpkey.c:139
uint8_t PgpKeyValidFlags
Definition pgpkey.c:86
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 202 of file pgpkey.c.

204{
206 struct PgpKeyInfo *key = NULL;
207 struct PgpCache *l = NULL;
208 struct Buffer *resp = buf_pool_get();
209
211
212 if (whatfor)
213 {
214 for (l = (struct PgpCache *) mod_data->pgp_id_defaults; l; l = l->next)
215 {
216 if (mutt_istr_equal(whatfor, l->what))
217 {
218 buf_strcpy(resp, l->dflt);
219 break;
220 }
221 }
222 }
223
224 while (true)
225 {
226 buf_reset(resp);
227 if (mw_get_field(tag, resp, MUTT_COMP_NONE, HC_OTHER, NULL, NULL) != 0)
228 {
229 goto done;
230 }
231
232 if (buf_is_empty(resp))
233 goto done;
234
235 if (whatfor)
236 {
237 if (l)
238 {
239 mutt_str_replace(&l->dflt, buf_string(resp));
240 }
241 else
242 {
243 l = MUTT_MEM_MALLOC(1, struct PgpCache);
244 l->next = (struct PgpCache *) mod_data->pgp_id_defaults;
245 mod_data->pgp_id_defaults = l;
246 l->what = mutt_str_dup(whatfor);
247 l->dflt = buf_strdup(resp);
248 }
249 }
250
251 key = pgp_getkeybystr(buf_string(resp), abilities, keyring);
252 if (key)
253 goto done;
254
255 mutt_error(_("No matching keys found for \"%s\""), buf_string(resp));
256 }
257
258done:
259 buf_pool_release(&resp);
260 return key;
261}
void buf_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition buffer.c:89
bool buf_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition buffer.c:298
size_t buf_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition buffer.c:401
char * buf_strdup(const struct Buffer *buf)
Copy a Buffer's string.
Definition buffer.c:577
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition buffer.h:96
@ MUTT_COMP_NONE
No flags are set.
Definition wdata.h:46
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:502
#define mutt_error(...)
Definition logging2.h:94
@ HC_OTHER
Miscellaneous strings.
Definition lib.h:61
#define MUTT_MEM_MALLOC(n, type)
Definition memory.h:53
@ MODULE_ID_NCRYPT
ModuleNcrypt, Ncrypt
Definition module_api.h:82
#define _(a)
Definition message.h:28
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition string.c:678
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)
void * neomutt_get_module_data(struct NeoMutt *n, enum ModuleId id)
Get the private data for a Module.
Definition neomutt.c:666
struct PgpKeyInfo * pgp_getkeybystr(const char *cp, KeyFlags abilities, enum PgpRing keyring)
Find a PGP key by string.
Definition pgpkey.c:523
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
Ncrypt private Module data.
Definition module_data.h:39
struct PgpCache * pgp_id_defaults
PGP IdDefaults cache.
Definition module_data.h:53
Container for Accounts, Notifications.
Definition neomutt.h:41
List of cached PGP keys.
Definition pgpkey.c:67
char * dflt
Default key ID.
Definition pgpkey.c:69
struct PgpCache * next
Linked list.
Definition pgpkey.c:70
char * what
Cached key identifier.
Definition pgpkey.c:68
+ 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 345 of file pgpkey.c.

346{
347 char *scratch = mutt_str_dup(str);
348 if (!scratch)
349 return;
350
351 for (char *t = strtok(scratch, " ,.:\"()<>\n"); t; t = strtok(NULL, " ,.:\"()<>\n"))
352 {
353 if (strlen(t) > 3)
355 }
356
357 FREE(&scratch);
358}
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 365 of file pgpkey.c.

366{
367 for (; p; p = p->next)
368 if (!p->next)
369 return &p->next;
370
371 return NULL;
372}
+ 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 382 of file pgpkey.c.

384{
385 if (!a)
386 return NULL;
387
388 struct ListHead hints = STAILQ_HEAD_INITIALIZER(hints);
389
390 bool multi = false;
391
392 struct PgpKeyInfo *keys = NULL;
393 struct PgpKeyInfo *k = NULL;
394 struct PgpKeyInfo *kn = NULL;
395 struct PgpKeyInfo *the_strong_valid_key = NULL;
396 struct PgpKeyInfo *a_valid_addrmatch_key = NULL;
397 struct PgpKeyInfo *matches = NULL;
398 struct PgpKeyInfo **last = &matches;
399 struct PgpUid *q = NULL;
400
401 if (a->mailbox)
403 if (a->personal)
405
406 if (!oppenc_mode)
407 mutt_message(_("Looking for keys matching \"%s\"..."), buf_string(a->mailbox));
408 keys = pgp_get_candidates(keyring, &hints);
409
410 mutt_list_free(&hints);
411
412 if (!keys)
413 return NULL;
414
415 mutt_debug(LL_DEBUG5, "looking for %s <%s>\n", buf_string(a->personal),
416 buf_string(a->mailbox));
417
418 for (k = keys; k; k = kn)
419 {
420 kn = k->next;
421
422 mutt_debug(LL_DEBUG5, " looking at key: %s\n", pgp_keyid(k));
423
424 if (abilities && !(k->flags & abilities))
425 {
426 mutt_debug(LL_DEBUG3, " insufficient abilities: Has %x, want %x\n", k->flags, abilities);
427 continue;
428 }
429
430 bool match = false; /* any match */
431
432 for (q = k->address; q; q = q->next)
433 {
434 struct AddressList al = TAILQ_HEAD_INITIALIZER(al);
436 struct Address *qa = NULL;
437 TAILQ_FOREACH(qa, &al, entries)
438 {
439 PgpKeyValidFlags validity = pgp_id_matches_addr(a, qa, q);
440
441 if (validity & PGP_KV_MATCH) /* something matches */
442 match = true;
443
444 if ((validity & PGP_KV_VALID) && (validity & PGP_KV_ADDR))
445 {
446 if (validity & PGP_KV_STRONGID)
447 {
448 if (the_strong_valid_key && (the_strong_valid_key != k))
449 multi = true;
450 the_strong_valid_key = k;
451 }
452 else
453 {
454 a_valid_addrmatch_key = k;
455 }
456 }
457 }
458
460 }
461
462 if (match)
463 {
464 *last = pgp_principal_key(k);
465 kn = pgp_remove_key(&keys, *last);
466 last = pgp_get_lastp(k);
467 }
468 }
469
470 pgp_key_free(&keys);
471
472 if (matches)
473 {
474 if (oppenc_mode || !isatty(STDIN_FILENO))
475 {
476 const bool c_crypt_opportunistic_encrypt_strong_keys =
477 cs_subset_bool(NeoMutt->sub, "crypt_opportunistic_encrypt_strong_keys");
478 if (the_strong_valid_key)
479 {
480 pgp_remove_key(&matches, the_strong_valid_key);
481 k = the_strong_valid_key;
482 }
483 else if (a_valid_addrmatch_key && !c_crypt_opportunistic_encrypt_strong_keys)
484 {
485 pgp_remove_key(&matches, a_valid_addrmatch_key);
486 k = a_valid_addrmatch_key;
487 }
488 else
489 {
490 k = NULL;
491 }
492 }
493 else if (the_strong_valid_key && !multi)
494 {
495 /* There was precisely one strong match on a valid ID.
496 * Proceed without asking the user. */
497 pgp_remove_key(&matches, the_strong_valid_key);
498 k = the_strong_valid_key;
499 }
500 else
501 {
502 /* Else: Ask the user. */
503 k = dlg_pgp(matches, a, NULL);
504 if (k)
505 pgp_remove_key(&matches, k);
506 }
507
508 pgp_key_free(&matches);
509
510 return k;
511 }
512
513 return NULL;
514}
void mutt_addrlist_clear(struct AddressList *al)
Unlink and free all Address in an AddressList.
Definition address.c:1475
int mutt_addrlist_parse(struct AddressList *al, const char *s)
Parse a list of email addresses.
Definition address.c:481
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: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:201
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:345
#define PGP_KV_MATCH
Definition pgpkey.c:88
static PgpKeyValidFlags pgp_id_matches_addr(struct Address *addr, struct Address *u_addr, struct PgpUid *uid)
Does the key ID match the address.
Definition pgpkey.c:169
static struct PgpKeyInfo ** pgp_get_lastp(struct PgpKeyInfo *p)
Get the last PGP key in a list.
Definition pgpkey.c:365
void pgp_key_free(struct PgpKeyInfo **kpp)
Free a PGP key info.
Definition pgplib.c:204
struct PgpKeyInfo * pgp_remove_key(struct PgpKeyInfo **klist, struct PgpKeyInfo *key)
Remove a PGP key from a list.
Definition pgplib.c:170
#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
struct ConfigSubset * sub
Inherited config items.
Definition neomutt.h:49
struct PgpUid * address
User IDs.
Definition pgplib.h:52
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 523 of file pgpkey.c.

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

◆ pgp_id_defaults_cleanup()

void pgp_id_defaults_cleanup ( struct PgpCache ** pgp_id_defaults)

Free the PGP IdDefaults cache.

Parameters
pgp_id_defaultsPointer to the PGP cache head

Definition at line 626 of file pgpkey.c.

627{
628 struct PgpCache *l = *pgp_id_defaults;
629 while (l)
630 {
631 struct PgpCache *next = l->next;
632 FREE(&l->what);
633 FREE(&l->dflt);
634 FREE(&l);
635 l = next;
636 }
637 *pgp_id_defaults = NULL;
638}
+ Here is the caller graph for this function: