mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2025-12-25 21:10:08 +01:00
core: add generic device authorization request signal
Allows devices to generically request authorization from the manager for whatever operation they want, and allows us to keep the devices from including the auth code directly.
This commit is contained in:
parent
ddb28d3e1a
commit
0ab9c25646
3 changed files with 114 additions and 1 deletions
|
|
@ -91,6 +91,7 @@ enum {
|
|||
STATE_CHANGED,
|
||||
DISCONNECT_REQUEST,
|
||||
AUTOCONNECT_ALLOWED,
|
||||
AUTH_REQUEST,
|
||||
LAST_SIGNAL,
|
||||
};
|
||||
static guint signals[LAST_SIGNAL] = { 0 };
|
||||
|
|
@ -4157,6 +4158,15 @@ nm_device_class_init (NMDeviceClass *klass)
|
|||
_nm_marshal_BOOLEAN__VOID,
|
||||
G_TYPE_BOOLEAN, 0);
|
||||
|
||||
signals[AUTH_REQUEST] =
|
||||
g_signal_new (NM_DEVICE_AUTH_REQUEST,
|
||||
G_OBJECT_CLASS_TYPE (object_class),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
0, NULL, NULL,
|
||||
/* dbus-glib context, permission, allow_interaction, callback, user_data */
|
||||
_nm_marshal_VOID__POINTER_STRING_BOOLEAN_POINTER_POINTER,
|
||||
G_TYPE_NONE, 5, G_TYPE_POINTER, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_POINTER, G_TYPE_POINTER);
|
||||
|
||||
dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (klass),
|
||||
&dbus_glib_nm_device_interface_object_info);
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
#define NM_DEVICE_H
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <dbus/dbus.h>
|
||||
#include <dbus/dbus-glib.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include "NetworkManager.h"
|
||||
|
|
@ -60,6 +60,7 @@
|
|||
|
||||
/* Internal signal */
|
||||
#define NM_DEVICE_DISCONNECT_REQUEST "disconnect-request"
|
||||
#define NM_DEVICE_AUTH_REQUEST "auth-request"
|
||||
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
|
@ -171,6 +172,11 @@ typedef struct {
|
|||
} NMDeviceClass;
|
||||
|
||||
|
||||
typedef void (*NMDeviceAuthRequestFunc) (NMDevice *device,
|
||||
DBusGMethodInvocation *context,
|
||||
GError *error,
|
||||
gpointer user_data);
|
||||
|
||||
GType nm_device_get_type (void);
|
||||
|
||||
const char * nm_device_get_path (NMDevice *dev);
|
||||
|
|
|
|||
|
|
@ -1640,6 +1640,99 @@ manager_device_disconnect_request (NMDevice *device,
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
device_auth_done_cb (NMAuthChain *chain,
|
||||
GError *auth_error,
|
||||
DBusGMethodInvocation *context,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMManager *self = NM_MANAGER (user_data);
|
||||
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
||||
GError *error = NULL;
|
||||
NMAuthCallResult result;
|
||||
NMDevice *device;
|
||||
const char *permission;
|
||||
NMDeviceAuthRequestFunc callback;
|
||||
|
||||
priv->auth_chains = g_slist_remove (priv->auth_chains, chain);
|
||||
|
||||
permission = nm_auth_chain_get_data (chain, "requested-permission");
|
||||
g_assert (permission);
|
||||
callback = nm_auth_chain_get_data (chain, "callback");
|
||||
g_assert (callback);
|
||||
device = nm_auth_chain_get_data (chain, "device");
|
||||
g_assert (device);
|
||||
|
||||
result = GPOINTER_TO_UINT (nm_auth_chain_get_data (chain, permission));
|
||||
if (auth_error) {
|
||||
/* translate the auth error into a manager permission denied error */
|
||||
nm_log_dbg (LOGD_CORE, "%s request failed: %s", permission, auth_error->message);
|
||||
error = g_error_new (NM_MANAGER_ERROR,
|
||||
NM_MANAGER_ERROR_PERMISSION_DENIED,
|
||||
"%s request failed: %s",
|
||||
permission, auth_error->message);
|
||||
} else if (result != NM_AUTH_CALL_RESULT_YES) {
|
||||
nm_log_dbg (LOGD_CORE, "%s request failed: not authorized", permission);
|
||||
error = g_error_new (NM_MANAGER_ERROR,
|
||||
NM_MANAGER_ERROR_PERMISSION_DENIED,
|
||||
"%s request failed: not authorized",
|
||||
permission);
|
||||
}
|
||||
|
||||
g_assert (error || (result == NM_AUTH_CALL_RESULT_YES));
|
||||
|
||||
callback (device,
|
||||
context,
|
||||
error,
|
||||
nm_auth_chain_get_data (chain, "user-data"));
|
||||
|
||||
g_clear_error (&error);
|
||||
nm_auth_chain_unref (chain);
|
||||
}
|
||||
|
||||
static void
|
||||
device_auth_request_cb (NMDevice *device,
|
||||
DBusGMethodInvocation *context,
|
||||
const char *permission,
|
||||
gboolean allow_interaction,
|
||||
NMDeviceAuthRequestFunc callback,
|
||||
gpointer user_data,
|
||||
NMManager *self)
|
||||
{
|
||||
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
||||
GError *error = NULL;
|
||||
gulong sender_uid = G_MAXULONG;
|
||||
char *error_desc = NULL;
|
||||
NMAuthChain *chain;
|
||||
|
||||
/* Get the caller's UID for the root check */
|
||||
if (!nm_auth_get_caller_uid (context, priv->dbus_mgr, &sender_uid, &error_desc)) {
|
||||
error = g_error_new_literal (NM_MANAGER_ERROR,
|
||||
NM_MANAGER_ERROR_PERMISSION_DENIED,
|
||||
error_desc);
|
||||
callback (device, context, error, user_data);
|
||||
g_error_free (error);
|
||||
g_free (error_desc);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Yay for root */
|
||||
if (0 == sender_uid)
|
||||
callback (device, context, NULL, user_data);
|
||||
else {
|
||||
/* Otherwise validate the non-root request */
|
||||
chain = nm_auth_chain_new (context, NULL, device_auth_done_cb, self);
|
||||
g_assert (chain);
|
||||
priv->auth_chains = g_slist_append (priv->auth_chains, chain);
|
||||
|
||||
nm_auth_chain_set_data (chain, "device", g_object_ref (device), g_object_unref);
|
||||
nm_auth_chain_set_data (chain, "requested-permission", g_strdup (permission), g_free);
|
||||
nm_auth_chain_set_data (chain, "callback", callback, NULL);
|
||||
nm_auth_chain_set_data (chain, "user-data", user_data, NULL);
|
||||
nm_auth_chain_add_call (chain, permission, allow_interaction);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
add_device (NMManager *self, NMDevice *device)
|
||||
{
|
||||
|
|
@ -1683,6 +1776,10 @@ add_device (NMManager *self, NMDevice *device)
|
|||
G_CALLBACK (manager_device_disconnect_request),
|
||||
self);
|
||||
|
||||
g_signal_connect (device, NM_DEVICE_AUTH_REQUEST,
|
||||
G_CALLBACK (device_auth_request_cb),
|
||||
self);
|
||||
|
||||
if (devtype == NM_DEVICE_TYPE_WIFI) {
|
||||
/* Attach to the access-point-added signal so that the manager can fill
|
||||
* non-SSID-broadcasting APs with an SSID.
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue