lib/pull: Fetch summary if cached version doesn't match signature
authorDan Nicholson <nicholson@endlessm.com>
Thu, 2 Aug 2018 20:15:28 +0000 (15:15 -0500)
committerAtomic Bot <atomic-devel@projectatomic.io>
Tue, 14 Aug 2018 13:38:11 +0000 (13:38 +0000)
If for some reason the cached summary doesn't match the cached signature
then fetch the remote summary and verify again. Since commit c4c2b5eb
this is unlikely to happen since the summary will only be cached if it
matches the signature. However, if the summary cache has been corrupted
for any other reason then it's best to be safe and fetch the remote
summary again.

This is essentially the corollary to c4c2b5eb. Where that commit helps
you from getting into the corrupted summary cache in the first place,
this helps you get out of it. Without this the client can get wedged
until a prune or the remote server republishes the summary.

Closes: #1698
Approved by: cgwalters

src/libostree/ostree-repo-pull.c

index 9eac6376bc6e8f8e13b420c56266e5408c6f4326..f692874d443f32adf7636d23f49b1ca00c078634 100644 (file)
@@ -4027,12 +4027,43 @@ ostree_repo_pull_with_options (OstreeRepo             *self,
     if (pull_data->gpg_verify_summary && bytes_summary && bytes_sig)
       {
         g_autoptr(OstreeGpgVerifyResult) result = NULL;
+        g_autoptr(GError) temp_error = NULL;
 
         result = ostree_repo_verify_summary (self, pull_data->remote_name,
                                              bytes_summary, bytes_sig,
-                                             cancellable, error);
-        if (!ostree_gpg_verify_result_require_valid_signature (result, error))
-          goto out;
+                                             cancellable, &temp_error);
+        if (!ostree_gpg_verify_result_require_valid_signature (result, &temp_error))
+          {
+            if (summary_from_cache)
+              {
+                /* The cached summary doesn't match, fetch a new one and verify again */
+                summary_from_cache = FALSE;
+                g_clear_pointer (&bytes_summary, (GDestroyNotify)g_bytes_unref);
+                g_debug ("Remote %s cached summary invalid, pulling new version",
+                         pull_data->remote_name);
+                if (!_ostree_fetcher_mirrored_request_to_membuf (pull_data->fetcher,
+                                                                 pull_data->meta_mirrorlist,
+                                                                 "summary",
+                                                                 OSTREE_FETCHER_REQUEST_OPTIONAL_CONTENT,
+                                                                 pull_data->n_network_retries,
+                                                                 &bytes_summary,
+                                                                 OSTREE_MAX_METADATA_SIZE,
+                                                                 cancellable, error))
+                  goto out;
+
+                g_autoptr(OstreeGpgVerifyResult) retry =
+                  ostree_repo_verify_summary (self, pull_data->remote_name,
+                                              bytes_summary, bytes_sig,
+                                              cancellable, error);
+                if (!ostree_gpg_verify_result_require_valid_signature (retry, error))
+                  goto out;
+              }
+            else
+              {
+                g_propagate_error (error, g_steal_pointer (&temp_error));
+                goto out;
+              }
+          }
       }
 
     if (bytes_summary)