From: Michael Tremer Date: Wed, 7 Jul 2021 17:14:57 +0000 (+0000) Subject: key: Move GPGME context into Pakfire object X-Git-Tag: 0.9.28~1090 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b3727f625ae724cabefe8463afa62919de92ceaf;p=pakfire.git key: Move GPGME context into Pakfire object Signed-off-by: Michael Tremer --- diff --git a/src/libpakfire/include/pakfire/key.h b/src/libpakfire/include/pakfire/key.h index f9d73d03b..60a2dc9a4 100644 --- a/src/libpakfire/include/pakfire/key.h +++ b/src/libpakfire/include/pakfire/key.h @@ -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 */ diff --git a/src/libpakfire/include/pakfire/pakfire.h b/src/libpakfire/include/pakfire/pakfire.h index d30b018ec..d519bc961 100644 --- a/src/libpakfire/include/pakfire/pakfire.h +++ b/src/libpakfire/include/pakfire/pakfire.h @@ -105,6 +105,7 @@ int pakfire_sync(Pakfire pakfire, int solver_flags, int flags, int* changed); #ifdef PAKFIRE_PRIVATE +#include #include #include @@ -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); diff --git a/src/libpakfire/key.c b/src/libpakfire/key.c index 9ac9d0a55..60d70d680 100644 --- a/src/libpakfire/key.c +++ b/src/libpakfire/key.c @@ -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; } diff --git a/src/libpakfire/pakfire.c b/src/libpakfire/pakfire.c index 56c865db1..7b0026ec4 100644 --- a/src/libpakfire/pakfire.c +++ b/src/libpakfire/pakfire.c @@ -35,6 +35,7 @@ #include #include +#include #include #include #include @@ -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;