diff options
author | Matthew Barnes <mbarnes@redhat.com> | 2015-04-26 21:25:35 -0400 |
---|---|---|
committer | Matthew Barnes <mbarnes@redhat.com> | 2015-05-01 10:21:40 -0400 |
commit | 97379ec38c7de6144089372c16a875e209eb4c2c (patch) | |
tree | a4c4955b9301d37d48896aa41e6f8d4bb90ab034 /src/libotutil/ot-gpg-utils.c | |
parent | ceacc5720647a4d1661889431786c267153d536c (diff) | |
download | ostree-97379ec38c7de6144089372c16a875e209eb4c2c.tar.gz |
libotutil: Add ot_gpgme_ctx_tmp_home_dir()
Currently used for signature verification, will also be used for
importing GPG keys.
Diffstat (limited to 'src/libotutil/ot-gpg-utils.c')
-rw-r--r-- | src/libotutil/ot-gpg-utils.c | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/src/libotutil/ot-gpg-utils.c b/src/libotutil/ot-gpg-utils.c index d1e2a9f8..959f0f41 100644 --- a/src/libotutil/ot-gpg-utils.c +++ b/src/libotutil/ot-gpg-utils.c @@ -22,6 +22,10 @@ #include "ot-gpg-utils.h" +#include <stdlib.h> + +#include "libglnx.h" + void ot_gpgme_error_to_gio_error (gpgme_error_t gpg_error, GError **error) @@ -55,3 +59,82 @@ ot_gpgme_error_to_gio_error (gpgme_error_t gpg_error, gpgme_strsource (gpg_error), gpgme_strerror (gpg_error)); } + +gboolean +ot_gpgme_ctx_tmp_home_dir (gpgme_ctx_t gpgme_ctx, + const char *tmp_dir, + char **out_tmp_home_dir, + GOutputStream **out_pubring_stream, + GCancellable *cancellable, + GError **error) +{ + g_autoptr(GFile) pubring_file = NULL; + g_autoptr(GOutputStream) target_stream = NULL; + g_autofree char *pubring_path = NULL; + g_autofree char *tmp_home_dir = NULL; + gpgme_error_t gpg_error; + gboolean ret = FALSE; + + g_return_val_if_fail (gpgme_ctx != NULL, FALSE); + + /* GPGME has no API for using multiple keyrings (aka, gpg --keyring), + * so we create a temporary directory and tell GPGME to use it as the + * home directory. Then (optionally) create a pubring.gpg file there + * and hand the caller an open output stream to concatenate necessary + * keyring files. */ + + if (tmp_dir == NULL) + tmp_dir = g_get_tmp_dir (); + + tmp_home_dir = g_build_filename (tmp_dir, "ostree-gpg-XXXXXX", NULL); + + if (mkdtemp (tmp_home_dir) == NULL) + { + glnx_set_error_from_errno (error); + goto out; + } + + /* Not documented, but gpgme_ctx_set_engine_info() accepts NULL for + * the executable file name, which leaves the old setting unchanged. */ + gpg_error = gpgme_ctx_set_engine_info (gpgme_ctx, + GPGME_PROTOCOL_OpenPGP, + NULL, tmp_home_dir); + if (gpg_error != GPG_ERR_NO_ERROR) + { + ot_gpgme_error_to_gio_error (gpg_error, error); + goto out; + } + + if (out_pubring_stream != NULL) + { + GFileOutputStream *pubring_stream; + glnx_unref_object GFile *pubring_file = NULL; + g_autofree char *pubring_path = NULL; + + pubring_path = g_build_filename (tmp_home_dir, "pubring.gpg", NULL); + pubring_file = g_file_new_for_path (pubring_path); + + pubring_stream = g_file_create (pubring_file, + G_FILE_CREATE_NONE, + cancellable, error); + if (pubring_stream == NULL) + goto out; + + /* Sneaky cast from GFileOutputStream to GOutputStream. */ + *out_pubring_stream = g_steal_pointer (&pubring_stream); + } + + if (out_tmp_home_dir != NULL) + *out_tmp_home_dir = g_steal_pointer (&tmp_home_dir); + + ret = TRUE; + +out: + if (!ret) + { + /* Clean up our mess on error. */ + (void) glnx_shutil_rm_rf_at (AT_FDCWD, tmp_home_dir, NULL, NULL); + } + + return ret; +} |