From 46a9783be650758eb1617a200a0d3866abc30c55 Mon Sep 17 00:00:00 2001 From: Bastien Nocera Date: Wed, 21 May 2008 14:36:36 +0100 Subject: [PATCH] Add PolicyKit checking Add PolicyKit checks to all the public functions, grouped in 2 main groups: Verify and Enroll By default, only the user is able to enroll new fingers, or verify themselves. You need to be allowed at least one of those 2 actions to be allowed to claim or release the device. We also add a new SetUsername function, for administration functions. Users will need to be authenticate as admins to be allowed to change the username on which the actions will be taken. Any prints loaded before the change of username will be unloaded. --- Makefile.am | 2 +- autogen.sh | 1 + configure.ac | 6 +- data/Makefile.am | 12 +- data/net.reactivated.fprint.device.policy.in | 42 +++++ src/device.c | 156 ++++++++++++++++--- src/device.xml | 5 + 7 files changed, 199 insertions(+), 25 deletions(-) create mode 100644 data/net.reactivated.fprint.device.policy.in diff --git a/Makefile.am b/Makefile.am index 62e9de8..095c889 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,4 +1,4 @@ AUTOMAKE_OPTIONS = dist-bzip2 SUBDIRS = src data tests po -EXTRA_DIST = TODO +EXTRA_DIST = TODO intltool-extract.in intltool-merge.in intltool-update.in diff --git a/autogen.sh b/autogen.sh index 096ac20..16bc9ec 100755 --- a/autogen.sh +++ b/autogen.sh @@ -2,6 +2,7 @@ aclocal || exit 1 autoheader || exit 1 glib-gettextize -f -c || exit 1 +intltoolize -c -f || exit 1 autoconf || exit 1 automake -a -c || exit 1 ./configure $* diff --git a/configure.ac b/configure.ac index 59d6394..2c2665c 100644 --- a/configure.ac +++ b/configure.ac @@ -11,6 +11,7 @@ GETTEXT_PACKAGE=fprintd AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE, ["$GETTEXT_PACKAGE"], [Define to the Gettext package name]) AC_SUBST(GETTEXT_PACKAGE) AM_GLIB_GNU_GETTEXT +IT_PROG_INTLTOOL([0.35.0]) PKG_CHECK_MODULES(FPRINT, [libfprint > 0.1.0]) AC_SUBST(FPRINT_LIBS) @@ -24,10 +25,13 @@ PKG_CHECK_MODULES(DBUS_GLIB, "dbus-glib-1") AC_SUBST(DBUS_GLIB_LIBS) AC_SUBST(DBUS_GLIB_CFLAGS) -PKG_CHECK_MODULES(POLKIT, "polkit") +PKG_CHECK_MODULES(POLKIT, "polkit polkit-dbus") AC_SUBST(POLKIT_LIBS) AC_SUBST(POLKIT_CFLAGS) +AC_CHECK_PROG([POLKIT_POLICY_FILE_VALIDATE], + [polkit-policy-file-validate], [polkit-policy-file-validate]) + AS_AC_EXPAND(DATADIR, $datadir) DBUS_SERVICES_DIR="$DATADIR/dbus-1/services" diff --git a/data/Makefile.am b/data/Makefile.am index 0243423..98c9afa 100644 --- a/data/Makefile.am +++ b/data/Makefile.am @@ -1,15 +1,21 @@ dbus_servicesdir = $(datadir)/dbus-1/system-services -dbus_confdir = $(sysconfdir)/dbus-1/system.d - dbus_services_in_files = net.reactivated.Fprint.service.in - dbus_services_DATA = $(dbus_services_in_files:.service.in=.service) $(dbus_services_DATA): $(dbus_services_in_files) sed -e "s|\@LIBEXECDIR\@|$(libexecdir)|" $< > $@ +dbus_confdir = $(sysconfdir)/dbus-1/system.d dbus_conf_DATA = net.reactivated.Fprint.conf +polkitdir = $(datadir)/PolicyKit/policy +polkit_in_files = net.reactivated.fprint.device.policy.in + +@INTLTOOL_POLICY_RULE@ +polkit_DATA = $(polkit_in_files:.policy.in=.policy) + +check: + $(POLKIT_POLICY_FILE_VALIDATE) $(polkit_DATA) diff --git a/data/net.reactivated.fprint.device.policy.in b/data/net.reactivated.fprint.device.policy.in new file mode 100644 index 0000000..af2eddb --- /dev/null +++ b/data/net.reactivated.fprint.device.policy.in @@ -0,0 +1,42 @@ + + + + + + The FPrint Project + http://reactivated.net/fprint/ + fprint + + + <_description>Verify a fingerprint + <_message>Privileges are required to verify fingerprints. + + no + no + yes + + + + + <_description>Enroll new fingerprints + <_message>Privileges are required to enroll new fingerprints. + + no + no + yes + + + + + <_description>Select a user to enroll + <_message>Privileges are required to enroll new fingerprints for other users. + + no + no + auth_admin_keep_always + + + + diff --git a/src/device.c b/src/device.c index 391b4d3..26552a1 100644 --- a/src/device.c +++ b/src/device.c @@ -34,6 +34,9 @@ extern DBusGConnection *fprintd_dbus_conn; +static void fprint_device_set_username(FprintDevice *rdev, + const char *username, + DBusGMethodInvocation *context); static void fprint_device_claim(FprintDevice *rdev, DBusGMethodInvocation *context); static void fprint_device_release(FprintDevice *rdev, @@ -89,9 +92,8 @@ struct FprintDevicePrivate { char *sender; /* Either the current user of the device, or if allowed, - * what was set using SetCurrentUid */ + * what was set using SetUsername */ char *username; - uid_t uid; /* type of storage */ int storage_type; @@ -257,18 +259,15 @@ _fprint_device_check_claimed (FprintDevice *rdev, } static gboolean -_check_polkit_for_action (FprintDevice *rdev, DBusGMethodInvocation *context, const char *action) +_fprint_device_check_polkit_for_action (FprintDevice *rdev, DBusGMethodInvocation *context, const char *action, GError **error) { FprintDevicePrivate *priv = DEVICE_GET_PRIVATE(rdev); const char *sender; - GError *error; DBusError dbus_error; PolKitCaller *pk_caller; PolKitAction *pk_action; PolKitResult pk_result; - error = NULL; - /* Check that caller is privileged */ sender = dbus_g_method_get_sender (context); dbus_error_init (&dbus_error); @@ -277,38 +276,103 @@ _check_polkit_for_action (FprintDevice *rdev, DBusGMethodInvocation *context, co sender, &dbus_error); if (pk_caller == NULL) { - error = g_error_new (FPRINT_ERROR, - FPRINT_ERROR_INTERNAL, - "Error getting information about caller: %s: %s", - dbus_error.name, dbus_error.message); + g_set_error (error, FPRINT_ERROR, + FPRINT_ERROR_INTERNAL, + "Error getting information about caller: %s: %s", + dbus_error.name, dbus_error.message); dbus_error_free (&dbus_error); - dbus_g_method_return_error (context, error); - g_error_free (error); return FALSE; } pk_action = polkit_action_new (); polkit_action_set_action_id (pk_action, action); pk_result = polkit_context_is_caller_authorized (priv->pol_ctx, pk_action, pk_caller, - FALSE, NULL); + TRUE, NULL); polkit_caller_unref (pk_caller); polkit_action_unref (pk_action); if (pk_result != POLKIT_RESULT_YES) { - error = g_error_new (FPRINT_ERROR, - FPRINT_ERROR_INTERNAL, - "%s %s <-- (action, result)", - action, - polkit_result_to_string_representation (pk_result)); + g_set_error (error, FPRINT_ERROR, + FPRINT_ERROR_INTERNAL, + "%s %s <-- (action, result)", + action, + polkit_result_to_string_representation (pk_result)); dbus_error_free (&dbus_error); - dbus_g_method_return_error (context, error); - g_error_free (error); return FALSE; } return TRUE; } +static gboolean +_fprint_device_check_polkit_for_actions (FprintDevice *rdev, + DBusGMethodInvocation *context, + const char *action1, + const char *action2, + GError **error) +{ + if (_fprint_device_check_polkit_for_action (rdev, context, action1, error) != FALSE) + return TRUE; + + g_error_free (*error); + *error = NULL; + + return _fprint_device_check_polkit_for_action (rdev, context, action2, error); +} + +static void +fprint_device_set_username (FprintDevice *rdev, + const char *username, + DBusGMethodInvocation *context) +{ + FprintDevicePrivate *priv = DEVICE_GET_PRIVATE(rdev); + GError *error = NULL; + struct session_data *session = priv->session; + GSList *elem = session->loaded_prints; + + if (_fprint_device_check_claimed(rdev, context, &error) == FALSE) { + dbus_g_method_return_error (context, error); + return; + } + + if (_fprint_device_check_polkit_for_action (rdev, context, "net.reactivated.fprint.device.setusername", &error) == FALSE) { + dbus_g_method_return_error (context, error); + return; + } + + if (username == NULL) { + dbus_g_method_return (context); + return; + } + + /* We already have a username, check if the one we're + * setting is the same */ + if (g_str_equal (username, priv->username) != FALSE) { + dbus_g_method_return (context); + return; + } + + g_free (priv->username); + priv->username = g_strdup (username); + + /* Any fingerprints to unload? */ + if (!elem) { + dbus_g_method_return (context); + return; + } + + /* Empty the fingerprints, as we have a different user */ + do { + struct loaded_print *print = elem->data; + + session->loaded_prints = g_slist_delete_link(session->loaded_prints, + elem); + g_slice_free(struct loaded_print, print); + } while ((elem = g_slist_next(elem)) != NULL); + + dbus_g_method_return (context); +} + static void dev_open_cb(struct fp_dev *dev, int status, void *user_data) { FprintDevice *rdev = user_data; @@ -353,6 +417,14 @@ static void fprint_device_claim(FprintDevice *rdev, return; } + if (_fprint_device_check_polkit_for_actions (rdev, context, + "net.reactivated.fprint.device.verify", + "net.reactivated.fprint.device.enroll", + &error) == FALSE) { + dbus_g_method_return_error (context, error); + return; + } + /* Get details about the current sender, and username/uid */ conn = dbus_g_connection_get_connection (fprintd_dbus_conn); sender = dbus_g_method_get_sender (context); @@ -430,6 +502,15 @@ static void fprint_device_release(FprintDevice *rdev, return; } + /* People that can claim can also release */ + if (_fprint_device_check_polkit_for_actions (rdev, context, + "net.reactivated.fprint.device.verify", + "net.reactivated.fprint.device.enroll", + &error) == FALSE) { + dbus_g_method_return_error (context, error); + return; + } + /* Unload any loaded prints */ if (elem) { do @@ -455,6 +536,11 @@ static void fprint_device_unload_print_data(FprintDevice *rdev, return; } + if (_fprint_device_check_polkit_for_action (rdev, context, "net.reactivated.fprint.device.verify", &error) == FALSE) { + dbus_g_method_return_error (context, error); + return; + } + g_message("unload print data %d for device %d", print_id, priv->id); if (!elem) { g_set_error(&error, FPRINT_ERROR, FPRINT_ERROR_NO_SUCH_LOADED_PRINT, @@ -505,6 +591,11 @@ static void fprint_device_verify_start(FprintDevice *rdev, return; } + if (_fprint_device_check_polkit_for_action (rdev, context, "net.reactivated.fprint.device.verify", &error) == FALSE) { + dbus_g_method_return_error (context, error); + return; + } + g_message("start verification device %d print %d", priv->id, print_id); if (!elem) { g_set_error(&error, FPRINT_ERROR, FPRINT_ERROR_NO_SUCH_LOADED_PRINT, @@ -557,6 +648,11 @@ static void fprint_device_verify_stop(FprintDevice *rdev, return; } + if (_fprint_device_check_polkit_for_action (rdev, context, "net.reactivated.fprint.device.verify", &error) == FALSE) { + dbus_g_method_return_error (context, error); + return; + } + r = fp_async_verify_stop(priv->dev, verify_stop_cb, context); if (r < 0) { g_set_error(&error, FPRINT_ERROR, FPRINT_ERROR_VERIFY_STOP, @@ -598,6 +694,11 @@ static void fprint_device_enroll_start(FprintDevice *rdev, return; } + if (_fprint_device_check_polkit_for_action (rdev, context, "net.reactivated.fprint.device.enroll", &error) == FALSE) { + dbus_g_method_return_error (context, error); + return; + } + g_message("start enrollment device %d finger %d", priv->id, finger_num); session->enroll_finger = finger_num; @@ -629,6 +730,11 @@ static void fprint_device_enroll_stop(FprintDevice *rdev, return; } + if (_fprint_device_check_polkit_for_action (rdev, context, "net.reactivated.fprint.device.enroll", &error) == FALSE) { + dbus_g_method_return_error (context, error); + return; + } + r = fp_async_enroll_stop(priv->dev, enroll_stop_cb, context); if (r < 0) { g_set_error(&error, FPRINT_ERROR, FPRINT_ERROR_ENROLL_STOP, @@ -666,6 +772,11 @@ static void fprint_device_list_enrolled_fingers(FprintDevice *rdev, return; } + if (_fprint_device_check_polkit_for_action (rdev, context, "net.reactivated.fprint.device.verify", &error) == FALSE) { + dbus_g_method_return_error (context, error); + return; + } + prints = storages[priv->storage_type].discover_prints(priv->dev, priv->username); if (!prints) { g_set_error(&error, FPRINT_ERROR, FPRINT_ERROR_DISCOVER_PRINTS, @@ -700,6 +811,11 @@ static void fprint_device_load_print_data(FprintDevice *rdev, return; } + if (_fprint_device_check_polkit_for_action (rdev, context, "net.reactivated.fprint.device.verify", &error) == FALSE) { + dbus_g_method_return_error (context, error); + return; + } + r = storages[priv->storage_type].print_data_load(priv->dev, (enum fp_finger)finger_num, &data, priv->username); diff --git a/src/device.xml b/src/device.xml index 6ef5801..f7d1656 100644 --- a/src/device.xml +++ b/src/device.xml @@ -60,6 +60,11 @@ + + + + + -- GitLab