lib/pull: Split verify_bindings() out into a cmdprivate method

It will be used by the fsck utility in future. We could expose it
publicly in future too, if needed.

Signed-off-by: Philip Withnall <withnall@endlessm.com>

Closes: #1347
Approved by: cgwalters
This commit is contained in:
Philip Withnall authored and Atomic Bot committed 2017-12-14 14:18:44 +00:00
1 parent 1160d3a110
commit 1b7d83114e
6 files changed
+82 -26

No files matched your search

+44 -25
View File
@@ -32,6 +32,7 @@
#include "ostree-core-private.h"
#include "ostree-repo-private.h"
#include "ostree-repo-pull-private.h"
#include "ostree-repo-static-delta-private.h"
#include "ostree-metalink.h"
#include "ostree-fetcher-util.h"
@@ -1475,30 +1476,40 @@ get_remote_repo_collection_id (OtPullData *pull_data)
}
#endif /* OSTREE_ENABLE_EXPERIMENTAL_API */
/* Verify the ref and collection bindings.
#endif /* HAVE_LIBCURL_OR_LIBSOUP */
/**
* _ostree_repo_verify_bindings:
* @collection_id: (nullable): Locally specified collection ID for the remote
* the @commit was retrieved from, or %NULL if none is configured
* @ref_name: (nullable): Ref name the commit was retrieved using, or %NULL if
* the commit was retrieved by checksum
* @commit: Commit data to check
* @error: Return location for a #GError, or %NULL
*
* Verify the ref and collection bindings.
*
* The ref binding is verified only if it exists. But if we have the
* collection ID specified in the remote configuration then the ref
* binding must exist, otherwise the verification will fail. Parts of
* the verification can be skipped by passing NULL to the requested_ref
* parameter (in case we requested a checksum directly, without looking it up
* from a ref).
* collection ID specified in the remote configuration (@collection_id is
* non-%NULL) then the ref binding must exist, otherwise the verification will
* fail. Parts of the verification can be skipped by passing %NULL to the
* @ref_name parameter (in case we requested a checksum directly, without
* looking it up from a ref).
*
* The collection binding is verified only when we have collection ID
* specified in the remote configuration. If it is specified, then the
* binding must exist and must be equal to the remote repository
* collection ID.
*
* Returns: %TRUE if bindings are correct, %FALSE otherwise
* Since: 2017.14
*/
static gboolean
verify_bindings (OtPullData *pull_data,
GVariant *commit,
const OstreeCollectionRef *requested_ref,
GError **error)
gboolean
_ostree_repo_verify_bindings (const char *collection_id,
const char *ref_name,
GVariant *commit,
GError **error)
{
g_autofree char *remote_collection_id = NULL;
#ifdef OSTREE_ENABLE_EXPERIMENTAL_API
remote_collection_id = get_remote_repo_collection_id (pull_data);
#endif /* OSTREE_ENABLE_EXPERIMENTAL_API */
g_autoptr(GVariant) metadata = g_variant_get_child_value (commit, 0);
g_autofree const char **refs = NULL;
if (!g_variant_lookup (metadata,
@@ -1510,7 +1521,7 @@ verify_bindings (OtPullData *pull_data,
* we certainly will not verify the collection binding in the
* commit.
*/
if (remote_collection_id == NULL)
if (collection_id == NULL)
return TRUE;
return glnx_throw (error,
@@ -1518,9 +1529,9 @@ verify_bindings (OtPullData *pull_data,
"binding information, found none");
}
if (requested_ref != NULL)
if (ref_name != NULL)
{
if (!g_strv_contains ((const char *const *) refs, requested_ref->ref_name))
if (!g_strv_contains ((const char *const *) refs, ref_name))
{
g_autoptr(GString) refs_dump = g_string_new (NULL);
const char *refs_str;
@@ -1545,33 +1556,35 @@ verify_bindings (OtPullData *pull_data,
return glnx_throw (error, "commit has no requested ref ‘%s’ "
"in ref binding metadata (%s)",
requested_ref->ref_name, refs_str);
ref_name, refs_str);
}
}
if (remote_collection_id != NULL)
if (collection_id != NULL)
{
#ifdef OSTREE_ENABLE_EXPERIMENTAL_API
const char *collection_id;
const char *collection_id_binding;
if (!g_variant_lookup (metadata,
OSTREE_COMMIT_META_KEY_COLLECTION_BINDING,
"&s",
&collection_id))
&collection_id_binding))
return glnx_throw (error,
"expected commit metadata to have collection ID "
"binding information, found none");
if (!g_str_equal (collection_id, remote_collection_id))
if (!g_str_equal (collection_id_binding, collection_id))
return glnx_throw (error,
"commit has collection ID ‘%s’ in collection binding "
"metadata, while the remote it came from has "
"collection ID ‘%s’",
collection_id, remote_collection_id);
collection_id_binding, collection_id);
#endif
}
return TRUE;
}
#ifdef HAVE_LIBCURL_OR_LIBSOUP
/* Look at a commit object, and determine whether there are
* more things to fetch.
*/
@@ -1626,7 +1639,13 @@ scan_commit_object (OtPullData *pull_data,
/* If ref is non-NULL then the commit we fetched was requested through the
* branch, otherwise we requested a commit checksum without specifying a branch.
*/
if (!verify_bindings (pull_data, commit, ref, error))
g_autofree char *remote_collection_id = NULL;
#ifdef OSTREE_ENABLE_EXPERIMENTAL_API
remote_collection_id = get_remote_repo_collection_id (pull_data);
#endif /* OSTREE_ENABLE_EXPERIMENTAL_API */
if (!_ostree_repo_verify_bindings (remote_collection_id,
(ref != NULL) ? ref->ref_name : NULL,
commit, error))
return glnx_prefix_error (error, "Commit %s", checksum);
if (pull_data->timestamp_check)