From c19b6a777f10afbcbe077500520822f0070e4962 Mon Sep 17 00:00:00 2001 From: Philip Withnall Date: Fri, 12 Oct 2018 17:59:04 +1300 Subject: [PATCH] libeos-parental-controls: Add support for flatpak refs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As well as handling paths on the file system, we should allow flatpak refs to be explicitly handled in the app filter. Both refs and paths can be stored safely in the same app filter GStrv because paths are always absolute and refs always start with ‘app/’ or ‘runtime/’. Signed-off-by: Philip Withnall https://phabricator.endlessm.com/T24020 --- .../eos-parental-controls-client.py | 26 +++++--- libeos-parental-controls/app-filter.c | 60 +++++++++++++++++++ libeos-parental-controls/app-filter.h | 20 ++++--- libeos-parental-controls/tests/app-filter.c | 13 ++++ 4 files changed, 103 insertions(+), 16 deletions(-) diff --git a/eos-parental-controls-client/eos-parental-controls-client.py b/eos-parental-controls-client/eos-parental-controls-client.py index d5a163e..cbc6af2 100644 --- a/eos-parental-controls-client/eos-parental-controls-client.py +++ b/eos-parental-controls-client/eos-parental-controls-client.py @@ -171,20 +171,28 @@ def command_get(user, quiet=False, interactive=True): def command_check(user, path, quiet=False, interactive=True): - """Check the given path is runnable by the given user, according to their - app filter.""" + """Check the given path or flatpak ref is runnable by the given user, + according to their app filter.""" user_id = __lookup_user_id_or_error(user) app_filter = __get_app_filter_or_error(user_id, interactive) - path = os.path.abspath(path) + if path.startswith('app/') or path.startswith('runtime/'): + # Flatpak ref + is_allowed = app_filter.is_flatpak_ref_allowed(path) + noun = 'Flatpak ref' + else: + # File system path + path = os.path.abspath(path) + is_allowed = app_filter.is_path_allowed(path) + noun = 'Path' - if app_filter.is_path_allowed(path): - print('Path {} is allowed by app filter for user {}'.format( - path, user_id)) + if is_allowed: + print('{} {} is allowed by app filter for user {}'.format( + noun, path, user_id)) return else: - print('Path {} is not allowed by app filter for user {}'.format( - path, user_id)) + print('{} {} is not allowed by app filter for user {}'.format( + noun, path, user_id)) raise SystemExit(EXIT_PATH_NOT_ALLOWED) @@ -214,6 +222,8 @@ def command_set(user, app_filter_args=None, quiet=False, interactive=True): file=sys.stderr) raise SystemExit(EXIT_INVALID_OPTION) builder.set_oars_value(section, value) + elif arg.startswith('app/') or arg.startswith('runtime/'): + builder.blacklist_flatpak_ref(arg) else: builder.blacklist_path(arg) app_filter = builder.end() diff --git a/libeos-parental-controls/app-filter.c b/libeos-parental-controls/app-filter.c index da7efdf..9dcacc1 100644 --- a/libeos-parental-controls/app-filter.c +++ b/libeos-parental-controls/app-filter.c @@ -162,6 +162,40 @@ 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 + * + * Check whether the flatpak app with the given @app_ref is allowed to be run + * according to this app filter. + * + * Returns: %TRUE if the user this @filter corresponds to is allowed to run the + * flatpak called @app_ref according to the @filter policy; %FALSE otherwise + * Since: 0.1.0 + */ +gboolean +epc_app_filter_is_flatpak_ref_allowed (EpcAppFilter *filter, + const gchar *app_ref) +{ + g_return_val_if_fail (filter != NULL, FALSE); + g_return_val_if_fail (filter->ref_count >= 1, FALSE); + g_return_val_if_fail (app_ref != NULL, FALSE); + + gboolean ref_in_list = g_strv_contains ((const gchar * const *) filter->app_list, + app_ref); + + switch (filter->app_list_type) + { + case EPC_APP_FILTER_LIST_BLACKLIST: + return !ref_in_list; + case EPC_APP_FILTER_LIST_WHITELIST: + return ref_in_list; + default: + g_assert_not_reached (); + } +} + /** * epc_app_filter_get_oars_value: * @filter: an #EpcAppFilter @@ -977,6 +1011,32 @@ epc_app_filter_builder_blacklist_path (EpcAppFilterBuilder *builder, g_ptr_array_add (_builder->paths_blacklist, g_steal_pointer (&canonical_path)); } +/** + * epc_app_filter_builder_blacklist_flatpak_ref: + * @builder: an initialised #EpcAppFilterBuilder + * @app_ref: a flatpak app ref to blacklist + * + * Add @app_ref to the blacklist of flatpak refs in the filter under + * construction. The @app_ref will not be added again if it’s already been + * added. + * + * Since: 0.1.0 + */ +void +epc_app_filter_builder_blacklist_flatpak_ref (EpcAppFilterBuilder *builder, + const gchar *app_ref) +{ + EpcAppFilterBuilderReal *_builder = (EpcAppFilterBuilderReal *) builder; + + g_return_if_fail (_builder != NULL); + g_return_if_fail (_builder->paths_blacklist != NULL); + g_return_if_fail (app_ref != NULL); + + if (!g_ptr_array_find_with_equal_func (_builder->paths_blacklist, + app_ref, g_str_equal, NULL)) + g_ptr_array_add (_builder->paths_blacklist, g_strdup (app_ref)); +} + /** * epc_app_filter_builder_set_oars_value: * @builder: an initialised #EpcAppFilterBuilder diff --git a/libeos-parental-controls/app-filter.h b/libeos-parental-controls/app-filter.h index 458827b..98652d0 100644 --- a/libeos-parental-controls/app-filter.h +++ b/libeos-parental-controls/app-filter.h @@ -97,9 +97,11 @@ void epc_app_filter_unref (EpcAppFilter *filter); G_DEFINE_AUTOPTR_CLEANUP_FUNC (EpcAppFilter, epc_app_filter_unref) -uid_t epc_app_filter_get_user_id (EpcAppFilter *filter); -gboolean epc_app_filter_is_path_allowed (EpcAppFilter *filter, - const gchar *path); +uid_t epc_app_filter_get_user_id (EpcAppFilter *filter); +gboolean epc_app_filter_is_path_allowed (EpcAppFilter *filter, + const gchar *path); +gboolean epc_app_filter_is_flatpak_ref_allowed (EpcAppFilter *filter, + const gchar *flatpak_ref); EpcAppFilterOarsValue epc_app_filter_get_oars_value (EpcAppFilter *filter, const gchar *oars_section); @@ -177,10 +179,12 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC (EpcAppFilterBuilder, epc_app_filter_builder_free) EpcAppFilter *epc_app_filter_builder_end (EpcAppFilterBuilder *builder); -void epc_app_filter_builder_blacklist_path (EpcAppFilterBuilder *builder, - const gchar *path); -void epc_app_filter_builder_set_oars_value (EpcAppFilterBuilder *builder, - const gchar *oars_section, - EpcAppFilterOarsValue value); +void epc_app_filter_builder_blacklist_path (EpcAppFilterBuilder *builder, + const gchar *path); +void epc_app_filter_builder_blacklist_flatpak_ref (EpcAppFilterBuilder *builder, + const gchar *app_ref); +void epc_app_filter_builder_set_oars_value (EpcAppFilterBuilder *builder, + const gchar *oars_section, + EpcAppFilterOarsValue value); G_END_DECLS diff --git a/libeos-parental-controls/tests/app-filter.c b/libeos-parental-controls/tests/app-filter.c index bd72dad..c0062c3 100644 --- a/libeos-parental-controls/tests/app-filter.c +++ b/libeos-parental-controls/tests/app-filter.c @@ -102,6 +102,9 @@ test_app_filter_builder_non_empty (BuilderFixture *fixture, epc_app_filter_builder_blacklist_path (fixture->builder, "/bin/true"); epc_app_filter_builder_blacklist_path (fixture->builder, "/usr/bin/gnome-software"); + epc_app_filter_builder_blacklist_flatpak_ref (fixture->builder, + "app/org.doom.Doom/x86_64/master"); + epc_app_filter_builder_set_oars_value (fixture->builder, "drugs-alcohol", EPC_APP_FILTER_OARS_VALUE_MILD); epc_app_filter_builder_set_oars_value (fixture->builder, "language-humor", @@ -113,6 +116,11 @@ test_app_filter_builder_non_empty (BuilderFixture *fixture, g_assert_false (epc_app_filter_is_path_allowed (filter, "/usr/bin/gnome-software")); + g_assert_true (epc_app_filter_is_flatpak_ref_allowed (filter, + "app/org.gnome.Ponies/x86_64/master")); + g_assert_false (epc_app_filter_is_flatpak_ref_allowed (filter, + "app/org.doom.Doom/x86_64/master")); + g_assert_cmpint (epc_app_filter_get_oars_value (filter, "drugs-alcohol"), ==, EPC_APP_FILTER_OARS_VALUE_MILD); g_assert_cmpint (epc_app_filter_get_oars_value (filter, "language-humor"), ==, @@ -134,6 +142,11 @@ test_app_filter_builder_empty (BuilderFixture *fixture, g_assert_true (epc_app_filter_is_path_allowed (filter, "/usr/bin/gnome-software")); + 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_ref_allowed (filter, + "app/org.doom.Doom/x86_64/master")); + g_assert_cmpint (epc_app_filter_get_oars_value (filter, "drugs-alcohol"), ==, EPC_APP_FILTER_OARS_VALUE_UNKNOWN); g_assert_cmpint (epc_app_filter_get_oars_value (filter, "language-humor"), ==,