mirror of
https://git.proxmox.com/git/fwupd
synced 2025-12-25 11:31:38 +00:00
Use PolicyKit to check the authorisation of the firmware update
This commit is contained in:
parent
8bbfdf49a8
commit
f508e76a7a
173
src/fu-main.c
173
src/fu-main.c
@ -26,6 +26,7 @@
|
||||
#include <gio/gunixfdlist.h>
|
||||
#include <glib/gi18n.h>
|
||||
#include <locale.h>
|
||||
#include <polkit/polkit.h>
|
||||
|
||||
#include "fu-cleanup.h"
|
||||
#include "fu-common.h"
|
||||
@ -40,8 +41,14 @@ typedef struct {
|
||||
GMainLoop *loop;
|
||||
GPtrArray *devices;
|
||||
GPtrArray *providers;
|
||||
PolkitAuthority *authority;
|
||||
} FuMainPrivate;
|
||||
|
||||
typedef struct {
|
||||
FuDevice *device;
|
||||
FuProvider *provider;
|
||||
} FuDeviceItem;
|
||||
|
||||
/**
|
||||
* fu_main_get_device_list_as_strv:
|
||||
**/
|
||||
@ -61,22 +68,112 @@ fu_main_get_device_list_as_strv (FuMainPrivate *priv)
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_main_get_device_by_id:
|
||||
* fu_main_item_free:
|
||||
**/
|
||||
static FuDevice *
|
||||
fu_main_get_device_by_id (FuMainPrivate *priv, const gchar *id)
|
||||
static void
|
||||
fu_main_item_free (FuDeviceItem *item)
|
||||
{
|
||||
FuDevice *device_tmp;
|
||||
g_object_unref (item->device);
|
||||
g_object_unref (item->provider);
|
||||
g_free (item);
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_main_get_item_by_id:
|
||||
**/
|
||||
static FuDeviceItem *
|
||||
fu_main_get_item_by_id (FuMainPrivate *priv, const gchar *id)
|
||||
{
|
||||
FuDeviceItem *item;
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < priv->devices->len; i++) {
|
||||
device_tmp = g_ptr_array_index (priv->devices, i);
|
||||
if (g_strcmp0 (fu_device_get_id (device_tmp), id) == 0)
|
||||
return device_tmp;
|
||||
item = g_ptr_array_index (priv->devices, i);
|
||||
if (g_strcmp0 (fu_device_get_id (item->device), id) == 0)
|
||||
return item;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
GDBusMethodInvocation *invocation;
|
||||
FuMainPrivate *priv;
|
||||
gint fd;
|
||||
gchar *id;
|
||||
} FuMainAuthHelper;
|
||||
|
||||
/**
|
||||
* fu_main_helper_free:
|
||||
**/
|
||||
static void
|
||||
fu_main_helper_free (FuMainAuthHelper *helper)
|
||||
{
|
||||
g_object_unref (helper->invocation);
|
||||
g_free (helper->id);
|
||||
g_free (helper);
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_main_check_authorization_cb:
|
||||
**/
|
||||
static void
|
||||
fu_main_check_authorization_cb (GObject *source, GAsyncResult *res, gpointer user_data)
|
||||
{
|
||||
FuMainAuthHelper *helper = (FuMainAuthHelper *) user_data;
|
||||
FuDeviceItem *item;
|
||||
_cleanup_error_free_ GError *error = NULL;
|
||||
_cleanup_object_unref_ PolkitAuthorizationResult *auth = NULL;
|
||||
|
||||
/* get result */
|
||||
auth = polkit_authority_check_authorization_finish (POLKIT_AUTHORITY (source),
|
||||
res, &error);
|
||||
if (auth == NULL) {
|
||||
g_dbus_method_invocation_return_error (helper->invocation,
|
||||
FU_ERROR,
|
||||
FU_ERROR_INTERNAL,
|
||||
"could not check for auth: %s",
|
||||
error->message);
|
||||
fu_main_helper_free (helper);
|
||||
return;
|
||||
}
|
||||
|
||||
/* did not auth */
|
||||
if (!polkit_authorization_result_get_is_authorized (auth)) {
|
||||
g_dbus_method_invocation_return_error (helper->invocation,
|
||||
FU_ERROR,
|
||||
FU_ERROR_INTERNAL,
|
||||
"failed to obtain auth");
|
||||
fu_main_helper_free (helper);
|
||||
return;
|
||||
}
|
||||
|
||||
/* check the device still exists */
|
||||
item = fu_main_get_item_by_id (helper->priv, helper->id);
|
||||
if (item == NULL) {
|
||||
g_dbus_method_invocation_return_error (helper->invocation,
|
||||
FU_ERROR,
|
||||
FU_ERROR_INTERNAL,
|
||||
"device %s was removed",
|
||||
helper->id);
|
||||
fu_main_helper_free (helper);
|
||||
return;
|
||||
}
|
||||
|
||||
/* run the correct provider that added this */
|
||||
if (!fu_provider_update_offline (item->provider,
|
||||
item->device,
|
||||
helper->fd, &error)) {
|
||||
g_dbus_method_invocation_return_gerror (helper->invocation,
|
||||
error);
|
||||
fu_main_helper_free (helper);
|
||||
return;
|
||||
}
|
||||
|
||||
/* success */
|
||||
g_dbus_method_invocation_return_value (helper->invocation, NULL);
|
||||
fu_main_helper_free (helper);
|
||||
}
|
||||
|
||||
/**
|
||||
* fu_main_daemon_method_call:
|
||||
**/
|
||||
@ -89,11 +186,10 @@ fu_main_daemon_method_call (GDBusConnection *connection, const gchar *sender,
|
||||
FuMainPrivate *priv = (FuMainPrivate *) user_data;
|
||||
GVariant *val;
|
||||
|
||||
g_debug ("Called %s()", method_name);
|
||||
|
||||
/* return 'as' */
|
||||
if (g_strcmp0 (method_name, "GetDevices") == 0) {
|
||||
_cleanup_strv_free_ gchar **devices = NULL;
|
||||
g_debug ("Called %s()", method_name);
|
||||
devices = fu_main_get_device_list_as_strv (priv);
|
||||
val = g_variant_new ("(^as)", devices);
|
||||
g_dbus_method_invocation_return_value (invocation, val);
|
||||
@ -104,16 +200,19 @@ fu_main_daemon_method_call (GDBusConnection *connection, const gchar *sender,
|
||||
if (g_strcmp0 (method_name, "UpdateOffline") == 0) {
|
||||
GDBusMessage *message;
|
||||
GUnixFDList *fd_list;
|
||||
FuDevice *device;
|
||||
FuDeviceItem *item;
|
||||
FuMainAuthHelper *helper;
|
||||
const gchar *id = NULL;
|
||||
gint32 fd_handle = 0;
|
||||
gint fd;
|
||||
_cleanup_error_free_ GError *error = NULL;
|
||||
_cleanup_object_unref_ PolkitSubject *subject = NULL;
|
||||
|
||||
/* check the id exists */
|
||||
g_variant_get (parameters, "(&sh)", &id, &fd_handle);
|
||||
device = fu_main_get_device_by_id (priv, id);
|
||||
if (device == NULL) {
|
||||
g_debug ("Called %s(%s,%i)", method_name, id, fd_handle);
|
||||
item = fu_main_get_item_by_id (priv, id);
|
||||
if (item == NULL) {
|
||||
g_dbus_method_invocation_return_error (invocation,
|
||||
FU_ERROR,
|
||||
FU_ERROR_INTERNAL,
|
||||
@ -139,13 +238,21 @@ fu_main_daemon_method_call (GDBusConnection *connection, const gchar *sender,
|
||||
return;
|
||||
}
|
||||
|
||||
/* TODO: run the correct provider that can handle this */
|
||||
// if (!fu_provider_update_offline (provider, device, fd, &error)) {
|
||||
// g_dbus_method_invocation_return_gerror (invocation,
|
||||
// error);
|
||||
// return;
|
||||
// }
|
||||
g_dbus_method_invocation_return_value (invocation, NULL);
|
||||
|
||||
/* do authorization async */
|
||||
helper = g_new0 (FuMainAuthHelper, 1);
|
||||
helper->invocation = g_object_ref (invocation);
|
||||
helper->fd = fd;
|
||||
helper->id = g_strdup (id);
|
||||
helper->priv = priv;
|
||||
subject = polkit_system_bus_name_new (sender);
|
||||
polkit_authority_check_authorization (priv->authority, subject,
|
||||
"org.freedesktop.fwupd.update",
|
||||
NULL,
|
||||
POLKIT_CHECK_AUTHORIZATION_FLAGS_ALLOW_USER_INTERACTION,
|
||||
NULL,
|
||||
fu_main_check_authorization_cb,
|
||||
helper);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -281,7 +388,12 @@ cd_main_provider_device_added_cb (FuProvider *provider,
|
||||
gpointer user_data)
|
||||
{
|
||||
FuMainPrivate *priv = (FuMainPrivate *) user_data;
|
||||
g_ptr_array_add (priv->devices, g_object_ref (device));
|
||||
FuDeviceItem *item;
|
||||
|
||||
item = g_new0 (FuDeviceItem, 1);
|
||||
item->device = g_object_ref (device);
|
||||
item->provider = g_object_ref (provider);
|
||||
g_ptr_array_add (priv->devices, item);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -293,7 +405,14 @@ cd_main_provider_device_removed_cb (FuProvider *provider,
|
||||
gpointer user_data)
|
||||
{
|
||||
FuMainPrivate *priv = (FuMainPrivate *) user_data;
|
||||
g_ptr_array_remove (priv->devices, g_object_ref (device));
|
||||
FuDeviceItem *item;
|
||||
|
||||
item = fu_main_get_item_by_id (priv, fu_device_get_id (device));
|
||||
if (item == NULL) {
|
||||
g_warning ("can't remove device %s", fu_device_get_id (device));
|
||||
return;
|
||||
}
|
||||
g_ptr_array_remove (priv->devices, item);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -356,7 +475,7 @@ main (int argc, char *argv[])
|
||||
|
||||
/* create new objects */
|
||||
priv = g_new0 (FuMainPrivate, 1);
|
||||
priv->devices = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref);
|
||||
priv->devices = g_ptr_array_new_with_free_func ((GDestroyNotify) fu_main_item_free);
|
||||
priv->loop = g_main_loop_new (NULL, FALSE);
|
||||
|
||||
/* add providers */
|
||||
@ -372,6 +491,14 @@ main (int argc, char *argv[])
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* get authority */
|
||||
priv->authority = polkit_authority_get_sync (NULL, &error);
|
||||
if (priv->authority == NULL) {
|
||||
g_warning ("FuMain: failed to load polkit authority: %s",
|
||||
error->message);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* own the object */
|
||||
owner_id = g_bus_own_name (G_BUS_TYPE_SYSTEM,
|
||||
FWUPD_DBUS_SERVICE,
|
||||
@ -404,6 +531,8 @@ out:
|
||||
g_main_loop_unref (priv->loop);
|
||||
if (priv->connection != NULL)
|
||||
g_object_unref (priv->connection);
|
||||
if (priv->authority != NULL)
|
||||
g_object_unref (priv->authority);
|
||||
if (priv->introspection_daemon != NULL)
|
||||
g_dbus_node_info_unref (priv->introspection_daemon);
|
||||
g_ptr_array_unref (priv->providers);
|
||||
|
||||
@ -73,7 +73,10 @@ fu_provider_uefi_update_offline (FuProvider *provider,
|
||||
gint fd,
|
||||
GError **error)
|
||||
{
|
||||
// FuProviderUefi *provider_uefi = FU_PROVIDER_UEFI (provider);
|
||||
|
||||
//FIXME
|
||||
g_debug ("DOING UEFI UPDATE USING FD %i", fd);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -89,7 +92,7 @@ fu_provider_uefi_coldplug (FuProvider *provider, GError **error)
|
||||
//FIXME
|
||||
g_debug ("Adding fake UEFI device");
|
||||
dev = fu_device_new ();
|
||||
fu_device_set_id (dev, "819b858e-c52c-402f-80e1-5b311b6c1959");
|
||||
fu_device_set_id (dev, "UEFI-819b858e-c52c-402f-80e1-5b311b6c1959-dev1");
|
||||
fu_provider_emit_added (provider, dev);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -281,7 +281,7 @@ fu_util_update_offline (FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
close (fd);
|
||||
|
||||
/* send message */
|
||||
body = g_variant_new ("(sh)", values[0], fd);
|
||||
body = g_variant_new ("(sh)", values[0], fd > -1 ? 0 : -1);
|
||||
g_dbus_message_set_body (request, body);
|
||||
message = g_dbus_connection_send_message_with_reply_sync (conn,
|
||||
request,
|
||||
@ -292,6 +292,8 @@ fu_util_update_offline (FuUtilPrivate *priv, gchar **values, GError **error)
|
||||
error);
|
||||
if (message == NULL)
|
||||
return FALSE;
|
||||
if (g_dbus_message_to_gerror (message, error))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user