[ostree] pull: verify signature for the summary file



commit ef7a4dee100e1b5470e98b4f8a86edbe2e0bebf5
Author: Giuseppe Scrivano <gscrivan redhat com>
Date:   Wed Apr 29 15:24:28 2015 +0200

    pull: verify signature for the summary file
    
    Signed-off-by: Giuseppe Scrivano <gscrivan redhat com>

 src/libostree/ostree-core.h      |    3 ++
 src/libostree/ostree-repo-pull.c |   51 ++++++++++++++++++++++++++++++++++---
 src/libostree/ostree-repo.c      |    2 +-
 3 files changed, 50 insertions(+), 6 deletions(-)
---
diff --git a/src/libostree/ostree-core.h b/src/libostree/ostree-core.h
index c0f8798..711c699 100644
--- a/src/libostree/ostree-core.h
+++ b/src/libostree/ostree-core.h
@@ -142,6 +142,9 @@ typedef enum {
 #define OSTREE_SUMMARY_GVARIANT_STRING "(a(s(taya{sv}))a{sv})"
 #define OSTREE_SUMMARY_GVARIANT_FORMAT G_VARIANT_TYPE (OSTREE_SUMMARY_GVARIANT_STRING)
 
+#define OSTREE_SUMMARY_SIG_GVARIANT_STRING "a{sv}"
+#define OSTREE_SUMMARY_SIG_GVARIANT_FORMAT G_VARIANT_TYPE (OSTREE_SUMMARY_SIG_GVARIANT_STRING)
+
 /**
  * OstreeRepoMode:
  * @OSTREE_REPO_MODE_BARE: Files are stored as themselves; can only be written as root
diff --git a/src/libostree/ostree-repo-pull.c b/src/libostree/ostree-repo-pull.c
index 2995cb2..66b789f 100644
--- a/src/libostree/ostree-repo-pull.c
+++ b/src/libostree/ostree-repo-pull.c
@@ -60,6 +60,7 @@ typedef struct {
   gboolean          gpg_verify;
 
   GBytes           *summary_data;
+  GBytes           *summary_data_sig;
   GVariant         *summary;
   GHashTable       *summary_deltas_checksums;
   GPtrArray        *static_delta_superblocks;
@@ -1885,16 +1886,23 @@ ostree_repo_pull_with_options (OstreeRepo             *self,
 
   if (pull_data->is_mirror && !refs_to_fetch && !configured_branches)
     {
-      SoupURI *summary_uri = NULL;
+      SoupURI *uri = NULL;
       g_autoptr(GBytes) bytes = NULL;
+      g_autoptr(GBytes) bytes_sig = NULL;
       g_autofree char *ret_contents = NULL;
       
-      summary_uri = suburi_new (pull_data->base_uri, "summary", NULL);
-      if (!fetch_uri_contents_membuf_sync (pull_data, summary_uri, FALSE, TRUE,
+      uri = suburi_new (pull_data->base_uri, "summary", NULL);
+      if (!fetch_uri_contents_membuf_sync (pull_data, uri, FALSE, TRUE,
                                            &bytes, cancellable, error))
         goto out;
-      soup_uri_free (summary_uri);
-      
+      soup_uri_free (uri);
+
+      uri = suburi_new (pull_data->base_uri, "summary.sig", NULL);
+      if (!fetch_uri_contents_membuf_sync (pull_data, uri, FALSE, TRUE,
+                                           &bytes_sig, cancellable, error))
+        goto out;
+      soup_uri_free (uri);
+
       if (bytes)
         {
           g_autoptr(GVariant) refs = NULL;
@@ -1903,6 +1911,32 @@ ostree_repo_pull_with_options (OstreeRepo             *self,
           gsize i, n;
 
           pull_data->summary_data = g_bytes_ref (bytes);
+          if (bytes_sig)
+            pull_data->summary_data_sig = g_bytes_ref (bytes_sig);
+          if (pull_data->gpg_verify && bytes_sig)
+            {
+              glnx_unref_object OstreeGpgVerifyResult *result = NULL;
+              g_autoptr(GVariant) sig_variant = g_variant_new_from_bytes (OSTREE_SUMMARY_SIG_GVARIANT_FORMAT,
+                                                                          bytes_sig,
+                                                                          FALSE);
+              result = _ostree_repo_gpg_verify_with_metadata (self,
+                                                              bytes,
+                                                              sig_variant,
+                                                              NULL,
+                                                              NULL,
+                                                              cancellable,
+                                                              error);
+              if (result == NULL)
+                goto out;
+
+              if (ostree_gpg_verify_result_count_valid (result) == 0)
+                {
+                  g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                               "GPG signatures found, but none are in trusted keyring");
+                  goto out;
+                }
+            }
+
           pull_data->summary = g_variant_new_from_bytes (OSTREE_SUMMARY_GVARIANT_FORMAT, bytes, FALSE);
           refs = g_variant_get_child_value (pull_data->summary, 0);
           n = g_variant_n_children (refs);
@@ -2143,6 +2177,12 @@ ostree_repo_pull_with_options (OstreeRepo             *self,
                                         pull_data->summary_data, !pull_data->repo->disable_fsync,
                                         cancellable, error))
         goto out;
+
+      if (pull_data->summary_data_sig &&
+          !ot_file_replace_contents_at (pull_data->repo->repo_dir_fd, "summary.sig",
+                                        pull_data->summary_data_sig, !pull_data->repo->disable_fsync,
+                                        cancellable, error))
+        goto out;
     }
 
   if (!ostree_repo_commit_transaction (pull_data->repo, NULL, cancellable, error))
@@ -2215,6 +2255,7 @@ ostree_repo_pull_with_options (OstreeRepo             *self,
   if (pull_data->base_uri)
     soup_uri_free (pull_data->base_uri);
   g_clear_pointer (&pull_data->summary_data, (GDestroyNotify) g_bytes_unref);
+  g_clear_pointer (&pull_data->summary_data_sig, (GDestroyNotify) g_bytes_unref);
   g_clear_pointer (&pull_data->summary, (GDestroyNotify) g_variant_unref);
   g_clear_pointer (&pull_data->static_delta_superblocks, (GDestroyNotify) g_ptr_array_unref);
   g_clear_pointer (&pull_data->commit_to_depth, (GDestroyNotify) g_hash_table_unref);
diff --git a/src/libostree/ostree-repo.c b/src/libostree/ostree-repo.c
index 8affec5..c0313fe 100644
--- a/src/libostree/ostree-repo.c
+++ b/src/libostree/ostree-repo.c
@@ -3373,7 +3373,7 @@ ostree_repo_add_gpg_signature_summary (OstreeRepo     *self,
   if (!summary_data)
     goto out;
 
-  if (!ot_util_variant_map (signature_path, G_VARIANT_TYPE ("a{sv}"),
+  if (!ot_util_variant_map (signature_path, G_VARIANT_TYPE (OSTREE_SUMMARY_SIG_GVARIANT_STRING),
                             TRUE, &existing_signatures, &temp_error))
     {
       if (g_error_matches (temp_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND))


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]