summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/xdg-app-builtins-install.c17
-rw-r--r--common/xdg-app-dir.c109
-rw-r--r--common/xdg-app-dir.h7
-rw-r--r--common/xdg-app-utils.c105
-rw-r--r--common/xdg-app-utils.h8
-rw-r--r--lib/xdg-app-installation.c17
6 files changed, 133 insertions, 130 deletions
diff --git a/app/xdg-app-builtins-install.c b/app/xdg-app-builtins-install.c
index e8634a6..66aaf1d 100644
--- a/app/xdg-app-builtins-install.c
+++ b/app/xdg-app-builtins-install.c
@@ -171,13 +171,16 @@ install_bundle (XdgAppDir *dir,
/* From here we need to goto out on error, to clean up */
added_remote = TRUE;
- if (!xdg_app_dir_pull_from_bundle (dir,
- file,
- remote,
- ref,
- gpg_data != NULL,
- cancellable,
- error))
+ if (!xdg_app_dir_ensure_repo (dir, cancellable, error))
+ goto out;
+
+ if (!xdg_app_pull_from_bundle (xdg_app_dir_get_repo (dir),
+ file,
+ remote,
+ ref,
+ gpg_data != NULL,
+ cancellable,
+ error))
goto out;
if (!xdg_app_dir_lock (dir, &lock,
diff --git a/common/xdg-app-dir.c b/common/xdg-app-dir.c
index 8b97437..f0571ab 100644
--- a/common/xdg-app-dir.c
+++ b/common/xdg-app-dir.c
@@ -995,115 +995,6 @@ xdg_app_dir_pull (XdgAppDir *self,
return ret;
}
-gboolean
-xdg_app_dir_pull_from_bundle (XdgAppDir *self,
- GFile *file,
- const char *remote,
- const char *ref,
- gboolean require_gpg_signature,
- GCancellable *cancellable,
- GError **error)
-{
- g_autofree char *metadata_contents = NULL;
- g_autofree char *to_checksum = NULL;
- g_autoptr(GFile) root = NULL;
- g_autoptr(GFile) metadata_file = NULL;
- g_autoptr(GInputStream) in = NULL;
- g_autoptr(OstreeGpgVerifyResult) gpg_result = NULL;
- g_autoptr(GError) my_error = NULL;
- g_autoptr(GVariant) metadata = NULL;
- gboolean metadata_valid;
-
- if (!xdg_app_dir_ensure_repo (self, cancellable, error))
- return FALSE;
-
- if (!xdg_app_supports_bundles (self->repo))
- return xdg_app_fail (error, "Your version of ostree is too old to support single-file bundles");
-
- metadata = xdg_app_bundle_load (file, &to_checksum, NULL, NULL, NULL, NULL, error);
- if (metadata == NULL)
- return FALSE;
-
- g_variant_lookup (metadata, "metadata", "s", &metadata_contents);
-
- if (!ostree_repo_prepare_transaction (self->repo, NULL, cancellable, error))
- return FALSE;
-
- ostree_repo_transaction_set_ref (self->repo, remote, ref, to_checksum);
-
- if (!ostree_repo_static_delta_execute_offline (self->repo,
- file,
- FALSE,
- cancellable,
- error))
- return FALSE;
-
- gpg_result = ostree_repo_verify_commit_ext (self->repo, to_checksum,
- NULL, NULL, cancellable, &my_error);
- if (gpg_result == NULL)
- {
- /* NOT_FOUND means no gpg signature, we ignore this *if* there
- * is no gpg key specified in the bundle or by the user */
- if (g_error_matches (my_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND) &&
- !require_gpg_signature)
- g_clear_error (&my_error);
- else
- {
- g_propagate_error (error, g_steal_pointer (&my_error));
- return FALSE;
- }
- }
- else
- {
- /* If there is no valid gpg signature we fail, unless there is no gpg
- key specified (on the command line or in the file) because then we
- trust the source bundle. */
- if (ostree_gpg_verify_result_count_valid (gpg_result) == 0 &&
- require_gpg_signature)
- return xdg_app_fail (error, "GPG signatures found, but none are in trusted keyring");
- }
-
- if (!ostree_repo_read_commit (self->repo, to_checksum, &root, NULL, NULL, error))
- return FALSE;
-
- if (!ostree_repo_commit_transaction (self->repo, NULL, cancellable, error))
- return FALSE;
-
- /* We ensure that the actual installed metadata matches the one in the
- header, because you may have made decisions on wheter to install it or not
- based on that data. */
- metadata_file = g_file_resolve_relative_path (root, "metadata");
- in = (GInputStream*)g_file_read (metadata_file, cancellable, NULL);
- if (in != NULL)
- {
- g_autoptr(GMemoryOutputStream) data_stream = (GMemoryOutputStream*)g_memory_output_stream_new_resizable ();
-
- if (g_output_stream_splice (G_OUTPUT_STREAM (data_stream), in,
- G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE,
- cancellable, error) < 0)
- return FALSE;
-
- /* Null terminate */
- g_output_stream_write (G_OUTPUT_STREAM (data_stream), "\0", 1, NULL, NULL);
-
- metadata_valid =
- metadata_contents != NULL &&
- strcmp (metadata_contents, g_memory_output_stream_get_data (data_stream)) == 0;
- }
- else
- metadata_valid = (metadata_contents == NULL);
-
- if (!metadata_valid)
- {
- /* Immediately remove this broken commit */
- ostree_repo_set_ref_immediate (self->repo, remote, ref, NULL, cancellable, error);
- return xdg_app_fail (error, "Metadata in header and app are inconsistent");
- }
-
- return TRUE;
-}
-
-
char *
xdg_app_dir_current_ref (XdgAppDir *self,
const char *name,
diff --git a/common/xdg-app-dir.h b/common/xdg-app-dir.h
index 2816de1..7665fc7 100644
--- a/common/xdg-app-dir.h
+++ b/common/xdg-app-dir.h
@@ -157,13 +157,6 @@ gboolean xdg_app_dir_pull (XdgAppDir *self,
OstreeAsyncProgress *progress,
GCancellable *cancellable,
GError **error);
-gboolean xdg_app_dir_pull_from_bundle (XdgAppDir *self,
- GFile *file,
- const char *remote,
- const char *ref,
- gboolean require_gpg_signature,
- GCancellable *cancellable,
- GError **error);
gboolean xdg_app_dir_list_refs_for_name (XdgAppDir *self,
const char *kind,
const char *name,
diff --git a/common/xdg-app-utils.c b/common/xdg-app-utils.c
index 4406a56..cf055ed 100644
--- a/common/xdg-app-utils.c
+++ b/common/xdg-app-utils.c
@@ -2673,3 +2673,108 @@ xdg_app_bundle_load (GFile *file,
g_variant_get_size (metadata)),
FALSE);
}
+
+gboolean
+xdg_app_pull_from_bundle (OstreeRepo *repo,
+ GFile *file,
+ const char *remote,
+ const char *ref,
+ gboolean require_gpg_signature,
+ GCancellable *cancellable,
+ GError **error)
+{
+ g_autofree char *metadata_contents = NULL;
+ g_autofree char *to_checksum = NULL;
+ g_autoptr(GFile) root = NULL;
+ g_autoptr(GFile) metadata_file = NULL;
+ g_autoptr(GInputStream) in = NULL;
+ g_autoptr(OstreeGpgVerifyResult) gpg_result = NULL;
+ g_autoptr(GError) my_error = NULL;
+ g_autoptr(GVariant) metadata = NULL;
+ gboolean metadata_valid;
+
+ if (!xdg_app_supports_bundles (repo))
+ return xdg_app_fail (error, "Your version of ostree is too old to support single-file bundles");
+
+ metadata = xdg_app_bundle_load (file, &to_checksum, NULL, NULL, NULL, NULL, error);
+ if (metadata == NULL)
+ return FALSE;
+
+ g_variant_lookup (metadata, "metadata", "s", &metadata_contents);
+
+ if (!ostree_repo_prepare_transaction (repo, NULL, cancellable, error))
+ return FALSE;
+
+ ostree_repo_transaction_set_ref (repo, remote, ref, to_checksum);
+
+ if (!ostree_repo_static_delta_execute_offline (repo,
+ file,
+ FALSE,
+ cancellable,
+ error))
+ return FALSE;
+
+ gpg_result = ostree_repo_verify_commit_ext (repo, to_checksum,
+ NULL, NULL, cancellable, &my_error);
+ if (gpg_result == NULL)
+ {
+ /* NOT_FOUND means no gpg signature, we ignore this *if* there
+ * is no gpg key specified in the bundle or by the user */
+ if (g_error_matches (my_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND) &&
+ !require_gpg_signature)
+ g_clear_error (&my_error);
+ else
+ {
+ g_propagate_error (error, g_steal_pointer (&my_error));
+ return FALSE;
+ }
+ }
+ else
+ {
+ /* If there is no valid gpg signature we fail, unless there is no gpg
+ key specified (on the command line or in the file) because then we
+ trust the source bundle. */
+ if (ostree_gpg_verify_result_count_valid (gpg_result) == 0 &&
+ require_gpg_signature)
+ return xdg_app_fail (error, "GPG signatures found, but none are in trusted keyring");
+ }
+
+ if (!ostree_repo_read_commit (repo, to_checksum, &root, NULL, NULL, error))
+ return FALSE;
+
+ if (!ostree_repo_commit_transaction (repo, NULL, cancellable, error))
+ return FALSE;
+
+ /* We ensure that the actual installed metadata matches the one in the
+ header, because you may have made decisions on wheter to install it or not
+ based on that data. */
+ metadata_file = g_file_resolve_relative_path (root, "metadata");
+ in = (GInputStream*)g_file_read (metadata_file, cancellable, NULL);
+ if (in != NULL)
+ {
+ g_autoptr(GMemoryOutputStream) data_stream = (GMemoryOutputStream*)g_memory_output_stream_new_resizable ();
+
+ if (g_output_stream_splice (G_OUTPUT_STREAM (data_stream), in,
+ G_OUTPUT_STREAM_SPLICE_CLOSE_SOURCE,
+ cancellable, error) < 0)
+ return FALSE;
+
+ /* Null terminate */
+ g_output_stream_write (G_OUTPUT_STREAM (data_stream), "\0", 1, NULL, NULL);
+
+ metadata_valid =
+ metadata_contents != NULL &&
+ strcmp (metadata_contents, g_memory_output_stream_get_data (data_stream)) == 0;
+ }
+ else
+ metadata_valid = (metadata_contents == NULL);
+
+ if (!metadata_valid)
+ {
+ /* Immediately remove this broken commit */
+ ostree_repo_set_ref_immediate (repo, remote, ref, NULL, cancellable, error);
+ return xdg_app_fail (error, "Metadata in header and app are inconsistent");
+ }
+
+ return TRUE;
+}
diff --git a/common/xdg-app-utils.h b/common/xdg-app-utils.h
index 106627f..b1b7936 100644
--- a/common/xdg-app-utils.h
+++ b/common/xdg-app-utils.h
@@ -191,6 +191,14 @@ GVariant * xdg_app_bundle_load (GFile *file,
GBytes **gpg_keys,
GError **error);
+gboolean xdg_app_pull_from_bundle (OstreeRepo *repo,
+ GFile *file,
+ const char *remote,
+ const char *ref,
+ gboolean require_gpg_signature,
+ GCancellable *cancellable,
+ GError **error);
+
typedef struct {
char *id;
diff --git a/lib/xdg-app-installation.c b/lib/xdg-app-installation.c
index d97f7c0..c6ab372 100644
--- a/lib/xdg-app-installation.c
+++ b/lib/xdg-app-installation.c
@@ -868,13 +868,16 @@ xdg_app_installation_install_bundle (XdgAppInstallation *self,
/* Pull, prune, etc are not threadsafe, so we work on a copy */
dir_clone = xdg_app_dir_clone (priv->dir);
- if (!xdg_app_dir_pull_from_bundle (dir_clone,
- file,
- remote,
- ref,
- gpg_data != NULL,
- cancellable,
- error))
+ if (!xdg_app_dir_ensure_repo (dir_clone, cancellable, error))
+ goto out;
+
+ if (!xdg_app_pull_from_bundle (xdg_app_dir_get_repo (dir_clone),
+ file,
+ remote,
+ ref,
+ gpg_data != NULL,
+ cancellable,
+ error))
goto out;
if (!xdg_app_dir_lock (dir_clone, &lock,