device: Use GFlags to handle permission types easily as flags

And thanks to the GEnumValues we can easily get their nick string from
them that we can pass to Polkit
This commit is contained in:
Marco Trevisan (Treviño)
2020-11-06 18:22:15 +01:00
committed by Benjamin Berg
parent 1a860aa882
commit e59f3cbc4f

View File

@ -32,10 +32,6 @@
#include "fprintd.h" #include "fprintd.h"
#include "storage.h" #include "storage.h"
#define FPRINTD_DEVICE_ACTION_ENROLL (gpointer) "net.reactivated.fprint.device.enroll"
#define FPRINTD_DEVICE_ACTION_SETUSERNAME (gpointer) "net.reactivated.fprint.device.setusername"
#define FPRINTD_DEVICE_ACTION_VERIFY (gpointer) "net.reactivated.fprint.device.verify"
static const char *FINGERS_NAMES[] = { static const char *FINGERS_NAMES[] = {
[FP_FINGER_UNKNOWN] = "unknown", [FP_FINGER_UNKNOWN] = "unknown",
"left-thumb", "left-thumb",
@ -72,6 +68,13 @@ typedef enum {
STATE_IGNORED, STATE_IGNORED,
} FprintDeviceClaimState; } FprintDeviceClaimState;
typedef enum {
FPRINT_DEVICE_PERMISSION_NONE = 0,
FPRINT_DEVICE_PERMISSION_ENROLL = (1 << 0),
FPRINT_DEVICE_PERMISSION_SETUSERNAME = (1 << 1),
FPRINT_DEVICE_PERMISSION_VERIFY = (1 << 2),
} FprintDevicePermission;
typedef struct { typedef struct {
/* current method invocation */ /* current method invocation */
GDBusMethodInvocation *invocation; GDBusMethodInvocation *invocation;
@ -132,6 +135,39 @@ enum fprint_device_signals {
static guint32 last_id = ~0; static guint32 last_id = ~0;
static guint signals[NUM_SIGNALS] = { 0, }; static guint signals[NUM_SIGNALS] = { 0, };
static GType
fprint_device_permission_get_type (void)
{
static volatile gsize define_type_id = 0;
if (g_once_init_enter (&define_type_id)) {
static const GFlagsValue values[] = {
{
FPRINT_DEVICE_PERMISSION_ENROLL,
"FPRINT_DEVICE_PERMISSION_ENROLL",
"net.reactivated.fprint.device.enroll"
},
{
FPRINT_DEVICE_PERMISSION_SETUSERNAME,
"FPRINT_DEVICE_PERMISSION_SETUSERNAME",
"net.reactivated.fprint.device.setusername"
},
{
FPRINT_DEVICE_PERMISSION_VERIFY,
"FPRINT_DEVICE_PERMISSION_VERIFY",
"net.reactivated.fprint.device.verify"
},
{ 0, NULL, NULL }
};
GType type_id = g_flags_register_static (
"FprintDevicePermission", values);
g_once_init_leave (&define_type_id, type_id);
}
return define_type_id;
}
static void session_data_free(SessionData *session) static void session_data_free(SessionData *session)
{ {
g_clear_pointer(&session->sender, g_free); g_clear_pointer(&session->sender, g_free);
@ -478,19 +514,29 @@ _fprint_device_check_polkit_for_action (FprintDevice *rdev,
} }
static gboolean static gboolean
_fprint_device_check_polkit_for_actions (FprintDevice *rdev, fprint_device_check_polkit_for_permissions (FprintDevice *rdev,
GDBusMethodInvocation *invocation, GDBusMethodInvocation *invocation,
GPtrArray *actions, FprintDevicePermission permissions,
GError **error) GError **error)
{ {
g_autoptr(GFlagsClass) permission_flags = NULL;
unsigned i; unsigned i;
if (!actions || !actions->len) if (permissions == FPRINT_DEVICE_PERMISSION_NONE)
return TRUE; return TRUE;
for (i = 0; i < actions->len; ++i) { permission_flags =
const char *action = g_ptr_array_index (actions, i); g_type_class_ref (fprint_device_permission_get_type ());
for (i = 0; i < permission_flags->n_values; ++i) {
GFlagsValue *value = &permission_flags->values[i];
const char *action;
if (!(value->value & permissions)) {
continue;
}
action = value->value_nick;
g_debug ("Getting authorization to perform Polkit action %s", g_debug ("Getting authorization to perform Polkit action %s",
action); action);
@ -557,8 +603,8 @@ _fprint_device_check_for_username (FprintDevice *rdev,
/* If we're not allowed to set a different username, /* If we're not allowed to set a different username,
* then fail */ * then fail */
if (!_fprint_device_check_polkit_for_action (rdev, invocation, if (!fprint_device_check_polkit_for_permissions (rdev, invocation,
FPRINTD_DEVICE_ACTION_SETUSERNAME, FPRINT_DEVICE_PERMISSION_SETUSERNAME,
error)) { error)) {
return NULL; return NULL;
} }
@ -1545,13 +1591,12 @@ action_authorization_handler (GDBusInterfaceSkeleton *interface,
FprintDevice *rdev = FPRINT_DEVICE (dbus_dev); FprintDevice *rdev = FPRINT_DEVICE (dbus_dev);
FprintDevicePrivate *priv = fprint_device_get_instance_private (rdev); FprintDevicePrivate *priv = fprint_device_get_instance_private (rdev);
FprintDeviceClaimState required_state = STATE_IGNORED; FprintDeviceClaimState required_state = STATE_IGNORED;
FprintDevicePermission required_perms = FPRINT_DEVICE_PERMISSION_NONE;
gboolean needs_user_auth = FALSE; gboolean needs_user_auth = FALSE;
g_autoptr(GError) error = NULL; g_autoptr(GError) error = NULL;
g_autoptr(GPtrArray) required_actions = NULL;
const gchar *method_name; const gchar *method_name;
method_name = g_dbus_method_invocation_get_method_name (invocation); method_name = g_dbus_method_invocation_get_method_name (invocation);
required_actions = g_ptr_array_new ();
g_debug ("Requesting device '%s' authorization for method %s from %s", g_debug ("Requesting device '%s' authorization for method %s from %s",
fp_device_get_name (priv->dev), method_name, fp_device_get_name (priv->dev), method_name,
@ -1560,44 +1605,33 @@ action_authorization_handler (GDBusInterfaceSkeleton *interface,
if (g_str_equal (method_name, "Claim")) { if (g_str_equal (method_name, "Claim")) {
needs_user_auth = TRUE; needs_user_auth = TRUE;
required_state = STATE_UNCLAIMED; required_state = STATE_UNCLAIMED;
g_ptr_array_add (required_actions, required_perms |= FPRINT_DEVICE_PERMISSION_VERIFY;
FPRINTD_DEVICE_ACTION_VERIFY); required_perms |= FPRINT_DEVICE_PERMISSION_ENROLL;
g_ptr_array_add (required_actions,
FPRINTD_DEVICE_ACTION_ENROLL);
} else if (g_str_equal (method_name, "DeleteEnrolledFingers")) { } else if (g_str_equal (method_name, "DeleteEnrolledFingers")) {
needs_user_auth = TRUE; needs_user_auth = TRUE;
g_ptr_array_add (required_actions, required_perms |= FPRINT_DEVICE_PERMISSION_ENROLL;
FPRINTD_DEVICE_ACTION_ENROLL);
} else if (g_str_equal (method_name, "DeleteEnrolledFingers2")) { } else if (g_str_equal (method_name, "DeleteEnrolledFingers2")) {
required_state = STATE_CLAIMED; required_state = STATE_CLAIMED;
g_ptr_array_add (required_actions, required_perms |= FPRINT_DEVICE_PERMISSION_ENROLL;
FPRINTD_DEVICE_ACTION_ENROLL);
} else if (g_str_equal (method_name, "EnrollStart")) { } else if (g_str_equal (method_name, "EnrollStart")) {
required_state = STATE_CLAIMED; required_state = STATE_CLAIMED;
g_ptr_array_add (required_actions, required_perms |= FPRINT_DEVICE_PERMISSION_ENROLL;
FPRINTD_DEVICE_ACTION_ENROLL);
} else if (g_str_equal (method_name, "EnrollStop")) { } else if (g_str_equal (method_name, "EnrollStop")) {
required_state = STATE_CLAIMED; required_state = STATE_CLAIMED;
g_ptr_array_add (required_actions, required_perms |= FPRINT_DEVICE_PERMISSION_ENROLL;
FPRINTD_DEVICE_ACTION_ENROLL);
} else if (g_str_equal (method_name, "ListEnrolledFingers")) { } else if (g_str_equal (method_name, "ListEnrolledFingers")) {
needs_user_auth = TRUE; needs_user_auth = TRUE;
g_ptr_array_add (required_actions, required_perms |= FPRINT_DEVICE_PERMISSION_VERIFY;
FPRINTD_DEVICE_ACTION_VERIFY);
} else if (g_str_equal (method_name, "Release")) { } else if (g_str_equal (method_name, "Release")) {
required_state = STATE_CLAIMED; required_state = STATE_CLAIMED;
g_ptr_array_add (required_actions, required_perms |= FPRINT_DEVICE_PERMISSION_VERIFY;
FPRINTD_DEVICE_ACTION_VERIFY); required_perms |= FPRINT_DEVICE_PERMISSION_ENROLL;
g_ptr_array_add (required_actions,
FPRINTD_DEVICE_ACTION_ENROLL);
} else if (g_str_equal (method_name, "VerifyStart")) { } else if (g_str_equal (method_name, "VerifyStart")) {
required_state = STATE_CLAIMED; required_state = STATE_CLAIMED;
g_ptr_array_add (required_actions, required_perms |= FPRINT_DEVICE_PERMISSION_VERIFY;
FPRINTD_DEVICE_ACTION_VERIFY);
} else if (g_str_equal (method_name, "VerifyStop")) { } else if (g_str_equal (method_name, "VerifyStop")) {
required_state = STATE_CLAIMED; required_state = STATE_CLAIMED;
g_ptr_array_add (required_actions, required_perms |= FPRINT_DEVICE_PERMISSION_VERIFY;
FPRINTD_DEVICE_ACTION_VERIFY);
} else { } else {
g_assert_not_reached (); g_assert_not_reached ();
} }
@ -1614,8 +1648,8 @@ action_authorization_handler (GDBusInterfaceSkeleton *interface,
/* This may possibly block the invocation till the user has not /* This may possibly block the invocation till the user has not
* provided an authentication method, so other calls could arrive */ * provided an authentication method, so other calls could arrive */
if (!_fprint_device_check_polkit_for_actions (rdev, invocation, if (!fprint_device_check_polkit_for_permissions (rdev, invocation,
required_actions, required_perms,
&error)) { &error)) {
return handle_unauthorized_access (rdev, invocation, error); return handle_unauthorized_access (rdev, invocation, error);
} }