]> git.ipfire.org Git - people/stevee/pakfire.git/commitdiff
key: Move GPGME context into Pakfire object
authorMichael Tremer <michael.tremer@ipfire.org>
Wed, 7 Jul 2021 17:14:57 +0000 (17:14 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Wed, 7 Jul 2021 17:14:57 +0000 (17:14 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libpakfire/include/pakfire/key.h
src/libpakfire/include/pakfire/pakfire.h
src/libpakfire/key.c
src/libpakfire/pakfire.c

index f9d73d03b0cfa7498d1543e6d268c403756b857d..60a2dc9a4e7c5b97c720d8d8457dcbe2a56ee8d2 100644 (file)
@@ -59,10 +59,4 @@ struct pakfire_key** pakfire_key_import(Pakfire pakfire, const char* data);
 
 char* pakfire_key_dump(struct pakfire_key* key);
 
-#ifdef PAKFIRE_PRIVATE
-
-gpgme_ctx_t pakfire_get_gpgctx(Pakfire pakfire);
-
-#endif
-
 #endif /* PAKFIRE_KEY_H */
index d30b018ec4700804792a87ec974866dd7e06816f..d519bc961bc23807d4593aad7ca9bc590d6badef 100644 (file)
@@ -105,6 +105,7 @@ int pakfire_sync(Pakfire pakfire, int solver_flags, int flags, int* changed);
 
 #ifdef PAKFIRE_PRIVATE
 
+#include <gpgme.h>
 #include <solv/pool.h>
 
 #include <pakfire/config.h>
@@ -120,6 +121,8 @@ int pakfire_has_flag(Pakfire pakfire, int flag);
 struct pakfire_config* pakfire_get_config(Pakfire pakfire);
 int pakfire_is_mountpoint(Pakfire pakfire, const char* path);
 
+gpgme_ctx_t pakfire_get_gpgctx(Pakfire pakfire);
+
 const char* pakfire_get_distro_name(Pakfire pakfire);
 const char* pakfire_get_distro_id(Pakfire pakfire);
 const char* pakfire_get_distro_vendor(Pakfire pakfire);
index 9ac9d0a55b351680f7897414252accea04a8b929..60d70d680afe8afb710ae0c9b5660421ab3d3021 100644 (file)
@@ -36,7 +36,6 @@
 
 #define DEFAULT_KEY_SIZE "rsa4096"
 
-
 struct pakfire_key {
        Pakfire pakfire;
        int nrefs;
@@ -44,70 +43,6 @@ struct pakfire_key {
        gpgme_key_t gpgkey;
 };
 
-gpgme_ctx_t pakfire_get_gpgctx(Pakfire pakfire) {
-       static int gpg_initialized = 0;
-       gpgme_error_t error;
-       const char* error_string;
-
-       if (!gpg_initialized) {
-               // Initialise gpgme
-               const char* version = gpgme_check_version(NULL);
-               DEBUG(pakfire, "Loaded gpgme %s\n", version);
-
-               // Check if we support GPG
-               error = gpgme_engine_check_version(GPGME_PROTOCOL_OpenPGP);
-               if (gpg_err_code(error) != GPG_ERR_NO_ERROR)
-                       goto FAIL;
-
-               // GPG has been initialized
-               gpg_initialized++;
-       }
-
-       // Create a new context
-       gpgme_ctx_t ctx;
-       error = gpgme_new(&ctx);
-       if (gpg_err_code(error) != GPG_ERR_NO_ERROR)
-               goto FAIL;
-
-       // Set output to be ASCII armoured
-       gpgme_set_armor(ctx, 1);
-
-       char home[PATH_MAX];
-
-       // Use GPG
-       const char* path = pakfire_get_path(pakfire);
-       int r = pakfire_path_join(home, path, "etc/pakfire/gnupg");
-       if (r < 0)
-               goto FAIL;
-
-       DEBUG(pakfire, "Using GPG database at %s\n", home);
-
-       r = pakfire_mkdir(home, S_IRUSR|S_IWUSR|S_IXUSR);
-       if (r && errno != EEXIST) {
-               ERROR(pakfire, "Could not initialize the GPG database at %s\n", home);
-               goto FAIL;
-       }
-
-       // Setup engine
-       error = gpgme_ctx_set_engine_info(ctx, GPGME_PROTOCOL_OpenPGP, NULL, home);
-       if (gpg_err_code(error) != GPG_ERR_NO_ERROR)
-               goto FAIL;
-
-       gpgme_engine_info_t engine_info = gpgme_ctx_get_engine_info(ctx);
-       DEBUG(pakfire, "GPGME engine info: %s, home = %s\n",
-               engine_info->file_name, engine_info->home_dir);
-
-       return ctx;
-
-FAIL:
-       gpgme_release(ctx);
-
-       error_string = gpgme_strerror(error);
-       ERROR(pakfire, "%s\n", error_string);
-
-       return NULL;
-}
-
 static size_t pakfire_count_keys(Pakfire pakfire) {
        gpgme_ctx_t gpgctx = pakfire_get_gpgctx(pakfire);
 
@@ -126,7 +61,6 @@ static size_t pakfire_count_keys(Pakfire pakfire) {
        }
 
        DEBUG(pakfire, "%zu key(s) in keystore\n", count);
-       gpgme_release(gpgctx);
 
        return count;
 }
@@ -157,8 +91,6 @@ PAKFIRE_EXPORT struct pakfire_key** pakfire_key_list(Pakfire pakfire) {
        // Last list item must be NULL
        *list = NULL;
 
-       gpgme_release(gpgctx);
-
        return first;
 }
 
@@ -224,10 +156,7 @@ static struct pakfire_key* __pakfire_get_key(Pakfire pakfire, gpgme_ctx_t gpgctx
 PAKFIRE_EXPORT struct pakfire_key* pakfire_key_get(Pakfire pakfire, const char* fingerprint) {
        gpgme_ctx_t gpgctx = pakfire_get_gpgctx(pakfire);
 
-       struct pakfire_key* key = __pakfire_get_key(pakfire, gpgctx, fingerprint);
-       gpgme_release(gpgctx);
-
-       return key;
+       return __pakfire_get_key(pakfire, gpgctx, fingerprint);
 }
 
 PAKFIRE_EXPORT int pakfire_key_delete(struct pakfire_key* key) {
@@ -238,8 +167,6 @@ PAKFIRE_EXPORT int pakfire_key_delete(struct pakfire_key* key) {
        if (error != GPG_ERR_NO_ERROR)
                r = 1;
 
-       gpgme_release(gpgctx);
-
        return r;
 }
 
@@ -330,7 +257,6 @@ PAKFIRE_EXPORT struct pakfire_key* pakfire_key_generate(Pakfire pakfire, const c
 
        // Retrieve the result
        gpgme_genkey_result_t result = gpgme_op_genkey_result(gpgctx);
-       gpgme_release(gpgctx);
 
        // Retrieve the key by its fingerprint
        return pakfire_key_get(pakfire, result->fpr);
@@ -370,7 +296,6 @@ PAKFIRE_EXPORT char* pakfire_key_export(struct pakfire_key* key, pakfire_key_exp
        // Export key in ASCII format
        size_t length;
        char* mem = gpgme_data_release_and_get_mem(keydata, &length);
-       gpgme_release(gpgctx);
 
        // Terminate the string
        mem[length] = '\0';
@@ -385,7 +310,6 @@ PAKFIRE_EXPORT char* pakfire_key_export(struct pakfire_key* key, pakfire_key_exp
 
 FAIL:
        gpgme_data_release(keydata);
-       gpgme_release(gpgctx);
 
        return NULL;
 }
@@ -440,7 +364,6 @@ PAKFIRE_EXPORT struct pakfire_key** pakfire_key_import(Pakfire pakfire, const ch
                        *list = NULL;
 
                        gpgme_data_release(keydata);
-                       gpgme_release(gpgctx);
 
                        return head;
 
@@ -457,7 +380,6 @@ PAKFIRE_EXPORT struct pakfire_key** pakfire_key_import(Pakfire pakfire, const ch
 
 FAIL:
        gpgme_data_release(keydata);
-       gpgme_release(gpgctx);
 
        return NULL;
 }
index 56c865db1dc17be53c33bbefc4c2d59e5d51ebcf..7b0026ec4980fa1fe2c597752eaee9882e80713f 100644 (file)
@@ -35,6 +35,7 @@
 
 #include <archive.h>
 #include <archive_entry.h>
+#include <gpgme.h>
 #include <solv/evr.h>
 #include <solv/pool.h>
 #include <solv/poolarch.h>
@@ -98,6 +99,9 @@ struct _Pakfire {
                char version_codename[32];
                char version_id[8];
        } distro;
+
+       // GPG Context
+       gpgme_ctx_t gpgctx;
 };
 
 /*
@@ -490,6 +494,10 @@ static int pakfire_mount_interpreter(Pakfire pakfire) {
 }
 
 static void pakfire_free(Pakfire pakfire) {
+       // Release GPGME context
+       if (pakfire->gpgctx)
+               gpgme_release(pakfire->gpgctx);
+
        // umount everything
        pakfire_umount(pakfire);
 
@@ -1054,6 +1062,80 @@ PAKFIRE_EXPORT int pakfire_bind(Pakfire pakfire, const char* src, const char* ds
        return __mount(pakfire, src, mountpoint, NULL, flags|MS_BIND, NULL);
 }
 
+static int pakfire_init_gpgme(Pakfire pakfire) {
+       static int gpgme_initialized = 0;
+
+       // Do nothing if gpgme is already initialized
+       if (gpgme_initialized)
+               return 0;
+
+       // Initialize gpgme
+       const char* version = gpgme_check_version(NULL);
+       DEBUG(pakfire, "Loaded gpgme %s\n", version);
+
+       // Check if we support OpenPGP
+       gpgme_error_t error = gpgme_engine_check_version(GPGME_PROTOCOL_OpenPGP);
+       if (gpg_err_code(error) != GPG_ERR_NO_ERROR) {
+               ERROR(pakfire, "GPGME does not support OpenPGP\n");
+               errno = ENOTSUP;
+               return 1;
+       }
+
+       // Success
+       gpgme_initialized = 1;
+       return 0;
+}
+
+gpgme_ctx_t pakfire_get_gpgctx(Pakfire pakfire) {
+       int r = pakfire_init_gpgme(pakfire);
+       if (r)
+               return NULL;
+
+       char path[PATH_MAX];
+
+       // Create a new context if not done, yet
+       if (!pakfire->gpgctx) {
+               gpgme_error_t error = gpgme_new(&pakfire->gpgctx);
+               if (gpg_err_code(error) != GPG_ERR_NO_ERROR)
+                       goto ERROR;
+
+               // Set output to be ASCII armoured
+               gpgme_set_armor(pakfire->gpgctx, 1);
+
+               // Set home
+               r = pakfire_make_path(pakfire, path, "/etc/pakfire/gnupg");
+               if (r < 0)
+                       goto ERROR;
+
+               DEBUG(pakfire, "Using PGP database at %s\n", path);
+
+               // Create home
+               r = pakfire_mkdir(path, S_IRUSR|S_IWUSR|S_IXUSR);
+               if (r && errno != EEXIST) {
+                       ERROR(pakfire, "Could not initialize the PGP database at %s: %m\n", path);
+                       goto ERROR;
+               }
+
+               // Setup engine
+               error = gpgme_ctx_set_engine_info(pakfire->gpgctx, GPGME_PROTOCOL_OpenPGP, NULL, path);
+               if (gpg_err_code(error) != GPG_ERR_NO_ERROR)
+                       goto ERROR;
+
+               // Show engine status
+               gpgme_engine_info_t engine_info = gpgme_ctx_get_engine_info(pakfire->gpgctx);
+               DEBUG(pakfire, "GPGME engine info: %s, path = %s\n",
+                       engine_info->file_name, engine_info->home_dir);
+       }
+
+       return pakfire->gpgctx;
+
+ERROR:
+       gpgme_release(pakfire->gpgctx);
+       pakfire->gpgctx = NULL;
+
+       return NULL;
+}
+
 static int pakfire_foreach_repo(Pakfire pakfire,
                int (*func)(struct pakfire_repo* repo, int flags), int flags) {
        struct pakfire_repo* repo;