From 7290da5ddaa7d436f1ce4a778036ae93580c7ab6 Mon Sep 17 00:00:00 2001 From: Richard Hughes Date: Fri, 28 Jan 2022 15:20:26 +0000 Subject: [PATCH] Allow the root user to ask the daemon to quit This makes it easier to test the fwupd in the installed tests: sudo gdbus call --system \ --dest org.freedesktop.fwupd \ --object-path / \ --method org.freedesktop.fwupd.Quit --- src/fu-engine-request.c | 7 ++++++ src/fu-engine-request.h | 2 ++ src/fu-main.c | 41 +++++++++++++++++++++++++++++++++++ src/org.freedesktop.fwupd.xml | 11 ++++++++++ 4 files changed, 61 insertions(+) diff --git a/src/fu-engine-request.c b/src/fu-engine-request.c index 1ba8f5fdf..c39427976 100644 --- a/src/fu-engine-request.c +++ b/src/fu-engine-request.c @@ -80,6 +80,13 @@ fu_engine_request_set_device_flags(FuEngineRequest *self, FwupdDeviceFlags devic self->device_flags = device_flags; } +gboolean +fu_engine_request_has_device_flag(FuEngineRequest *self, FwupdDeviceFlags device_flag) +{ + g_return_val_if_fail(FU_IS_ENGINE_REQUEST(self), FALSE); + return (self->device_flags & device_flag) > 0; +} + static void fu_engine_request_init(FuEngineRequest *self) { diff --git a/src/fu-engine-request.h b/src/fu-engine-request.h index c26fc79b9..c33cade0f 100644 --- a/src/fu-engine-request.h +++ b/src/fu-engine-request.h @@ -31,6 +31,8 @@ void fu_engine_request_set_locale(FuEngineRequest *self, const gchar *locale); gboolean fu_engine_request_has_feature_flag(FuEngineRequest *self, FwupdFeatureFlags feature_flag); +gboolean +fu_engine_request_has_device_flag(FuEngineRequest *self, FwupdDeviceFlags device_flag); FwupdDeviceFlags fu_engine_request_get_device_flags(FuEngineRequest *self); void diff --git a/src/fu-main.c b/src/fu-main.c index fa8845c4d..aedc82ea5 100644 --- a/src/fu-main.c +++ b/src/fu-main.c @@ -77,6 +77,7 @@ typedef struct { PolkitAuthority *authority; #endif guint owner_id; + guint process_quit_id; FuEngine *engine; gboolean update_in_progress; gboolean pending_sigterm; @@ -982,6 +983,32 @@ fu_main_device_id_valid(const gchar *device_id, GError **error) return FALSE; } +static gboolean +fu_main_schedule_process_quit_cb(gpointer user_data) +{ + FuMainPrivate *priv = (FuMainPrivate *)user_data; + + g_debug("daemon asked to quit, shutting down"); + priv->process_quit_id = 0; + g_main_loop_quit(priv->loop); + return G_SOURCE_REMOVE; +} + +static void +fu_main_schedule_process_quit(FuMainPrivate *priv) +{ + /* busy? */ + if (priv->update_in_progress) { + g_warning("asked to quit during a firmware update, ignoring"); + return; + } + + /* allow the daemon to respond to the request, then quit */ + if (priv->process_quit_id != 0) + g_source_remove(priv->process_quit_id); + priv->process_quit_id = g_idle_add(fu_main_schedule_process_quit_cb, priv); +} + static void fu_main_daemon_method_call(GDBusConnection *connection, const gchar *sender, @@ -1165,6 +1192,18 @@ fu_main_daemon_method_call(GDBusConnection *connection, #endif /* HAVE_POLKIT */ return; } + if (g_strcmp0(method_name, "Quit") == 0) { + if (!fu_engine_request_has_device_flag(request, FWUPD_DEVICE_FLAG_TRUSTED)) { + g_dbus_method_invocation_return_error_literal(invocation, + FWUPD_ERROR, + FWUPD_ERROR_PERMISSION_DENIED, + "Permission denied"); + return; + } + fu_main_schedule_process_quit(priv); + g_dbus_method_invocation_return_value(invocation, NULL); + return; + } if (g_strcmp0(method_name, "SelfSign") == 0) { GVariant *prop_value; const gchar *prop_key; @@ -1990,6 +2029,8 @@ static void fu_main_private_free(FuMainPrivate *priv) { g_hash_table_unref(priv->sender_items); + if (priv->process_quit_id != 0) + g_source_remove(priv->process_quit_id); if (priv->loop != NULL) g_main_loop_unref(priv->loop); if (priv->owner_id > 0) diff --git a/src/org.freedesktop.fwupd.xml b/src/org.freedesktop.fwupd.xml index d7502a82c..2d34d675a 100644 --- a/src/org.freedesktop.fwupd.xml +++ b/src/org.freedesktop.fwupd.xml @@ -821,6 +821,17 @@ + + + + + + Ask the daemon to quit. This can only be called by the root user. + + + + +