diff --git a/src/libostree/ostree-core.h b/src/libostree/ostree-core.h index 1fef003a..92b56bb7 100644 --- a/src/libostree/ostree-core.h +++ b/src/libostree/ostree-core.h @@ -226,6 +226,33 @@ typedef enum { * Since: 2017.7 */ #define OSTREE_COMMIT_META_KEY_ENDOFLIFE "ostree.endoflife" +/** + * OSTREE_COMMIT_META_KEY_REF_BINDING: + * + * GVariant type `as`; each element is a branch name. If this is added to a + * commit, `ostree_repo_pull()` will enforce that the commit was retrieved from + * one of the branch names in this array. This prevents "sidegrade" attacks. + * The rationale for having this support multiple branch names is that it helps + * support a "promotion" model of taking a commit and moving it between development + * and production branches. + * + * Since: 2017.9 + */ +#define OSTREE_COMMIT_META_KEY_REF_BINDING "ostree.ref-binding" +/** + * OSTREE_COMMIT_META_KEY_COLLECTION_BINDING: + * + * GVariant type `s`. If this is added to a commit, `ostree_repo_pull()` + * will enforce that the commit was retrieved from a repository which has + * the same collection ID. See `ostree_repo_set_collection_id()`. + * This is most useful in concert with `OSTREE_COMMIT_META_KEY_REF_BINDING`, + * as it more strongly binds the commit to the repository and branch. + * + * Since: 2017.9 + */ +#ifdef OSTREE_ENABLE_EXPERIMENTAL_API +#define OSTREE_COMMIT_META_KEY_COLLECTION_BINDING "ostree.collection-binding" +#endif _OSTREE_PUBLIC const GVariantType *ostree_metadata_variant_type (OstreeObjectType objtype); diff --git a/src/libostree/ostree-repo-private.h b/src/libostree/ostree-repo-private.h index da448bbe..5dd0dea7 100644 --- a/src/libostree/ostree-repo-private.h +++ b/src/libostree/ostree-repo-private.h @@ -56,10 +56,6 @@ G_BEGIN_DECLS * in a summary file. */ #define OSTREE_COMMIT_TIMESTAMP "ostree.commit.timestamp" -/* Well-known keys for the commit metadata */ -#define OSTREE_REF_BINDING "ostree.ref-binding" -#define OSTREE_COLLECTION_BINDING "ostree.collection-binding" - typedef enum { OSTREE_REPO_TEST_ERROR_PRE_COMMIT = (1 << 0) } OstreeRepoTestErrorFlags; diff --git a/src/libostree/ostree-repo-pull.c b/src/libostree/ostree-repo-pull.c index 1c0f79ea..8ba69580 100644 --- a/src/libostree/ostree-repo-pull.c +++ b/src/libostree/ostree-repo-pull.c @@ -1506,7 +1506,7 @@ verify_bindings (OtPullData *pull_data, g_autoptr(GVariant) metadata = g_variant_get_child_value (commit, 0); g_autofree const char **refs = NULL; if (!g_variant_lookup (metadata, - OSTREE_REF_BINDING, + OSTREE_COMMIT_META_KEY_REF_BINDING, "^a&s", &refs)) { @@ -1555,9 +1555,10 @@ verify_bindings (OtPullData *pull_data, if (remote_collection_id != NULL) { +#ifdef OSTREE_ENABLE_EXPERIMENTAL_API const char *collection_id; if (!g_variant_lookup (metadata, - OSTREE_COLLECTION_BINDING, + OSTREE_COMMIT_META_KEY_COLLECTION_BINDING, "&s", &collection_id)) return glnx_throw (error, @@ -1569,6 +1570,7 @@ verify_bindings (OtPullData *pull_data, "metadata, while the remote it came from has " "collection ID ā€˜%s’", collection_id, remote_collection_id); +#endif } return TRUE; diff --git a/src/ostree/ot-builtin-commit.c b/src/ostree/ot-builtin-commit.c index 35340a04..8f359380 100644 --- a/src/ostree/ot-builtin-commit.c +++ b/src/ostree/ot-builtin-commit.c @@ -316,7 +316,7 @@ add_collection_binding (OstreeRepo *repo, if (collection_id == NULL) return; - g_variant_builder_add (metadata_builder, "{s@v}", OSTREE_COLLECTION_BINDING, + g_variant_builder_add (metadata_builder, "{s@v}", OSTREE_COMMIT_META_KEY_COLLECTION_BINDING, g_variant_new_variant (g_variant_new_string (collection_id))); } #endif /* OSTREE_ENABLE_EXPERIMENTAL_API */ @@ -345,10 +345,11 @@ add_ref_binding (GVariantBuilder *metadata_builder) g_ptr_array_sort (refs, compare_strings); g_autoptr(GVariant) refs_v = g_variant_new_strv ((const char *const *)refs->pdata, refs->len); - g_variant_builder_add (metadata_builder, "{s@v}", OSTREE_REF_BINDING, + g_variant_builder_add (metadata_builder, "{s@v}", OSTREE_COMMIT_META_KEY_REF_BINDING, g_variant_new_variant (g_steal_pointer (&refs_v))); } +/* Note if you're using the API, you currently need to do this yourself */ static void fill_bindings (OstreeRepo *repo, GVariant *metadata, @@ -363,7 +364,7 @@ fill_bindings (OstreeRepo *repo, /* Allow the collection ID to be overridden using * --add-metadata-string=ostree.collection-binding=blah */ if (metadata == NULL || - !g_variant_lookup (metadata, OSTREE_COLLECTION_BINDING, "*", NULL)) + !g_variant_lookup (metadata, OSTREE_COMMIT_META_KEY_COLLECTION_BINDING, "*", NULL)) add_collection_binding (repo, metadata_builder); #endif /* OSTREE_ENABLE_EXPERIMENTAL_API */