From 9d6e1735f3859ce8ead1847bc473e44a27b82f65 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Tue, 28 Sep 2021 12:55:59 +0200 Subject: [PATCH 1/3] data: Add polkit policy description Describe and set defaults for switching and holding power profiles. --- data/meson.build | 15 ++++++++++++++ data/net.hadess.PowerProfiles.policy | 31 ++++++++++++++++++++++++++++ meson.build | 1 + 3 files changed, 47 insertions(+) create mode 100644 data/net.hadess.PowerProfiles.policy Index: power-profiles-daemon-0.9.0/data/meson.build =================================================================== --- power-profiles-daemon-0.9.0.orig/data/meson.build +++ power-profiles-daemon-0.9.0/data/meson.build @@ -19,3 +19,18 @@ install_data( 'net.hadess.PowerProfiles.service', install_dir: dbusservicedir ) + +polkit_policy = 'net.hadess.PowerProfiles.policy' +if xmllint.found() + test(polkit_policy, + xmllint, + args: [ + '--noout', + meson.source_root() / 'data' / polkit_policy, + ]) +endif + +install_data( + polkit_policy, + install_dir: polkit_policy_directory, +) Index: power-profiles-daemon-0.9.0/data/net.hadess.PowerProfiles.policy =================================================================== --- /dev/null +++ power-profiles-daemon-0.9.0/data/net.hadess.PowerProfiles.policy @@ -0,0 +1,31 @@ + + + + + + power-profiles-daemon + https://gitlab.freedesktop.org/hadess/power-profiles-daemon + + + Switch Power Profile + Privileges are required to switch power profiles. + + no + no + yes + + + + + Hold Power Profile + Privileges are required to hold power profiles. + + no + no + yes + + + + Index: power-profiles-daemon-0.9.0/meson.build =================================================================== --- power-profiles-daemon-0.9.0.orig/meson.build +++ power-profiles-daemon-0.9.0/meson.build @@ -34,6 +34,8 @@ endif gio_dep = dependency('gio-2.0') gudev_dep = dependency('gudev-1.0', version: '>= 234') upower_dep = dependency('upower-glib') +polkit_gobject_dep = dependency('polkit-gobject-1', version: '>= 0.91') +polkit_policy_directory = polkit_gobject_dep.get_pkgconfig_variable('policydir') gnome = import('gnome') @@ -42,6 +44,7 @@ add_global_arguments(common_cflags, lang pylint = find_program('pylint-3', 'pylint3', 'pylint', required: false) pylint_flags = ['-d', 'C0116', '-d', 'C0114', '-d', 'W0707'] +xmllint = find_program('xmllint', required: false) subdir('src') subdir('data') Index: power-profiles-daemon-0.9.0/.gitlab-ci.yml =================================================================== --- power-profiles-daemon-0.9.0.orig/.gitlab-ci.yml +++ power-profiles-daemon-0.9.0/.gitlab-ci.yml @@ -8,6 +8,7 @@ variables: pkgconfig(gio-2.0) pkgconfig(gudev-1.0) pkgconfig(upower-glib) + pkgconfig(polkit-gobject-1) systemd meson git Index: power-profiles-daemon-0.9.0/README.md =================================================================== --- power-profiles-daemon-0.9.0.orig/README.md +++ power-profiles-daemon-0.9.0/README.md @@ -9,7 +9,7 @@ Installation $ meson _build -Dprefix=/usr $ ninja -v -C _build install ``` -It requires libgudev and systemd. +It requires libgudev, systemd and polkit-gobject. Introduction ------------ Index: power-profiles-daemon-0.9.0/src/meson.build =================================================================== --- power-profiles-daemon-0.9.0.orig/src/meson.build +++ power-profiles-daemon-0.9.0/src/meson.build @@ -1,4 +1,4 @@ -deps = [ gio_dep, gudev_dep, upower_dep ] +deps = [ gio_dep, gudev_dep, upower_dep, polkit_gobject_dep ] resources = gnome.compile_resources( 'power-profiles-daemon-resources', 'power-profiles-daemon.gresource.xml', Index: power-profiles-daemon-0.9.0/src/power-profiles-daemon.c =================================================================== --- power-profiles-daemon-0.9.0.orig/src/power-profiles-daemon.c +++ power-profiles-daemon-0.9.0/src/power-profiles-daemon.c @@ -9,6 +9,7 @@ */ #include +#include #include "power-profiles-daemon-resources.h" #include "power-profiles-daemon.h" @@ -31,6 +32,8 @@ typedef struct { GKeyFile *config; const char *config_path; + PolkitAuthority *auth; + PpdProfile active_profile; PpdProfile selected_profile; GPtrArray *probed_drivers; @@ -591,6 +594,36 @@ release_profile (PpdApp * g_dbus_method_invocation_return_value (invocation, NULL); } +static gboolean +check_action_permission (PpdApp *data, + const char *sender, + const char *action, + GError **error) +{ + g_autoptr(GError) local_error = NULL; + g_autoptr(PolkitAuthorizationResult) result = NULL; + g_autoptr(PolkitSubject) subject = NULL; + + subject = polkit_system_bus_name_new (sender); + result = polkit_authority_check_authorization_sync (data->auth, + subject, + action, + NULL, + POLKIT_CHECK_AUTHORIZATION_FLAGS_NONE, + NULL, &local_error); + if (result == NULL || + !polkit_authorization_result_get_is_authorized (result)) + { + g_set_error (error, G_DBUS_ERROR, + G_DBUS_ERROR_ACCESS_DENIED, + "Not Authorized: %s", local_error ? local_error->message : action); + return FALSE; + } + + return TRUE; + +} + static GVariant * handle_get_property (GDBusConnection *connection, const gchar *sender, @@ -639,6 +672,8 @@ handle_set_property (GDBusConnection *c "No such property: %s", property_name); return FALSE; } + if (!check_action_permission (data, sender, "net.hadess.PowerProfiles.switch-profile", error)) + return FALSE; g_variant_get (value, "&s", &profile); return set_active_profile (data, profile, error); @@ -664,6 +699,13 @@ handle_method_call (GDBusConnection } if (g_strcmp0 (method_name, "HoldProfile") == 0) { + g_autoptr(GError) local_error = NULL; + if (!check_action_permission (data, + g_dbus_method_invocation_get_sender (invocation), + "net.hadess.PowerProfiles.hold-profile", + &local_error)) { + g_dbus_method_invocation_return_gerror (invocation, local_error); + } hold_profile (data, parameters, invocation); } else if (g_strcmp0 (method_name, "ReleaseProfile") == 0) { release_profile (data, parameters, invocation); @@ -900,6 +942,8 @@ free_app_data (PpdApp *data) g_clear_object (&data->driver); g_hash_table_destroy (data->profile_holds); + g_clear_object (&data->auth); + g_clear_pointer (&data->main_loop, g_main_loop_unref); g_clear_pointer (&data->introspection_data, g_dbus_node_info_unref); g_clear_object (&data->connection); @@ -942,6 +986,7 @@ int main (int argc, char **argv) data = g_new0 (PpdApp, 1); data->main_loop = g_main_loop_new (NULL, TRUE); + data->auth = polkit_authority_get_sync (NULL, NULL); data->probed_drivers = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref); data->actions = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref); data->profile_holds = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, (GDestroyNotify) profile_hold_free);