[ostree] libotutil: Add ot_gpgme_ctx_tmp_home_dir()
- From: Matthew Barnes <mbarnes src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [ostree] libotutil: Add ot_gpgme_ctx_tmp_home_dir()
- Date: Fri, 1 May 2015 18:43:06 +0000 (UTC)
commit 97379ec38c7de6144089372c16a875e209eb4c2c
Author: Matthew Barnes <mbarnes redhat com>
Date: Sun Apr 26 21:25:35 2015 -0400
libotutil: Add ot_gpgme_ctx_tmp_home_dir()
Currently used for signature verification, will also be used for
importing GPG keys.
Makefile-tests.am | 2 +-
src/libostree/ostree-gpg-verifier.c | 167 +++++++++--------------------------
src/libotutil/ot-gpg-utils.c | 83 +++++++++++++++++
src/libotutil/ot-gpg-utils.h | 7 ++
4 files changed, 133 insertions(+), 126 deletions(-)
---
diff --git a/Makefile-tests.am b/Makefile-tests.am
index 46bf499..c697333 100644
--- a/Makefile-tests.am
+++ b/Makefile-tests.am
@@ -116,7 +116,7 @@ check_PROGRAMS = $(TESTS)
TESTS_ENVIRONMENT = \
G_TEST_SRCDIR=$(abs_srcdir)/tests \
G_TEST_BUILDDIR=$(abs_builddir)/tests
-TESTS_CFLAGS = $(ostree_bin_shared_cflags) $(OT_INTERNAL_GIO_UNIX_CFLAGS)
+TESTS_CFLAGS = $(ostree_bin_shared_cflags) $(OT_INTERNAL_GIO_UNIX_CFLAGS) -I$(srcdir)/libglnx
TESTS_LDADD = $(ostree_bin_shared_ldadd) $(OT_INTERNAL_GIO_UNIX_LIBS)
tests_test_rollsum_SOURCES = src/libostree/ostree-rollsum.c tests/test-rollsum.c
diff --git a/src/libostree/ostree-gpg-verifier.c b/src/libostree/ostree-gpg-verifier.c
index 17282a9..96ca7c6 100644
--- a/src/libostree/ostree-gpg-verifier.c
+++ b/src/libostree/ostree-gpg-verifier.c
@@ -104,120 +104,17 @@ _ostree_gpg_verifier_initable_iface_init (GInitableIface *iface)
iface->init = ostree_gpg_verifier_initable_init;
}
-static gboolean
-concatenate_keyrings (OstreeGpgVerifier *self,
- GFile *destination,
- GCancellable *cancellable,
- GError **error)
-{
- gs_unref_object GOutputStream *target_stream = NULL;
- GList *link;
- gboolean ret = FALSE;
-
- target_stream = (GOutputStream *) g_file_replace (destination,
- NULL, /* no etag */
- FALSE, /* no backup */
- G_FILE_CREATE_NONE,
- cancellable, error);
- if (target_stream == NULL)
- goto out;
-
- for (link = self->keyrings; link != NULL; link = link->next)
- {
- gs_unref_object GInputStream *source_stream = NULL;
- GFile *keyring_file = link->data;
- gssize bytes_written;
- GError *local_error = NULL;
-
- source_stream = (GInputStream *) g_file_read (keyring_file, cancellable, &local_error);
-
- /* Disregard non-existent keyrings. */
- if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
- {
- g_clear_error (&local_error);
- continue;
- }
- else if (local_error != NULL)
- {
- g_propagate_error (error, local_error);
- goto out;
- }
-
- bytes_written = g_output_stream_splice (target_stream,
- source_stream,
- G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE,
- cancellable, error);
- if (bytes_written == -1)
- goto out;
- }
-
- if (!g_output_stream_close (target_stream, cancellable, error))
- goto out;
-
- ret = TRUE;
-
-out:
- return ret;
-}
-
-static gboolean
-override_gpgme_home_dir (gpgme_ctx_t gpg_ctx,
- const char *home_dir,
- GError **error)
-{
- gpgme_engine_info_t gpg_engine_info;
- gboolean ret = FALSE;
-
- /* Override the OpenPGP engine's configuration directory without
- * affecting other parameters. This requires finding the current
- * parameters since the engine API takes all parameters at once. */
-
- for (gpg_engine_info = gpgme_ctx_get_engine_info (gpg_ctx);
- gpg_engine_info != NULL;
- gpg_engine_info = gpg_engine_info->next)
- {
- if (gpg_engine_info->protocol == GPGME_PROTOCOL_OpenPGP)
- {
- gpgme_error_t gpg_error;
-
- gpg_error = gpgme_ctx_set_engine_info (gpg_ctx,
- gpg_engine_info->protocol,
- gpg_engine_info->file_name,
- home_dir);
- if (gpg_error != GPG_ERR_NO_ERROR)
- {
- ot_gpgme_error_to_gio_error (gpg_error, error);
- goto out;
- }
-
- break;
- }
- }
-
- if (gpg_engine_info == NULL)
- {
- g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "GPGME: No OpenPGP engine available");
- goto out;
- }
-
- ret = TRUE;
-
-out:
- return ret;
-}
-
static void
verify_result_finalized_cb (gpointer data,
GObject *finalized_verify_result)
{
- g_autofree gchar *temp_dir = data; /* assume ownership */
+ g_autofree gchar *tmp_dir = data; /* assume ownership */
/* XXX OstreeGpgVerifyResult could do this cleanup in its own
* finalize() method, but I didn't want this keyring hack
* bleeding into multiple classes. */
- (void) glnx_shutil_rm_rf_at (AT_FDCWD, temp_dir, NULL, NULL);
+ (void) glnx_shutil_rm_rf_at (AT_FDCWD, tmp_dir, NULL, NULL);
}
OstreeGpgVerifyResult *
@@ -231,11 +128,11 @@ _ostree_gpg_verifier_check_signature (OstreeGpgVerifier *self,
gpgme_error_t gpg_error = NULL;
gpgme_data_t data_buffer = NULL;
gpgme_data_t signature_buffer = NULL;
- gs_unref_object GFile *pubring_file = NULL;
- gs_free char *pubring_path = NULL;
- gs_free char *temp_dir = NULL;
+ g_autofree char *tmp_dir = NULL;
+ glnx_unref_object GOutputStream *target_stream = NULL;
OstreeGpgVerifyResult *result = NULL;
gboolean success = FALSE;
+ GList *link;
/* GPGME has no API for using multiple keyrings (aka, gpg --keyring),
* so we concatenate all the keyring files into one pubring.gpg in a
@@ -245,26 +142,46 @@ _ostree_gpg_verifier_check_signature (OstreeGpgVerifier *self,
if (g_cancellable_set_error_if_cancelled (cancellable, error))
goto out;
- temp_dir = g_build_filename (g_get_tmp_dir (), "ostree-gpg-XXXXXX", NULL);
+ result = g_initable_new (OSTREE_TYPE_GPG_VERIFY_RESULT,
+ cancellable, error, NULL);
+ if (result == NULL)
+ goto out;
+
+ if (!ot_gpgme_ctx_tmp_home_dir (result->context, NULL,
+ &tmp_dir, &target_stream,
+ cancellable, error))
+ goto out;
- if (mkdtemp (temp_dir) == NULL)
+ for (link = self->keyrings; link != NULL; link = link->next)
{
- gs_set_error_from_errno (error, errno);
- goto out;
- }
+ glnx_unref_object GFileInputStream *source_stream = NULL;
+ GFile *keyring_file = link->data;
+ gssize bytes_written;
+ GError *local_error = NULL;
- pubring_path = g_build_filename (temp_dir, "pubring.gpg", NULL);
+ source_stream = g_file_read (keyring_file, cancellable, &local_error);
- pubring_file = g_file_new_for_path (pubring_path);
- if (!concatenate_keyrings (self, pubring_file, cancellable, error))
- goto out;
+ /* Disregard non-existent keyrings. */
+ if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))
+ {
+ g_clear_error (&local_error);
+ continue;
+ }
+ else if (local_error != NULL)
+ {
+ g_propagate_error (error, local_error);
+ goto out;
+ }
- result = g_initable_new (OSTREE_TYPE_GPG_VERIFY_RESULT,
- cancellable, error, NULL);
- if (result == NULL)
- goto out;
+ bytes_written = g_output_stream_splice (target_stream,
+ G_INPUT_STREAM (source_stream),
+ G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE,
+ cancellable, error);
+ if (bytes_written < 0)
+ goto out;
+ }
- if (!override_gpgme_home_dir (result->context, temp_dir, error))
+ if (!g_output_stream_close (target_stream, cancellable, error))
goto out;
/* Both the signed data and signature GBytes instances will outlive the
@@ -325,7 +242,7 @@ out:
* the fabricated pubring.gpg keyring. */
g_object_weak_ref (G_OBJECT (result),
verify_result_finalized_cb,
- g_strdup (temp_dir));
+ g_strdup (tmp_dir));
}
else
{
@@ -333,8 +250,8 @@ out:
g_clear_object (&result);
/* Try to clean up the temporary directory. */
- if (temp_dir != NULL)
- (void) glnx_shutil_rm_rf_at (AT_FDCWD, temp_dir, NULL, NULL);
+ if (tmp_dir != NULL)
+ (void) glnx_shutil_rm_rf_at (AT_FDCWD, tmp_dir, NULL, NULL);
}
g_prefix_error (error, "GPG: ");
diff --git a/src/libotutil/ot-gpg-utils.c b/src/libotutil/ot-gpg-utils.c
index d1e2a9f..959f0f4 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;
+}
diff --git a/src/libotutil/ot-gpg-utils.h b/src/libotutil/ot-gpg-utils.h
index 1ec9e9e..0a67070 100644
--- a/src/libotutil/ot-gpg-utils.h
+++ b/src/libotutil/ot-gpg-utils.h
@@ -27,4 +27,11 @@ G_BEGIN_DECLS
void ot_gpgme_error_to_gio_error (gpgme_error_t gpg_error, GError **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_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]