[gnome-software] Try to detect sandboxed applications
- From: Richard Hughes <rhughes src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-software] Try to detect sandboxed applications
- Date: Thu, 7 Jul 2016 19:39:53 +0000 (UTC)
commit f0b304333aa8ed1133b166788dfbc428f41a19a9
Author: Richard Hughes <richard hughsie com>
Date: Wed Jul 6 18:38:27 2016 +0100
Try to detect sandboxed applications
src/gs-app.c | 8 +++++
src/gs-app.h | 4 +++
src/gs-cmd.c | 2 +
src/gs-plugin.h | 2 +
src/gs-self-test.c | 4 +++
src/gs-shell-details.c | 2 +
src/gs-shell-search.c | 1 +
src/plugins/gs-flatpak.c | 66 ++++++++++++++++++++++++++++++++++-----------
8 files changed, 73 insertions(+), 16 deletions(-)
---
diff --git a/src/gs-app.c b/src/gs-app.c
index 6d027fa..73c8df9 100644
--- a/src/gs-app.c
+++ b/src/gs-app.c
@@ -281,6 +281,10 @@ gs_app_to_string (GsApp *app)
gs_app_kv_lpad (str, "kudo", "high-contrast");
if ((app->kudos & GS_APP_KUDO_HI_DPI_ICON) > 0)
gs_app_kv_lpad (str, "kudo", "hi-dpi-icon");
+ if ((app->kudos & GS_APP_KUDO_SANDBOXED) > 0)
+ gs_app_kv_lpad (str, "kudo", "sandboxed");
+ if ((app->kudos & GS_APP_KUDO_SANDBOXED_SECURE) > 0)
+ gs_app_kv_lpad (str, "kudo", "sandboxed-secure");
gs_app_kv_printf (str, "kudo-percentage", "%i",
gs_app_get_kudos_percentage (app));
if (app->name != NULL)
@@ -2467,6 +2471,10 @@ gs_app_get_kudos_percentage (GsApp *app)
percentage += 20;
if ((app->kudos & GS_APP_KUDO_HI_DPI_ICON) > 0)
percentage += 20;
+ if ((app->kudos & GS_APP_KUDO_SANDBOXED) > 0)
+ percentage += 20;
+ if ((app->kudos & GS_APP_KUDO_SANDBOXED_SECURE) > 0)
+ percentage += 20;
/* popular apps should be at *least* 50% */
if ((app->kudos & GS_APP_KUDO_POPULAR) > 0)
diff --git a/src/gs-app.h b/src/gs-app.h
index a152dda..0a696a6 100644
--- a/src/gs-app.h
+++ b/src/gs-app.h
@@ -51,6 +51,8 @@ G_DECLARE_FINAL_TYPE (GsApp, gs_app, GS, APP, GObject)
* @GS_APP_KUDO_PERFECT_SCREENSHOTS: Supplies perfect screenshots
* @GS_APP_KUDO_HIGH_CONTRAST: Installs a high contrast icon
* @GS_APP_KUDO_HI_DPI_ICON: Installs a HiDPI icon
+ * @GS_APP_KUDO_SANDBOXED: Application is sandboxed
+ * @GS_APP_KUDO_SANDBOXED_SECURE: Application is sandboxed securely
*
* Any awards given to the application.
**/
@@ -69,6 +71,8 @@ typedef enum {
GS_APP_KUDO_PERFECT_SCREENSHOTS = 1 << 12,
GS_APP_KUDO_HIGH_CONTRAST = 1 << 13,
GS_APP_KUDO_HI_DPI_ICON = 1 << 14,
+ GS_APP_KUDO_SANDBOXED = 1 << 15,
+ GS_APP_KUDO_SANDBOXED_SECURE = 1 << 16,
/*< private >*/
GS_APP_KUDO_LAST
} GsAppKudo;
diff --git a/src/gs-cmd.c b/src/gs-cmd.c
index e373dca..9872b5e 100644
--- a/src/gs-cmd.c
+++ b/src/gs-cmd.c
@@ -138,6 +138,8 @@ gs_cmd_refine_flag_from_string (const gchar *flag, GError **error)
return GS_PLUGIN_REFINE_FLAGS_REQUIRE_KEY_COLORS;
if (g_strcmp0 (flag, "icon") == 0)
return GS_PLUGIN_REFINE_FLAGS_REQUIRE_ICON;
+ if (g_strcmp0 (flag, "permissions") == 0)
+ return GS_PLUGIN_REFINE_FLAGS_REQUIRE_PERMISSIONS;
g_set_error (error,
GS_PLUGIN_ERROR,
GS_PLUGIN_ERROR_NOT_SUPPORTED,
diff --git a/src/gs-plugin.h b/src/gs-plugin.h
index aa2bb86..dd1b1af 100644
--- a/src/gs-plugin.h
+++ b/src/gs-plugin.h
@@ -155,6 +155,7 @@ typedef enum {
* @GS_PLUGIN_REFINE_FLAGS_REQUIRE_REVIEW_RATINGS: Require user-ratings
* @GS_PLUGIN_REFINE_FLAGS_REQUIRE_KEY_COLORS: Require the key colors
* @GS_PLUGIN_REFINE_FLAGS_REQUIRE_ICON: Require the icon to be loaded
+ * @GS_PLUGIN_REFINE_FLAGS_REQUIRE_PERMISSIONS: Require the needed permissions
*
* The refine flags.
**/
@@ -182,6 +183,7 @@ typedef enum {
GS_PLUGIN_REFINE_FLAGS_REQUIRE_REVIEW_RATINGS = 1 << 19,
GS_PLUGIN_REFINE_FLAGS_REQUIRE_KEY_COLORS = 1 << 20,
GS_PLUGIN_REFINE_FLAGS_REQUIRE_ICON = 1 << 21,
+ GS_PLUGIN_REFINE_FLAGS_REQUIRE_PERMISSIONS = 1 << 22,
/*< private >*/
GS_PLUGIN_REFINE_FLAGS_LAST
} GsPluginRefineFlags;
diff --git a/src/gs-self-test.c b/src/gs-self-test.c
index 52084af..4e59955 100644
--- a/src/gs-self-test.c
+++ b/src/gs-self-test.c
@@ -729,6 +729,7 @@ gs_plugin_loader_flatpak_func (GsPluginLoader *plugin_loader)
/* find available application */
list = gs_plugin_loader_search (plugin_loader,
"Bingo",
+ GS_PLUGIN_REFINE_FLAGS_REQUIRE_PERMISSIONS |
GS_PLUGIN_REFINE_FLAGS_REQUIRE_ICON,
NULL,
&error);
@@ -741,6 +742,9 @@ gs_plugin_loader_flatpak_func (GsPluginLoader *plugin_loader)
g_assert_cmpstr (gs_app_get_id (app), ==, "org.test.Chiron.desktop");
g_assert_cmpint (gs_app_get_kind (app), ==, AS_APP_KIND_DESKTOP);
g_assert_cmpint (gs_app_get_state (app), ==, AS_APP_STATE_AVAILABLE);
+ g_assert_cmpint (gs_app_get_kudos (app), ==, GS_APP_KUDO_HAS_KEYWORDS |
+ GS_APP_KUDO_SANDBOXED_SECURE |
+ GS_APP_KUDO_SANDBOXED);
/* install, also installing runtime */
ret = gs_plugin_loader_app_action (plugin_loader, app,
diff --git a/src/gs-shell-details.c b/src/gs-shell-details.c
index 26ee6d0..1690530 100644
--- a/src/gs-shell-details.c
+++ b/src/gs-shell-details.c
@@ -1494,6 +1494,7 @@ gs_shell_details_set_filename (GsShellDetails *self, const gchar *filename)
gs_plugin_loader_file_to_app_async (self->plugin_loader,
file,
GS_PLUGIN_REFINE_FLAGS_REQUIRE_ICON |
+ GS_PLUGIN_REFINE_FLAGS_REQUIRE_PERMISSIONS |
GS_PLUGIN_REFINE_FLAGS_REQUIRE_RATING |
GS_PLUGIN_REFINE_FLAGS_REQUIRE_REVIEW_RATINGS |
GS_PLUGIN_REFINE_FLAGS_REQUIRE_REVIEWS,
@@ -1507,6 +1508,7 @@ gs_shell_details_load (GsShellDetails *self)
{
gs_plugin_loader_app_refine_async (self->plugin_loader, self->app,
GS_PLUGIN_REFINE_FLAGS_REQUIRE_ICON |
+ GS_PLUGIN_REFINE_FLAGS_REQUIRE_PERMISSIONS |
GS_PLUGIN_REFINE_FLAGS_REQUIRE_LICENSE |
GS_PLUGIN_REFINE_FLAGS_REQUIRE_SIZE |
GS_PLUGIN_REFINE_FLAGS_REQUIRE_RATING |
diff --git a/src/gs-shell-search.c b/src/gs-shell-search.c
index 21b2e67..1f7de0a 100644
--- a/src/gs-shell-search.c
+++ b/src/gs-shell-search.c
@@ -187,6 +187,7 @@ gs_shell_search_load (GsShellSearch *self)
GS_PLUGIN_REFINE_FLAGS_REQUIRE_SETUP_ACTION |
GS_PLUGIN_REFINE_FLAGS_REQUIRE_DESCRIPTION |
GS_PLUGIN_REFINE_FLAGS_REQUIRE_LICENSE |
+ GS_PLUGIN_REFINE_FLAGS_REQUIRE_PERMISSIONS |
GS_PLUGIN_REFINE_FLAGS_REQUIRE_RATING,
self->search_cancellable,
gs_shell_search_get_search_cb,
diff --git a/src/plugins/gs-flatpak.c b/src/plugins/gs-flatpak.c
index 78acc6d..ff002a5 100644
--- a/src/plugins/gs-flatpak.c
+++ b/src/plugins/gs-flatpak.c
@@ -258,6 +258,7 @@ gs_flatpak_set_metadata_installed (GsFlatpak *self, GsApp *app,
metadata_fn = g_build_filename (flatpak_installed_ref_get_deploy_dir (xref),
"..",
"active",
+ "metadata",
NULL);
file = g_file_new_for_path (metadata_fn);
info = g_file_query_info (file,
@@ -269,6 +270,12 @@ gs_flatpak_set_metadata_installed (GsFlatpak *self, GsApp *app,
gs_app_set_install_date (app, mtime);
}
+#if 0
+g_error ("%s :%p", metadata_fn, info);
+
+// /var/lib/flatpak/app/org.gnome.Builder/current/active/metadata
+#endif
+
/* this is faster than resolving */
gs_app_set_origin (app, flatpak_installed_ref_get_origin (xref));
@@ -922,11 +929,15 @@ gs_flatpak_set_app_metadata (GsFlatpak *self,
gsize length,
GError **error)
{
+ gboolean secure = TRUE;
g_autofree gchar *name = NULL;
g_autofree gchar *runtime = NULL;
g_autofree gchar *source = NULL;
g_autoptr(GKeyFile) kf = NULL;
g_autoptr(GsApp) app_runtime = NULL;
+ g_auto(GStrv) shared = NULL;
+ g_auto(GStrv) sockets = NULL;
+ g_auto(GStrv) filesystems = NULL;
kf = g_key_file_new ();
if (!g_key_file_load_from_data (kf, data, length, G_KEY_FILE_NONE, error))
@@ -940,16 +951,43 @@ gs_flatpak_set_app_metadata (GsFlatpak *self,
return FALSE;
g_debug ("runtime for %s is %s", name, runtime);
+ /* we always get this, but it's a low bar... */
+ gs_app_add_kudo (app, GS_APP_KUDO_SANDBOXED);
+ shared = g_key_file_get_string_list (kf, "Context", "shared", NULL, NULL);
+ if (shared != NULL) {
+ /* SHM isn't secure enough */
+ if (g_strv_contains ((const gchar * const *) shared, "ipc"))
+ secure = FALSE;
+ }
+ sockets = g_key_file_get_string_list (kf, "Context", "sockets", NULL, NULL);
+ if (sockets != NULL) {
+ /* X11 isn't secure enough */
+ if (g_strv_contains ((const gchar * const *) sockets, "x11"))
+ secure = FALSE;
+ }
+ filesystems = g_key_file_get_string_list (kf, "Context", "filesystems", NULL, NULL);
+ if (filesystems != NULL) {
+ /* secure apps should be using portals */
+ if (g_strv_contains ((const gchar * const *) filesystems, "home"))
+ secure = FALSE;
+ }
+
+ /* this is actually quite hard to achieve */
+ if (secure)
+ gs_app_add_kudo (app, GS_APP_KUDO_SANDBOXED_SECURE);
+
/* create runtime */
- app_runtime = gs_appstream_create_runtime (self->plugin, app, runtime);
- if (app_runtime != NULL)
- gs_app_set_runtime (app, app_runtime);
+ if (gs_app_get_runtime (app) == NULL) {
+ app_runtime = gs_appstream_create_runtime (self->plugin, app, runtime);
+ if (app_runtime != NULL)
+ gs_app_set_runtime (app, app_runtime);
+ }
return TRUE;
}
static gboolean
-gs_plugin_refine_item_runtime (GsFlatpak *self,
+gs_plugin_refine_item_metadata (GsFlatpak *self,
GsApp *app,
GCancellable *cancellable,
GError **error)
@@ -966,10 +1004,6 @@ gs_plugin_refine_item_runtime (GsFlatpak *self,
if (gs_app_get_flatpak_kind (app) != FLATPAK_REF_KIND_APP)
return TRUE;
- /* already exists */
- if (gs_app_get_runtime (app) != NULL)
- return TRUE;
-
/* this is quicker than doing network IO */
installation_path = flatpak_installation_get_path (self->installation);
installation_path_str = g_file_get_path (installation_path);
@@ -1027,7 +1061,7 @@ gs_plugin_refine_item_size (GsFlatpak *self,
return TRUE;
/* need runtime */
- if (!gs_plugin_refine_item_runtime (self, app, cancellable, error))
+ if (!gs_plugin_refine_item_metadata (self, app, cancellable, error))
return FALSE;
/* calculate the platform size too if the app is not installed */
@@ -1035,13 +1069,6 @@ gs_plugin_refine_item_size (GsFlatpak *self,
gs_app_get_flatpak_kind (app) == FLATPAK_REF_KIND_APP) {
GsApp *app_runtime;
- /* find out what runtime the application depends on */
- if (!gs_plugin_refine_item_runtime (self,
- app,
- cancellable,
- error))
- return FALSE;
-
/* is the app_runtime already installed? */
app_runtime = gs_app_get_runtime (app);
if (!gs_plugin_refine_item_state (self,
@@ -1134,6 +1161,13 @@ gs_flatpak_refine_app (GsFlatpak *self,
return FALSE;
}
+ /* permissions */
+ if (flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_PERMISSIONS) {
+ if (!gs_plugin_refine_item_metadata (self, app,
+ cancellable, error))
+ return FALSE;
+ }
+
/* origin */
if (flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_ORIGIN) {
if (!gs_plugin_refine_item_origin_ui (self, app,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]