From 244985f45fe59d3de92bebcdb49cf3f9461bd09e Mon Sep 17 00:00:00 2001 From: Philip Withnall Date: Wed, 14 Nov 2018 15:17:18 +0000 Subject: [PATCH] libeos-parental-controls: Support matching against flatpak app IDs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These are the app-specific part of a flatpak ref, and are what’s available when you have a .desktop file, via the X-Flatpak key in the .desktop file. For example, for a flatpak ref ‘app/org.gnome.Builder/x86_64/master’, the app ID is ‘org.gnome.Builder’. It makes sense that we’d want to match against app IDs in some situations, since the user probably doesn’t care about the architecture or branch of the app they want to proscribe. Signed-off-by: Philip Withnall https://phabricator.endlessm.com/T24016 --- .../eos-parental-controls-client.py | 7 ++- libeos-parental-controls/app-filter.c | 53 ++++++++++++++++++- libeos-parental-controls/app-filter.h | 2 + libeos-parental-controls/tests/app-filter.c | 4 ++ 4 files changed, 64 insertions(+), 2 deletions(-) diff --git a/eos-parental-controls-client/eos-parental-controls-client.py b/eos-parental-controls-client/eos-parental-controls-client.py index 24c4b73..5e6ca4f 100644 --- a/eos-parental-controls-client/eos-parental-controls-client.py +++ b/eos-parental-controls-client/eos-parental-controls-client.py @@ -150,7 +150,12 @@ def command_check(user, path, quiet=False, interactive=True): user_id = __lookup_user_id_or_error(user) app_filter = __get_app_filter_or_error(user_id, interactive) - if path.startswith('app/') or path.startswith('runtime/'): + if path.startswith('app/') and path.count('/') < 3: + # Flatpak app ID + path = path[4:] + is_allowed = app_filter.is_flatpak_app_allowed(path) + noun = 'Flatpak app ID' + elif path.startswith('app/') or path.startswith('runtime/'): # Flatpak ref is_allowed = app_filter.is_flatpak_ref_allowed(path) noun = 'Flatpak ref' diff --git a/libeos-parental-controls/app-filter.c b/libeos-parental-controls/app-filter.c index 8d8e085..bd146da 100644 --- a/libeos-parental-controls/app-filter.c +++ b/libeos-parental-controls/app-filter.c @@ -166,7 +166,7 @@ epc_app_filter_is_path_allowed (EpcAppFilter *filter, /** * epc_app_filter_is_flatpak_ref_allowed: * @filter: an #EpcAppFilter - * @app_ref: flatpak ref for the app + * @app_ref: flatpak ref for the app, for example `app/org.gnome.Builder/x86_64/master` * * Check whether the flatpak app with the given @app_ref is allowed to be run * according to this app filter. @@ -197,6 +197,57 @@ epc_app_filter_is_flatpak_ref_allowed (EpcAppFilter *filter, } } +/** + * epc_app_filter_is_flatpak_app_allowed: + * @filter: an #EpcAppFilter + * @app_id: flatpak ID for the app, for example `org.gnome.Builder` + * + * Check whether the flatpak app with the given @app_id is allowed to be run + * according to this app filter. This is a globbing match, matching @app_id + * against potentially multiple entries in the blacklist, as the blacklist + * contains flatpak refs (for example, `app/org.gnome.Builder/x86_64/master`) + * which contain architecture and branch information. App IDs (for example, + * `org.gnome.Builder`) do not contain architecture or branch information. + * + * Returns: %TRUE if the user this @filter corresponds to is allowed to run the + * flatpak called @app_id according to the @filter policy; %FALSE otherwise + * Since: 0.1.0 + */ +gboolean +epc_app_filter_is_flatpak_app_allowed (EpcAppFilter *filter, + const gchar *app_id) +{ + g_return_val_if_fail (filter != NULL, FALSE); + g_return_val_if_fail (filter->ref_count >= 1, FALSE); + g_return_val_if_fail (app_id != NULL, FALSE); + + gsize app_id_len = strlen (app_id); + + gboolean id_in_list = FALSE; + for (gsize i = 0; filter->app_list[i] != NULL; i++) + { + /* Avoid using flatpak_ref_parse() to avoid a dependency on libflatpak + * just for that one function. */ + if (g_str_has_prefix (filter->app_list[i], "app/") && + strncmp (filter->app_list[i] + strlen ("app/"), app_id, app_id_len) == 0 && + filter->app_list[i][strlen ("app/") + app_id_len] == '/') + { + id_in_list = TRUE; + break; + } + } + + switch (filter->app_list_type) + { + case EPC_APP_FILTER_LIST_BLACKLIST: + return !id_in_list; + case EPC_APP_FILTER_LIST_WHITELIST: + return id_in_list; + default: + g_assert_not_reached (); + } +} + static gint strcmp_cb (gconstpointer a, gconstpointer b) diff --git a/libeos-parental-controls/app-filter.h b/libeos-parental-controls/app-filter.h index ab6280a..fbca57a 100644 --- a/libeos-parental-controls/app-filter.h +++ b/libeos-parental-controls/app-filter.h @@ -102,6 +102,8 @@ gboolean epc_app_filter_is_path_allowed (EpcAppFilter *filter, const gchar *path); gboolean epc_app_filter_is_flatpak_ref_allowed (EpcAppFilter *filter, const gchar *app_ref); +gboolean epc_app_filter_is_flatpak_app_allowed (EpcAppFilter *filter, + const gchar *app_id); const gchar **epc_app_filter_get_oars_sections (EpcAppFilter *filter); EpcAppFilterOarsValue epc_app_filter_get_oars_value (EpcAppFilter *filter, diff --git a/libeos-parental-controls/tests/app-filter.c b/libeos-parental-controls/tests/app-filter.c index 2bbbb63..7fb4e5e 100644 --- a/libeos-parental-controls/tests/app-filter.c +++ b/libeos-parental-controls/tests/app-filter.c @@ -135,8 +135,10 @@ test_app_filter_builder_non_empty (BuilderFixture *fixture, g_assert_true (epc_app_filter_is_flatpak_ref_allowed (filter, "app/org.gnome.Ponies/x86_64/master")); + g_assert_true (epc_app_filter_is_flatpak_app_allowed (filter, "org.gnome.Ponies")); g_assert_false (epc_app_filter_is_flatpak_ref_allowed (filter, "app/org.doom.Doom/x86_64/master")); + g_assert_false (epc_app_filter_is_flatpak_app_allowed (filter, "org.doom.Doom")); g_assert_cmpint (epc_app_filter_get_oars_value (filter, "drugs-alcohol"), ==, EPC_APP_FILTER_OARS_VALUE_MILD); @@ -168,8 +170,10 @@ test_app_filter_builder_empty (BuilderFixture *fixture, g_assert_true (epc_app_filter_is_flatpak_ref_allowed (filter, "app/org.gnome.Ponies/x86_64/master")); + g_assert_true (epc_app_filter_is_flatpak_app_allowed (filter, "org.gnome.Ponies")); g_assert_true (epc_app_filter_is_flatpak_ref_allowed (filter, "app/org.doom.Doom/x86_64/master")); + g_assert_true (epc_app_filter_is_flatpak_app_allowed (filter, "org.doom.Doom")); g_assert_cmpint (epc_app_filter_get_oars_value (filter, "drugs-alcohol"), ==, EPC_APP_FILTER_OARS_VALUE_UNKNOWN);