From 92e4ee62201947ab00a97cc7a4d779684c90c9fd Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Thu, 16 Jun 2022 16:54:59 +0200 Subject: [PATCH 1/7] misc: Rename GsAppPermissions into GsAppPermissionsFlags Simple search & replace on the type name and the enum value. It's needed to be able to declare a GsAppPermissions object, which will hold the flags and additional information. --- lib/gs-app.c | 22 ++++---- lib/gs-app.h | 56 +++++++++---------- plugins/epiphany/gs-plugin-epiphany.c | 2 +- plugins/flatpak/gs-flatpak.c | 74 ++++++++++++------------- src/gs-app-context-bar.c | 42 +++++++-------- src/gs-app-details-page.c | 32 +++++------ src/gs-safety-context-dialog.c | 78 +++++++++++++-------------- 7 files changed, 155 insertions(+), 151 deletions(-) diff --git a/lib/gs-app.c b/lib/gs-app.c index 4666c3c85..159d55b5f 100644 --- a/lib/gs-app.c +++ b/lib/gs-app.c @@ -93,7 +93,7 @@ typedef struct gchar *update_version_ui; gchar *update_details_markup; AsUrgencyKind update_urgency; - GsAppPermissions update_permissions; + GsAppPermissionsFlags update_permissions; GWeakRef management_plugin_weak; /* (element-type GsPlugin) */ guint match_value; guint priority; @@ -135,7 +135,7 @@ typedef struct AsScreenshot *action_screenshot; /* (nullable) (owned) */ GCancellable *cancellable; GsPluginAction pending_action; - GsAppPermissions permissions; + GsAppPermissionsFlags permissions; gboolean is_update_downloaded; GPtrArray *version_history; /* (element-type AsRelease) (nullable) (owned) */ GPtrArray *relations; /* (nullable) (element-type AsRelation) (owned) */ @@ -5929,13 +5929,13 @@ gs_app_class_init (GsAppClass *klass) * * The permissions the app requires to run. * - * This is %GS_APP_PERMISSIONS_UNKNOWN if the permissions are unknown. + * This is %GS_APP_PERMISSIONS_FLAGS_UNKNOWN if the permissions are unknown. * * Since: 41 */ obj_props[PROP_PERMISSIONS] = g_param_spec_flags ("permissions", NULL, NULL, - GS_TYPE_APP_PERMISSIONS, GS_APP_PERMISSIONS_UNKNOWN, + GS_TYPE_APP_PERMISSIONS_FLAGS, GS_APP_PERMISSIONS_FLAGS_UNKNOWN, G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); /** @@ -6315,16 +6315,17 @@ gs_app_subsume_metadata (GsApp *app, GsApp *donor) } } -GsAppPermissions +GsAppPermissionsFlags gs_app_get_permissions (GsApp *app) { GsAppPrivate *priv = gs_app_get_instance_private (app); - g_return_val_if_fail (GS_IS_APP (app), GS_APP_PERMISSIONS_UNKNOWN); + g_return_val_if_fail (GS_IS_APP (app), GS_APP_PERMISSIONS_FLAGS_UNKNOWN); return priv->permissions; } void -gs_app_set_permissions (GsApp *app, GsAppPermissions permissions) +gs_app_set_permissions (GsApp *app, + GsAppPermissionsFlags permissions) { GsAppPrivate *priv = gs_app_get_instance_private (app); g_return_if_fail (GS_IS_APP (app)); @@ -6335,16 +6336,17 @@ gs_app_set_permissions (GsApp *app, GsAppPermissions permissions) gs_app_queue_notify (app, obj_props[PROP_PERMISSIONS]); } -GsAppPermissions +GsAppPermissionsFlags gs_app_get_update_permissions (GsApp *app) { GsAppPrivate *priv = gs_app_get_instance_private (app); - g_return_val_if_fail (GS_IS_APP (app), GS_APP_PERMISSIONS_UNKNOWN); + g_return_val_if_fail (GS_IS_APP (app), GS_APP_PERMISSIONS_FLAGS_UNKNOWN); return priv->update_permissions; } void -gs_app_set_update_permissions (GsApp *app, GsAppPermissions update_permissions) +gs_app_set_update_permissions (GsApp *app, + GsAppPermissionsFlags update_permissions) { GsAppPrivate *priv = gs_app_get_instance_private (app); g_return_if_fail (GS_IS_APP (app)); diff --git a/lib/gs-app.h b/lib/gs-app.h index 663a65677..7eec0f227 100644 --- a/lib/gs-app.h +++ b/lib/gs-app.h @@ -209,31 +209,31 @@ typedef enum { } GsAppQuality; typedef enum { - GS_APP_PERMISSIONS_UNKNOWN = 0, - GS_APP_PERMISSIONS_NONE = 1 << 0, - GS_APP_PERMISSIONS_NETWORK = 1 << 1, - GS_APP_PERMISSIONS_SYSTEM_BUS = 1 << 2, - GS_APP_PERMISSIONS_SESSION_BUS = 1 << 3, - GS_APP_PERMISSIONS_DEVICES = 1 << 4, - GS_APP_PERMISSIONS_HOME_FULL = 1 << 5, - GS_APP_PERMISSIONS_HOME_READ = 1 << 6, - GS_APP_PERMISSIONS_FILESYSTEM_FULL = 1 << 7, - GS_APP_PERMISSIONS_FILESYSTEM_READ = 1 << 8, - GS_APP_PERMISSIONS_DOWNLOADS_FULL = 1 << 9, - GS_APP_PERMISSIONS_DOWNLOADS_READ = 1 << 10, - GS_APP_PERMISSIONS_SETTINGS = 1 << 11, - GS_APP_PERMISSIONS_X11 = 1 << 12, - GS_APP_PERMISSIONS_ESCAPE_SANDBOX = 1 << 13, - GS_APP_PERMISSIONS_FILESYSTEM_OTHER = 1 << 14, - GS_APP_PERMISSIONS_LAST /*< skip >*/ -} GsAppPermissions; + GS_APP_PERMISSIONS_FLAGS_UNKNOWN = 0, + GS_APP_PERMISSIONS_FLAGS_NONE = 1 << 0, + GS_APP_PERMISSIONS_FLAGS_NETWORK = 1 << 1, + GS_APP_PERMISSIONS_FLAGS_SYSTEM_BUS = 1 << 2, + GS_APP_PERMISSIONS_FLAGS_SESSION_BUS = 1 << 3, + GS_APP_PERMISSIONS_FLAGS_DEVICES = 1 << 4, + GS_APP_PERMISSIONS_FLAGS_HOME_FULL = 1 << 5, + GS_APP_PERMISSIONS_FLAGS_HOME_READ = 1 << 6, + GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_FULL = 1 << 7, + GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_READ = 1 << 8, + GS_APP_PERMISSIONS_FLAGS_DOWNLOADS_FULL = 1 << 9, + GS_APP_PERMISSIONS_FLAGS_DOWNLOADS_READ = 1 << 10, + GS_APP_PERMISSIONS_FLAGS_SETTINGS = 1 << 11, + GS_APP_PERMISSIONS_FLAGS_X11 = 1 << 12, + GS_APP_PERMISSIONS_FLAGS_ESCAPE_SANDBOX = 1 << 13, + GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_OTHER = 1 << 14, + GS_APP_PERMISSIONS_FLAGS_LAST /*< skip >*/ +} GsAppPermissionsFlags; -#define LIMITED_PERMISSIONS (GS_APP_PERMISSIONS_SETTINGS | \ - GS_APP_PERMISSIONS_NETWORK | \ - GS_APP_PERMISSIONS_DOWNLOADS_READ | \ - GS_APP_PERMISSIONS_DOWNLOADS_FULL) +#define LIMITED_PERMISSIONS (GS_APP_PERMISSIONS_FLAGS_SETTINGS | \ + GS_APP_PERMISSIONS_FLAGS_NETWORK | \ + GS_APP_PERMISSIONS_FLAGS_DOWNLOADS_READ | \ + GS_APP_PERMISSIONS_FLAGS_DOWNLOADS_FULL) #define MEDIUM_PERMISSIONS (LIMITED_PERMISSIONS | \ - GS_APP_PERMISSIONS_X11) + GS_APP_PERMISSIONS_FLAGS_X11) /** * GS_APP_PROGRESS_UNKNOWN: @@ -516,12 +516,14 @@ gchar *gs_app_get_packaging_format (GsApp *app); const gchar *gs_app_get_packaging_format_raw(GsApp *app); void gs_app_subsume_metadata (GsApp *app, GsApp *donor); -GsAppPermissions gs_app_get_permissions (GsApp *app); +GsAppPermissionsFlags + gs_app_get_permissions (GsApp *app); void gs_app_set_permissions (GsApp *app, - GsAppPermissions permissions); -GsAppPermissions gs_app_get_update_permissions (GsApp *app); + GsAppPermissionsFlags permissions); +GsAppPermissionsFlags + gs_app_get_update_permissions (GsApp *app); void gs_app_set_update_permissions (GsApp *app, - GsAppPermissions update_permissions); + GsAppPermissionsFlags update_permissions); GPtrArray *gs_app_get_version_history (GsApp *app); void gs_app_set_version_history (GsApp *app, GPtrArray *version_history); diff --git a/plugins/epiphany/gs-plugin-epiphany.c b/plugins/epiphany/gs-plugin-epiphany.c index 78e5e2af5..1f7e20072 100644 --- a/plugins/epiphany/gs-plugin-epiphany.c +++ b/plugins/epiphany/gs-plugin-epiphany.c @@ -487,7 +487,7 @@ refine_app (GsPluginEpiphany *self, gs_app_set_size_download (app, GS_SIZE_TYPE_VALID, 0); - gs_app_set_permissions (app, GS_APP_PERMISSIONS_NETWORK); + gs_app_set_permissions (app, GS_APP_PERMISSIONS_FLAGS_NETWORK); if (gs_app_get_url (app, AS_URL_KIND_HOMEPAGE) == NULL) gs_app_set_url (app, AS_URL_KIND_HOMEPAGE, url); diff --git a/plugins/flatpak/gs-flatpak.c b/plugins/flatpak/gs-flatpak.c index 4ac84022c..0ce47d8ef 100644 --- a/plugins/flatpak/gs-flatpak.c +++ b/plugins/flatpak/gs-flatpak.c @@ -212,51 +212,51 @@ gs_flatpak_set_kind_from_flatpak (GsApp *app, FlatpakRef *xref) } } -static GsAppPermissions +static GsAppPermissionsFlags perms_from_metadata (GKeyFile *keyfile) { char **strv; char *str; - GsAppPermissions permissions = GS_APP_PERMISSIONS_UNKNOWN; + GsAppPermissionsFlags permissions = GS_APP_PERMISSIONS_FLAGS_UNKNOWN; strv = g_key_file_get_string_list (keyfile, "Context", "sockets", NULL, NULL); if (strv != NULL && g_strv_contains ((const gchar * const*)strv, "system-bus")) - permissions |= GS_APP_PERMISSIONS_SYSTEM_BUS; + permissions |= GS_APP_PERMISSIONS_FLAGS_SYSTEM_BUS; if (strv != NULL && g_strv_contains ((const gchar * const*)strv, "session-bus")) - permissions |= GS_APP_PERMISSIONS_SESSION_BUS; + permissions |= GS_APP_PERMISSIONS_FLAGS_SESSION_BUS; if (strv != NULL && !g_strv_contains ((const gchar * const*)strv, "fallback-x11") && g_strv_contains ((const gchar * const*)strv, "x11")) - permissions |= GS_APP_PERMISSIONS_X11; + permissions |= GS_APP_PERMISSIONS_FLAGS_X11; g_strfreev (strv); strv = g_key_file_get_string_list (keyfile, "Context", "devices", NULL, NULL); if (strv != NULL && g_strv_contains ((const gchar * const*)strv, "all")) - permissions |= GS_APP_PERMISSIONS_DEVICES; + permissions |= GS_APP_PERMISSIONS_FLAGS_DEVICES; g_strfreev (strv); strv = g_key_file_get_string_list (keyfile, "Context", "shared", NULL, NULL); if (strv != NULL && g_strv_contains ((const gchar * const*)strv, "network")) - permissions |= GS_APP_PERMISSIONS_NETWORK; + permissions |= GS_APP_PERMISSIONS_FLAGS_NETWORK; g_strfreev (strv); strv = g_key_file_get_string_list (keyfile, "Context", "filesystems", NULL, NULL); if (strv != NULL) { const struct { const gchar *key; - GsAppPermissions perm; + GsAppPermissionsFlags perm; } filesystems_access[] = { /* Reference: https://docs.flatpak.org/en/latest/flatpak-command-reference.html#idm45858571325264 */ - { "home", GS_APP_PERMISSIONS_HOME_FULL }, - { "home:rw", GS_APP_PERMISSIONS_HOME_FULL }, - { "home:ro", GS_APP_PERMISSIONS_HOME_READ }, - { "host", GS_APP_PERMISSIONS_FILESYSTEM_FULL }, - { "host:rw", GS_APP_PERMISSIONS_FILESYSTEM_FULL }, - { "host:ro", GS_APP_PERMISSIONS_FILESYSTEM_READ }, - { "xdg-download", GS_APP_PERMISSIONS_DOWNLOADS_FULL }, - { "xdg-download:rw", GS_APP_PERMISSIONS_DOWNLOADS_FULL }, - { "xdg-download:ro", GS_APP_PERMISSIONS_DOWNLOADS_READ }, - { "xdg-data/flatpak/overrides:create", GS_APP_PERMISSIONS_ESCAPE_SANDBOX } + { "home", GS_APP_PERMISSIONS_FLAGS_HOME_FULL }, + { "home:rw", GS_APP_PERMISSIONS_FLAGS_HOME_FULL }, + { "home:ro", GS_APP_PERMISSIONS_FLAGS_HOME_READ }, + { "host", GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_FULL }, + { "host:rw", GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_FULL }, + { "host:ro", GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_READ }, + { "xdg-download", GS_APP_PERMISSIONS_FLAGS_DOWNLOADS_FULL }, + { "xdg-download:rw", GS_APP_PERMISSIONS_FLAGS_DOWNLOADS_FULL }, + { "xdg-download:ro", GS_APP_PERMISSIONS_FLAGS_DOWNLOADS_READ }, + { "xdg-data/flatpak/overrides:create", GS_APP_PERMISSIONS_FLAGS_ESCAPE_SANDBOX } }; guint filesystems_hits = 0; @@ -267,40 +267,40 @@ perms_from_metadata (GKeyFile *keyfile) } } - if ((permissions & GS_APP_PERMISSIONS_HOME_FULL) != 0) - permissions = permissions & ~GS_APP_PERMISSIONS_HOME_READ; - if ((permissions & GS_APP_PERMISSIONS_FILESYSTEM_FULL) != 0) - permissions = permissions & ~GS_APP_PERMISSIONS_FILESYSTEM_READ; - if ((permissions & GS_APP_PERMISSIONS_DOWNLOADS_FULL) != 0) - permissions = permissions & ~GS_APP_PERMISSIONS_DOWNLOADS_READ; + if ((permissions & GS_APP_PERMISSIONS_FLAGS_HOME_FULL) != 0) + permissions = permissions & ~GS_APP_PERMISSIONS_FLAGS_HOME_READ; + if ((permissions & GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_FULL) != 0) + permissions = permissions & ~GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_READ; + if ((permissions & GS_APP_PERMISSIONS_FLAGS_DOWNLOADS_FULL) != 0) + permissions = permissions & ~GS_APP_PERMISSIONS_FLAGS_DOWNLOADS_READ; if (g_strv_length (strv) > filesystems_hits) - permissions |= GS_APP_PERMISSIONS_FILESYSTEM_OTHER; + permissions |= GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_OTHER; } g_strfreev (strv); str = g_key_file_get_string (keyfile, "Session Bus Policy", "ca.desrt.dconf", NULL); if (str != NULL && g_str_equal (str, "talk")) - permissions |= GS_APP_PERMISSIONS_SETTINGS; + permissions |= GS_APP_PERMISSIONS_FLAGS_SETTINGS; g_free (str); - if (!(permissions & GS_APP_PERMISSIONS_ESCAPE_SANDBOX)) { + if (!(permissions & GS_APP_PERMISSIONS_FLAGS_ESCAPE_SANDBOX)) { str = g_key_file_get_string (keyfile, "Session Bus Policy", "org.freedesktop.Flatpak", NULL); if (str != NULL && g_str_equal (str, "talk")) - permissions |= GS_APP_PERMISSIONS_ESCAPE_SANDBOX; + permissions |= GS_APP_PERMISSIONS_FLAGS_ESCAPE_SANDBOX; g_free (str); } - if (!(permissions & GS_APP_PERMISSIONS_ESCAPE_SANDBOX)) { + if (!(permissions & GS_APP_PERMISSIONS_FLAGS_ESCAPE_SANDBOX)) { str = g_key_file_get_string (keyfile, "Session Bus Policy", "org.freedesktop.impl.portal.PermissionStore", NULL); if (str != NULL && g_str_equal (str, "talk")) - permissions |= GS_APP_PERMISSIONS_ESCAPE_SANDBOX; + permissions |= GS_APP_PERMISSIONS_FLAGS_ESCAPE_SANDBOX; g_free (str); } /* no permissions set */ - if (permissions == GS_APP_PERMISSIONS_UNKNOWN) - return GS_APP_PERMISSIONS_NONE; + if (permissions == GS_APP_PERMISSIONS_FLAGS_UNKNOWN) + return GS_APP_PERMISSIONS_FLAGS_NONE; return permissions; } @@ -316,7 +316,7 @@ gs_flatpak_set_update_permissions (GsFlatpak *self, g_autoptr(GKeyFile) old_keyfile = NULL; g_autoptr(GBytes) bytes = NULL; g_autoptr(GKeyFile) keyfile = NULL; - GsAppPermissions permissions; + GsAppPermissionsFlags permissions; g_autoptr(GError) error_local = NULL; old_bytes = flatpak_installed_ref_load_metadata (FLATPAK_INSTALLED_REF (xref), NULL, NULL); @@ -335,7 +335,7 @@ gs_flatpak_set_update_permissions (GsFlatpak *self, g_debug ("Failed to get metadata for remote ‘%s’: %s", gs_app_get_origin (app), error_local->message); g_clear_error (&error_local); - permissions = GS_APP_PERMISSIONS_UNKNOWN; + permissions = GS_APP_PERMISSIONS_FLAGS_UNKNOWN; } else { keyfile = g_key_file_new (); g_key_file_load_from_data (keyfile, @@ -346,12 +346,12 @@ gs_flatpak_set_update_permissions (GsFlatpak *self, } /* no new permissions set */ - if (permissions == GS_APP_PERMISSIONS_UNKNOWN) - permissions = GS_APP_PERMISSIONS_NONE; + if (permissions == GS_APP_PERMISSIONS_FLAGS_UNKNOWN) + permissions = GS_APP_PERMISSIONS_FLAGS_NONE; gs_app_set_update_permissions (app, permissions); - if (permissions != GS_APP_PERMISSIONS_NONE) + if (permissions != GS_APP_PERMISSIONS_FLAGS_NONE) gs_app_add_quirk (app, GS_APP_QUIRK_NEW_PERMISSIONS); } diff --git a/src/gs-app-context-bar.c b/src/gs-app-context-bar.c index d2ff4b95b..31202f83c 100644 --- a/src/gs-app-context-bar.c +++ b/src/gs-app-context-bar.c @@ -256,7 +256,7 @@ update_safety_tile (GsAppContextBar *self) const gchar *icon_name, *title, *css_class; g_autoptr(GPtrArray) descriptions = g_ptr_array_new_with_free_func (NULL); g_autofree gchar *description = NULL; - GsAppPermissions permissions; + GsAppPermissionsFlags permissions; GtkStyleContext *context; /* Treat everything as safe to begin with, and downgrade its safety @@ -266,19 +266,19 @@ update_safety_tile (GsAppContextBar *self) g_assert (self->app != NULL); permissions = gs_app_get_permissions (self->app); - for (GsAppPermissions i = GS_APP_PERMISSIONS_NONE; i < GS_APP_PERMISSIONS_LAST; i <<= 1) { + for (GsAppPermissionsFlags i = GS_APP_PERMISSIONS_FLAGS_NONE; i < GS_APP_PERMISSIONS_FLAGS_LAST; i <<= 1) { if (!(permissions & i)) continue; switch (i) { - case GS_APP_PERMISSIONS_NONE: + case GS_APP_PERMISSIONS_FLAGS_NONE: add_to_safety_rating (&chosen_rating, descriptions, SAFETY_SAFE, /* Translators: This indicates an app requires no permissions to run. * It’s used in a context tile, so should be short. */ _("No permissions")); break; - case GS_APP_PERMISSIONS_NETWORK: + case GS_APP_PERMISSIONS_FLAGS_NETWORK: add_to_safety_rating (&chosen_rating, descriptions, /* This isn’t actually safe (network access can expand a local * vulnerability into a remotely exploitable one), but it’s @@ -289,31 +289,31 @@ update_safety_tile (GsAppContextBar *self) * It’s used in a context tile, so should be short. */ _("Has network access")); break; - case GS_APP_PERMISSIONS_SYSTEM_BUS: + case GS_APP_PERMISSIONS_FLAGS_SYSTEM_BUS: add_to_safety_rating (&chosen_rating, descriptions, SAFETY_POTENTIALLY_UNSAFE, /* Translators: This indicates an app uses D-Bus system services. * It’s used in a context tile, so should be short. */ _("Uses system services")); break; - case GS_APP_PERMISSIONS_SESSION_BUS: + case GS_APP_PERMISSIONS_FLAGS_SESSION_BUS: add_to_safety_rating (&chosen_rating, descriptions, SAFETY_UNSAFE, /* Translators: This indicates an app uses D-Bus session services. * It’s used in a context tile, so should be short. */ _("Uses session services")); break; - case GS_APP_PERMISSIONS_DEVICES: + case GS_APP_PERMISSIONS_FLAGS_DEVICES: add_to_safety_rating (&chosen_rating, descriptions, SAFETY_POTENTIALLY_UNSAFE, /* Translators: This indicates an app can access arbitrary hardware devices. * It’s used in a context tile, so should be short. */ _("Can access hardware devices")); break; - case GS_APP_PERMISSIONS_HOME_FULL: - case GS_APP_PERMISSIONS_FILESYSTEM_FULL: + case GS_APP_PERMISSIONS_FLAGS_HOME_FULL: + case GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_FULL: /* Don’t add twice. */ - if (i == GS_APP_PERMISSIONS_HOME_FULL && (permissions & GS_APP_PERMISSIONS_FILESYSTEM_FULL)) + if (i == GS_APP_PERMISSIONS_FLAGS_HOME_FULL && (permissions & GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_FULL)) break; add_to_safety_rating (&chosen_rating, descriptions, @@ -322,10 +322,10 @@ update_safety_tile (GsAppContextBar *self) * It’s used in a context tile, so should be short. */ _("Can read/write all your data")); break; - case GS_APP_PERMISSIONS_HOME_READ: - case GS_APP_PERMISSIONS_FILESYSTEM_READ: + case GS_APP_PERMISSIONS_FLAGS_HOME_READ: + case GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_READ: /* Don’t add twice. */ - if (i == GS_APP_PERMISSIONS_HOME_READ && (permissions & GS_APP_PERMISSIONS_FILESYSTEM_READ)) + if (i == GS_APP_PERMISSIONS_FLAGS_HOME_READ && (permissions & GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_READ)) break; add_to_safety_rating (&chosen_rating, descriptions, @@ -334,42 +334,42 @@ update_safety_tile (GsAppContextBar *self) * It’s used in a context tile, so should be short. */ _("Can read all your data")); break; - case GS_APP_PERMISSIONS_DOWNLOADS_FULL: + case GS_APP_PERMISSIONS_FLAGS_DOWNLOADS_FULL: add_to_safety_rating (&chosen_rating, descriptions, SAFETY_POTENTIALLY_UNSAFE, /* Translators: This indicates an app can read/write to the user’s Downloads directory. * It’s used in a context tile, so should be short. */ _("Can read/write your downloads")); break; - case GS_APP_PERMISSIONS_DOWNLOADS_READ: + case GS_APP_PERMISSIONS_FLAGS_DOWNLOADS_READ: add_to_safety_rating (&chosen_rating, descriptions, SAFETY_POTENTIALLY_UNSAFE, /* Translators: This indicates an app can read (but not write) from the user’s Downloads directory. * It’s used in a context tile, so should be short. */ _("Can read your downloads")); break; - case GS_APP_PERMISSIONS_FILESYSTEM_OTHER: + case GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_OTHER: add_to_safety_rating (&chosen_rating, descriptions, SAFETY_POTENTIALLY_UNSAFE, /* Translators: This indicates an app can access data in the system unknown to the Software. * It’s used in a context tile, so should be short. */ _("Can access arbitrary files")); break; - case GS_APP_PERMISSIONS_SETTINGS: + case GS_APP_PERMISSIONS_FLAGS_SETTINGS: add_to_safety_rating (&chosen_rating, descriptions, SAFETY_POTENTIALLY_UNSAFE, /* Translators: This indicates an app can access or change user settings. * It’s used in a context tile, so should be short. */ _("Can access and change user settings")); break; - case GS_APP_PERMISSIONS_X11: + case GS_APP_PERMISSIONS_FLAGS_X11: add_to_safety_rating (&chosen_rating, descriptions, SAFETY_UNSAFE, /* Translators: This indicates an app uses the X11 windowing system. * It’s used in a context tile, so should be short. */ _("Uses a legacy windowing system")); break; - case GS_APP_PERMISSIONS_ESCAPE_SANDBOX: + case GS_APP_PERMISSIONS_FLAGS_ESCAPE_SANDBOX: add_to_safety_rating (&chosen_rating, descriptions, SAFETY_UNSAFE, /* Translators: This indicates an app can escape its sandbox. @@ -393,7 +393,7 @@ update_safety_tile (GsAppContextBar *self) * FIXME: We could do better by potentially adding a ‘trusted’ state * to indicate that something is probably safe, but isn’t sandboxed. * See https://gitlab.gnome.org/GNOME/gnome-software/-/issues/1451 */ - if (permissions == GS_APP_PERMISSIONS_UNKNOWN && + if (permissions == GS_APP_PERMISSIONS_FLAGS_UNKNOWN && gs_app_has_quirk (self->app, GS_APP_QUIRK_PROVENANCE)) add_to_safety_rating (&chosen_rating, descriptions, SAFETY_SAFE, @@ -401,7 +401,7 @@ update_safety_tile (GsAppContextBar *self) * by the user’s distribution and is safe. * It’s used in a context tile, so should be short. */ _("Reviewed by your distribution")); - else if (permissions == GS_APP_PERMISSIONS_UNKNOWN) + else if (permissions == GS_APP_PERMISSIONS_FLAGS_UNKNOWN) add_to_safety_rating (&chosen_rating, descriptions, SAFETY_POTENTIALLY_UNSAFE, /* Translators: This indicates that an application has been packaged diff --git a/src/gs-app-details-page.c b/src/gs-app-details-page.c index 6eb39317d..ee902793f 100644 --- a/src/gs-app-details-page.c +++ b/src/gs-app-details-page.c @@ -61,28 +61,28 @@ struct _GsAppDetailsPage G_DEFINE_TYPE (GsAppDetailsPage, gs_app_details_page, GTK_TYPE_BOX) static const struct { - GsAppPermissions permission; + GsAppPermissionsFlags permission; const char *title; const char *subtitle; } permission_display_data[] = { - { GS_APP_PERMISSIONS_NETWORK, N_("Network"), N_("Can communicate over the network") }, - { GS_APP_PERMISSIONS_SYSTEM_BUS, N_("System Services"), N_("Can access D-Bus services on the system bus") }, - { GS_APP_PERMISSIONS_SESSION_BUS, N_("Session Services"), N_("Can access D-Bus services on the session bus") }, - { GS_APP_PERMISSIONS_DEVICES, N_("Devices"), N_("Can access system device files") }, - { GS_APP_PERMISSIONS_HOME_FULL, N_("Home folder"), N_("Can view, edit and create files") }, - { GS_APP_PERMISSIONS_HOME_READ, N_("Home folder"), N_("Can view files") }, - { GS_APP_PERMISSIONS_FILESYSTEM_FULL, N_("File system"), N_("Can view, edit and create files") }, - { GS_APP_PERMISSIONS_FILESYSTEM_READ, N_("File system"), N_("Can view files") }, - { GS_APP_PERMISSIONS_FILESYSTEM_OTHER, N_("File system"), N_("Can access arbitrary files") }, - { GS_APP_PERMISSIONS_DOWNLOADS_FULL, N_("Downloads folder"), N_("Can view, edit and create files") }, - { GS_APP_PERMISSIONS_DOWNLOADS_READ, N_("Downloads folder"), N_("Can view files") }, - { GS_APP_PERMISSIONS_SETTINGS, N_("Settings"), N_("Can view and change any settings") }, - { GS_APP_PERMISSIONS_X11, N_("Legacy display system"), N_("Uses an old, insecure display system") }, - { GS_APP_PERMISSIONS_ESCAPE_SANDBOX, N_("Sandbox escape"), N_("Can escape the sandbox and circumvent any other restrictions") }, + { GS_APP_PERMISSIONS_FLAGS_NETWORK, N_("Network"), N_("Can communicate over the network") }, + { GS_APP_PERMISSIONS_FLAGS_SYSTEM_BUS, N_("System Services"), N_("Can access D-Bus services on the system bus") }, + { GS_APP_PERMISSIONS_FLAGS_SESSION_BUS, N_("Session Services"), N_("Can access D-Bus services on the session bus") }, + { GS_APP_PERMISSIONS_FLAGS_DEVICES, N_("Devices"), N_("Can access system device files") }, + { GS_APP_PERMISSIONS_FLAGS_HOME_FULL, N_("Home folder"), N_("Can view, edit and create files") }, + { GS_APP_PERMISSIONS_FLAGS_HOME_READ, N_("Home folder"), N_("Can view files") }, + { GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_FULL, N_("File system"), N_("Can view, edit and create files") }, + { GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_READ, N_("File system"), N_("Can view files") }, + { GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_OTHER, N_("File system"), N_("Can access arbitrary files") }, + { GS_APP_PERMISSIONS_FLAGS_DOWNLOADS_FULL, N_("Downloads folder"), N_("Can view, edit and create files") }, + { GS_APP_PERMISSIONS_FLAGS_DOWNLOADS_READ, N_("Downloads folder"), N_("Can view files") }, + { GS_APP_PERMISSIONS_FLAGS_SETTINGS, N_("Settings"), N_("Can view and change any settings") }, + { GS_APP_PERMISSIONS_FLAGS_X11, N_("Legacy display system"), N_("Uses an old, insecure display system") }, + { GS_APP_PERMISSIONS_FLAGS_ESCAPE_SANDBOX, N_("Sandbox escape"), N_("Can escape the sandbox and circumvent any other restrictions") }, }; static void -populate_permissions_section (GsAppDetailsPage *page, GsAppPermissions permissions) +populate_permissions_section (GsAppDetailsPage *page, GsAppPermissionsFlags permissions) { gs_widget_remove_all (page->permissions_section_list, (GsRemoveFunc) gtk_list_box_remove); diff --git a/src/gs-safety-context-dialog.c b/src/gs-safety-context-dialog.c index a05a3543b..dbf42d06d 100644 --- a/src/gs-safety-context-dialog.c +++ b/src/gs-safety-context-dialog.c @@ -110,7 +110,7 @@ update_permissions_list (GsSafetyContextDialog *self) g_autofree gchar *title = NULL; g_autoptr(GPtrArray) descriptions = g_ptr_array_new_with_free_func (NULL); g_autofree gchar *description = NULL; - GsAppPermissions permissions; + GsAppPermissionsFlags permissions; GtkStyleContext *context; GsContextDialogRowImportance chosen_rating; @@ -130,9 +130,9 @@ update_permissions_list (GsSafetyContextDialog *self) * sandboxed, so we can only really base decisions on whether it was * packaged by an organisation we trust or not. * - * FIXME: See the comment for GS_APP_PERMISSIONS_UNKNOWN in + * FIXME: See the comment for GS_APP_PERMISSIONS_FLAGS_UNKNOWN in * gs-app-context-bar.c. */ - if (permissions == GS_APP_PERMISSIONS_UNKNOWN) { + if (permissions == GS_APP_PERMISSIONS_FLAGS_UNKNOWN) { add_permission_row (self->permissions_list, &chosen_rating, !gs_app_has_quirk (self->app, GS_APP_QUIRK_PROVENANCE), GS_CONTEXT_DIALOG_ROW_IMPORTANCE_WARNING, @@ -144,7 +144,7 @@ update_permissions_list (GsSafetyContextDialog *self) _("Application isn’t sandboxed but the distribution has checked that it is not malicious")); } else { add_permission_row (self->permissions_list, &chosen_rating, - (permissions & GS_APP_PERMISSIONS_NONE) != 0, + (permissions & GS_APP_PERMISSIONS_FLAGS_NONE) != 0, GS_CONTEXT_DIALOG_ROW_IMPORTANCE_UNIMPORTANT, "folder-documents-symbolic", /* Translators: This refers to permissions (for example, from flatpak) which an app requests from the user. */ @@ -152,7 +152,7 @@ update_permissions_list (GsSafetyContextDialog *self) _("App is fully sandboxed"), NULL, NULL, NULL); add_permission_row (self->permissions_list, &chosen_rating, - (permissions & GS_APP_PERMISSIONS_NETWORK) != 0, + (permissions & GS_APP_PERMISSIONS_FLAGS_NETWORK) != 0, /* This isn’t actually unimportant (network access can expand a local * vulnerability into a remotely exploitable one), but it’s * needed commonly enough that marking it as @@ -167,7 +167,7 @@ update_permissions_list (GsSafetyContextDialog *self) _("No Network Access"), _("Cannot access the internet")); add_permission_row (self->permissions_list, &chosen_rating, - (permissions & GS_APP_PERMISSIONS_SYSTEM_BUS) != 0, + (permissions & GS_APP_PERMISSIONS_FLAGS_SYSTEM_BUS) != 0, GS_CONTEXT_DIALOG_ROW_IMPORTANCE_WARNING, "emblem-system-symbolic", /* Translators: This refers to permissions (for example, from flatpak) which an app requests from the user. */ @@ -175,7 +175,7 @@ update_permissions_list (GsSafetyContextDialog *self) _("Can request data from system services"), NULL, NULL, NULL); add_permission_row (self->permissions_list, &chosen_rating, - (permissions & GS_APP_PERMISSIONS_SESSION_BUS) != 0, + (permissions & GS_APP_PERMISSIONS_FLAGS_SESSION_BUS) != 0, GS_CONTEXT_DIALOG_ROW_IMPORTANCE_IMPORTANT, "emblem-system-symbolic", /* Translators: This refers to permissions (for example, from flatpak) which an app requests from the user. */ @@ -183,7 +183,7 @@ update_permissions_list (GsSafetyContextDialog *self) _("Can request data from session services"), NULL, NULL, NULL); add_permission_row (self->permissions_list, &chosen_rating, - (permissions & GS_APP_PERMISSIONS_DEVICES) != 0, + (permissions & GS_APP_PERMISSIONS_FLAGS_DEVICES) != 0, GS_CONTEXT_DIALOG_ROW_IMPORTANCE_WARNING, "camera-photo-symbolic", /* Translators: This refers to permissions (for example, from flatpak) which an app requests from the user. */ @@ -194,7 +194,7 @@ update_permissions_list (GsSafetyContextDialog *self) _("No Device Access"), _("Cannot access devices such as webcams or gaming controllers")); add_permission_row (self->permissions_list, &chosen_rating, - (permissions & GS_APP_PERMISSIONS_X11) != 0, + (permissions & GS_APP_PERMISSIONS_FLAGS_X11) != 0, GS_CONTEXT_DIALOG_ROW_IMPORTANCE_IMPORTANT, "desktop-symbolic", /* Translators: This refers to permissions (for example, from flatpak) which an app requests from the user. */ @@ -202,7 +202,7 @@ update_permissions_list (GsSafetyContextDialog *self) _("Uses a legacy windowing system"), NULL, NULL, NULL); add_permission_row (self->permissions_list, &chosen_rating, - (permissions & GS_APP_PERMISSIONS_ESCAPE_SANDBOX) != 0, + (permissions & GS_APP_PERMISSIONS_FLAGS_ESCAPE_SANDBOX) != 0, GS_CONTEXT_DIALOG_ROW_IMPORTANCE_IMPORTANT, "dialog-warning-symbolic", /* Translators: This refers to permissions (for example, from flatpak) which an app requests from the user. */ @@ -210,7 +210,7 @@ update_permissions_list (GsSafetyContextDialog *self) _("Can acquire arbitrary permissions"), NULL, NULL, NULL); add_permission_row (self->permissions_list, &chosen_rating, - (permissions & GS_APP_PERMISSIONS_SETTINGS) != 0, + (permissions & GS_APP_PERMISSIONS_FLAGS_SETTINGS) != 0, GS_CONTEXT_DIALOG_ROW_IMPORTANCE_WARNING, "preferences-system-symbolic", /* Translators: This refers to permissions (for example, from flatpak) which an app requests from the user. */ @@ -222,7 +222,7 @@ update_permissions_list (GsSafetyContextDialog *self) * varying scopes of what’s readable/writable, and a difference between * read-only and writable access. */ add_permission_row (self->permissions_list, &chosen_rating, - (permissions & GS_APP_PERMISSIONS_FILESYSTEM_FULL) != 0, + (permissions & GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_FULL) != 0, GS_CONTEXT_DIALOG_ROW_IMPORTANCE_IMPORTANT, "folder-documents-symbolic", /* Translators: This refers to permissions (for example, from flatpak) which an app requests from the user. */ @@ -230,8 +230,8 @@ update_permissions_list (GsSafetyContextDialog *self) _("Can read and write all data on the file system"), NULL, NULL, NULL); add_permission_row (self->permissions_list, &chosen_rating, - ((permissions & GS_APP_PERMISSIONS_HOME_FULL) != 0 && - !(permissions & GS_APP_PERMISSIONS_FILESYSTEM_FULL)), + ((permissions & GS_APP_PERMISSIONS_FLAGS_HOME_FULL) != 0 && + !(permissions & GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_FULL)), GS_CONTEXT_DIALOG_ROW_IMPORTANCE_IMPORTANT, "user-home-symbolic", /* Translators: This refers to permissions (for example, from flatpak) which an app requests from the user. */ @@ -239,8 +239,8 @@ update_permissions_list (GsSafetyContextDialog *self) _("Can read and write all data in your home directory"), NULL, NULL, NULL); add_permission_row (self->permissions_list, &chosen_rating, - ((permissions & GS_APP_PERMISSIONS_FILESYSTEM_READ) != 0 && - !(permissions & GS_APP_PERMISSIONS_FILESYSTEM_FULL)), + ((permissions & GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_READ) != 0 && + !(permissions & GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_FULL)), GS_CONTEXT_DIALOG_ROW_IMPORTANCE_IMPORTANT, "folder-documents-symbolic", /* Translators: This refers to permissions (for example, from flatpak) which an app requests from the user. */ @@ -248,9 +248,9 @@ update_permissions_list (GsSafetyContextDialog *self) _("Can read all data on the file system"), NULL, NULL, NULL); add_permission_row (self->permissions_list, &chosen_rating, - ((permissions & GS_APP_PERMISSIONS_HOME_READ) != 0 && - !(permissions & (GS_APP_PERMISSIONS_FILESYSTEM_FULL | - GS_APP_PERMISSIONS_FILESYSTEM_READ))), + ((permissions & GS_APP_PERMISSIONS_FLAGS_HOME_READ) != 0 && + !(permissions & (GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_FULL | + GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_READ))), GS_CONTEXT_DIALOG_ROW_IMPORTANCE_IMPORTANT, "user-home-symbolic", /* Translators: This refers to permissions (for example, from flatpak) which an app requests from the user. */ @@ -258,9 +258,9 @@ update_permissions_list (GsSafetyContextDialog *self) _("Can read all data in your home directory"), NULL, NULL, NULL); add_permission_row (self->permissions_list, &chosen_rating, - ((permissions & GS_APP_PERMISSIONS_DOWNLOADS_FULL) != 0 && - !(permissions & (GS_APP_PERMISSIONS_FILESYSTEM_FULL | - GS_APP_PERMISSIONS_HOME_FULL))), + ((permissions & GS_APP_PERMISSIONS_FLAGS_DOWNLOADS_FULL) != 0 && + !(permissions & (GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_FULL | + GS_APP_PERMISSIONS_FLAGS_HOME_FULL))), GS_CONTEXT_DIALOG_ROW_IMPORTANCE_WARNING, "folder-download-symbolic", /* Translators: This refers to permissions (for example, from flatpak) which an app requests from the user. */ @@ -268,11 +268,11 @@ update_permissions_list (GsSafetyContextDialog *self) _("Can read and write all data in your downloads directory"), NULL, NULL, NULL); add_permission_row (self->permissions_list, &chosen_rating, - ((permissions & GS_APP_PERMISSIONS_DOWNLOADS_READ) != 0 && - !(permissions & (GS_APP_PERMISSIONS_FILESYSTEM_FULL | - GS_APP_PERMISSIONS_FILESYSTEM_READ | - GS_APP_PERMISSIONS_HOME_FULL | - GS_APP_PERMISSIONS_HOME_READ))), + ((permissions & GS_APP_PERMISSIONS_FLAGS_DOWNLOADS_READ) != 0 && + !(permissions & (GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_FULL | + GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_READ | + GS_APP_PERMISSIONS_FLAGS_HOME_FULL | + GS_APP_PERMISSIONS_FLAGS_HOME_READ))), GS_CONTEXT_DIALOG_ROW_IMPORTANCE_WARNING, "folder-download-symbolic", /* Translators: This refers to permissions (for example, from flatpak) which an app requests from the user. */ @@ -280,11 +280,11 @@ update_permissions_list (GsSafetyContextDialog *self) _("Can read all data in your downloads directory"), NULL, NULL, NULL); add_permission_row (self->permissions_list, &chosen_rating, - ((permissions & GS_APP_PERMISSIONS_FILESYSTEM_OTHER) != 0 && - !(permissions & (GS_APP_PERMISSIONS_FILESYSTEM_FULL | - GS_APP_PERMISSIONS_FILESYSTEM_READ | - GS_APP_PERMISSIONS_HOME_FULL | - GS_APP_PERMISSIONS_HOME_READ))), + ((permissions & GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_OTHER) != 0 && + !(permissions & (GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_FULL | + GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_READ | + GS_APP_PERMISSIONS_FLAGS_HOME_FULL | + GS_APP_PERMISSIONS_FLAGS_HOME_READ))), GS_CONTEXT_DIALOG_ROW_IMPORTANCE_WARNING, "folder-documents-symbolic", /* Translators: This refers to permissions (for example, from flatpak) which an app requests from the user. */ @@ -293,13 +293,13 @@ update_permissions_list (GsSafetyContextDialog *self) NULL, NULL, NULL); add_permission_row (self->permissions_list, &chosen_rating, - !(permissions & (GS_APP_PERMISSIONS_FILESYSTEM_FULL | - GS_APP_PERMISSIONS_FILESYSTEM_READ | - GS_APP_PERMISSIONS_FILESYSTEM_OTHER | - GS_APP_PERMISSIONS_HOME_FULL | - GS_APP_PERMISSIONS_HOME_READ | - GS_APP_PERMISSIONS_DOWNLOADS_FULL | - GS_APP_PERMISSIONS_DOWNLOADS_READ)), + !(permissions & (GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_FULL | + GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_READ | + GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_OTHER | + GS_APP_PERMISSIONS_FLAGS_HOME_FULL | + GS_APP_PERMISSIONS_FLAGS_HOME_READ | + GS_APP_PERMISSIONS_FLAGS_DOWNLOADS_FULL | + GS_APP_PERMISSIONS_FLAGS_DOWNLOADS_READ)), GS_CONTEXT_DIALOG_ROW_IMPORTANCE_UNIMPORTANT, "folder-documents-symbolic", /* Translators: This refers to permissions (for example, from flatpak) which an app requests from the user. */ -- GitLab From 2d8b16205b9cd8982d84abba4a89a017180fff45 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Thu, 16 Jun 2022 18:04:18 +0200 Subject: [PATCH 2/7] lib: Add GsAppPermissions object This will serve as an extensible object to store app permissions, instead of a bare enum with limited size. --- lib/gnome-software.h | 1 + lib/gs-app-permissions.c | 430 +++++++++++++++++++++++++++++++++++++++ lib/gs-app-permissions.h | 74 +++++++ lib/gs-app.h | 29 +-- lib/meson.build | 2 + 5 files changed, 509 insertions(+), 27 deletions(-) create mode 100644 lib/gs-app-permissions.c create mode 100644 lib/gs-app-permissions.h diff --git a/lib/gnome-software.h b/lib/gnome-software.h index a78b767c9..1594bfc14 100644 --- a/lib/gnome-software.h +++ b/lib/gnome-software.h @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include diff --git a/lib/gs-app-permissions.c b/lib/gs-app-permissions.c new file mode 100644 index 000000000..bbae07c1a --- /dev/null +++ b/lib/gs-app-permissions.c @@ -0,0 +1,430 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * vi:set noexpandtab tabstop=8 shiftwidth=8: + * + * Copyright (C) 2022 Red Hat + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +/** + * SECTION:gs-app-permissions + * @short_description: A representation of the permissions requested by an app + * + * #GsAppPermissions is an object to represent the permissions requested by an app. + * + * While some common permissions are handled with the #GsAppPermissionsFlags, + * the object allows more detailed permissions to be represented, such as + * specific file system path access. + * + * Since: 43 + */ + +#include "config.h" + +#include + +#include +#include + +#include "gs-app-permissions.h" + +#define DOES_NOT_CONTAIN ((guint) ~0) + +struct _GsAppPermissions +{ + GObject parent; + + gboolean is_sealed; + GsAppPermissionsFlags flags; + GPtrArray *filesystem_read; /* (owner) (nullable) (element-type utf-8) */ + GPtrArray *filesystem_full; /* (owner) (nullable) (element-type utf-8) */ +}; + +G_DEFINE_TYPE (GsAppPermissions, gs_app_permissions, G_TYPE_OBJECT) + +static gint +cmp_filename_qsort (gconstpointer item1, + gconstpointer item2) +{ + const gchar * const *pitem1 = item1; + const gchar * const *pitem2 = item2; + return strcmp (*pitem1, *pitem2); +} + +static gint +cmp_filename_bsearch (gconstpointer item1, + gconstpointer item2) +{ + return strcmp (item1, item2); +} + +static void +gs_app_permissions_finalize (GObject *object) +{ + GsAppPermissions *self = GS_APP_PERMISSIONS (object); + + g_clear_pointer (&self->filesystem_read, g_ptr_array_unref); + g_clear_pointer (&self->filesystem_full, g_ptr_array_unref); + + G_OBJECT_CLASS (gs_app_permissions_parent_class)->finalize (object); +} + +static void +gs_app_permissions_class_init (GsAppPermissionsClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = gs_app_permissions_finalize; +} + +static void +gs_app_permissions_init (GsAppPermissions *self) +{ +} + +/** + * gs_app_permissions_new: + * + * Create a new #GsAppPermissions containing the app permissions. + * + * Returns: (transfer full): a new #GsAppPermissions + * Since: 43 + */ +GsAppPermissions * +gs_app_permissions_new (void) +{ + return g_object_new (GS_TYPE_APP_PERMISSIONS, NULL); +} + +/** + * gs_app_permissions_seal: + * @self: a #GsAppPermissions + * + * Seal the @self. After being called, no modifications can be + * done on the @self. + * + * Since: 43 + **/ +void +gs_app_permissions_seal (GsAppPermissions *self) +{ + g_return_if_fail (GS_IS_APP_PERMISSIONS (self)); + + if (self->is_sealed) + return; + + self->is_sealed = TRUE; + + /* Sort the arrays, which will help with searching */ + if (self->filesystem_read) + qsort (self->filesystem_read->pdata, self->filesystem_read->len, sizeof (gpointer), cmp_filename_qsort); + + if (self->filesystem_full) + qsort (self->filesystem_full->pdata, self->filesystem_full->len, sizeof (gpointer), cmp_filename_qsort); +} + +/** + * gs_app_permissions_is_sealed: + * @self: a #GsAppPermissions + * + * Checks whether the @self had been sealed. Once the @self is sealed, + * no modifications can be made to it. + * + * Returns: whether the @self had been sealed + * + * Since: 43 + **/ +gboolean +gs_app_permissions_is_sealed (GsAppPermissions *self) +{ + g_return_val_if_fail (GS_IS_APP_PERMISSIONS (self), TRUE); + + return self->is_sealed; +} + +/** + * gs_app_permissions_set_flags: + * @self: a #GsAppPermissions + * @flags: a #GsAppPermissionsFlags to set + * + * Set the permission flags, overwriting any previously set flags. + * Compare to gs_app_permissions_add_flag() and + * gs_app_permissions_remove_flag(). + * + * Since: 43 + */ +void +gs_app_permissions_set_flags (GsAppPermissions *self, + GsAppPermissionsFlags flags) +{ + g_return_if_fail (GS_IS_APP_PERMISSIONS (self)); + + g_assert (!self->is_sealed); + + self->flags = flags; +} + +/** + * gs_app_permissions_get_flags: + * @self: a #GsAppPermissions + * + * Get the permission flags. + * + * Returns: the permission flags + * Since: 43 + */ +GsAppPermissionsFlags +gs_app_permissions_get_flags (GsAppPermissions *self) +{ + g_return_val_if_fail (GS_IS_APP_PERMISSIONS (self), GS_APP_PERMISSIONS_FLAGS_UNKNOWN); + + return self->flags; +} + +/** + * gs_app_permissions_add_flag: + * @self: a #GsAppPermissions + * @flags: a #GsAppPermissionsFlags to add + * + * Add the @flags into the already set flags. The @flags cannot contain + * #GS_APP_PERMISSIONS_FLAGS_NONE, neither cannot be #GS_APP_PERMISSIONS_FLAGS_UNKNOWN. + * To set these two use gs_app_permissions_set_flags() instead. + * + * In case the current flags contain #GS_APP_PERMISSIONS_FLAGS_NONE, it's + * automatically unset. + * + * Since: 43 + */ +void +gs_app_permissions_add_flag (GsAppPermissions *self, + GsAppPermissionsFlags flags) +{ + g_return_if_fail (GS_IS_APP_PERMISSIONS (self)); + g_return_if_fail (flags != GS_APP_PERMISSIONS_FLAGS_UNKNOWN); + g_return_if_fail ((flags & GS_APP_PERMISSIONS_FLAGS_NONE) == 0); + + g_assert (!self->is_sealed); + + self->flags = (self->flags & (~GS_APP_PERMISSIONS_FLAGS_NONE)) | flags; +} + +/** + * gs_app_permissions_remove_flag: + * @self: a #GsAppPermissions + * @flags: a #GsAppPermissionsFlags to remove + * + * Remove the @flags from the already set flags. The @flags cannot contain + * #GS_APP_PERMISSIONS_FLAGS_NONE, neither cannot be #GS_APP_PERMISSIONS_FLAGS_UNKNOWN. + * To set these two use gs_app_permissions_set_flags() instead. + * + * In case the result of the removal would lead to no flag set the #GS_APP_PERMISSIONS_FLAGS_NONE + * is set automatically. + * + * Since: 43 + */ +void +gs_app_permissions_remove_flag (GsAppPermissions *self, + GsAppPermissionsFlags flags) +{ + g_return_if_fail (GS_IS_APP_PERMISSIONS (self)); + g_return_if_fail (flags != GS_APP_PERMISSIONS_FLAGS_UNKNOWN); + g_return_if_fail ((flags & GS_APP_PERMISSIONS_FLAGS_NONE) == 0); + + g_assert (!self->is_sealed); + + self->flags = (self->flags & (~flags)); + + if (!self->flags) + self->flags = GS_APP_PERMISSIONS_FLAGS_NONE; +} + +static guint +app_permissions_get_array_index (GPtrArray *array, + const gchar *filename) +{ + g_return_val_if_fail (filename != NULL, DOES_NOT_CONTAIN); + + if (array == NULL) + return DOES_NOT_CONTAIN; + + for (guint i = 0; i < array->len; i++) { + const gchar *item = g_ptr_array_index (array, i); + if (g_strcmp0 (item, filename) == 0) + return 0; + } + + return DOES_NOT_CONTAIN; +} + +/** + * gs_app_permissions_add_filesystem_read: + * @self: a #GsAppPermissions + * @filename: a filename to access + * + * Add @filename as a file to access for read. The @filename + * can be either a path or a localized pretty name of it, like "Documents". + * The addition is ignored in case the same @filename is part of + * the read or full access file names. + * + * Since: 43 + */ +void +gs_app_permissions_add_filesystem_read (GsAppPermissions *self, + const gchar *filename) +{ + g_return_if_fail (GS_IS_APP_PERMISSIONS (self)); + g_return_if_fail (filename != NULL); + + g_assert (!self->is_sealed); + + /* Already known */ + if (app_permissions_get_array_index (self->filesystem_read, filename) != DOES_NOT_CONTAIN || + app_permissions_get_array_index (self->filesystem_full, filename) != DOES_NOT_CONTAIN) + return; + + if (self->filesystem_read == NULL) + self->filesystem_read = g_ptr_array_new_with_free_func (g_free); + + g_ptr_array_add (self->filesystem_read, g_strdup (filename)); +} + +/** + * gs_app_permissions_get_filesystem_read: + * @self: a #GsAppPermissions + * + * Get the list of filesystem file names requested for read access using + * gs_app_permissions_add_filesystem_read(). + * The array is owned by the @self and should not be modified by any way. + * It can be %NULL, when no file access was set. + * + * Returns: (nullable) (transfer none) (element-type utf-8): an array of + * file names requesting read access or %NULL, when none was set. + * + * Since: 43 + */ +const GPtrArray * +gs_app_permissions_get_filesystem_read (GsAppPermissions *self) +{ + g_return_val_if_fail (GS_IS_APP_PERMISSIONS (self), NULL); + + return self->filesystem_read; +} + +static gboolean +array_contains_filename (GPtrArray *array, + const gchar *filename) +{ + if (array == NULL) + return FALSE; + + return bsearch (filename, array->pdata, array->len, sizeof (gpointer), cmp_filename_bsearch) != NULL; +} + +/** + * gs_app_permissions_contains_filesystem_read: + * @self: a #GsAppPermissions + * @filename: a file name to search for + * + * Checks whether the @filename is included in the filesystem read permissions. + * This can be called only after the @self is sealed. + * + * Returns: whether the @filename is part of the filesystem read permissions + * + * Since: 43 + **/ +gboolean +gs_app_permissions_contains_filesystem_read (GsAppPermissions *self, + const gchar *filename) +{ + g_return_val_if_fail (GS_IS_APP_PERMISSIONS (self), FALSE); + g_return_val_if_fail (filename != NULL, FALSE); + g_return_val_if_fail (self->is_sealed, FALSE); + + return array_contains_filename (self->filesystem_read, filename); +} + +/** + * gs_app_permissions_add_filesystem_full: + * @self: a #GsAppPermissions + * @filename: a filename to access + * + * Add @filename as a file to access for read and write. The @filename + * can be either a path or a localized pretty name of it, like "Documents". + * The addition is ignored in case the same @filename is include in the list + * already. The @filename is removed from the read list, if it's part of it. + * + * Since: 43 + */ +void +gs_app_permissions_add_filesystem_full (GsAppPermissions *self, + const gchar *filename) +{ + guint read_index; + + g_return_if_fail (GS_IS_APP_PERMISSIONS (self)); + g_return_if_fail (filename != NULL); + + g_assert (!self->is_sealed); + + /* Already known */ + if (app_permissions_get_array_index (self->filesystem_full, filename) != DOES_NOT_CONTAIN) + return; + + if (self->filesystem_full == NULL) + self->filesystem_full = g_ptr_array_new_with_free_func (g_free); + + g_ptr_array_add (self->filesystem_full, g_strdup (filename)); + + /* Remove from the read list and free the read list if becomes empty */ + read_index = app_permissions_get_array_index (self->filesystem_read, filename); + if (read_index != DOES_NOT_CONTAIN) { + g_ptr_array_remove_index (self->filesystem_read, read_index); + if (self->filesystem_read->len == 0) + g_clear_pointer (&self->filesystem_read, g_ptr_array_unref); + } +} + +/** + * gs_app_permissions_get_filesystem_full: + * @self: a #GsAppPermissions + * + * Get the list of filesystem file names requested for read and write access using + * gs_app_permissions_add_filesystem_full(). + * The array is owned by the @self and should not be modified by any way. + * It can be %NULL, when no file access was set. + * + * Returns: (nullable) (transfer none) (element-type utf-8): an array of + * file names requesting read and write access or %NULL, when none was set. + * + * Since: 43 + */ +const GPtrArray * +gs_app_permissions_get_filesystem_full (GsAppPermissions *self) +{ + g_return_val_if_fail (GS_IS_APP_PERMISSIONS (self), NULL); + + return self->filesystem_full; +} + +/** + * gs_app_permissions_contains_filesystem_full: + * @self: a #GsAppPermissions + * @filename: a file name to search for + * + * Checks whether the @filename is included in the filesystem full permissions. + * This can be called only after the @self is sealed. + * + * Returns: whether the @filename is part of the filesystem full permissions + * + * Since: 43 + **/ +gboolean +gs_app_permissions_contains_filesystem_full (GsAppPermissions *self, + const gchar *filename) +{ + g_return_val_if_fail (GS_IS_APP_PERMISSIONS (self), FALSE); + g_return_val_if_fail (filename != NULL, FALSE); + g_return_val_if_fail (self->is_sealed, FALSE); + + return array_contains_filename (self->filesystem_full, filename); +} diff --git a/lib/gs-app-permissions.h b/lib/gs-app-permissions.h new file mode 100644 index 000000000..96c482bc3 --- /dev/null +++ b/lib/gs-app-permissions.h @@ -0,0 +1,74 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * vi:set noexpandtab tabstop=8 shiftwidth=8: + * + * Copyright (C) 2022 Red Hat + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#pragma once + +#include +#include + +G_BEGIN_DECLS + +typedef enum { + GS_APP_PERMISSIONS_FLAGS_UNKNOWN = 0, + GS_APP_PERMISSIONS_FLAGS_NONE = 1 << 0, + GS_APP_PERMISSIONS_FLAGS_NETWORK = 1 << 1, + GS_APP_PERMISSIONS_FLAGS_SYSTEM_BUS = 1 << 2, + GS_APP_PERMISSIONS_FLAGS_SESSION_BUS = 1 << 3, + GS_APP_PERMISSIONS_FLAGS_DEVICES = 1 << 4, + GS_APP_PERMISSIONS_FLAGS_HOME_FULL = 1 << 5, + GS_APP_PERMISSIONS_FLAGS_HOME_READ = 1 << 6, + GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_FULL = 1 << 7, + GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_READ = 1 << 8, + GS_APP_PERMISSIONS_FLAGS_DOWNLOADS_FULL = 1 << 9, + GS_APP_PERMISSIONS_FLAGS_DOWNLOADS_READ = 1 << 10, + GS_APP_PERMISSIONS_FLAGS_SETTINGS = 1 << 11, + GS_APP_PERMISSIONS_FLAGS_X11 = 1 << 12, + GS_APP_PERMISSIONS_FLAGS_ESCAPE_SANDBOX = 1 << 13, + GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_OTHER = 1 << 14, + GS_APP_PERMISSIONS_FLAGS_LAST /*< skip >*/ +} GsAppPermissionsFlags; + +#define LIMITED_PERMISSIONS (GS_APP_PERMISSIONS_FLAGS_SETTINGS | \ + GS_APP_PERMISSIONS_FLAGS_NETWORK | \ + GS_APP_PERMISSIONS_FLAGS_DOWNLOADS_READ | \ + GS_APP_PERMISSIONS_FLAGS_DOWNLOADS_FULL) +#define MEDIUM_PERMISSIONS (LIMITED_PERMISSIONS | \ + GS_APP_PERMISSIONS_FLAGS_X11) + +#define GS_TYPE_APP_PERMISSIONS (gs_app_permissions_get_type ()) + +G_DECLARE_FINAL_TYPE (GsAppPermissions, gs_app_permissions, GS, APP_PERMISSIONS, GObject) + +GsAppPermissions *gs_app_permissions_new (void); +void gs_app_permissions_seal (GsAppPermissions *self); +gboolean gs_app_permissions_is_sealed (GsAppPermissions *self); +void gs_app_permissions_set_flags (GsAppPermissions *self, + GsAppPermissionsFlags flags); +GsAppPermissionsFlags gs_app_permissions_get_flags (GsAppPermissions *self); +void gs_app_permissions_add_flag (GsAppPermissions *self, + GsAppPermissionsFlags flags); +void gs_app_permissions_remove_flag (GsAppPermissions *self, + GsAppPermissionsFlags flags); +void gs_app_permissions_add_filesystem_read + (GsAppPermissions *self, + const gchar *filename); +const GPtrArray *gs_app_permissions_get_filesystem_read + (GsAppPermissions *self); +gboolean gs_app_permissions_contains_filesystem_read + (GsAppPermissions *self, + const gchar *filename); +void gs_app_permissions_add_filesystem_full + (GsAppPermissions *self, + const gchar *filename); +const GPtrArray *gs_app_permissions_get_filesystem_full + (GsAppPermissions *self); +gboolean gs_app_permissions_contains_filesystem_full + (GsAppPermissions *self, + const gchar *filename); + +G_END_DECLS diff --git a/lib/gs-app.h b/lib/gs-app.h index 7eec0f227..f93903366 100644 --- a/lib/gs-app.h +++ b/lib/gs-app.h @@ -15,6 +15,8 @@ #include #include +#include + G_BEGIN_DECLS /* Dependency loop means we can’t include the header. */ @@ -208,33 +210,6 @@ typedef enum { GS_APP_QUALITY_LAST /*< skip >*/ } GsAppQuality; -typedef enum { - GS_APP_PERMISSIONS_FLAGS_UNKNOWN = 0, - GS_APP_PERMISSIONS_FLAGS_NONE = 1 << 0, - GS_APP_PERMISSIONS_FLAGS_NETWORK = 1 << 1, - GS_APP_PERMISSIONS_FLAGS_SYSTEM_BUS = 1 << 2, - GS_APP_PERMISSIONS_FLAGS_SESSION_BUS = 1 << 3, - GS_APP_PERMISSIONS_FLAGS_DEVICES = 1 << 4, - GS_APP_PERMISSIONS_FLAGS_HOME_FULL = 1 << 5, - GS_APP_PERMISSIONS_FLAGS_HOME_READ = 1 << 6, - GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_FULL = 1 << 7, - GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_READ = 1 << 8, - GS_APP_PERMISSIONS_FLAGS_DOWNLOADS_FULL = 1 << 9, - GS_APP_PERMISSIONS_FLAGS_DOWNLOADS_READ = 1 << 10, - GS_APP_PERMISSIONS_FLAGS_SETTINGS = 1 << 11, - GS_APP_PERMISSIONS_FLAGS_X11 = 1 << 12, - GS_APP_PERMISSIONS_FLAGS_ESCAPE_SANDBOX = 1 << 13, - GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_OTHER = 1 << 14, - GS_APP_PERMISSIONS_FLAGS_LAST /*< skip >*/ -} GsAppPermissionsFlags; - -#define LIMITED_PERMISSIONS (GS_APP_PERMISSIONS_FLAGS_SETTINGS | \ - GS_APP_PERMISSIONS_FLAGS_NETWORK | \ - GS_APP_PERMISSIONS_FLAGS_DOWNLOADS_READ | \ - GS_APP_PERMISSIONS_FLAGS_DOWNLOADS_FULL) -#define MEDIUM_PERMISSIONS (LIMITED_PERMISSIONS | \ - GS_APP_PERMISSIONS_FLAGS_X11) - /** * GS_APP_PROGRESS_UNKNOWN: * diff --git a/lib/meson.build b/lib/meson.build index 036bb3068..a99a80abb 100644 --- a/lib/meson.build +++ b/lib/meson.build @@ -6,6 +6,7 @@ libgnomesoftware_public_headers = [ 'gs-app.h', 'gs-app-collation.h', 'gs-app-list.h', + 'gs-app-permissions.h', 'gs-app-query.h', 'gs-appstream.h', 'gs-category.h', @@ -83,6 +84,7 @@ libgnomesoftware = library( sources : [ 'gs-app.c', 'gs-app-list.c', + 'gs-app-permissions.c', 'gs-app-query.c', 'gs-appstream.c', 'gs-category.c', -- GitLab From 835ae5a40ab7b8a8fa1b3a6ddfcdd25308aff519 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Fri, 17 Jun 2022 09:58:21 +0200 Subject: [PATCH 3/7] flatpak: Switch to use GsAppPermissions object Gather details information about the filesystem permissions, though pass to the GsApp only the flags, until the GsApp itself will be changed to use the GsAppPermissions object too. --- plugins/flatpak/gs-flatpak.c | 205 +++++++++++++++++++++++++++++------ 1 file changed, 173 insertions(+), 32 deletions(-) diff --git a/plugins/flatpak/gs-flatpak.c b/plugins/flatpak/gs-flatpak.c index 0ce47d8ef..ac80636df 100644 --- a/plugins/flatpak/gs-flatpak.c +++ b/plugins/flatpak/gs-flatpak.c @@ -212,32 +212,47 @@ gs_flatpak_set_kind_from_flatpak (GsApp *app, FlatpakRef *xref) } } -static GsAppPermissionsFlags +static guint +gs_get_strv_index (const gchar * const *strv, + const gchar *value) +{ + guint ii; + + for (ii = 0; strv[ii]; ii++) { + if (g_str_equal (strv[ii], value)) + break; + } + + return ii; +} + +static GsAppPermissions * perms_from_metadata (GKeyFile *keyfile) { char **strv; char *str; - GsAppPermissionsFlags permissions = GS_APP_PERMISSIONS_FLAGS_UNKNOWN; + GsAppPermissions *permissions = gs_app_permissions_new (); + GsAppPermissionsFlags flags = GS_APP_PERMISSIONS_FLAGS_UNKNOWN; strv = g_key_file_get_string_list (keyfile, "Context", "sockets", NULL, NULL); if (strv != NULL && g_strv_contains ((const gchar * const*)strv, "system-bus")) - permissions |= GS_APP_PERMISSIONS_FLAGS_SYSTEM_BUS; + flags |= GS_APP_PERMISSIONS_FLAGS_SYSTEM_BUS; if (strv != NULL && g_strv_contains ((const gchar * const*)strv, "session-bus")) - permissions |= GS_APP_PERMISSIONS_FLAGS_SESSION_BUS; + flags |= GS_APP_PERMISSIONS_FLAGS_SESSION_BUS; if (strv != NULL && !g_strv_contains ((const gchar * const*)strv, "fallback-x11") && g_strv_contains ((const gchar * const*)strv, "x11")) - permissions |= GS_APP_PERMISSIONS_FLAGS_X11; + flags |= GS_APP_PERMISSIONS_FLAGS_X11; g_strfreev (strv); strv = g_key_file_get_string_list (keyfile, "Context", "devices", NULL, NULL); if (strv != NULL && g_strv_contains ((const gchar * const*)strv, "all")) - permissions |= GS_APP_PERMISSIONS_FLAGS_DEVICES; + flags |= GS_APP_PERMISSIONS_FLAGS_DEVICES; g_strfreev (strv); strv = g_key_file_get_string_list (keyfile, "Context", "shared", NULL, NULL); if (strv != NULL && g_strv_contains ((const gchar * const*)strv, "network")) - permissions |= GS_APP_PERMISSIONS_FLAGS_NETWORK; + flags |= GS_APP_PERMISSIONS_FLAGS_NETWORK; g_strfreev (strv); strv = g_key_file_get_string_list (keyfile, "Context", "filesystems", NULL, NULL); @@ -250,6 +265,9 @@ perms_from_metadata (GKeyFile *keyfile) { "home", GS_APP_PERMISSIONS_FLAGS_HOME_FULL }, { "home:rw", GS_APP_PERMISSIONS_FLAGS_HOME_FULL }, { "home:ro", GS_APP_PERMISSIONS_FLAGS_HOME_READ }, + { "~", GS_APP_PERMISSIONS_FLAGS_HOME_FULL }, + { "~:rw", GS_APP_PERMISSIONS_FLAGS_HOME_FULL }, + { "~:ro", GS_APP_PERMISSIONS_FLAGS_HOME_READ }, { "host", GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_FULL }, { "host:rw", GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_FULL }, { "host:ro", GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_READ }, @@ -259,48 +277,142 @@ perms_from_metadata (GKeyFile *keyfile) { "xdg-data/flatpak/overrides:create", GS_APP_PERMISSIONS_FLAGS_ESCAPE_SANDBOX } }; guint filesystems_hits = 0; + guint strv_len = g_strv_length (strv); for (guint i = 0; i < G_N_ELEMENTS (filesystems_access); i++) { - if (g_strv_contains ((const gchar * const *) strv, filesystems_access[i].key)) { - permissions |= filesystems_access[i].perm; + guint index = gs_get_strv_index ((const gchar * const *) strv, filesystems_access[i].key); + if (index < strv_len) { + flags |= filesystems_access[i].perm; filesystems_hits++; + /* Mark it as used */ + strv[index][0] = '\0'; } } - if ((permissions & GS_APP_PERMISSIONS_FLAGS_HOME_FULL) != 0) - permissions = permissions & ~GS_APP_PERMISSIONS_FLAGS_HOME_READ; - if ((permissions & GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_FULL) != 0) - permissions = permissions & ~GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_READ; - if ((permissions & GS_APP_PERMISSIONS_FLAGS_DOWNLOADS_FULL) != 0) - permissions = permissions & ~GS_APP_PERMISSIONS_FLAGS_DOWNLOADS_READ; + if ((flags & GS_APP_PERMISSIONS_FLAGS_HOME_FULL) != 0) + flags = flags & ~GS_APP_PERMISSIONS_FLAGS_HOME_READ; + if ((flags & GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_FULL) != 0) + flags = flags & ~GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_READ; + if ((flags & GS_APP_PERMISSIONS_FLAGS_DOWNLOADS_FULL) != 0) + flags = flags & ~GS_APP_PERMISSIONS_FLAGS_DOWNLOADS_READ; + + if (strv_len > filesystems_hits) { + /* Cover those not being part of the above filesystem_access array */ + const struct { + const gchar *prefix; + const gchar *title; + const gchar *title_subdir; + } filesystems_other[] = { + /* Reference: https://docs.flatpak.org/en/latest/flatpak-command-reference.html#idm45858571325264 */ + { "/", NULL, N_("System folder %s") }, + { "home/", NULL, N_("Home subfolder %s") }, + { "~/", NULL, N_("Home subfolder %s") }, + { "host-os", N_("Host system folders"), NULL }, + { "host-etc", N_("Host system configuration from /etc"), NULL }, + { "xdg-desktop", N_("Desktop folder"), N_("Desktop subfolder %s") }, + { "xdg-documents", N_("Documents folder"), N_("Documents subfolder %s") }, + { "xdg-music", N_("Music folder"), N_("Music subfolder %s") }, + { "xdg-pictures", N_("Pictures folder"), N_("Pictures subfolder %s") }, + { "xdg-public-share", N_("Public Share folder"), N_("Public Share subfolder %s") }, + { "xdg-videos", N_("Videos folder"), N_("Videos subfolder %s") }, + { "xdg-templates", N_("Templates folder"), N_("Templates subfolder %s") }, + { "xdg-cache", N_("User cache folder"), N_("User cache subfolder %s") }, + { "xdg-config", N_("User configuration folder"), N_("User configuration subfolder %s") }, + { "xdg-data", N_("User data folder"), N_("User data subfolder %s") }, + { "xdg-run", N_("User runtime folder"), N_("User runtime subfolder %s") } + }; + + flags |= GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_OTHER; + + for (guint j = 0; strv[j]; j++) { + gchar *perm = strv[j]; + gboolean is_readonly; + gchar *colon; + guint i; + + /* Already handled by the flags */ + if (!perm[0]) + continue; + + is_readonly = g_str_has_suffix (perm, ":ro"); + colon = strrchr (perm, ':'); + /* modifiers are ":ro", ":rw", ":create", where ":create" is ":rw" + create + and ":rw" is default; treat ":create" as ":rw" */ + if (colon) { + /* Completeness check */ + if (!g_str_equal (colon, ":ro") && + !g_str_equal (colon, ":rw") && + !g_str_equal (colon, ":create")) + g_debug ("Unknown filesystem permission modifier '%s' from '%s'", colon, perm); + /* cut it off */ + *colon = '\0'; + } + + for (i = 0; i < G_N_ELEMENTS (filesystems_other); i++) { + if (g_str_has_prefix (perm, filesystems_other[i].prefix)) { + g_autofree gchar *title_tmp = NULL; + const gchar *slash, *title = NULL; + slash = strchr (perm, '/'); + /* Catch and ignore invalid permission definitions */ + if (slash && filesystems_other[i].title_subdir != NULL) { + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wformat-nonliteral" + title_tmp = g_strdup_printf ( + _(filesystems_other[i].title_subdir), + slash + (slash == perm ? 0 : 1)); + #pragma GCC diagnostic pop + title = title_tmp; + } else if (!slash && filesystems_other[i].title != NULL) { + title = _(filesystems_other[i].title); + } + if (title != NULL) { + if (is_readonly) + gs_app_permissions_add_filesystem_read (permissions, title); + else + gs_app_permissions_add_filesystem_full (permissions, title); + } + break; + } + } - if (g_strv_length (strv) > filesystems_hits) - permissions |= GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_OTHER; + /* Nothing matched, use a generic entry */ + if (i == G_N_ELEMENTS (filesystems_other)) { + g_autofree gchar *title = g_strdup_printf (_("Filesystem access to %s"), perm); + if (is_readonly) + gs_app_permissions_add_filesystem_read (permissions, title); + else + gs_app_permissions_add_filesystem_full (permissions, title); + } + } + } } g_strfreev (strv); str = g_key_file_get_string (keyfile, "Session Bus Policy", "ca.desrt.dconf", NULL); if (str != NULL && g_str_equal (str, "talk")) - permissions |= GS_APP_PERMISSIONS_FLAGS_SETTINGS; + flags |= GS_APP_PERMISSIONS_FLAGS_SETTINGS; g_free (str); - if (!(permissions & GS_APP_PERMISSIONS_FLAGS_ESCAPE_SANDBOX)) { + if (!(flags & GS_APP_PERMISSIONS_FLAGS_ESCAPE_SANDBOX)) { str = g_key_file_get_string (keyfile, "Session Bus Policy", "org.freedesktop.Flatpak", NULL); if (str != NULL && g_str_equal (str, "talk")) - permissions |= GS_APP_PERMISSIONS_FLAGS_ESCAPE_SANDBOX; + flags |= GS_APP_PERMISSIONS_FLAGS_ESCAPE_SANDBOX; g_free (str); } - if (!(permissions & GS_APP_PERMISSIONS_FLAGS_ESCAPE_SANDBOX)) { + if (!(flags & GS_APP_PERMISSIONS_FLAGS_ESCAPE_SANDBOX)) { str = g_key_file_get_string (keyfile, "Session Bus Policy", "org.freedesktop.impl.portal.PermissionStore", NULL); if (str != NULL && g_str_equal (str, "talk")) - permissions |= GS_APP_PERMISSIONS_FLAGS_ESCAPE_SANDBOX; + flags |= GS_APP_PERMISSIONS_FLAGS_ESCAPE_SANDBOX; g_free (str); } /* no permissions set */ - if (permissions == GS_APP_PERMISSIONS_FLAGS_UNKNOWN) - return GS_APP_PERMISSIONS_FLAGS_NONE; + if (flags == GS_APP_PERMISSIONS_FLAGS_UNKNOWN) + flags = GS_APP_PERMISSIONS_FLAGS_NONE; + + gs_app_permissions_set_flags (permissions, flags); + gs_app_permissions_seal (permissions); return permissions; } @@ -316,7 +428,7 @@ gs_flatpak_set_update_permissions (GsFlatpak *self, g_autoptr(GKeyFile) old_keyfile = NULL; g_autoptr(GBytes) bytes = NULL; g_autoptr(GKeyFile) keyfile = NULL; - GsAppPermissionsFlags permissions; + g_autoptr(GsAppPermissions) additional_permissions = gs_app_permissions_new (); g_autoptr(GError) error_local = NULL; old_bytes = flatpak_installed_ref_load_metadata (FLATPAK_INSTALLED_REF (xref), NULL, NULL); @@ -335,23 +447,49 @@ gs_flatpak_set_update_permissions (GsFlatpak *self, g_debug ("Failed to get metadata for remote ‘%s’: %s", gs_app_get_origin (app), error_local->message); g_clear_error (&error_local); - permissions = GS_APP_PERMISSIONS_FLAGS_UNKNOWN; + gs_app_permissions_set_flags (additional_permissions, GS_APP_PERMISSIONS_FLAGS_UNKNOWN); } else { + g_autoptr(GsAppPermissions) old_permissions = NULL; + g_autoptr(GsAppPermissions) new_permissions = NULL; + const GPtrArray *new_paths; + keyfile = g_key_file_new (); g_key_file_load_from_data (keyfile, g_bytes_get_data (bytes, NULL), g_bytes_get_size (bytes), 0, NULL); - permissions = perms_from_metadata (keyfile) & ~perms_from_metadata (old_keyfile); + + old_permissions = perms_from_metadata (old_keyfile); + new_permissions = perms_from_metadata (keyfile); + + gs_app_permissions_set_flags (additional_permissions, + gs_app_permissions_get_flags (new_permissions) & + ~gs_app_permissions_get_flags (old_permissions)); + + new_paths = gs_app_permissions_get_filesystem_read (new_permissions); + for (guint i = 0; new_paths && i < new_paths->len; i++) { + const gchar *new_path = g_ptr_array_index (new_paths, i); + if (!gs_app_permissions_contains_filesystem_read (old_permissions, new_path)) + gs_app_permissions_add_filesystem_read (additional_permissions, new_path); + } + + new_paths = gs_app_permissions_get_filesystem_full (new_permissions); + for (guint i = 0; new_paths && i < new_paths->len; i++) { + const gchar *new_path = g_ptr_array_index (new_paths, i); + if (!gs_app_permissions_contains_filesystem_full (old_permissions, new_path)) + gs_app_permissions_add_filesystem_full (additional_permissions, new_path); + } } /* no new permissions set */ - if (permissions == GS_APP_PERMISSIONS_FLAGS_UNKNOWN) - permissions = GS_APP_PERMISSIONS_FLAGS_NONE; + if (gs_app_permissions_get_flags (additional_permissions) == GS_APP_PERMISSIONS_FLAGS_UNKNOWN) + gs_app_permissions_set_flags (additional_permissions, GS_APP_PERMISSIONS_FLAGS_NONE); - gs_app_set_update_permissions (app, permissions); + gs_app_permissions_seal (additional_permissions); + /* Use only flags, until the GsApp holds the GsAppPermissions */ + gs_app_set_update_permissions (app, gs_app_permissions_get_flags (additional_permissions)); - if (permissions != GS_APP_PERMISSIONS_FLAGS_NONE) + if (gs_app_permissions_get_flags (additional_permissions) != GS_APP_PERMISSIONS_FLAGS_NONE) gs_app_add_quirk (app, GS_APP_QUIRK_NEW_PERMISSIONS); } @@ -2459,6 +2597,7 @@ gs_flatpak_set_app_metadata (GsFlatpak *self, g_autofree gchar *runtime = NULL; g_autoptr(GKeyFile) kf = NULL; g_autoptr(GsApp) app_runtime = NULL; + g_autoptr(GsAppPermissions) permissions = NULL; g_auto(GStrv) shared = NULL; g_auto(GStrv) sockets = NULL; g_auto(GStrv) filesystems = NULL; @@ -2499,7 +2638,9 @@ gs_flatpak_set_app_metadata (GsFlatpak *self, secure = FALSE; } - gs_app_set_permissions (app, perms_from_metadata (kf)); + permissions = perms_from_metadata (kf); + /* Use only flags, until the GsApp holds the GsAppPermissions */ + gs_app_set_permissions (app, gs_app_permissions_get_flags (permissions)); /* this is actually quite hard to achieve */ if (secure) gs_app_add_kudo (app, GS_APP_KUDO_SANDBOXED_SECURE); -- GitLab From 27b854e4f7df615cd1ccc4093d2f84661bb186c5 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Fri, 17 Jun 2022 10:32:00 +0200 Subject: [PATCH 4/7] gs-app-details-page: Extract permission row addition into a function It will be reused in the following commit. --- src/gs-app-details-page.c | 46 ++++++++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 17 deletions(-) diff --git a/src/gs-app-details-page.c b/src/gs-app-details-page.c index ee902793f..b210a9703 100644 --- a/src/gs-app-details-page.c +++ b/src/gs-app-details-page.c @@ -82,30 +82,42 @@ static const struct { }; static void -populate_permissions_section (GsAppDetailsPage *page, GsAppPermissionsFlags permissions) +add_permissions_row (GsAppDetailsPage *page, + const gchar *title, + const gchar *subtitle, + gboolean is_warning_row) { - gs_widget_remove_all (page->permissions_section_list, (GsRemoveFunc) gtk_list_box_remove); + GtkWidget *row, *image; - for (gsize i = 0; i < G_N_ELEMENTS (permission_display_data); i++) { - GtkWidget *row, *image; + row = adw_action_row_new (); + if (is_warning_row) + gtk_style_context_add_class (gtk_widget_get_style_context (row), "permission-row-warning"); - if ((permissions & permission_display_data[i].permission) == 0) - continue; + image = gtk_image_new_from_icon_name ("dialog-warning-symbolic"); + if (!is_warning_row) + gtk_widget_set_opacity (image, 0); + + adw_action_row_add_prefix (ADW_ACTION_ROW (row), image); + adw_preferences_row_set_title (ADW_PREFERENCES_ROW (row), title); + adw_action_row_set_subtitle (ADW_ACTION_ROW (row), subtitle); - row = adw_action_row_new (); - if ((permission_display_data[i].permission & ~MEDIUM_PERMISSIONS) != 0) { - gtk_style_context_add_class (gtk_widget_get_style_context (row), "permission-row-warning"); - } + gtk_list_box_append (GTK_LIST_BOX (page->permissions_section_list), row); +} - image = gtk_image_new_from_icon_name ("dialog-warning-symbolic"); - if ((permission_display_data[i].permission & ~MEDIUM_PERMISSIONS) == 0) - gtk_widget_set_opacity (image, 0); +static void +populate_permissions_section (GsAppDetailsPage *page, + GsAppPermissionsFlags permissions) +{ + gs_widget_remove_all (page->permissions_section_list, (GsRemoveFunc) gtk_list_box_remove); - adw_action_row_add_prefix (ADW_ACTION_ROW (row), image); - adw_preferences_row_set_title (ADW_PREFERENCES_ROW (row), _(permission_display_data[i].title)); - adw_action_row_set_subtitle (ADW_ACTION_ROW (row), _(permission_display_data[i].subtitle)); + for (gsize i = 0; i < G_N_ELEMENTS (permission_display_data); i++) { + if ((permissions & permission_display_data[i].permission) == 0) + continue; - gtk_list_box_append (GTK_LIST_BOX (page->permissions_section_list), row); + add_permissions_row (page, + _(permission_display_data[i].title), + _(permission_display_data[i].subtitle), + (permission_display_data[i].permission & ~MEDIUM_PERMISSIONS) != 0); } } -- GitLab From daa21b5744df637bbe77e881e5565b022d2486d8 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Fri, 17 Jun 2022 10:38:44 +0200 Subject: [PATCH 5/7] app: Turn update-permissions flags into a GsAppPermissions object Modify also related parts, to avoid unbuildable sources. --- lib/gs-app.c | 51 +++++++++++++++++++++++++++++++----- lib/gs-app.h | 6 ++--- plugins/flatpak/gs-flatpak.c | 3 +-- src/gs-app-details-page.c | 36 ++++++++++++++++++++++--- 4 files changed, 80 insertions(+), 16 deletions(-) diff --git a/lib/gs-app.c b/lib/gs-app.c index 159d55b5f..60a8ca12b 100644 --- a/lib/gs-app.c +++ b/lib/gs-app.c @@ -93,7 +93,7 @@ typedef struct gchar *update_version_ui; gchar *update_details_markup; AsUrgencyKind update_urgency; - GsAppPermissionsFlags update_permissions; + GsAppPermissions *update_permissions; GWeakRef management_plugin_weak; /* (element-type GsPlugin) */ guint match_value; guint priority; @@ -5537,6 +5537,7 @@ gs_app_finalize (GObject *object) g_clear_object (&priv->local_file); g_clear_object (&priv->content_rating); g_clear_object (&priv->action_screenshot); + g_clear_object (&priv->update_permissions); G_OBJECT_CLASS (gs_app_parent_class)->finalize (object); } @@ -6336,21 +6337,57 @@ gs_app_set_permissions (GsApp *app, gs_app_queue_notify (app, obj_props[PROP_PERMISSIONS]); } -GsAppPermissionsFlags -gs_app_get_update_permissions (GsApp *app) +/** + * gs_app_dup_update_permissions: + * @app: a #GsApp + * + * Get a reference to the update permissions. The returned value can + * be %NULL, when no update permissions had been set. Free + * the returned pointer, if not %NULL, with g_object_unref(), when + * no longer needed. + * + * Returns: (nullable) (transfer full): referenced #GsAppPermissions, + * or %NULL + * + * Since: 43 + **/ +GsAppPermissions * +gs_app_dup_update_permissions (GsApp *app) { GsAppPrivate *priv = gs_app_get_instance_private (app); - g_return_val_if_fail (GS_IS_APP (app), GS_APP_PERMISSIONS_FLAGS_UNKNOWN); - return priv->update_permissions; + g_autoptr(GMutexLocker) locker = NULL; + g_return_val_if_fail (GS_IS_APP (app), NULL); + locker = g_mutex_locker_new (&priv->mutex); + return priv->update_permissions ? g_object_ref (priv->update_permissions) : NULL; } +/** + * gs_app_set_update_permissions: + * @app: a #GsApp + * @update_permissions: (nullable) (transfer none): a #GsAppPermissions, or %NULL + * + * Set update permissions for the @app, that is, the permissions, which change + * in an update or similar reasons. The @update_permissions is referenced, + * if not %NULL. + * + * Note the @update_permissions need to be sealed. + * + * Since: 43 + **/ void gs_app_set_update_permissions (GsApp *app, - GsAppPermissionsFlags update_permissions) + GsAppPermissions *update_permissions) { GsAppPrivate *priv = gs_app_get_instance_private (app); + g_autoptr(GMutexLocker) locker = NULL; g_return_if_fail (GS_IS_APP (app)); - priv->update_permissions = update_permissions; + g_return_if_fail (update_permissions == NULL || gs_app_permissions_is_sealed (update_permissions)); + locker = g_mutex_locker_new (&priv->mutex); + if (priv->update_permissions != update_permissions) { + g_clear_object (&priv->update_permissions); + if (update_permissions != NULL) + priv->update_permissions = g_object_ref (update_permissions); + } } /** diff --git a/lib/gs-app.h b/lib/gs-app.h index f93903366..56a5ff7bf 100644 --- a/lib/gs-app.h +++ b/lib/gs-app.h @@ -495,10 +495,10 @@ GsAppPermissionsFlags gs_app_get_permissions (GsApp *app); void gs_app_set_permissions (GsApp *app, GsAppPermissionsFlags permissions); -GsAppPermissionsFlags - gs_app_get_update_permissions (GsApp *app); +GsAppPermissions * + gs_app_dup_update_permissions (GsApp *app); void gs_app_set_update_permissions (GsApp *app, - GsAppPermissionsFlags update_permissions); + GsAppPermissions *update_permissions); GPtrArray *gs_app_get_version_history (GsApp *app); void gs_app_set_version_history (GsApp *app, GPtrArray *version_history); diff --git a/plugins/flatpak/gs-flatpak.c b/plugins/flatpak/gs-flatpak.c index ac80636df..2408136e0 100644 --- a/plugins/flatpak/gs-flatpak.c +++ b/plugins/flatpak/gs-flatpak.c @@ -486,8 +486,7 @@ gs_flatpak_set_update_permissions (GsFlatpak *self, gs_app_permissions_set_flags (additional_permissions, GS_APP_PERMISSIONS_FLAGS_NONE); gs_app_permissions_seal (additional_permissions); - /* Use only flags, until the GsApp holds the GsAppPermissions */ - gs_app_set_update_permissions (app, gs_app_permissions_get_flags (additional_permissions)); + gs_app_set_update_permissions (app, additional_permissions); if (gs_app_permissions_get_flags (additional_permissions) != GS_APP_PERMISSIONS_FLAGS_NONE) gs_app_add_quirk (app, GS_APP_QUIRK_NEW_PERMISSIONS); diff --git a/src/gs-app-details-page.c b/src/gs-app-details-page.c index b210a9703..27a296d98 100644 --- a/src/gs-app-details-page.c +++ b/src/gs-app-details-page.c @@ -73,7 +73,7 @@ static const struct { { GS_APP_PERMISSIONS_FLAGS_HOME_READ, N_("Home folder"), N_("Can view files") }, { GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_FULL, N_("File system"), N_("Can view, edit and create files") }, { GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_READ, N_("File system"), N_("Can view files") }, - { GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_OTHER, N_("File system"), N_("Can access arbitrary files") }, + /* The GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_OTHER is used only as a flag, with actual files being part of the read/full lists */ { GS_APP_PERMISSIONS_FLAGS_DOWNLOADS_FULL, N_("Downloads folder"), N_("Can view, edit and create files") }, { GS_APP_PERMISSIONS_FLAGS_DOWNLOADS_READ, N_("Downloads folder"), N_("Can view files") }, { GS_APP_PERMISSIONS_FLAGS_SETTINGS, N_("Settings"), N_("Can view and change any settings") }, @@ -104,14 +104,31 @@ add_permissions_row (GsAppDetailsPage *page, gtk_list_box_append (GTK_LIST_BOX (page->permissions_section_list), row); } +static void +populate_permissions_filesystem (GsAppDetailsPage *page, + const GPtrArray *titles, /* (element-type utf-8) */ + const gchar *subtitle, + gboolean is_warning_row) +{ + if (titles == NULL) + return; + + for (guint i = 0; i < titles->len; i++) { + const gchar *title = g_ptr_array_index (titles, i); + add_permissions_row (page, title, subtitle, is_warning_row); + } +} + static void populate_permissions_section (GsAppDetailsPage *page, - GsAppPermissionsFlags permissions) + GsAppPermissions *permissions) { + GsAppPermissionsFlags flags = gs_app_permissions_get_flags (permissions); + gs_widget_remove_all (page->permissions_section_list, (GsRemoveFunc) gtk_list_box_remove); for (gsize i = 0; i < G_N_ELEMENTS (permission_display_data); i++) { - if ((permissions & permission_display_data[i].permission) == 0) + if ((flags & permission_display_data[i].permission) == 0) continue; add_permissions_row (page, @@ -119,6 +136,16 @@ populate_permissions_section (GsAppDetailsPage *page, _(permission_display_data[i].subtitle), (permission_display_data[i].permission & ~MEDIUM_PERMISSIONS) != 0); } + + populate_permissions_filesystem (page, + gs_app_permissions_get_filesystem_read (permissions), + _("Can view files"), + (GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_READ & ~MEDIUM_PERMISSIONS) != 0); + + populate_permissions_filesystem (page, + gs_app_permissions_get_filesystem_full (permissions), + _("Can view, edit and create files"), + (GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_FULL & ~MEDIUM_PERMISSIONS) != 0); } static void @@ -204,8 +231,9 @@ set_updates_description_ui (GsAppDetailsPage *page, GsApp *app) adw_status_page_set_paintable (ADW_STATUS_PAGE (page->status_page), GDK_PAINTABLE (paintable)); if (gs_app_has_quirk (app, GS_APP_QUIRK_NEW_PERMISSIONS)) { + g_autoptr(GsAppPermissions) permissions = gs_app_dup_update_permissions (app); gtk_widget_show (page->permissions_section); - populate_permissions_section (page, gs_app_get_update_permissions (app)); + populate_permissions_section (page, permissions); } else { gtk_widget_hide (page->permissions_section); } -- GitLab From 98f4064cbd6ed9346c7d1fe523ef8e90c242df47 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Fri, 17 Jun 2022 11:19:52 +0200 Subject: [PATCH 6/7] app: Turn 'permissions' flags into a GsAppPermissions object Modify also related parts, to avoid unbuildable sources. Closes https://gitlab.gnome.org/GNOME/gnome-software/-/issues/1722 --- lib/gs-app.c | 63 ++++++++++---- lib/gs-app.h | 6 +- plugins/epiphany/gs-plugin-epiphany.c | 6 +- plugins/flatpak/gs-flatpak.c | 3 +- src/gs-app-context-bar.c | 19 +++-- src/gs-safety-context-dialog.c | 114 +++++++++++++++----------- 6 files changed, 135 insertions(+), 76 deletions(-) diff --git a/lib/gs-app.c b/lib/gs-app.c index 60a8ca12b..29898765b 100644 --- a/lib/gs-app.c +++ b/lib/gs-app.c @@ -135,7 +135,7 @@ typedef struct AsScreenshot *action_screenshot; /* (nullable) (owned) */ GCancellable *cancellable; GsPluginAction pending_action; - GsAppPermissionsFlags permissions; + GsAppPermissions *permissions; gboolean is_update_downloaded; GPtrArray *version_history; /* (element-type AsRelease) (nullable) (owned) */ GPtrArray *relations; /* (nullable) (element-type AsRelation) (owned) */ @@ -5328,7 +5328,7 @@ gs_app_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec * break; } case PROP_PERMISSIONS: - g_value_set_flags (value, priv->permissions); + g_value_take_object (value, gs_app_dup_permissions (app)); break; case PROP_RELATIONS: g_value_take_boxed (value, gs_app_get_relations (app)); @@ -5456,7 +5456,7 @@ gs_app_set_property (GObject *object, guint prop_id, const GValue *value, GParam gs_app_set_size_user_data (app, priv->size_user_data_type, g_value_get_uint64 (value)); break; case PROP_PERMISSIONS: - gs_app_set_permissions (app, g_value_get_flags (value)); + gs_app_set_permissions (app, g_value_get_object (value)); break; case PROP_RELATIONS: gs_app_set_relations (app, g_value_get_boxed (value)); @@ -5538,6 +5538,7 @@ gs_app_finalize (GObject *object) g_clear_object (&priv->content_rating); g_clear_object (&priv->action_screenshot); g_clear_object (&priv->update_permissions); + g_clear_object (&priv->permissions); G_OBJECT_CLASS (gs_app_parent_class)->finalize (object); } @@ -5928,16 +5929,16 @@ gs_app_class_init (GsAppClass *klass) /** * GsApp:permissions * - * The permissions the app requires to run. + * The permissions the app requires to run, as a #GsAppPermissions object. * - * This is %GS_APP_PERMISSIONS_FLAGS_UNKNOWN if the permissions are unknown. + * This is %NULL, if the permissions are unknown. * - * Since: 41 + * Since: 43 */ obj_props[PROP_PERMISSIONS] = - g_param_spec_flags ("permissions", NULL, NULL, - GS_TYPE_APP_PERMISSIONS_FLAGS, GS_APP_PERMISSIONS_FLAGS_UNKNOWN, - G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); + g_param_spec_object ("permissions", NULL, NULL, + GS_TYPE_APP_PERMISSIONS, + G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); /** * GsApp:relations: (nullable) (element-type AsRelation) @@ -6316,24 +6317,56 @@ gs_app_subsume_metadata (GsApp *app, GsApp *donor) } } -GsAppPermissionsFlags -gs_app_get_permissions (GsApp *app) +/** + * gs_app_dup_permissions: + * @app: a #GsApp + * + * Get a reference to the @app permissions. The returned value can + * be %NULL, when the app's permissions are unknown. Free the returned pointer, + * if not %NULL, with g_object_unref(), when no longer needed. + * + * Returns: (nullable) (transfer full): referenced #GsAppPermissions, + * or %NULL + * + * Since: 43 + **/ +GsAppPermissions * +gs_app_dup_permissions (GsApp *app) { GsAppPrivate *priv = gs_app_get_instance_private (app); - g_return_val_if_fail (GS_IS_APP (app), GS_APP_PERMISSIONS_FLAGS_UNKNOWN); - return priv->permissions; + g_autoptr(GMutexLocker) locker = NULL; + g_return_val_if_fail (GS_IS_APP (app), NULL); + locker = g_mutex_locker_new (&priv->mutex); + return priv->permissions ? g_object_ref (priv->permissions) : NULL; } +/** + * gs_app_set_permissions: + * @app: a #GsApp + * @permissions: (nullable) (transfer none): a #GsAppPermissions, or %NULL + * + * Set permissions for the @app. The @permissions is referenced, + * if not %NULL. + * + * Note the @permissions need to be sealed. + * + * Since: 43 + **/ void gs_app_set_permissions (GsApp *app, - GsAppPermissionsFlags permissions) + GsAppPermissions *permissions) { GsAppPrivate *priv = gs_app_get_instance_private (app); + g_autoptr(GMutexLocker) locker = NULL; g_return_if_fail (GS_IS_APP (app)); + g_return_if_fail (permissions == NULL || gs_app_permissions_is_sealed (permissions)); + locker = g_mutex_locker_new (&priv->mutex); if (priv->permissions == permissions) return; - priv->permissions = permissions; + g_clear_object (&priv->permissions); + if (permissions != NULL) + priv->permissions = g_object_ref (permissions); gs_app_queue_notify (app, obj_props[PROP_PERMISSIONS]); } diff --git a/lib/gs-app.h b/lib/gs-app.h index 56a5ff7bf..d78503c3e 100644 --- a/lib/gs-app.h +++ b/lib/gs-app.h @@ -491,10 +491,10 @@ gchar *gs_app_get_packaging_format (GsApp *app); const gchar *gs_app_get_packaging_format_raw(GsApp *app); void gs_app_subsume_metadata (GsApp *app, GsApp *donor); -GsAppPermissionsFlags - gs_app_get_permissions (GsApp *app); +GsAppPermissions * + gs_app_dup_permissions (GsApp *app); void gs_app_set_permissions (GsApp *app, - GsAppPermissionsFlags permissions); + GsAppPermissions *permissions); GsAppPermissions * gs_app_dup_update_permissions (GsApp *app); void gs_app_set_update_permissions (GsApp *app, diff --git a/plugins/epiphany/gs-plugin-epiphany.c b/plugins/epiphany/gs-plugin-epiphany.c index 1f7e20072..bccf38f5c 100644 --- a/plugins/epiphany/gs-plugin-epiphany.c +++ b/plugins/epiphany/gs-plugin-epiphany.c @@ -455,6 +455,7 @@ refine_app (GsPluginEpiphany *self, { "stackedit.io", "Apache-2.0" }, { "squoosh.app", "Apache-2.0" }, }; + g_autoptr(GsAppPermissions) permissions = NULL; g_return_if_fail (GS_IS_APP (app)); g_return_if_fail (uri != NULL); @@ -487,7 +488,10 @@ refine_app (GsPluginEpiphany *self, gs_app_set_size_download (app, GS_SIZE_TYPE_VALID, 0); - gs_app_set_permissions (app, GS_APP_PERMISSIONS_FLAGS_NETWORK); + permissions = gs_app_permissions_new (); + gs_app_permissions_set_flags (permissions, GS_APP_PERMISSIONS_FLAGS_NETWORK); + gs_app_permissions_seal (permissions); + gs_app_set_permissions (app, permissions); if (gs_app_get_url (app, AS_URL_KIND_HOMEPAGE) == NULL) gs_app_set_url (app, AS_URL_KIND_HOMEPAGE, url); diff --git a/plugins/flatpak/gs-flatpak.c b/plugins/flatpak/gs-flatpak.c index 2408136e0..bc3e9d8e6 100644 --- a/plugins/flatpak/gs-flatpak.c +++ b/plugins/flatpak/gs-flatpak.c @@ -2638,8 +2638,7 @@ gs_flatpak_set_app_metadata (GsFlatpak *self, } permissions = perms_from_metadata (kf); - /* Use only flags, until the GsApp holds the GsAppPermissions */ - gs_app_set_permissions (app, gs_app_permissions_get_flags (permissions)); + gs_app_set_permissions (app, permissions); /* this is actually quite hard to achieve */ if (secure) gs_app_add_kudo (app, GS_APP_KUDO_SANDBOXED_SECURE); diff --git a/src/gs-app-context-bar.c b/src/gs-app-context-bar.c index 31202f83c..2a21c870b 100644 --- a/src/gs-app-context-bar.c +++ b/src/gs-app-context-bar.c @@ -254,9 +254,10 @@ static void update_safety_tile (GsAppContextBar *self) { const gchar *icon_name, *title, *css_class; - g_autoptr(GPtrArray) descriptions = g_ptr_array_new_with_free_func (NULL); g_autofree gchar *description = NULL; - GsAppPermissionsFlags permissions; + g_autoptr(GPtrArray) descriptions = g_ptr_array_new_with_free_func (NULL); + g_autoptr(GsAppPermissions) permissions = NULL; + GsAppPermissionsFlags perm_flags = GS_APP_PERMISSIONS_FLAGS_UNKNOWN; GtkStyleContext *context; /* Treat everything as safe to begin with, and downgrade its safety @@ -265,9 +266,11 @@ update_safety_tile (GsAppContextBar *self) g_assert (self->app != NULL); - permissions = gs_app_get_permissions (self->app); + permissions = gs_app_dup_permissions (self->app); + if (permissions != NULL) + perm_flags = gs_app_permissions_get_flags (permissions); for (GsAppPermissionsFlags i = GS_APP_PERMISSIONS_FLAGS_NONE; i < GS_APP_PERMISSIONS_FLAGS_LAST; i <<= 1) { - if (!(permissions & i)) + if (!(perm_flags & i)) continue; switch (i) { @@ -313,7 +316,7 @@ update_safety_tile (GsAppContextBar *self) case GS_APP_PERMISSIONS_FLAGS_HOME_FULL: case GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_FULL: /* Don’t add twice. */ - if (i == GS_APP_PERMISSIONS_FLAGS_HOME_FULL && (permissions & GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_FULL)) + if (i == GS_APP_PERMISSIONS_FLAGS_HOME_FULL && (perm_flags & GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_FULL)) break; add_to_safety_rating (&chosen_rating, descriptions, @@ -325,7 +328,7 @@ update_safety_tile (GsAppContextBar *self) case GS_APP_PERMISSIONS_FLAGS_HOME_READ: case GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_READ: /* Don’t add twice. */ - if (i == GS_APP_PERMISSIONS_FLAGS_HOME_READ && (permissions & GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_READ)) + if (i == GS_APP_PERMISSIONS_FLAGS_HOME_READ && (perm_flags & GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_READ)) break; add_to_safety_rating (&chosen_rating, descriptions, @@ -393,7 +396,7 @@ update_safety_tile (GsAppContextBar *self) * FIXME: We could do better by potentially adding a ‘trusted’ state * to indicate that something is probably safe, but isn’t sandboxed. * See https://gitlab.gnome.org/GNOME/gnome-software/-/issues/1451 */ - if (permissions == GS_APP_PERMISSIONS_FLAGS_UNKNOWN && + if (perm_flags == GS_APP_PERMISSIONS_FLAGS_UNKNOWN && gs_app_has_quirk (self->app, GS_APP_QUIRK_PROVENANCE)) add_to_safety_rating (&chosen_rating, descriptions, SAFETY_SAFE, @@ -401,7 +404,7 @@ update_safety_tile (GsAppContextBar *self) * by the user’s distribution and is safe. * It’s used in a context tile, so should be short. */ _("Reviewed by your distribution")); - else if (permissions == GS_APP_PERMISSIONS_FLAGS_UNKNOWN) + else if (perm_flags == GS_APP_PERMISSIONS_FLAGS_UNKNOWN) add_to_safety_rating (&chosen_rating, descriptions, SAFETY_POTENTIALLY_UNSAFE, /* Translators: This indicates that an application has been packaged diff --git a/src/gs-safety-context-dialog.c b/src/gs-safety-context-dialog.c index dbf42d06d..deccb38aa 100644 --- a/src/gs-safety-context-dialog.c +++ b/src/gs-safety-context-dialog.c @@ -108,9 +108,10 @@ update_permissions_list (GsSafetyContextDialog *self) { const gchar *icon_name, *css_class; g_autofree gchar *title = NULL; - g_autoptr(GPtrArray) descriptions = g_ptr_array_new_with_free_func (NULL); g_autofree gchar *description = NULL; - GsAppPermissionsFlags permissions; + g_autoptr(GPtrArray) descriptions = g_ptr_array_new_with_free_func (NULL); + g_autoptr(GsAppPermissions) permissions = NULL; + GsAppPermissionsFlags perm_flags = GS_APP_PERMISSIONS_FLAGS_UNKNOWN; GtkStyleContext *context; GsContextDialogRowImportance chosen_rating; @@ -124,7 +125,9 @@ update_permissions_list (GsSafetyContextDialog *self) if (self->app == NULL) return; - permissions = gs_app_get_permissions (self->app); + permissions = gs_app_dup_permissions (self->app); + if (permissions != NULL) + perm_flags = gs_app_permissions_get_flags (permissions); /* Handle unknown permissions. This means the application isn’t * sandboxed, so we can only really base decisions on whether it was @@ -132,7 +135,7 @@ update_permissions_list (GsSafetyContextDialog *self) * * FIXME: See the comment for GS_APP_PERMISSIONS_FLAGS_UNKNOWN in * gs-app-context-bar.c. */ - if (permissions == GS_APP_PERMISSIONS_FLAGS_UNKNOWN) { + if (perm_flags == GS_APP_PERMISSIONS_FLAGS_UNKNOWN) { add_permission_row (self->permissions_list, &chosen_rating, !gs_app_has_quirk (self->app, GS_APP_QUIRK_PROVENANCE), GS_CONTEXT_DIALOG_ROW_IMPORTANCE_WARNING, @@ -143,8 +146,14 @@ update_permissions_list (GsSafetyContextDialog *self) _("Reviewed by your distribution"), _("Application isn’t sandboxed but the distribution has checked that it is not malicious")); } else { + const GPtrArray *filesystem_read, *filesystem_full; + + filesystem_read = gs_app_permissions_get_filesystem_read (permissions); + filesystem_full = gs_app_permissions_get_filesystem_full (permissions); + add_permission_row (self->permissions_list, &chosen_rating, - (permissions & GS_APP_PERMISSIONS_FLAGS_NONE) != 0, + (perm_flags & GS_APP_PERMISSIONS_FLAGS_NONE) != 0 && + filesystem_read == NULL && filesystem_full == NULL, GS_CONTEXT_DIALOG_ROW_IMPORTANCE_UNIMPORTANT, "folder-documents-symbolic", /* Translators: This refers to permissions (for example, from flatpak) which an app requests from the user. */ @@ -152,7 +161,7 @@ update_permissions_list (GsSafetyContextDialog *self) _("App is fully sandboxed"), NULL, NULL, NULL); add_permission_row (self->permissions_list, &chosen_rating, - (permissions & GS_APP_PERMISSIONS_FLAGS_NETWORK) != 0, + (perm_flags & GS_APP_PERMISSIONS_FLAGS_NETWORK) != 0, /* This isn’t actually unimportant (network access can expand a local * vulnerability into a remotely exploitable one), but it’s * needed commonly enough that marking it as @@ -167,7 +176,7 @@ update_permissions_list (GsSafetyContextDialog *self) _("No Network Access"), _("Cannot access the internet")); add_permission_row (self->permissions_list, &chosen_rating, - (permissions & GS_APP_PERMISSIONS_FLAGS_SYSTEM_BUS) != 0, + (perm_flags & GS_APP_PERMISSIONS_FLAGS_SYSTEM_BUS) != 0, GS_CONTEXT_DIALOG_ROW_IMPORTANCE_WARNING, "emblem-system-symbolic", /* Translators: This refers to permissions (for example, from flatpak) which an app requests from the user. */ @@ -175,7 +184,7 @@ update_permissions_list (GsSafetyContextDialog *self) _("Can request data from system services"), NULL, NULL, NULL); add_permission_row (self->permissions_list, &chosen_rating, - (permissions & GS_APP_PERMISSIONS_FLAGS_SESSION_BUS) != 0, + (perm_flags & GS_APP_PERMISSIONS_FLAGS_SESSION_BUS) != 0, GS_CONTEXT_DIALOG_ROW_IMPORTANCE_IMPORTANT, "emblem-system-symbolic", /* Translators: This refers to permissions (for example, from flatpak) which an app requests from the user. */ @@ -183,7 +192,7 @@ update_permissions_list (GsSafetyContextDialog *self) _("Can request data from session services"), NULL, NULL, NULL); add_permission_row (self->permissions_list, &chosen_rating, - (permissions & GS_APP_PERMISSIONS_FLAGS_DEVICES) != 0, + (perm_flags & GS_APP_PERMISSIONS_FLAGS_DEVICES) != 0, GS_CONTEXT_DIALOG_ROW_IMPORTANCE_WARNING, "camera-photo-symbolic", /* Translators: This refers to permissions (for example, from flatpak) which an app requests from the user. */ @@ -194,7 +203,7 @@ update_permissions_list (GsSafetyContextDialog *self) _("No Device Access"), _("Cannot access devices such as webcams or gaming controllers")); add_permission_row (self->permissions_list, &chosen_rating, - (permissions & GS_APP_PERMISSIONS_FLAGS_X11) != 0, + (perm_flags & GS_APP_PERMISSIONS_FLAGS_X11) != 0, GS_CONTEXT_DIALOG_ROW_IMPORTANCE_IMPORTANT, "desktop-symbolic", /* Translators: This refers to permissions (for example, from flatpak) which an app requests from the user. */ @@ -202,7 +211,7 @@ update_permissions_list (GsSafetyContextDialog *self) _("Uses a legacy windowing system"), NULL, NULL, NULL); add_permission_row (self->permissions_list, &chosen_rating, - (permissions & GS_APP_PERMISSIONS_FLAGS_ESCAPE_SANDBOX) != 0, + (perm_flags & GS_APP_PERMISSIONS_FLAGS_ESCAPE_SANDBOX) != 0, GS_CONTEXT_DIALOG_ROW_IMPORTANCE_IMPORTANT, "dialog-warning-symbolic", /* Translators: This refers to permissions (for example, from flatpak) which an app requests from the user. */ @@ -210,7 +219,7 @@ update_permissions_list (GsSafetyContextDialog *self) _("Can acquire arbitrary permissions"), NULL, NULL, NULL); add_permission_row (self->permissions_list, &chosen_rating, - (permissions & GS_APP_PERMISSIONS_FLAGS_SETTINGS) != 0, + (perm_flags & GS_APP_PERMISSIONS_FLAGS_SETTINGS) != 0, GS_CONTEXT_DIALOG_ROW_IMPORTANCE_WARNING, "preferences-system-symbolic", /* Translators: This refers to permissions (for example, from flatpak) which an app requests from the user. */ @@ -222,7 +231,7 @@ update_permissions_list (GsSafetyContextDialog *self) * varying scopes of what’s readable/writable, and a difference between * read-only and writable access. */ add_permission_row (self->permissions_list, &chosen_rating, - (permissions & GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_FULL) != 0, + (perm_flags & GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_FULL) != 0, GS_CONTEXT_DIALOG_ROW_IMPORTANCE_IMPORTANT, "folder-documents-symbolic", /* Translators: This refers to permissions (for example, from flatpak) which an app requests from the user. */ @@ -230,8 +239,8 @@ update_permissions_list (GsSafetyContextDialog *self) _("Can read and write all data on the file system"), NULL, NULL, NULL); add_permission_row (self->permissions_list, &chosen_rating, - ((permissions & GS_APP_PERMISSIONS_FLAGS_HOME_FULL) != 0 && - !(permissions & GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_FULL)), + ((perm_flags & GS_APP_PERMISSIONS_FLAGS_HOME_FULL) != 0 && + !(perm_flags & GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_FULL)), GS_CONTEXT_DIALOG_ROW_IMPORTANCE_IMPORTANT, "user-home-symbolic", /* Translators: This refers to permissions (for example, from flatpak) which an app requests from the user. */ @@ -239,8 +248,8 @@ update_permissions_list (GsSafetyContextDialog *self) _("Can read and write all data in your home directory"), NULL, NULL, NULL); add_permission_row (self->permissions_list, &chosen_rating, - ((permissions & GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_READ) != 0 && - !(permissions & GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_FULL)), + ((perm_flags & GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_READ) != 0 && + !(perm_flags & GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_FULL)), GS_CONTEXT_DIALOG_ROW_IMPORTANCE_IMPORTANT, "folder-documents-symbolic", /* Translators: This refers to permissions (for example, from flatpak) which an app requests from the user. */ @@ -248,9 +257,9 @@ update_permissions_list (GsSafetyContextDialog *self) _("Can read all data on the file system"), NULL, NULL, NULL); add_permission_row (self->permissions_list, &chosen_rating, - ((permissions & GS_APP_PERMISSIONS_FLAGS_HOME_READ) != 0 && - !(permissions & (GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_FULL | - GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_READ))), + ((perm_flags & GS_APP_PERMISSIONS_FLAGS_HOME_READ) != 0 && + !(perm_flags & (GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_FULL | + GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_READ))), GS_CONTEXT_DIALOG_ROW_IMPORTANCE_IMPORTANT, "user-home-symbolic", /* Translators: This refers to permissions (for example, from flatpak) which an app requests from the user. */ @@ -258,9 +267,9 @@ update_permissions_list (GsSafetyContextDialog *self) _("Can read all data in your home directory"), NULL, NULL, NULL); add_permission_row (self->permissions_list, &chosen_rating, - ((permissions & GS_APP_PERMISSIONS_FLAGS_DOWNLOADS_FULL) != 0 && - !(permissions & (GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_FULL | - GS_APP_PERMISSIONS_FLAGS_HOME_FULL))), + ((perm_flags & GS_APP_PERMISSIONS_FLAGS_DOWNLOADS_FULL) != 0 && + !(perm_flags & (GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_FULL | + GS_APP_PERMISSIONS_FLAGS_HOME_FULL))), GS_CONTEXT_DIALOG_ROW_IMPORTANCE_WARNING, "folder-download-symbolic", /* Translators: This refers to permissions (for example, from flatpak) which an app requests from the user. */ @@ -268,38 +277,49 @@ update_permissions_list (GsSafetyContextDialog *self) _("Can read and write all data in your downloads directory"), NULL, NULL, NULL); add_permission_row (self->permissions_list, &chosen_rating, - ((permissions & GS_APP_PERMISSIONS_FLAGS_DOWNLOADS_READ) != 0 && - !(permissions & (GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_FULL | - GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_READ | - GS_APP_PERMISSIONS_FLAGS_HOME_FULL | - GS_APP_PERMISSIONS_FLAGS_HOME_READ))), + ((perm_flags & GS_APP_PERMISSIONS_FLAGS_DOWNLOADS_READ) != 0 && + !(perm_flags & (GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_FULL | + GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_READ | + GS_APP_PERMISSIONS_FLAGS_HOME_FULL | + GS_APP_PERMISSIONS_FLAGS_HOME_READ))), GS_CONTEXT_DIALOG_ROW_IMPORTANCE_WARNING, "folder-download-symbolic", /* Translators: This refers to permissions (for example, from flatpak) which an app requests from the user. */ _("Download Folder Read Access"), _("Can read all data in your downloads directory"), NULL, NULL, NULL); - add_permission_row (self->permissions_list, &chosen_rating, - ((permissions & GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_OTHER) != 0 && - !(permissions & (GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_FULL | - GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_READ | - GS_APP_PERMISSIONS_FLAGS_HOME_FULL | - GS_APP_PERMISSIONS_FLAGS_HOME_READ))), - GS_CONTEXT_DIALOG_ROW_IMPORTANCE_WARNING, - "folder-documents-symbolic", - /* Translators: This refers to permissions (for example, from flatpak) which an app requests from the user. */ - _("Access arbitrary files"), - _("Can access arbitrary files on the file system"), - NULL, NULL, NULL); + + for (guint i = 0; filesystem_full != NULL && i < filesystem_full->len; i++) { + const gchar *fs_title = g_ptr_array_index (filesystem_full, i); + add_permission_row (self->permissions_list, &chosen_rating, + TRUE, + GS_CONTEXT_DIALOG_ROW_IMPORTANCE_WARNING, + "folder-documents-symbolic", + fs_title, + _("Can read and write all data in the directory"), + NULL, NULL, NULL); + } + + for (guint i = 0; filesystem_read != NULL && i < filesystem_read->len; i++) { + const gchar *fs_title = g_ptr_array_index (filesystem_read, i); + add_permission_row (self->permissions_list, &chosen_rating, + TRUE, + GS_CONTEXT_DIALOG_ROW_IMPORTANCE_WARNING, + "folder-documents-symbolic", + fs_title, + _("Can read all data in the directory"), + NULL, NULL, NULL); + } add_permission_row (self->permissions_list, &chosen_rating, - !(permissions & (GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_FULL | - GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_READ | - GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_OTHER | - GS_APP_PERMISSIONS_FLAGS_HOME_FULL | - GS_APP_PERMISSIONS_FLAGS_HOME_READ | - GS_APP_PERMISSIONS_FLAGS_DOWNLOADS_FULL | - GS_APP_PERMISSIONS_FLAGS_DOWNLOADS_READ)), + !(perm_flags & (GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_FULL | + GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_READ | + GS_APP_PERMISSIONS_FLAGS_FILESYSTEM_OTHER | + GS_APP_PERMISSIONS_FLAGS_HOME_FULL | + GS_APP_PERMISSIONS_FLAGS_HOME_READ | + GS_APP_PERMISSIONS_FLAGS_DOWNLOADS_FULL | + GS_APP_PERMISSIONS_FLAGS_DOWNLOADS_READ)) && + filesystem_read == NULL && filesystem_full == NULL, GS_CONTEXT_DIALOG_ROW_IMPORTANCE_UNIMPORTANT, "folder-documents-symbolic", /* Translators: This refers to permissions (for example, from flatpak) which an app requests from the user. */ -- GitLab From 23700751a481d2fc3f891801f14a1e375d1603ac Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Wed, 22 Jun 2022 22:12:59 +0200 Subject: [PATCH 7/7] epiphany-plugin: Share single GsAppPermissions object between all GsApp instances As all the GsApp-s have the same permissions, the object can be reused some memory saved. The shared object can be modified only in the gs_plugin_epiphany_init() and nowhere else. --- plugins/epiphany/gs-plugin-epiphany.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/plugins/epiphany/gs-plugin-epiphany.c b/plugins/epiphany/gs-plugin-epiphany.c index bccf38f5c..4eafad6bd 100644 --- a/plugins/epiphany/gs-plugin-epiphany.c +++ b/plugins/epiphany/gs-plugin-epiphany.c @@ -61,6 +61,9 @@ struct _GsPluginEpiphany /* installed_apps_cached: whether the plugin cache has all installed apps */ gboolean installed_apps_cached; GHashTable *url_id_map; /* (owned) (not nullable) (element-type utf8 utf8) */ + + /* default permissions, shared between all applications */ + GsAppPermissions *permissions; /* (owned) (not nullable) */ }; G_DEFINE_TYPE (GsPluginEpiphany, gs_plugin_epiphany, GS_TYPE_PLUGIN) @@ -312,6 +315,12 @@ gs_plugin_epiphany_shutdown_finish (GsPlugin *plugin, static void gs_plugin_epiphany_init (GsPluginEpiphany *self) { + /* Re-used permissions by all GsApp instances; do not modify it out + of this place. */ + self->permissions = gs_app_permissions_new (); + gs_app_permissions_set_flags (self->permissions, GS_APP_PERMISSIONS_FLAGS_NETWORK); + gs_app_permissions_seal (self->permissions); + /* set name of MetaInfo file */ gs_plugin_set_appstream_id (GS_PLUGIN (self), "org.gnome.Software.Plugin.Epiphany"); @@ -347,6 +356,7 @@ gs_plugin_epiphany_finalize (GObject *object) GsPluginEpiphany *self = GS_PLUGIN_EPIPHANY (object); g_mutex_clear (&self->installed_apps_mutex); + g_clear_object (&self->permissions); G_OBJECT_CLASS (gs_plugin_epiphany_parent_class)->finalize (object); } @@ -455,7 +465,6 @@ refine_app (GsPluginEpiphany *self, { "stackedit.io", "Apache-2.0" }, { "squoosh.app", "Apache-2.0" }, }; - g_autoptr(GsAppPermissions) permissions = NULL; g_return_if_fail (GS_IS_APP (app)); g_return_if_fail (uri != NULL); @@ -488,10 +497,8 @@ refine_app (GsPluginEpiphany *self, gs_app_set_size_download (app, GS_SIZE_TYPE_VALID, 0); - permissions = gs_app_permissions_new (); - gs_app_permissions_set_flags (permissions, GS_APP_PERMISSIONS_FLAGS_NETWORK); - gs_app_permissions_seal (permissions); - gs_app_set_permissions (app, permissions); + /* Use the default permissions */ + gs_app_set_permissions (app, self->permissions); if (gs_app_get_url (app, AS_URL_KIND_HOMEPAGE) == NULL) gs_app_set_url (app, AS_URL_KIND_HOMEPAGE, url); -- GitLab