pull: Add OSTREE_REPO_PULL_FLAGS_UNTRUSTED flag

If this is set we verify all objects we pull, even for local remotes,
and we avoid hard-linking into local source repos.

https://bugzilla.gnome.org/show_bug.cgi?id=764125

Closes: #221
Approved by: cgwalters
This commit is contained in:
Alexander Larsson 2016-03-23 11:47:44 +01:00 committed by Colin Walters (automation)
parent f84c198006
commit ed1e0c6d04
5 changed files with 100 additions and 23 deletions

View File

@ -269,6 +269,7 @@ ostree_repo_load_file
ostree_repo_load_object_stream ostree_repo_load_object_stream
ostree_repo_query_object_storage_size ostree_repo_query_object_storage_size
ostree_repo_import_object_from ostree_repo_import_object_from
ostree_repo_import_object_from_with_trust
ostree_repo_delete_object ostree_repo_delete_object
OstreeRepoCommitFilterResult OstreeRepoCommitFilterResult
OstreeRepoCommitFilter OstreeRepoCommitFilter

View File

@ -328,8 +328,7 @@ global:
* NOTE NOTE NOTE * NOTE NOTE NOTE
*/ */
/* UNCOMMENT WITH NEW SYMBOLS HERE:
LIBOSTREE_2016.5 { LIBOSTREE_2016.5 {
global: global:
ostree_repo_import_object_from_with_trust;
} LIBOSTREE_2016.4; } LIBOSTREE_2016.4;
*/

View File

