diff options
author | OpenShift Merge Robot <openshift-merge-robot@users.noreply.github.com> | 2020-09-11 11:07:00 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-09-11 11:07:00 -0400 |
commit | 71acef2d33ec406dd7937742adb4d32fdd46100b (patch) | |
tree | 09311ac0c02104a50c540fc96513c1ac6cbe915b | |
parent | 69282a3dd3ef6a05339b31d46c095adfab92c4c1 (diff) | |
parent | b7d1a9746b51fdb4cf14aa173e46e7d165cfe6e4 (diff) | |
download | ostree-71acef2d33ec406dd7937742adb4d32fdd46100b.tar.gz |
Merge pull request #2193 from alexlarsson/preparatory-cleanup
Preparatory cleanup for summary work
-rw-r--r-- | src/libostree/libostree-devel.sym | 2 | ||||
-rw-r--r-- | src/libostree/libostree-released.sym | 5 | ||||
-rw-r--r-- | src/libostree/ostree-core.c | 2 | ||||
-rw-r--r-- | src/libostree/ostree-repo-pull.c | 584 | ||||
-rw-r--r-- | src/libostree/ostree-repo-static-delta-core.c | 24 | ||||
-rw-r--r-- | src/libostree/ostree-repo-static-delta-private.h | 6 | ||||
-rw-r--r-- | src/libostree/ostree-repo.c | 21 | ||||
-rw-r--r-- | src/libotutil/ot-checksum-utils.c | 10 | ||||
-rw-r--r-- | src/libotutil/ot-checksum-utils.h | 3 | ||||
-rw-r--r-- | src/libotutil/otutil.h | 25 | ||||
-rwxr-xr-x | tests/test-symbols.sh | 2 |
11 files changed, 374 insertions, 310 deletions
diff --git a/src/libostree/libostree-devel.sym b/src/libostree/libostree-devel.sym index 21669c4a..7f1f7e3e 100644 --- a/src/libostree/libostree-devel.sym +++ b/src/libostree/libostree-devel.sym @@ -17,7 +17,7 @@ Boston, MA 02111-1307, USA. ***/ -LIBOSTREE_2020.5 { +LIBOSTREE_2020.6 { global: /* Add symbols here, and uncomment the bits in * Makefile-libostree.am to enable this too. diff --git a/src/libostree/libostree-released.sym b/src/libostree/libostree-released.sym index 5c63f78f..aee434cb 100644 --- a/src/libostree/libostree-released.sym +++ b/src/libostree/libostree-released.sym @@ -593,6 +593,9 @@ global: ostree_sysroot_set_mount_namespace_in_use; } LIBOSTREE_2019.6; +/* No new symbols in 2020.2 */ +/* No new symbols in 2020.3 */ + /* Add new symbols here. Release commits should copy this section into -released.sym. */ LIBOSTREE_2020.4 { global: @@ -615,7 +618,7 @@ global: ostree_sign_summary; } LIBOSTREE_2020.1; -/* No new symbols in 2020.2 */ +/* No new symbols in 2020.5 */ /* NOTE: Only add more content here in release commits! See the * comments at the top of this file. diff --git a/src/libostree/ostree-core.c b/src/libostree/ostree-core.c index 523f57c0..29528fa5 100644 --- a/src/libostree/ostree-core.c +++ b/src/libostree/ostree-core.c @@ -2675,7 +2675,7 @@ _ostree_detached_metadata_append_gpg_sig (GVariant *existing_metadata, _OSTREE_METADATA_GPGSIGS_NAME, g_variant_builder_end (signature_builder)); - return g_variant_dict_end (&metadata_dict); + return g_variant_ref_sink (g_variant_dict_end (&metadata_dict)); } #endif /* OSTREE_DISABLE_GPGME */ diff --git a/src/libostree/ostree-repo-pull.c b/src/libostree/ostree-repo-pull.c index d817575b..2a791e59 100644 --- a/src/libostree/ostree-repo-pull.c +++ b/src/libostree/ostree-repo-pull.c @@ -2513,10 +2513,7 @@ on_superblock_fetched (GObject *src, const guchar *expected_summary_digest = g_hash_table_lookup (pull_data->summary_deltas_checksums, delta); guint8 actual_summary_digest[OSTREE_SHA256_DIGEST_LEN]; - g_auto(OtChecksum) hasher = { 0, }; - ot_checksum_init (&hasher); - ot_checksum_update_bytes (&hasher, delta_superblock_data); - ot_checksum_get_digest (&hasher, actual_summary_digest, sizeof (actual_summary_digest)); + ot_checksum_bytes (delta_superblock_data, actual_summary_digest); #ifndef OSTREE_DISABLE_GPGME /* At this point we've GPG verified the data, so in theory @@ -2626,88 +2623,198 @@ validate_variant_is_csum (GVariant *csum, return ostree_validate_structureof_csum_v (csum, error); } +static gboolean +_ostree_repo_verify_summary (OstreeRepo *self, + const char *name, + gboolean gpg_verify_summary, + GPtrArray *signapi_summary_verifiers, + GBytes *summary, + GBytes *signatures, + GCancellable *cancellable, + GError **error) +{ + if (gpg_verify_summary) + { + if (summary == NULL) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, + "GPG verification enabled, but no summary found (check that the configured URL in remote config is correct)"); + return FALSE; + } + + if (signatures == NULL) + { + g_set_error (error, OSTREE_GPG_ERROR, OSTREE_GPG_ERROR_NO_SIGNATURE, + "GPG verification enabled, but no summary signatures found (use gpg-verify-summary=false in remote config to disable)"); + return FALSE; + } + + /* Verify any summary signatures. */ + if (summary != NULL && signatures != NULL) + { + g_autoptr(OstreeGpgVerifyResult) result = NULL; + + result = ostree_repo_verify_summary (self, + name, + summary, + signatures, + cancellable, + error); + if (!ostree_gpg_verify_result_require_valid_signature (result, error)) + return FALSE; + } + } + + if (signapi_summary_verifiers) + { + if (summary == NULL) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, + "Signature verification enabled, but no summary found (check that the configured URL in remote config is correct)"); + return FALSE; + } + + if (signatures == NULL) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, + "Signature verification enabled, but no summary signatures found (use sign-verify-summary=false in remote config to disable)"); + return FALSE; + } + + /* Verify any summary signatures. */ + if (summary != NULL && signatures != NULL) + { + g_autoptr(GVariant) sig_variant = NULL; + + sig_variant = g_variant_new_from_bytes (OSTREE_SUMMARY_SIG_GVARIANT_FORMAT, + signatures, FALSE); + + if (!_sign_verify_for_remote (signapi_summary_verifiers, summary, sig_variant, NULL, error)) + return FALSE; + } + } + + return TRUE; +} + +static gboolean +_ostree_repo_load_cache_summary_file (OstreeRepo *self, + const char *filename, + const char *extension, + GBytes **out_data, + GCancellable *cancellable, + GError **error) +{ + const char *file = glnx_strjoina (_OSTREE_SUMMARY_CACHE_DIR, "/", filename, extension); + glnx_autofd int fd = -1; + g_autoptr(GBytes) data = NULL; + + *out_data = NULL; + + if (self->cache_dir_fd == -1) + return TRUE; + + fd = openat (self->cache_dir_fd, file, O_CLOEXEC | O_RDONLY); + if (fd < 0) + { + if (errno == ENOENT) + return TRUE; + return glnx_throw_errno_prefix (error, "openat(%s)", file); + } + + data = ot_fd_readall_or_mmap (fd, 0, error); + if (!data) + return FALSE; + + *out_data =g_steal_pointer (&data); + return TRUE; +} + /* Load the summary from the cache if the provided .sig file is the same as the cached version. */ static gboolean _ostree_repo_load_cache_summary_if_same_sig (OstreeRepo *self, const char *remote, GBytes *summary_sig, - GBytes **summary, + GBytes **out_summary, GCancellable *cancellable, GError **error) { - if (self->cache_dir_fd == -1) - return TRUE; + g_autoptr(GBytes) old_sig_contents = NULL; - const char *summary_cache_sig_file = glnx_strjoina (_OSTREE_SUMMARY_CACHE_DIR, "/", remote, ".sig"); - glnx_autofd int prev_fd = -1; - if (!ot_openat_ignore_enoent (self->cache_dir_fd, summary_cache_sig_file, &prev_fd, error)) - return FALSE; - if (prev_fd < 0) - return TRUE; /* Note early return */ + *out_summary = NULL; - g_autoptr(GBytes) old_sig_contents = ot_fd_readall_or_mmap (prev_fd, 0, error); - if (!old_sig_contents) + if (!_ostree_repo_load_cache_summary_file (self, remote, ".sig", + &old_sig_contents, + cancellable, error)) return FALSE; - if (g_bytes_compare (old_sig_contents, summary_sig) == 0) + if (old_sig_contents != NULL && + g_bytes_compare (old_sig_contents, summary_sig) == 0) { - const char *summary_cache_file = glnx_strjoina (_OSTREE_SUMMARY_CACHE_DIR, "/", remote); - glnx_autofd int summary_fd = -1; - GBytes *summary_data; + g_autoptr(GBytes) summary_data = NULL; + if (!_ostree_repo_load_cache_summary_file (self, remote, NULL, + &summary_data, + cancellable, error)) + return FALSE; - summary_fd = openat (self->cache_dir_fd, summary_cache_file, O_CLOEXEC | O_RDONLY); - if (summary_fd < 0) + if (summary_data == NULL) { - if (errno == ENOENT) - { - (void) unlinkat (self->cache_dir_fd, summary_cache_sig_file, 0); - return TRUE; /* Note early return */ - } - - return glnx_throw_errno_prefix (error, "openat(%s)", summary_cache_file); + /* Cached signature without cached summary, remove the signature */ + const char *summary_cache_sig_file = glnx_strjoina (_OSTREE_SUMMARY_CACHE_DIR, "/", remote, ".sig"); + (void) unlinkat (self->cache_dir_fd, summary_cache_sig_file, 0); } - - summary_data = glnx_fd_readall_bytes (summary_fd, cancellable, error); - if (!summary_data) - return FALSE; - *summary = summary_data; + else + *out_summary = g_steal_pointer (&summary_data); } + return TRUE; } -/* Replace the current summary+signature with new versions */ static gboolean -_ostree_repo_cache_summary (OstreeRepo *self, - const char *remote, - GBytes *summary, - GBytes *summary_sig, - GCancellable *cancellable, - GError **error) +_ostree_repo_save_cache_summary_file (OstreeRepo *self, + const char *filename, + const char *extension, + GBytes *data, + GCancellable *cancellable, + GError **error) { + const char *file = glnx_strjoina (_OSTREE_SUMMARY_CACHE_DIR, "/", filename, extension); + glnx_autofd int fd = -1; + if (self->cache_dir_fd == -1) return TRUE; if (!glnx_shutil_mkdir_p_at (self->cache_dir_fd, _OSTREE_SUMMARY_CACHE_DIR, DEFAULT_DIRECTORY_MODE, cancellable, error)) return FALSE; - const char *summary_cache_file = glnx_strjoina (_OSTREE_SUMMARY_CACHE_DIR, "/", remote); if (!glnx_file_replace_contents_at (self->cache_dir_fd, - summary_cache_file, - g_bytes_get_data (summary, NULL), - g_bytes_get_size (summary), + file, + g_bytes_get_data (data, NULL), + g_bytes_get_size (data), self->disable_fsync ? GLNX_FILE_REPLACE_NODATASYNC : GLNX_FILE_REPLACE_DATASYNC_NEW, cancellable, error)) return FALSE; - const char *summary_cache_sig_file = glnx_strjoina (_OSTREE_SUMMARY_CACHE_DIR, "/", remote, ".sig"); - if (!glnx_file_replace_contents_at (self->cache_dir_fd, - summary_cache_sig_file, - g_bytes_get_data (summary_sig, NULL), - g_bytes_get_size (summary_sig), - self->disable_fsync ? GLNX_FILE_REPLACE_NODATASYNC : GLNX_FILE_REPLACE_DATASYNC_NEW, - cancellable, error)) + return TRUE; +} + +/* Replace the current summary+signature with new versions */ +static gboolean +_ostree_repo_cache_summary (OstreeRepo *self, + const char *remote, + GBytes *summary, + GBytes *summary_sig, + GCancellable *cancellable, + GError **error) +{ + if (!_ostree_repo_save_cache_summary_file (self, remote, NULL, + summary, cancellable, error)) + return FALSE; + + if (!_ostree_repo_save_cache_summary_file (self, remote, ".sig", + summary_sig, cancellable, error)) return FALSE; return TRUE; @@ -2717,6 +2824,8 @@ static OstreeFetcher * _ostree_repo_remote_new_fetcher (OstreeRepo *self, const char *remote_name, gboolean gzip, + GVariant *extra_headers, + const char *append_user_agent, OstreeFetcherSecurityState *out_state, GError **error) { @@ -2830,6 +2939,12 @@ _ostree_repo_remote_new_fetcher (OstreeRepo *self, _ostree_fetcher_set_cookie_jar (fetcher, jar_path); } + if (extra_headers) + _ostree_fetcher_set_extra_headers (fetcher, extra_headers); + + if (append_user_agent) + _ostree_fetcher_set_extra_user_agent (fetcher, append_user_agent); + success = TRUE; out: @@ -2977,127 +3092,43 @@ fetch_mirrorlist (OstreeFetcher *fetcher, } static gboolean -repo_remote_fetch_summary (OstreeRepo *self, - const char *name, - const char *metalink_url_string, - GVariant *options, - GBytes **out_summary, - GBytes **out_signatures, - gboolean *out_from_cache, - GCancellable *cancellable, - GError **error) +compute_effective_mirrorlist (OstreeRepo *self, + const char *remote_name_or_baseurl, + const char *url_override, + OstreeFetcher *fetcher, + guint n_network_retries, + GPtrArray **out_mirrorlist, + GCancellable *cancellable, + GError **error) { - g_autoptr(OstreeFetcher) fetcher = NULL; - g_autoptr(GMainContext) mainctx = NULL; - gboolean ret = FALSE; - gboolean from_cache = FALSE; - const char *url_override = NULL; - g_autoptr(GVariant) extra_headers = NULL; - g_autoptr(GPtrArray) mirrorlist = NULL; - const char *append_user_agent = NULL; - guint n_network_retries = DEFAULT_N_NETWORK_RETRIES; + g_autofree char *baseurl = NULL; - if (options) - { - (void) g_variant_lookup (options, "override-url", "&s", &url_override); - (void) g_variant_lookup (options, "http-headers", "@a(ss)", &extra_headers); - (void) g_variant_lookup (options, "append-user-agent", "&s", &append_user_agent); - (void) g_variant_lookup (options, "n-network-retries", "&u", &n_network_retries); - } - - mainctx = g_main_context_new (); - g_main_context_push_thread_default (mainctx); - - fetcher = _ostree_repo_remote_new_fetcher (self, name, TRUE, NULL, error); - if (fetcher == NULL) - goto out; - - if (extra_headers) - _ostree_fetcher_set_extra_headers (fetcher, extra_headers); - - if (append_user_agent) - _ostree_fetcher_set_extra_user_agent (fetcher, append_user_agent); - - { - g_autofree char *url_string = NULL; - if (metalink_url_string) - url_string = g_strdup (metalink_url_string); - else if (url_override) - url_string = g_strdup (url_override); - else if (!ostree_repo_remote_get_url (self, name, &url_string, error)) - goto out; - - if (metalink_url_string == NULL && - g_str_has_prefix (url_string, "mirrorlist=")) - { - if (!fetch_mirrorlist (fetcher, url_string + strlen ("mirrorlist="), - n_network_retries, &mirrorlist, cancellable, error)) - goto out; - } - else - { - g_autoptr(OstreeFetcherURI) uri = _ostree_fetcher_uri_parse (url_string, error); - - if (!uri) - goto out; - - mirrorlist = - g_ptr_array_new_with_free_func ((GDestroyNotify) _ostree_fetcher_uri_free); - g_ptr_array_add (mirrorlist, g_steal_pointer (&uri)); - } - } - - /* FIXME: Send the ETag from the cache with the request for summary.sig to - * avoid downloading summary.sig unnecessarily. This won’t normally provide - * any benefits (but won’t do any harm) since summary.sig is typically 500B - * in size. But if a repository has multiple keys, the signature file will - * grow and this optimisation may be useful. */ - if (!_ostree_preload_metadata_file (self, - fetcher, - mirrorlist, - "summary.sig", - metalink_url_string ? TRUE : FALSE, - n_network_retries, - out_signatures, - cancellable, - error)) - goto out; + if (url_override != NULL) + baseurl = g_strdup (url_override); + else if (!ostree_repo_remote_get_url (self, remote_name_or_baseurl, &baseurl, error)) + return FALSE; - if (*out_signatures) + if (g_str_has_prefix (baseurl, "mirrorlist=")) { - if (!_ostree_repo_load_cache_summary_if_same_sig (self, - name, - *out_signatures, - out_summary, - cancellable, - error)) - goto out; + if (!fetch_mirrorlist (fetcher, + baseurl + strlen ("mirrorlist="), + n_network_retries, + out_mirrorlist, + cancellable, error)) + return FALSE; } - - if (*out_summary) - from_cache = TRUE; else { - if (!_ostree_preload_metadata_file (self, - fetcher, - mirrorlist, - "summary", - metalink_url_string ? TRUE : FALSE, - n_network_retries, - out_summary, - cancellable, - error)) - goto out; - } + g_autoptr(OstreeFetcherURI) baseuri = _ostree_fetcher_uri_parse (baseurl, error); - ret = TRUE; - - out: - if (mainctx) - g_main_context_pop_thread_default (mainctx); + if (!baseuri) + return FALSE; - *out_from_cache = from_cache; - return ret; + *out_mirrorlist = + g_ptr_array_new_with_free_func ((GDestroyNotify) _ostree_fetcher_uri_free); + g_ptr_array_add (*out_mirrorlist, g_steal_pointer (&baseuri)); + } + return TRUE; } /* Create the fetcher by unioning options from the remote config, plus @@ -3109,17 +3140,13 @@ reinitialize_fetcher (OtPullData *pull_data, const char *remote_name, { g_clear_object (&pull_data->fetcher); pull_data->fetcher = _ostree_repo_remote_new_fetcher (pull_data->repo, remote_name, FALSE, + pull_data->extra_headers, + pull_data->append_user_agent, &pull_data->fetcher_security_state, error); if (pull_data->fetcher == NULL) return FALSE; - if (pull_data->extra_headers) - _ostree_fetcher_set_extra_headers (pull_data->fetcher, pull_data->extra_headers); - - if (pull_data->append_user_agent) - _ostree_fetcher_set_extra_user_agent (pull_data->fetcher, pull_data->append_user_agent); - return TRUE; } @@ -3631,33 +3658,13 @@ ostree_repo_pull_with_options (OstreeRepo *self, if (!metalink_url_str) { - g_autofree char *baseurl = NULL; - - if (url_override != NULL) - baseurl = g_strdup (url_override); - else if (!ostree_repo_remote_get_url (self, remote_name_or_baseurl, &baseurl, error)) + if (!compute_effective_mirrorlist (self, remote_name_or_baseurl, + url_override, + pull_data->fetcher, + pull_data->n_network_retries, + &pull_data->meta_mirrorlist, + cancellable, error)) goto out; - - if (g_str_has_prefix (baseurl, "mirrorlist=")) - { - if (!fetch_mirrorlist (pull_data->fetcher, - baseurl + strlen ("mirrorlist="), - pull_data->n_network_retries, - &pull_data->meta_mirrorlist, - cancellable, error)) - goto out; - } - else - { - g_autoptr(OstreeFetcherURI) baseuri = _ostree_fetcher_uri_parse (baseurl, error); - - if (!baseuri) - goto out; - - pull_data->meta_mirrorlist = - g_ptr_array_new_with_free_func ((GDestroyNotify) _ostree_fetcher_uri_free); - g_ptr_array_add (pull_data->meta_mirrorlist, g_steal_pointer (&baseuri)); - } } else { @@ -3716,27 +3723,13 @@ ostree_repo_pull_with_options (OstreeRepo *self, } else { - if (g_str_has_prefix (contenturl, "mirrorlist=")) - { - if (!fetch_mirrorlist (pull_data->fetcher, - contenturl + strlen ("mirrorlist="), - pull_data->n_network_retries, - &pull_data->content_mirrorlist, - cancellable, error)) - goto out; - } - else - { - g_autoptr(OstreeFetcherURI) contenturi = _ostree_fetcher_uri_parse (contenturl, error); - - if (!contenturi) - goto out; - - pull_data->content_mirrorlist = - g_ptr_array_new_with_free_func ((GDestroyNotify) _ostree_fetcher_uri_free); - g_ptr_array_add (pull_data->content_mirrorlist, - g_steal_pointer (&contenturi)); - } + if (!compute_effective_mirrorlist (self, remote_name_or_baseurl, + contenturl, + pull_data->fetcher, + pull_data->n_network_retries, + &pull_data->content_mirrorlist, + cancellable, error)) + goto out; } } @@ -5471,7 +5464,7 @@ find_remotes_cb (GObject *obj, goto error; fetcher = _ostree_repo_remote_new_fetcher (self, result->remote->name, - TRUE, NULL, &error); + TRUE, NULL, NULL, NULL, &error); if (fetcher == NULL) goto error; @@ -6093,96 +6086,108 @@ ostree_repo_remote_fetch_summary_with_options (OstreeRepo *self, g_autoptr(GBytes) signatures = NULL; gboolean gpg_verify_summary; g_autoptr(GPtrArray) signapi_summary_verifiers = NULL; - gboolean ret = FALSE; - gboolean summary_is_from_cache; + gboolean summary_is_from_cache = FALSE; + g_autoptr(OstreeFetcher) fetcher = NULL; + g_autoptr(GMainContextPopDefault) mainctx = NULL; + const char *url_override = NULL; + g_autoptr(GVariant) extra_headers = NULL; + g_autoptr(GPtrArray) mirrorlist = NULL; + const char *append_user_agent = NULL; + guint n_network_retries = DEFAULT_N_NETWORK_RETRIES; g_return_val_if_fail (OSTREE_REPO (self), FALSE); g_return_val_if_fail (name != NULL, FALSE); if (!ostree_repo_get_remote_option (self, name, "metalink", NULL, &metalink_url_string, error)) - goto out; - - if (!repo_remote_fetch_summary (self, - name, - metalink_url_string, - options, - &summary, - &signatures, - &summary_is_from_cache, - cancellable, - error)) - goto out; - - if (!ostree_repo_remote_get_gpg_verify_summary (self, name, &gpg_verify_summary, error)) - goto out; + return FALSE; - if (gpg_verify_summary) + if (options) { - if (summary == NULL) - { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, - "GPG verification enabled, but no summary found (check that the configured URL in remote config is correct)"); - goto out; - } - - if (signatures == NULL) - { - g_set_error (error, OSTREE_GPG_ERROR, OSTREE_GPG_ERROR_NO_SIGNATURE, - "GPG verification enabled, but no summary signatures found (use gpg-verify-summary=false in remote config to disable)"); - goto out; - } - - /* Verify any summary signatures. */ - if (summary != NULL && signatures != NULL) - { - g_autoptr(OstreeGpgVerifyResult) result = NULL; - - result = ostree_repo_verify_summary (self, - name, - summary, - signatures, - cancellable, - error); - if (!ostree_gpg_verify_result_require_valid_signature (result, error)) - goto out; - } + (void) g_variant_lookup (options, "override-url", "&s", &url_override); + (void) g_variant_lookup (options, "http-headers", "@a(ss)", &extra_headers); + (void) g_variant_lookup (options, "append-user-agent", "&s", &append_user_agent); + (void) g_variant_lookup (options, "n-network-retries", "&u", &n_network_retries); } + if (!ostree_repo_remote_get_gpg_verify_summary (self, name, &gpg_verify_summary, error)) + return FALSE; + if (!_signapi_init_for_remote (self, name, NULL, &signapi_summary_verifiers, error)) - goto out; + return FALSE; - if (signapi_summary_verifiers) + mainctx = _ostree_main_context_new_default (); + + fetcher = _ostree_repo_remote_new_fetcher (self, name, TRUE, extra_headers, append_user_agent, NULL, error); + if (fetcher == NULL) + return FALSE; + + if (metalink_url_string) { - if (summary == NULL) - { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, - "Signature verification enabled, but no summary found (check that the configured URL in remote config is correct)"); - goto out; - } + g_autoptr(OstreeFetcherURI) uri = _ostree_fetcher_uri_parse (metalink_url_string, error); + if (!uri) + return FALSE; - if (signatures == NULL) - { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, - "Signature verification enabled, but no summary signatures found (use sign-verify-summary=false in remote config to disable)"); - goto out; - } + mirrorlist = + g_ptr_array_new_with_free_func ((GDestroyNotify) _ostree_fetcher_uri_free); + g_ptr_array_add (mirrorlist, g_steal_pointer (&uri)); + } + else if (!compute_effective_mirrorlist (self, name, url_override, + fetcher, n_network_retries, + &mirrorlist, cancellable, error)) + return FALSE; - /* Verify any summary signatures. */ - if (summary != NULL && signatures != NULL) - { - g_autoptr(GVariant) sig_variant = NULL; + /* FIXME: Send the ETag from the cache with the request for summary.sig to + * avoid downloading summary.sig unnecessarily. This won’t normally provide + * any benefits (but won’t do any harm) since summary.sig is typically 500B + * in size. But if a repository has multiple keys, the signature file will + * grow and this optimisation may be useful. */ + if (!_ostree_preload_metadata_file (self, + fetcher, + mirrorlist, + "summary.sig", + metalink_url_string ? TRUE : FALSE, + n_network_retries, + &signatures, + cancellable, + error)) + return FALSE; - sig_variant = g_variant_new_from_bytes (OSTREE_SUMMARY_SIG_GVARIANT_FORMAT, - signatures, FALSE); + if (signatures) + { + if (!_ostree_repo_load_cache_summary_if_same_sig (self, + name, + signatures, + &summary, + cancellable, + error)) + return FALSE; + } - if (!_sign_verify_for_remote (signapi_summary_verifiers, summary, sig_variant, NULL, error)) - goto out; - } + if (summary) + summary_is_from_cache = TRUE; + else + { + if (!_ostree_preload_metadata_file (self, + fetcher, + mirrorlist, + "summary", + metalink_url_string ? TRUE : FALSE, + n_network_retries, + &summary, + cancellable, + error)) + return FALSE; } + if (!_ostree_repo_verify_summary (self, name, + gpg_verify_summary, signapi_summary_verifiers, + summary, signatures, + cancellable, error)) + return FALSE; + if (!summary_is_from_cache && summary && signatures) { g_autoptr(GError) temp_error = NULL; @@ -6199,7 +6204,7 @@ ostree_repo_remote_fetch_summary_with_options (OstreeRepo *self, else { g_propagate_error (error, g_steal_pointer (&temp_error)); - goto out; + return FALSE; } } } @@ -6210,10 +6215,7 @@ ostree_repo_remote_fetch_summary_with_options (OstreeRepo *self, if (out_signatures != NULL) *out_signatures = g_steal_pointer (&signatures); - ret = TRUE; - -out: - return ret; + return TRUE; } #else /* HAVE_LIBCURL_OR_LIBSOUP */ diff --git a/src/libostree/ostree-repo-static-delta-core.c b/src/libostree/ostree-repo-static-delta-core.c index ade4e9df..835ec7f3 100644 --- a/src/libostree/ostree-repo-static-delta-core.c +++ b/src/libostree/ostree-repo-static-delta-core.c @@ -54,6 +54,28 @@ _ostree_static_delta_parse_checksum_array (GVariant *array, return TRUE; } +GVariant * +_ostree_repo_static_delta_superblock_digest (OstreeRepo *repo, + const char *from, + const char *to, + GCancellable *cancellable, + GError **error) +{ + g_autofree char *superblock = _ostree_get_relative_static_delta_superblock_path ((from && from[0]) ? from : NULL, to); + glnx_autofd int superblock_file_fd = -1; + guint8 digest[OSTREE_SHA256_DIGEST_LEN]; + + if (!glnx_openat_rdonly (repo->repo_dir_fd, superblock, TRUE, &superblock_file_fd, error)) + return NULL; + + g_autoptr(GBytes) superblock_content = ot_fd_readall_or_mmap (superblock_file_fd, 0, error); + if (!superblock_content) + return NULL; + + ot_checksum_bytes (superblock_content, digest); + + return ot_gvariant_new_bytearray (digest, sizeof (digest)); +} /** * ostree_repo_list_static_delta_names: @@ -109,7 +131,7 @@ ostree_repo_list_static_delta_names (OstreeRepo *self, return FALSE; if (sub_dent == NULL) break; - if (dent->d_type != DT_DIR) + if (sub_dent->d_type != DT_DIR) continue; const char *name1 = dent->d_name; diff --git a/src/libostree/ostree-repo-static-delta-private.h b/src/libostree/ostree-repo-static-delta-private.h index 155acd52..ff8de9d4 100644 --- a/src/libostree/ostree-repo-static-delta-private.h +++ b/src/libostree/ostree-repo-static-delta-private.h @@ -190,6 +190,12 @@ _ostree_repo_static_delta_query_exists (OstreeRepo *repo, gboolean *out_exists, GCancellable *cancellable, GError **error); +GVariant * +_ostree_repo_static_delta_superblock_digest (OstreeRepo *repo, + const char *from, + const char *to, + GCancellable *cancellable, + GError **error); gboolean _ostree_repo_static_delta_dump (OstreeRepo *repo, diff --git a/src/libostree/ostree-repo.c b/src/libostree/ostree-repo.c index 95eb0efc..621668d7 100644 --- a/src/libostree/ostree-repo.c +++ b/src/libostree/ostree-repo.c @@ -5793,25 +5793,18 @@ ostree_repo_regenerate_summary (OstreeRepo *self, { g_autofree char *from = NULL; g_autofree char *to = NULL; - if (!_ostree_parse_delta_name (delta_names->pdata[i], &from, &to, error)) - return FALSE; + GVariant *digest; - g_autofree char *superblock = _ostree_get_relative_static_delta_superblock_path ((from && from[0]) ? from : NULL, to); - glnx_autofd int superblock_file_fd = -1; - - if (!glnx_openat_rdonly (self->repo_dir_fd, superblock, TRUE, &superblock_file_fd, error)) + if (!_ostree_parse_delta_name (delta_names->pdata[i], &from, &to, error)) return FALSE; - g_autoptr(GBytes) superblock_content = ot_fd_readall_or_mmap (superblock_file_fd, 0, error); - if (!superblock_content) + digest = _ostree_repo_static_delta_superblock_digest (self, + (from && from[0]) ? from : NULL, + to, cancellable, error); + if (digest == NULL) return FALSE; - g_auto(OtChecksum) hasher = { 0, }; - ot_checksum_init (&hasher); - ot_checksum_update_bytes (&hasher, superblock_content); - guint8 digest[OSTREE_SHA256_DIGEST_LEN]; - ot_checksum_get_digest (&hasher, digest, sizeof (digest)); - g_variant_dict_insert_value (&deltas_builder, delta_names->pdata[i], ot_gvariant_new_bytearray (digest, sizeof (digest))); + g_variant_dict_insert_value (&deltas_builder, delta_names->pdata[i], digest); } if (delta_names->len > 0) diff --git a/src/libotutil/ot-checksum-utils.c b/src/libotutil/ot-checksum-utils.c index 66767368..26e0280a 100644 --- a/src/libotutil/ot-checksum-utils.c +++ b/src/libotutil/ot-checksum-utils.c @@ -275,3 +275,13 @@ ot_checksum_file_at (int dfd, ot_checksum_get_hexdigest (&checksum, hexdigest, sizeof (hexdigest)); return g_strdup (hexdigest); } + +void +ot_checksum_bytes (GBytes *data, + guint8 out_digest[_OSTREE_SHA256_DIGEST_LEN]) +{ + g_auto(OtChecksum) hasher = { 0, }; + ot_checksum_init (&hasher); + ot_checksum_update_bytes (&hasher, data); + ot_checksum_get_digest (&hasher, out_digest, _OSTREE_SHA256_DIGEST_LEN); +} diff --git a/src/libotutil/ot-checksum-utils.h b/src/libotutil/ot-checksum-utils.h index 411ef25d..5432c81e 100644 --- a/src/libotutil/ot-checksum-utils.h +++ b/src/libotutil/ot-checksum-utils.h @@ -96,4 +96,7 @@ char * ot_checksum_file_at (int dfd, GCancellable *cancellable, GError **error); +void ot_checksum_bytes (GBytes *data, + guint8 out_digest[_OSTREE_SHA256_DIGEST_LEN]); + G_END_DECLS diff --git a/src/libotutil/otutil.h b/src/libotutil/otutil.h index cd312365..7db7270d 100644 --- a/src/libotutil/otutil.h +++ b/src/libotutil/otutil.h @@ -52,6 +52,31 @@ #define ot_journal_print(...) {} #endif +typedef GMainContext GMainContextPopDefault; +static inline void +_ostree_main_context_pop_default_destroy (void *p) +{ + GMainContext *main_context = p; + + if (main_context) + { + g_main_context_pop_thread_default (main_context); + g_main_context_unref (main_context); + } +} + +static inline GMainContextPopDefault * +_ostree_main_context_new_default (void) +{ + GMainContext *main_context = g_main_context_new (); + + g_main_context_push_thread_default (main_context); + return main_context; +} + +G_DEFINE_AUTOPTR_CLEANUP_FUNC (GMainContextPopDefault, _ostree_main_context_pop_default_destroy) + + #include <ot-keyfile-utils.h> #include <ot-gio-utils.h> #include <ot-fs-utils.h> diff --git a/tests/test-symbols.sh b/tests/test-symbols.sh index 75df37e1..a0781618 100755 --- a/tests/test-symbols.sh +++ b/tests/test-symbols.sh @@ -66,7 +66,7 @@ echo 'ok documented symbols' # ONLY update this checksum in release commits! cat > released-sha256.txt <<EOF -1f83814b9a785f9f612ee8f707dadb86d0dcbdc22603937575b7beefb26b50cc ${released_syms} +55f21380aa7f9ecc447a680b5c091692f2a0b98aa96ea00fba6aa6406aa69a5a ${released_syms} EOF sha256sum -c released-sha256.txt |