summaryrefslogtreecommitdiff
path: root/src/libotutil/ot-gpg-utils.c
diff options
context:
space:
mode:
authorMatthew Barnes <mbarnes@redhat.com>2015-04-26 21:25:35 -0400
committerMatthew Barnes <mbarnes@redhat.com>2015-05-01 10:21:40 -0400
commit97379ec38c7de6144089372c16a875e209eb4c2c (patch)
treea4c4955b9301d37d48896aa41e6f8d4bb90ab034 /src/libotutil/ot-gpg-utils.c
parentceacc5720647a4d1661889431786c267153d536c (diff)
downloadostree-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.c83
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;
+}