Skip to content

Commit

Permalink
Add a rpmKeyring iterator
Browse files Browse the repository at this point in the history
Returns primary keys only. Returns weak references while holding the
reference to the current key itself.

Resolves: rpm-software-management#3337
  • Loading branch information
ffesti committed Oct 11, 2024
1 parent a715e7e commit a565ace
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 0 deletions.
23 changes: 23 additions & 0 deletions include/rpm/rpmkeyring.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,29 @@ rpmKeyring rpmKeyringFree(rpmKeyring keyring);
*/
int rpmKeyringAddKey(rpmKeyring keyring, rpmPubkey key);

/** \ingroup rpmkeyring
* Get iterator for all the primary keys in the keyring
* @param keyring keyring handle
* @param unused reserved for future use, must be 0
* @return iterator or NULL
*/
rpmKeyringIterator rpmKeyringInitIterator(rpmKeyring keyring, int unused);

/** \ingroup rpmkeyring
* Get next key in keyring
* @param iterator iterator handle
* @return weak reference to next public key
* or NULL if end is reached
*/
rpmPubkey rpmKeyringIteratorNext(rpmKeyringIterator iterator);

/** \ingroup rpmkeyring
* Free iterator
* @param iterator iterator handle
* @return NULL
*/
rpmKeyringIterator rpmKeyringIteratorFree(rpmKeyringIterator iterator);

/** \ingroup rpmkeyring
* Perform combined keyring lookup and signature verification
* @param keyring keyring handle
Expand Down
1 change: 1 addition & 0 deletions include/rpm/rpmtypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ typedef void * rpmCallbackData;

typedef struct rpmPubkey_s * rpmPubkey;
typedef struct rpmKeyring_s * rpmKeyring;
typedef struct rpmKeyringIterator_s * rpmKeyringIterator;

typedef uint32_t rpmsid;
typedef struct rpmstrPool_s * rpmstrPool;
Expand Down
53 changes: 53 additions & 0 deletions rpmio/rpmkeyring.cc
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,13 @@ struct rpmKeyring_s {
std::shared_mutex mutex;
};

struct rpmKeyringIterator_s {
rpmKeyring keyring;
rdlock keyringlock;
std::map<std::string,rpmPubkey>::const_iterator iterator;
rpmPubkey current;
};

static std::string key2str(const uint8_t *keyid)
{
return std::string(reinterpret_cast<const char *>(keyid), PGP_KEYID_LEN);
Expand All @@ -61,6 +68,52 @@ rpmKeyring rpmKeyringFree(rpmKeyring keyring)
return NULL;
}

rpmKeyringIterator rpmKeyringInitIterator(rpmKeyring keyring, int unused)
{
if (!keyring || unused != 0)
return NULL;

return new rpmKeyringIterator_s {
rpmKeyringLink(keyring),
rdlock(keyring->mutex),
keyring->keys.cbegin(),
NULL,
};
}

rpmPubkey rpmKeyringIteratorNext(rpmKeyringIterator iterator)
{
rpmPubkey next = NULL;

if (!iterator)
return NULL;

while (iterator->iterator != iterator->keyring->keys.end()) {
next = iterator->iterator->second;
iterator->iterator++;
if (!next->primarykey)
break;
else
next = NULL;
}
rpmPubkeyFree(iterator->current);
iterator->current = rpmPubkeyLink(next);
return iterator->current;
}

rpmKeyringIterator rpmKeyringIteratorFree(rpmKeyringIterator iterator)
{
if (!iterator)
return NULL;

rpmPubkeyFree(iterator->current);
iterator->keyringlock.unlock(); /* needed or rpmKeyringFree locks up */
rpmKeyringFree(iterator->keyring);
delete iterator;
return NULL;
}


int rpmKeyringModify(rpmKeyring keyring, rpmPubkey key, rpmKeyringModifyMode mode)
{
int rc = 1; /* assume already seen key */
Expand Down

0 comments on commit a565ace

Please sign in to comment.