From: Michael Tremer Date: Wed, 7 Jul 2021 17:39:09 +0000 (+0000) Subject: key: Refactor listing all keys X-Git-Tag: 0.9.28~1088 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=56f34ab4f082dce236e28b01d92f357ecb70def6;p=pakfire.git key: Refactor listing all keys Signed-off-by: Michael Tremer --- diff --git a/src/_pakfire/pakfire.c b/src/_pakfire/pakfire.c index a3e307980..d38cebb68 100644 --- a/src/_pakfire/pakfire.c +++ b/src/_pakfire/pakfire.c @@ -425,8 +425,15 @@ static PyObject* _import_keylist(PakfireObject* pakfire, struct pakfire_key** ke } static PyObject* Pakfire_get_keys(PakfireObject* self) { - struct pakfire_key** keys = pakfire_key_list(self->pakfire); + struct pakfire_key** keys = NULL; + int r = pakfire_list_keys(self->pakfire, &keys); + if (r) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + +#warning THIS LEAKS MEMORY return _import_keylist(self, keys); } diff --git a/src/libpakfire/include/pakfire/key.h b/src/libpakfire/include/pakfire/key.h index 9c3a4908d..4a93e31fe 100644 --- a/src/libpakfire/include/pakfire/key.h +++ b/src/libpakfire/include/pakfire/key.h @@ -32,8 +32,6 @@ typedef enum pakfire_key_export_mode { PAKFIRE_KEY_EXPORT_MODE_SECRET, } pakfire_key_export_mode_t; -struct pakfire_key** pakfire_key_list(Pakfire pakfire); - struct pakfire_key* pakfire_key_ref(struct pakfire_key* key); void pakfire_key_unref(struct pakfire_key* key); diff --git a/src/libpakfire/include/pakfire/pakfire.h b/src/libpakfire/include/pakfire/pakfire.h index d519bc961..88e74031b 100644 --- a/src/libpakfire/include/pakfire/pakfire.h +++ b/src/libpakfire/include/pakfire/pakfire.h @@ -27,6 +27,7 @@ #include #include +#include #include #include #include @@ -57,6 +58,8 @@ int pakfire_refresh(Pakfire pakfire, int flags); int pakfire_bind(Pakfire pakfire, const char* src, const char* dst, int flags); +int pakfire_list_keys(Pakfire pakfire, struct pakfire_key*** keys); + int pakfire_copy_in(Pakfire pakfire, const char* src, const char* dst); int pakfire_copy_out(Pakfire pakfire, const char* src, const char* dst); diff --git a/src/libpakfire/key.c b/src/libpakfire/key.c index ced2c7af5..7fc758640 100644 --- a/src/libpakfire/key.c +++ b/src/libpakfire/key.c @@ -43,61 +43,6 @@ struct pakfire_key { gpgme_key_t gpgkey; }; -static size_t pakfire_count_keys(Pakfire pakfire) { - gpgme_ctx_t gpgctx = pakfire_get_gpgctx(pakfire); - - size_t count = 0; - - gpgme_key_t key = NULL; - gpgme_error_t error = gpgme_op_keylist_start(gpgctx, NULL, 0); - while (!error) { - error = gpgme_op_keylist_next(gpgctx, &key); - if (error) - break; - - count++; - - gpgme_key_release(key); - } - - DEBUG(pakfire, "%zu key(s) in keystore\n", count); - - return count; -} - -PAKFIRE_EXPORT struct pakfire_key** pakfire_key_list(Pakfire pakfire) { - size_t count = pakfire_count_keys(pakfire); - if (count == 0) - return NULL; - - struct pakfire_key* key = NULL; - - gpgme_ctx_t gpgctx = pakfire_get_gpgctx(pakfire); - - struct pakfire_key** first = calloc(count + 1, sizeof(struct pakfire_key*)); - struct pakfire_key** list = first; - - gpgme_key_t gpgkey = NULL; - gpgme_error_t error = gpgme_op_keylist_start(gpgctx, NULL, 0); - while (!error) { - error = gpgme_op_keylist_next(gpgctx, &gpgkey); - if (error) - break; - - pakfire_key_create(&key, pakfire, gpgkey); - - // Add key to the list - *list++ = key; - - gpgme_key_release(gpgkey); - } - - // Last list item must be NULL - *list = NULL; - - return first; -} - int pakfire_key_create(struct pakfire_key** key, Pakfire pakfire, gpgme_key_t gpgkey) { struct pakfire_key* k = calloc(1, sizeof(*k)); if (!k) diff --git a/src/libpakfire/libpakfire.sym b/src/libpakfire/libpakfire.sym index 3f3e6a04e..a2b5b8630 100644 --- a/src/libpakfire/libpakfire.sym +++ b/src/libpakfire/libpakfire.sym @@ -36,6 +36,7 @@ global: pakfire_get_repo; pakfire_get_repos; pakfire_install; + pakfire_list_keys; pakfire_ref; pakfire_refresh; pakfire_search; @@ -121,7 +122,6 @@ global: pakfire_key_get_uid; pakfire_key_import; pakfire_key_is_revoked; - pakfire_key_list; pakfire_key_ref; pakfire_key_unref; diff --git a/src/libpakfire/pakfire.c b/src/libpakfire/pakfire.c index 7b0026ec4..901044531 100644 --- a/src/libpakfire/pakfire.c +++ b/src/libpakfire/pakfire.c @@ -1136,6 +1136,64 @@ ERROR: return NULL; } +PAKFIRE_EXPORT int pakfire_list_keys(Pakfire pakfire, struct pakfire_key*** keys) { + // Reset keys + *keys = NULL; + + // Fetch GPGME context + gpgme_ctx_t gpgctx = pakfire_get_gpgctx(pakfire); + if (!gpgctx) + return 1; + + struct pakfire_key* key = NULL; + gpgme_key_t gpgkey = NULL; + size_t length = 0; + int r = 1; + + // Iterate over all keys and import them to the list + gpgme_error_t e = gpgme_op_keylist_start(gpgctx, NULL, 0); + if (e) + goto ERROR; + + while (!e) { + e = gpgme_op_keylist_next(gpgctx, &gpgkey); + if (e) + break; + + // Create key + r = pakfire_key_create(&key, pakfire, gpgkey); + gpgme_key_unref(gpgkey); + if (r) + goto ERROR; + + // Append to keys + *keys = reallocarray(*keys, length + 2, sizeof(**keys)); + if (!*keys) { + r = 1; + goto ERROR; + } + + // Store key in array + (*keys)[length++] = key; + + // Terminate the array + (*keys)[length] = NULL; + } + + // Done + return 0; + +ERROR: + if (*keys) { + for (struct pakfire_key** key = *keys; *key; key++) + pakfire_key_unref(*key); + free(*keys); + keys = NULL; + } + + return r; +} + static int pakfire_foreach_repo(Pakfire pakfire, int (*func)(struct pakfire_repo* repo, int flags), int flags) { struct pakfire_repo* repo; diff --git a/tests/libpakfire/key.c b/tests/libpakfire/key.c index b740dd07c..dc7970567 100644 --- a/tests/libpakfire/key.c +++ b/tests/libpakfire/key.c @@ -28,8 +28,10 @@ #include "key.h" static int test_init(const struct test* t) { + struct pakfire_key** keys = NULL; + // Try loading any keys & delete them all - struct pakfire_key** keys = pakfire_key_list(t->pakfire); + ASSERT_SUCCESS(pakfire_list_keys(t->pakfire, &keys)); while (keys && *keys) { struct pakfire_key* key = *keys++; @@ -38,7 +40,7 @@ static int test_init(const struct test* t) { } // Load list of keys again - keys = pakfire_key_list(t->pakfire); + ASSERT_SUCCESS(pakfire_list_keys(t->pakfire, &keys)); // Must be empty now ASSERT(keys == NULL);