@ -93,6 +93,7 @@ typedef struct {
gboolean is_mirror; gboolean is_mirror;
gboolean is_commit_only; gboolean is_commit_only;
gboolean is_untrusted;
char *dir; char *dir;
gboolean commitpartial_exists; gboolean commitpartial_exists;
@ -473,9 +474,9 @@ scan_dirtree_object (OtPullData *pull_data,
if (!file_is_stored && pull_data->remote_repo_local) if (!file_is_stored && pull_data->remote_repo_local)
{ {
if (!ostree_repo_import_object_from (pull_data->repo, pull_data->remote_repo_local, if (!ostree_repo_import_object_from_with_trust (pull_data->repo, pull_data->remote_repo_local,
OSTREE_OBJECT_TYPE_FILE, file_checksum, OSTREE_OBJECT_TYPE_FILE, file_checksum, !pull_data->is_untrusted,
cancellable, error)) cancellable, error))
goto out; goto out;
} }
else if (!file_is_stored && !g_hash_table_lookup (pull_data->requested_content, file_checksum)) else if (!file_is_stored && !g_hash_table_lookup (pull_data->requested_content, file_checksum))
@ -1189,9 +1190,9 @@ scan_one_metadata_object_c (OtPullData *pull_data,
if (pull_data->remote_repo_local) if (pull_data->remote_repo_local)
{ {
if (!is_stored && if (!is_stored &&
!ostree_repo_import_object_from (pull_data->repo, pull_data->remote_repo_local, !ostree_repo_import_object_from_with_trust (pull_data->repo, pull_data->remote_repo_local,
objtype, tmp_checksum, objtype, tmp_checksum, !pull_data->is_untrusted,
cancellable, error)) cancellable, error))
goto out; goto out;
is_stored = TRUE; is_stored = TRUE;
is_requested = TRUE; is_requested = TRUE;
@ -1931,6 +1932,7 @@ ostree_repo_pull_with_options (OstreeRepo *self,
pull_data->is_mirror = (flags & OSTREE_REPO_PULL_FLAGS_MIRROR) > 0; pull_data->is_mirror = (flags & OSTREE_REPO_PULL_FLAGS_MIRROR) > 0;
pull_data->is_commit_only = (flags & OSTREE_REPO_PULL_FLAGS_COMMIT_ONLY) > 0; pull_data->is_commit_only = (flags & OSTREE_REPO_PULL_FLAGS_COMMIT_ONLY) > 0;
pull_data->is_untrusted = (flags & OSTREE_REPO_PULL_FLAGS_UNTRUSTED) > 0;
if (error) if (error)
pull_data->async_error = &pull_data->cached_async_error; pull_data->async_error = &pull_data->cached_async_error;

View File

@ -3310,24 +3310,37 @@ import_one_object_copy (OstreeRepo *self,
OstreeRepo *source, OstreeRepo *source,
const char *checksum, const char *checksum,
OstreeObjectType objtype, OstreeObjectType objtype,
gboolean trusted,
GCancellable *cancellable, GCancellable *cancellable,
GError **error) GError **error)
{ {
gboolean ret = FALSE; gboolean ret = FALSE;
guint64 length; guint64 length;
g_autoptr(GInputStream) object = NULL; g_autoptr(GInputStream) object_stream = NULL;
if (!ostree_repo_load_object_stream (source, objtype, checksum, if (!ostree_repo_load_object_stream (source, objtype, checksum,
&object, &length, &object_stream, &length,
cancellable, error)) cancellable, error))
goto out; goto out;
if (objtype == OSTREE_OBJECT_TYPE_FILE) if (objtype == OSTREE_OBJECT_TYPE_FILE)
{ {
if (!ostree_repo_write_content_trusted (self, checksum, if (trusted)
object, length, {
cancellable, error)) if (!ostree_repo_write_content_trusted (self, checksum,
goto out; object_stream, length,
cancellable, error))
goto out;
}
else
{
g_autofree guchar *real_csum = NULL;
if (!ostree_repo_write_content (self, checksum,
object_stream, length,
&real_csum,
cancellable, error))
goto out;
}
} }
else else
{ {
@ -3336,10 +3349,29 @@ import_one_object_copy (OstreeRepo *self,
if (!copy_detached_metadata (self, source, checksum, cancellable, error)) if (!copy_detached_metadata (self, source, checksum, cancellable, error))
goto out; goto out;
} }
if (!ostree_repo_write_metadata_stream_trusted (self, objtype,
checksum, object, length, if (trusted)
cancellable, error)) {
goto out; if (!ostree_repo_write_metadata_stream_trusted (self, objtype,
checksum, object_stream, length,
cancellable, error))
goto out;
}
else
{
g_autofree guchar *real_csum = NULL;
g_autoptr(GVariant) variant = NULL;
if (!ostree_repo_load_variant (source, objtype, checksum,
&variant, error))
goto out;
if (!ostree_repo_write_metadata (self, objtype,
checksum, variant,
&real_csum,
cancellable, error))
goto out;
}
} }
ret = TRUE; ret = TRUE;
@ -3419,11 +3451,43 @@ ostree_repo_import_object_from (OstreeRepo *self,
const char *checksum, const char *checksum,
GCancellable *cancellable, GCancellable *cancellable,
GError **error) GError **error)
{
return
ostree_repo_import_object_from_with_trust (self, source, objtype,
checksum, TRUE, cancellable, error);
}
/**
* ostree_repo_import_object_from_with_trust:
* @self: Destination repo
* @source: Source repo
* @objtype: Object type
* @checksum: checksum
* @trusted: If %TRUE, assume the source repo is valid and trusted
* @cancellable: Cancellable
* @error: Error
*
* Copy object named by @objtype and @checksum into @self from the
* source repository @source. If both repositories are of the same
* type and on the same filesystem, this will simply be a fast Unix
* hard link operation.
*
* Otherwise, a copy will be performed.
*/
gboolean
ostree_repo_import_object_from_with_trust (OstreeRepo *self,
OstreeRepo *source,
OstreeObjectType objtype,
const char *checksum,
gboolean trusted,
GCancellable *cancellable,
GError **error)
{ {
gboolean ret = FALSE; gboolean ret = FALSE;
gboolean hardlink_was_supported = FALSE; gboolean hardlink_was_supported = FALSE;
if (self->mode == source->mode) if (trusted && /* Don't hardlink into untrusted remotes */
self->mode == source->mode)
{ {
if (!import_one_object_link (self, source, checksum, objtype, if (!import_one_object_link (self, source, checksum, objtype,
&hardlink_was_supported, &hardlink_was_supported,
@ -3438,10 +3502,10 @@ ostree_repo_import_object_from (OstreeRepo *self,
if (!ostree_repo_has_object (self, objtype, checksum, &has_object, if (!ostree_repo_has_object (self, objtype, checksum, &has_object,
cancellable, error)) cancellable, error))
goto out; goto out;
if (!has_object) if (!has_object)
{ {
if (!import_one_object_copy (self, source, checksum, objtype, if (!import_one_object_copy (self, source, checksum, objtype, trusted,
cancellable, error)) cancellable, error))
goto out; goto out;
} }
@ -3452,6 +3516,7 @@ ostree_repo_import_object_from (OstreeRepo *self,
return ret; return ret;
} }
/** /**
* ostree_repo_query_object_storage_size: * ostree_repo_query_object_storage_size:
* @self: Repo * @self: Repo

View File

@ -423,6 +423,14 @@ gboolean ostree_repo_import_object_from (OstreeRepo *self,
const char *checksum, const char *checksum,
GCancellable *cancellable, GCancellable *cancellable,
GError **error); GError **error);
_OSTREE_PUBLIC
gboolean ostree_repo_import_object_from_with_trust (OstreeRepo *self,
OstreeRepo *source,
OstreeObjectType objtype,
const char *checksum,
gboolean trusted,
GCancellable *cancellable,
GError **error);
_OSTREE_PUBLIC _OSTREE_PUBLIC
gboolean ostree_repo_delete_object (OstreeRepo *self, gboolean ostree_repo_delete_object (OstreeRepo *self,
@ -891,11 +899,13 @@ gboolean ostree_repo_prune (OstreeRepo *self,
* @OSTREE_REPO_PULL_FLAGS_NONE: No special options for pull * @OSTREE_REPO_PULL_FLAGS_NONE: No special options for pull
* @OSTREE_REPO_PULL_FLAGS_MIRROR: Write out refs suitable for mirrors * @OSTREE_REPO_PULL_FLAGS_MIRROR: Write out refs suitable for mirrors
* @OSTREE_REPO_PULL_FLAGS_COMMIT_ONLY: Fetch only the commit metadata * @OSTREE_REPO_PULL_FLAGS_COMMIT_ONLY: Fetch only the commit metadata
* @OSTREE_REPO_PULL_FLAGS_UNTRUSTED: Don't trust local remote
*/ */
typedef enum { typedef enum {
OSTREE_REPO_PULL_FLAGS_NONE, OSTREE_REPO_PULL_FLAGS_NONE,
OSTREE_REPO_PULL_FLAGS_MIRROR = (1 << 0), OSTREE_REPO_PULL_FLAGS_MIRROR = (1 << 0),
OSTREE_REPO_PULL_FLAGS_COMMIT_ONLY = (1 << 1) OSTREE_REPO_PULL_FLAGS_COMMIT_ONLY = (1 << 1),
OSTREE_REPO_PULL_FLAGS_UNTRUSTED = (1 << 2)
} OstreeRepoPullFlags; } OstreeRepoPullFlags;
_OSTREE_PUBLIC _OSTREE_PUBLIC