[gnome-software] Try to detect sandboxed applications



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]