From 93bad825406d13ed5eb2cf27541dc58194bef8f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Mon, 3 Feb 2020 20:29:56 +0100 Subject: [PATCH] fprintd: Use GDBus codegen based implementation Fprintd is dependent on the deprecated dbus-glib, also this doesn't provide various features we can take advantage of, like the ones for async authentication mechanism. So, remove all the dbus-glib dependencies and simplify the code, but without any further refactor, and keeping everything as it used to work, while this will give room for further improvements in subsequent commits. Internally, we just use dbus-codegen to generate the skeletons, and we use the generated FprintdDBusManager with composition, while we implement the device skeleton interface in FprintDevice, so that we don't have to use it as a proxy, and keep being closer to what it used to be with dbus-glib. Fixes: #61 --- meson.build | 2 +- src/device.c | 555 ++++++++++++++++++---------------- src/device.xml | 21 -- src/fprintd-marshal.list | 1 - src/fprintd.h | 19 +- src/main.c | 62 ++-- src/manager.c | 208 ++++++++++--- src/manager.xml | 2 - src/meson.build | 34 +-- tests/pam/test_pam_fprintd.py | 3 - utils/delete.c | 105 ++++--- utils/enroll.c | 88 ++++-- utils/list.c | 94 +++--- utils/meson.build | 37 +-- utils/verify.c | 107 ++++--- 15 files changed, 750 insertions(+), 588 deletions(-) delete mode 100644 src/fprintd-marshal.list diff --git a/meson.build b/meson.build index 4f739d0..4c135f9 100644 --- a/meson.build +++ b/meson.build @@ -68,11 +68,11 @@ endif # Dependencies glib_dep = dependency('glib-2.0', version: '>=' + glib_min_version) gio_dep = dependency('gio-2.0', version: '>=' + glib_min_version) +gio_unix_dep = dependency('gio-unix-2.0', version: '>=' + glib_min_version) gmodule_dep = dependency('gmodule-2.0', version: '>=' + glib_min_version) libfprint_dep = dependency('libfprint-2', version: '>=' + libfprint_min_version) polkit_gobject_dep = dependency('polkit-gobject-1', version: '>= 0.91') dbus_dep = dependency('dbus-1', required: false) -dbus_glib_dep = dependency('dbus-glib-1') libsystemd_dep = dependency('libsystemd', required: get_option('pam')) pam_dep = cc.find_library('pam', required: get_option('pam'), diff --git a/src/device.c b/src/device.c index a7980af..bd6b1a4 100644 --- a/src/device.c +++ b/src/device.c @@ -1,6 +1,7 @@ /* * /net/reactivated/Fprint/Device/foo object implementation * Copyright (C) 2008 Daniel Drake + * Copyright (C) 2020 Marco Trevisan * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,8 +20,6 @@ #include "config.h" -#include -#include #include #include #include @@ -30,7 +29,6 @@ #include #include -#include "fprintd-marshal.h" #include "fprintd.h" #include "storage.h" @@ -48,31 +46,7 @@ static const char *FINGERS_NAMES[] = { "right-little-finger" }; -extern DBusGConnection *fprintd_dbus_conn; - -static void fprint_device_claim(FprintDevice *rdev, - const char *username, - DBusGMethodInvocation *context); -static void fprint_device_release(FprintDevice *rdev, - DBusGMethodInvocation *context); -static void fprint_device_verify_start(FprintDevice *rdev, - const char *finger_name, DBusGMethodInvocation *context); -static void fprint_device_verify_stop(FprintDevice *rdev, - DBusGMethodInvocation *context); -static void fprint_device_enroll_start(FprintDevice *rdev, - const char *finger_name, DBusGMethodInvocation *context); -static void fprint_device_enroll_stop(FprintDevice *rdev, - DBusGMethodInvocation *context); -static void fprint_device_list_enrolled_fingers(FprintDevice *rdev, - const char *username, - DBusGMethodInvocation *context); -static void fprint_device_delete_enrolled_fingers(FprintDevice *rdev, - const char *username, - DBusGMethodInvocation *context); -static void fprint_device_delete_enrolled_fingers2(FprintDevice *rdev, - DBusGMethodInvocation *context); - -#include "device-dbus-glue.h" +static void fprint_device_dbus_skeleton_iface_init (FprintDBusDeviceIface *); typedef enum { ACTION_NONE = 0, @@ -85,7 +59,7 @@ typedef enum { typedef struct { /* current method invocation */ - DBusGMethodInvocation *context; + GDBusMethodInvocation *invocation; /* The current user of the device, if claimed */ char *sender; @@ -115,10 +89,14 @@ typedef struct { /* whether we're running an identify, or a verify */ FprintDeviceAction current_action; GCancellable *current_cancellable; - DBusGMethodInvocation *current_cancel_context; + GDBusMethodInvocation *current_cancel_invocation; } FprintDevicePrivate; -G_DEFINE_TYPE_WITH_CODE(FprintDevice, fprint_device, G_TYPE_OBJECT, G_ADD_PRIVATE (FprintDevice)); +G_DEFINE_TYPE_WITH_CODE (FprintDevice, fprint_device, + FPRINT_DBUS_TYPE_DEVICE_SKELETON, + G_ADD_PRIVATE (FprintDevice) + G_IMPLEMENT_INTERFACE (FPRINT_DBUS_TYPE_DEVICE, + fprint_device_dbus_skeleton_iface_init)); enum fprint_device_properties { FPRINT_DEVICE_CONSTRUCT_DEV = 1, @@ -142,7 +120,7 @@ static void session_data_free(SessionData *session) { g_clear_pointer(&session->sender, g_free); g_clear_pointer(&session->username, g_free); - g_nullify_pointer((gpointer *) &session->context); + g_clear_object (&session->invocation); g_free(session); } G_DEFINE_AUTOPTR_CLEANUP_FUNC(SessionData, session_data_free); @@ -219,9 +197,6 @@ static void fprint_device_class_init(FprintDeviceClass *klass) GObjectClass *gobject_class = G_OBJECT_CLASS(klass); GParamSpec *pspec; - dbus_g_object_type_install_info(FPRINT_TYPE_DEVICE, - &dbus_glib_fprint_device_object_info); - gobject_class->finalize = fprint_device_finalize; gobject_class->set_property = fprint_device_set_property; gobject_class->get_property = fprint_device_get_property; @@ -239,33 +214,24 @@ static void fprint_device_class_init(FprintDeviceClass *klass) g_object_class_install_property(gobject_class, FPRINT_DEVICE_IN_USE, pspec); - pspec = g_param_spec_string("name", "Name", - "The product name of the device", NULL, - G_PARAM_READABLE); - g_object_class_install_property(gobject_class, - FPRINT_DEVICE_NAME, pspec); + g_object_class_override_property (gobject_class, + FPRINT_DEVICE_NAME, + "name"); - pspec = g_param_spec_string("scan-type", "Scan Type", - "The scan type of the device", "press", - G_PARAM_READABLE); - g_object_class_install_property(gobject_class, - FPRINT_DEVICE_SCAN_TYPE, pspec); + g_object_class_override_property (gobject_class, + FPRINT_DEVICE_SCAN_TYPE, + "scan-type"); - pspec = g_param_spec_int("num-enroll-stages", "Number of enrollments stages", - "Number of enrollment stages for the device.", - -1, G_MAXINT, -1, G_PARAM_READABLE); - g_object_class_install_property(gobject_class, - FPRINT_DEVICE_NUM_ENROLL, pspec); + g_object_class_override_property (gobject_class, + FPRINT_DEVICE_NUM_ENROLL, + "num-enroll-stages"); - signals[SIGNAL_VERIFY_STATUS] = g_signal_new("verify-status", - G_TYPE_FROM_CLASS(gobject_class), G_SIGNAL_RUN_LAST, 0, NULL, NULL, - fprintd_marshal_VOID__STRING_BOOLEAN, G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_BOOLEAN); - signals[SIGNAL_ENROLL_STATUS] = g_signal_new("enroll-status", - G_TYPE_FROM_CLASS(gobject_class), G_SIGNAL_RUN_LAST, 0, NULL, NULL, - fprintd_marshal_VOID__STRING_BOOLEAN, G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_BOOLEAN); - signals[SIGNAL_VERIFY_FINGER_SELECTED] = g_signal_new("verify-finger-selected", - G_TYPE_FROM_CLASS(gobject_class), G_SIGNAL_RUN_LAST, 0, NULL, NULL, - g_cclosure_marshal_VOID__STRING, G_TYPE_NONE, 1, G_TYPE_STRING); + signals[SIGNAL_VERIFY_STATUS] = + g_signal_lookup ("verify-status", FPRINT_TYPE_DEVICE); + signals[SIGNAL_ENROLL_STATUS] = + g_signal_lookup ("enroll-status", FPRINT_TYPE_DEVICE); + signals[SIGNAL_VERIFY_FINGER_SELECTED] = + g_signal_lookup ("verify-finger-selected", FPRINT_TYPE_DEVICE); } static void fprint_device_init(FprintDevice *device) @@ -394,11 +360,11 @@ enroll_result_to_name (gboolean completed, gboolean enrolled, GError *error) static gboolean _fprint_device_check_claimed (FprintDevice *rdev, - DBusGMethodInvocation *context, + GDBusMethodInvocation *invocation, GError **error) { FprintDevicePrivate *priv = fprint_device_get_instance_private(rdev); - char *sender; + const char *sender; gboolean retval; /* The device wasn't claimed, exit */ @@ -408,12 +374,11 @@ _fprint_device_check_claimed (FprintDevice *rdev, return FALSE; } - sender = dbus_g_method_get_sender (context); + sender = g_dbus_method_invocation_get_sender (invocation); retval = g_str_equal (sender, priv->session->sender); - g_free (sender); if (retval == FALSE || - priv->session->context != NULL) { + priv->session->invocation != NULL) { g_set_error (error, FPRINT_ERROR, FPRINT_ERROR_ALREADY_IN_USE, _("Device already in use by another user")); } @@ -422,18 +387,20 @@ _fprint_device_check_claimed (FprintDevice *rdev, } static gboolean -_fprint_device_check_polkit_for_action (FprintDevice *rdev, DBusGMethodInvocation *context, const char *action, GError **error) +_fprint_device_check_polkit_for_action (FprintDevice *rdev, + GDBusMethodInvocation *invocation, + const char *action, + GError **error) { FprintDevicePrivate *priv = fprint_device_get_instance_private(rdev); - char *sender; + const char *sender; PolkitSubject *subject; PolkitAuthorizationResult *result; GError *_error = NULL; /* Check that caller is privileged */ - sender = dbus_g_method_get_sender (context); + sender = g_dbus_method_invocation_get_sender (invocation); subject = polkit_system_bus_name_new (sender); - g_free (sender); result = polkit_authority_check_authorization_sync (priv->auth, subject, @@ -466,49 +433,60 @@ _fprint_device_check_polkit_for_action (FprintDevice *rdev, DBusGMethodInvocatio static gboolean _fprint_device_check_polkit_for_actions (FprintDevice *rdev, - DBusGMethodInvocation *context, + GDBusMethodInvocation *invocation, const char *action1, const char *action2, GError **error) { - if (_fprint_device_check_polkit_for_action (rdev, context, action1, error) != FALSE) + if (_fprint_device_check_polkit_for_action (rdev, invocation, action1, error) != FALSE) return TRUE; g_clear_error (error); - return _fprint_device_check_polkit_for_action (rdev, context, action2, error); + return _fprint_device_check_polkit_for_action (rdev, invocation, action2, error); } static char * _fprint_device_check_for_username (FprintDevice *rdev, - DBusGMethodInvocation *context, + GDBusMethodInvocation *invocation, const char *username, char **ret_sender, GError **error) { - DBusConnection *conn; - DBusError dbus_error; - char *sender; - unsigned long uid; + g_autoptr(GVariant) ret = NULL; + g_autoptr(GError) err = NULL; + GDBusConnection *connection; + const char *sender; struct passwd *user; + guint32 uid; /* 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); - dbus_error_init (&dbus_error); - uid = dbus_bus_get_unix_user (conn, sender, &dbus_error); + connection = g_dbus_method_invocation_get_connection (invocation); + sender = g_dbus_method_invocation_get_sender (invocation); - if (dbus_error_is_set(&dbus_error)) { - g_free (sender); - dbus_set_g_error (error, &dbus_error); + ret = g_dbus_connection_call_sync (connection, + "org.freedesktop.DBus", + "/org/freedesktop/DBus", + "org.freedesktop.DBus", + "GetConnectionUnixUser", + g_variant_new ("(s)", sender), + NULL, G_DBUS_CALL_FLAGS_NONE, -1, + NULL, &err); + + if (!ret) { + g_autoptr(GError) e = NULL; + + g_set_error (error, FPRINT_ERROR, FPRINT_ERROR_INTERNAL, + "Could not get conection unix user ID: %s", + err->message); return NULL; } + g_variant_get (ret, "(u)", &uid); user = getpwuid (uid); if (user == NULL) { - g_free (sender); g_set_error(error, FPRINT_ERROR, FPRINT_ERROR_INTERNAL, - "Failed to get information about user UID %lu", uid); + "Failed to get information about user UID %u", uid); return NULL; } @@ -517,23 +495,20 @@ _fprint_device_check_for_username (FprintDevice *rdev, * anyway */ if (username == NULL || *username == '\0' || g_str_equal (username, user->pw_name)) { if (ret_sender != NULL) - *ret_sender = sender; - else - g_free (sender); + *ret_sender = g_strdup (sender); return g_strdup (user->pw_name); } /* If we're not allowed to set a different username, * then fail */ - if (_fprint_device_check_polkit_for_action (rdev, context, "net.reactivated.fprint.device.setusername", error) == FALSE) { - g_free (sender); + if (!_fprint_device_check_polkit_for_action (rdev, invocation, + "net.reactivated.fprint.device.setusername", + error)) { return NULL; } if (ret_sender != NULL) - *ret_sender = sender; - else - g_free (sender); + *ret_sender = g_strdup (sender); return g_strdup (username); } @@ -596,7 +571,8 @@ static void dev_open_cb(FpDevice *dev, GAsyncResult *res, void *user_data) g_autoptr(GError) error = NULL; FprintDevice *rdev = user_data; FprintDevicePrivate *priv = fprint_device_get_instance_private(rdev); - DBusGMethodInvocation *context = g_steal_pointer(&priv->session->context); + g_autoptr(GDBusMethodInvocation) invocation = + g_steal_pointer (&priv->session->invocation); priv->current_action = ACTION_NONE; if (!fp_device_open_finish (dev, res, &error)) { @@ -605,20 +581,22 @@ static void dev_open_cb(FpDevice *dev, GAsyncResult *res, void *user_data) dbus_error = g_error_new (FPRINT_ERROR, FPRINT_ERROR_INTERNAL, "Open failed with error: %s", error->message); - dbus_g_method_return_error(context, dbus_error); + g_dbus_method_invocation_return_gerror (invocation, dbus_error); g_clear_pointer(&priv->session, session_data_free); return; } g_debug("claimed device %d", priv->id); - dbus_g_method_return(context); + fprint_dbus_device_complete_claim (FPRINT_DBUS_DEVICE (rdev), + invocation); } -static void fprint_device_claim(FprintDevice *rdev, - const char *username, - DBusGMethodInvocation *context) +static gboolean fprint_device_claim (FprintDBusDevice *dbus_dev, + GDBusMethodInvocation *invocation, + const char *username) { + FprintDevice *rdev = FPRINT_DEVICE (dbus_dev); FprintDevicePrivate *priv = fprint_device_get_instance_private(rdev); GError *error = NULL; char *sender, *user; @@ -627,41 +605,41 @@ static void fprint_device_claim(FprintDevice *rdev, if (priv->session) { g_set_error(&error, FPRINT_ERROR, FPRINT_ERROR_ALREADY_IN_USE, "Device was already claimed"); - dbus_g_method_return_error(context, error); + g_dbus_method_invocation_return_gerror (invocation, error); g_error_free(error); - return; + return TRUE; } g_assert_null(priv->session); sender = NULL; user = _fprint_device_check_for_username (rdev, - context, + invocation, username, &sender, &error); if (user == NULL) { g_free (sender); - dbus_g_method_return_error (context, error); + g_dbus_method_invocation_return_gerror (invocation, error); g_error_free (error); - return; + return TRUE; } - if (_fprint_device_check_polkit_for_actions (rdev, context, - "net.reactivated.fprint.device.verify", - "net.reactivated.fprint.device.enroll", - &error) == FALSE) { + if (!_fprint_device_check_polkit_for_actions (rdev, invocation, + "net.reactivated.fprint.device.verify", + "net.reactivated.fprint.device.enroll", + &error)) { g_free (sender); g_free (user); - dbus_g_method_return_error (context, error); + g_dbus_method_invocation_return_gerror (invocation, error); g_error_free (error); - return; + return TRUE; } _fprint_device_add_client (rdev, sender); priv->session = g_new0(SessionData, 1); - priv->session->context = context; + priv->session->invocation = g_object_ref (invocation); priv->session->username = user; priv->session->sender = sender; @@ -669,6 +647,8 @@ static void fprint_device_claim(FprintDevice *rdev, priv->current_action = ACTION_OPEN; fp_device_open (priv->dev, NULL, (GAsyncReadyCallback) dev_open_cb, rdev); + + return TRUE; } static void dev_close_cb(FpDevice *dev, GAsyncResult *res, void *user_data) @@ -677,7 +657,8 @@ static void dev_close_cb(FpDevice *dev, GAsyncResult *res, void *user_data) FprintDevice *rdev = user_data; FprintDevicePrivate *priv = fprint_device_get_instance_private(rdev); g_autoptr(SessionData) session = g_steal_pointer(&priv->session); - DBusGMethodInvocation *context = g_steal_pointer(&session->context); + g_autoptr(GDBusMethodInvocation) invocation = + g_steal_pointer (&session->invocation); priv->current_action = ACTION_NONE; if (!fp_device_close_finish (dev, res, &error)) { @@ -686,35 +667,37 @@ static void dev_close_cb(FpDevice *dev, GAsyncResult *res, void *user_data) dbus_error = g_error_new (FPRINT_ERROR, FPRINT_ERROR_INTERNAL, "Release failed with error: %s", error->message); - dbus_g_method_return_error(context, dbus_error); + g_dbus_method_invocation_return_gerror (invocation, dbus_error); return; } g_debug("released device %d", priv->id); - dbus_g_method_return(context); + fprint_dbus_device_complete_release (FPRINT_DBUS_DEVICE (rdev), + invocation); } -static void fprint_device_release(FprintDevice *rdev, - DBusGMethodInvocation *context) +static gboolean fprint_device_release (FprintDBusDevice *dbus_dev, + GDBusMethodInvocation *invocation) { + FprintDevice *rdev = FPRINT_DEVICE (dbus_dev); FprintDevicePrivate *priv = fprint_device_get_instance_private(rdev); GError *error = NULL; - if (_fprint_device_check_claimed(rdev, context, &error) == FALSE) { - dbus_g_method_return_error (context, error); + if (!_fprint_device_check_claimed (rdev, invocation, &error)) { + g_dbus_method_invocation_return_gerror (invocation, error); g_error_free(error); - return; + return TRUE; } /* 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); + if (!_fprint_device_check_polkit_for_actions (rdev, invocation, + "net.reactivated.fprint.device.verify", + "net.reactivated.fprint.device.enroll", + &error)) { + g_dbus_method_invocation_return_gerror (invocation, error); g_error_free(error); - return; + return TRUE; } if (priv->current_cancellable) { @@ -730,9 +713,11 @@ static void fprint_device_release(FprintDevice *rdev, g_main_context_iteration (NULL, TRUE); } - priv->session->context = context; + priv->session->invocation = g_object_ref (invocation); priv->current_action = ACTION_CLOSE; fp_device_close (priv->dev, NULL, (GAsyncReadyCallback) dev_close_cb, rdev); + + return TRUE; } static void report_verify_status (FprintDevice *rdev, @@ -786,6 +771,7 @@ static void verify_cb(FpDevice *dev, GAsyncResult *res, void *user_data) g_autoptr(GError) error = NULL; FprintDevice *rdev = user_data; FprintDevicePrivate *priv = fprint_device_get_instance_private(rdev); + FprintDBusDevice *dbus_dev = FPRINT_DBUS_DEVICE (rdev); gboolean success; const char *name; gboolean match; @@ -817,9 +803,9 @@ static void verify_cb(FpDevice *dev, GAsyncResult *res, void *user_data) } /* Return the cancellation or reset action right away if vanished. */ - if (priv->current_cancel_context) { - dbus_g_method_return(priv->current_cancel_context); - priv->current_cancel_context = NULL; + if (priv->current_cancel_invocation) { + fprint_dbus_device_complete_verify_stop (dbus_dev, + g_steal_pointer (&priv->current_cancel_invocation)); priv->current_action = ACTION_NONE; priv->session->verify_status_reported = FALSE; } else if (g_cancellable_is_cancelled (priv->current_cancellable)) { @@ -837,6 +823,7 @@ static void identify_cb(FpDevice *dev, GAsyncResult *res, void *user_data) g_autoptr(FpPrint) match = NULL; FprintDevice *rdev = user_data; FprintDevicePrivate *priv = fprint_device_get_instance_private(rdev); + FprintDBusDevice *dbus_dev = FPRINT_DBUS_DEVICE (rdev); const char *name; gboolean success; @@ -867,9 +854,9 @@ static void identify_cb(FpDevice *dev, GAsyncResult *res, void *user_data) } /* Return the cancellation or reset action right away if vanished. */ - if (priv->current_cancel_context) { - dbus_g_method_return(priv->current_cancel_context); - priv->current_cancel_context = NULL; + if (priv->current_cancel_invocation) { + fprint_dbus_device_complete_verify_stop (dbus_dev, + g_steal_pointer (&priv->current_cancel_invocation)); priv->current_action = ACTION_NONE; } else if (g_cancellable_is_cancelled (priv->current_cancellable)) { priv->current_action = ACTION_NONE; @@ -880,23 +867,27 @@ static void identify_cb(FpDevice *dev, GAsyncResult *res, void *user_data) } } -static void fprint_device_verify_start(FprintDevice *rdev, - const char *finger_name, DBusGMethodInvocation *context) +static gboolean fprint_device_verify_start (FprintDBusDevice *dbus_dev, + GDBusMethodInvocation *invocation, + const char *finger_name) { + FprintDevice *rdev = FPRINT_DEVICE (dbus_dev); FprintDevicePrivate *priv = fprint_device_get_instance_private(rdev); g_autoptr(GPtrArray) gallery = NULL; g_autoptr(FpPrint) print = NULL; g_autoptr(GError) error = NULL; guint finger_num = finger_name_to_num (finger_name); - if (_fprint_device_check_claimed(rdev, context, &error) == FALSE) { - dbus_g_method_return_error (context, error); - return; + if (!_fprint_device_check_claimed (rdev, invocation, &error)) { + g_dbus_method_invocation_return_gerror (invocation, error); + return TRUE; } - if (_fprint_device_check_polkit_for_action (rdev, context, "net.reactivated.fprint.device.verify", &error) == FALSE) { - dbus_g_method_return_error (context, error); - return; + if (!_fprint_device_check_polkit_for_action (rdev, invocation, + "net.reactivated.fprint.device.verify", + &error)) { + g_dbus_method_invocation_return_gerror (invocation, error); + return TRUE; } if (priv->current_action != ACTION_NONE) { @@ -907,8 +898,8 @@ static void fprint_device_verify_start(FprintDevice *rdev, g_set_error(&error, FPRINT_ERROR, FPRINT_ERROR_ALREADY_IN_USE, "Verification already in progress"); } - dbus_g_method_return_error(context, error); - return; + g_dbus_method_invocation_return_gerror (invocation, error); + return TRUE; } if (finger_num == -1) { @@ -918,8 +909,8 @@ static void fprint_device_verify_start(FprintDevice *rdev, if (prints == NULL) { g_set_error(&error, FPRINT_ERROR, FPRINT_ERROR_NO_ENROLLED_PRINTS, "No fingerprints enrolled"); - dbus_g_method_return_error(context, error); - return; + g_dbus_method_invocation_return_gerror (invocation, error); + return TRUE; } if (fp_device_supports_identify (priv->dev)) { GSList *l; @@ -944,8 +935,8 @@ static void fprint_device_verify_start(FprintDevice *rdev, if (gallery->len == 0) { g_set_error(&error, FPRINT_ERROR, FPRINT_ERROR_NO_ENROLLED_PRINTS, "No fingerprints on that device"); - dbus_g_method_return_error(context, error); - return; + g_dbus_method_invocation_return_gerror (invocation, error); + return TRUE; } priv->current_action = ACTION_IDENTIFY; @@ -966,8 +957,9 @@ static void fprint_device_verify_start(FprintDevice *rdev, if (!print) { g_set_error(&error, FPRINT_ERROR, FPRINT_ERROR_NO_ENROLLED_PRINTS, "No such print %d", finger_num); - dbus_g_method_return_error(context, error); - return; + g_dbus_method_invocation_return_gerror (invocation, + error); + return TRUE; } priv->current_cancellable = g_cancellable_new (); @@ -982,50 +974,57 @@ static void fprint_device_verify_start(FprintDevice *rdev, g_signal_emit(rdev, signals[SIGNAL_VERIFY_FINGER_SELECTED], 0, finger_num_to_name (finger_num)); - dbus_g_method_return(context); + fprint_dbus_device_complete_verify_start (dbus_dev, invocation); + + return TRUE; } -static void fprint_device_verify_stop(FprintDevice *rdev, - DBusGMethodInvocation *context) +static gboolean fprint_device_verify_stop (FprintDBusDevice *dbus_dev, + GDBusMethodInvocation *invocation) { + FprintDevice *rdev = FPRINT_DEVICE (dbus_dev); FprintDevicePrivate *priv = fprint_device_get_instance_private(rdev); GError *error = NULL; - if (_fprint_device_check_claimed(rdev, context, &error) == FALSE) { - dbus_g_method_return_error (context, error); + if (!_fprint_device_check_claimed (rdev, invocation, &error)) { + g_dbus_method_invocation_return_gerror (invocation, error); g_error_free(error); - return; + return TRUE; } - if (_fprint_device_check_polkit_for_action (rdev, context, "net.reactivated.fprint.device.verify", &error) == FALSE) { - dbus_g_method_return_error (context, error); + if (!_fprint_device_check_polkit_for_action (rdev, invocation, + "net.reactivated.fprint.device.verify", + &error)) { + g_dbus_method_invocation_return_gerror (invocation, error); g_error_free(error); - return; + return TRUE; } if (priv->current_action == ACTION_NONE) { g_set_error(&error, FPRINT_ERROR, FPRINT_ERROR_NO_ACTION_IN_PROGRESS, "No verification in progress"); - dbus_g_method_return_error(context, error); + g_dbus_method_invocation_return_gerror (invocation, error); g_error_free (error); - return; + return TRUE; } else if (priv->current_action == ACTION_ENROLL) { g_set_error(&error, FPRINT_ERROR, FPRINT_ERROR_ALREADY_IN_USE, "Enrollment in progress"); - dbus_g_method_return_error(context, error); + g_dbus_method_invocation_return_gerror (invocation, error); g_error_free (error); - return; + return TRUE; } if (priv->current_cancellable) { /* We return only when the action was cancelled */ g_cancellable_cancel (priv->current_cancellable); - priv->current_cancel_context = context; + priv->current_cancel_invocation = invocation; } else { - dbus_g_method_return (context); + fprint_dbus_device_complete_verify_stop (dbus_dev, invocation); priv->current_action = ACTION_NONE; priv->session->verify_status_reported = FALSE; } + + return TRUE; } static void enroll_progress_cb(FpDevice *dev, @@ -1139,6 +1138,7 @@ static void enroll_cb(FpDevice *dev, GAsyncResult *res, void *user_data) g_autoptr(GError) error = NULL; FprintDevice *rdev = user_data; FprintDevicePrivate *priv = fprint_device_get_instance_private(rdev); + FprintDBusDevice *dbus_dev = FPRINT_DBUS_DEVICE (rdev); g_autoptr(FpPrint) print = NULL; const char *name; @@ -1183,9 +1183,9 @@ static void enroll_cb(FpDevice *dev, GAsyncResult *res, void *user_data) g_warning ("Device reported an error during enroll: %s", error->message); /* Return the cancellation or reset action right away if vanished. */ - if (priv->current_cancel_context) { - dbus_g_method_return(priv->current_cancel_context); - priv->current_cancel_context = NULL; + if (priv->current_cancel_invocation) { + fprint_dbus_device_complete_enroll_stop (dbus_dev, + g_steal_pointer (&priv->current_cancel_invocation)); priv->current_action = ACTION_NONE; } else if (g_cancellable_is_cancelled (priv->current_cancellable)) { priv->current_action = ACTION_NONE; @@ -1194,28 +1194,32 @@ static void enroll_cb(FpDevice *dev, GAsyncResult *res, void *user_data) } -static void fprint_device_enroll_start(FprintDevice *rdev, - const char *finger_name, DBusGMethodInvocation *context) +static gboolean fprint_device_enroll_start (FprintDBusDevice *dbus_dev, + GDBusMethodInvocation *invocation, + const char *finger_name) { g_autoptr(GError) error = NULL; + FprintDevice *rdev = FPRINT_DEVICE (dbus_dev); FprintDevicePrivate *priv = fprint_device_get_instance_private(rdev); int finger_num = finger_name_to_num (finger_name); if (finger_num == -1) { g_set_error(&error, FPRINT_ERROR, FPRINT_ERROR_INVALID_FINGERNAME, "Invalid finger name"); - dbus_g_method_return_error(context, error); - return; + g_dbus_method_invocation_return_gerror (invocation, error); + return TRUE; } - if (_fprint_device_check_claimed(rdev, context, &error) == FALSE) { - dbus_g_method_return_error (context, error); - return; + if (!_fprint_device_check_claimed (rdev, invocation, &error)) { + g_dbus_method_invocation_return_gerror (invocation, error); + return TRUE; } - if (_fprint_device_check_polkit_for_action (rdev, context, "net.reactivated.fprint.device.enroll", &error) == FALSE) { - dbus_g_method_return_error (context, error); - return; + if (!_fprint_device_check_polkit_for_action (rdev, invocation, + "net.reactivated.fprint.device.enroll", + &error)) { + g_dbus_method_invocation_return_gerror (invocation, error); + return TRUE; } if (priv->current_action != ACTION_NONE) { @@ -1226,8 +1230,8 @@ static void fprint_device_enroll_start(FprintDevice *rdev, g_set_error(&error, FPRINT_ERROR, FPRINT_ERROR_ALREADY_IN_USE, "Verification in progress"); } - dbus_g_method_return_error(context, error); - return; + g_dbus_method_invocation_return_gerror (invocation, error); + return TRUE; } g_debug("start enrollment device %d finger %d", priv->id, finger_num); @@ -1245,25 +1249,30 @@ static void fprint_device_enroll_start(FprintDevice *rdev, priv->current_action = ACTION_ENROLL; - dbus_g_method_return(context); + fprint_dbus_device_complete_enroll_start (dbus_dev, invocation); + + return TRUE; } -static void fprint_device_enroll_stop(FprintDevice *rdev, - DBusGMethodInvocation *context) +static gboolean fprint_device_enroll_stop (FprintDBusDevice *dbus_dev, + GDBusMethodInvocation *invocation) { + FprintDevice *rdev = FPRINT_DEVICE (dbus_dev); FprintDevicePrivate *priv = fprint_device_get_instance_private(rdev); GError *error = NULL; - if (_fprint_device_check_claimed(rdev, context, &error) == FALSE) { - dbus_g_method_return_error (context, error); + if (!_fprint_device_check_claimed (rdev, invocation, &error)) { + g_dbus_method_invocation_return_gerror (invocation, error); g_error_free (error); - return; + return TRUE; } - if (_fprint_device_check_polkit_for_action (rdev, context, "net.reactivated.fprint.device.enroll", &error) == FALSE) { - dbus_g_method_return_error (context, error); + if (!_fprint_device_check_polkit_for_action (rdev, invocation, + "net.reactivated.fprint.device.enroll", + &error)) { + g_dbus_method_invocation_return_gerror (invocation, error); g_error_free (error); - return; + return TRUE; } if (priv->current_action != ACTION_ENROLL) { @@ -1278,74 +1287,82 @@ static void fprint_device_enroll_stop(FprintDevice *rdev, "Identification in progress"); } else g_assert_not_reached (); - dbus_g_method_return_error(context, error); + g_dbus_method_invocation_return_gerror (invocation, error); g_error_free (error); - return; + return TRUE; } if (priv->current_cancellable) { /* We return only when the action was cancelled */ g_cancellable_cancel (priv->current_cancellable); - priv->current_cancel_context = context; + priv->current_cancel_invocation = invocation; } else { - dbus_g_method_return (context); + fprint_dbus_device_complete_enroll_stop (dbus_dev, invocation); priv->current_action = ACTION_NONE; } + + return TRUE; } -static void fprint_device_list_enrolled_fingers(FprintDevice *rdev, - const char *username, - DBusGMethodInvocation *context) +static gboolean fprint_device_list_enrolled_fingers (FprintDBusDevice *dbus_dev, + GDBusMethodInvocation *invocation, + const char *username) { + FprintDevice *rdev = FPRINT_DEVICE (dbus_dev); FprintDevicePrivate *priv = fprint_device_get_instance_private(rdev); + g_autoptr (GPtrArray) ret = NULL; GError *error = NULL; GSList *prints; GSList *item; - GPtrArray *ret; - char *user, *sender; + const char *sender; + char *user; user = _fprint_device_check_for_username (rdev, - context, + invocation, username, NULL, &error); if (user == NULL) { - dbus_g_method_return_error (context, error); + g_dbus_method_invocation_return_gerror (invocation, error); g_error_free (error); - return; + return TRUE; } - if (_fprint_device_check_polkit_for_action (rdev, context, "net.reactivated.fprint.device.verify", &error) == FALSE) { + if (!_fprint_device_check_polkit_for_action (rdev, invocation, + "net.reactivated.fprint.device.verify", + &error)) { g_free (user); - dbus_g_method_return_error (context, error); + g_dbus_method_invocation_return_gerror (invocation, error); g_error_free (error); - return; + return TRUE; } - sender = dbus_g_method_get_sender (context); + sender = g_dbus_method_invocation_get_sender (invocation); _fprint_device_add_client (rdev, sender); - g_free (sender); prints = store.discover_prints(priv->dev, user); g_free (user); if (!prints) { g_set_error(&error, FPRINT_ERROR, FPRINT_ERROR_NO_ENROLLED_PRINTS, "Failed to discover prints"); - dbus_g_method_return_error(context, error); + g_dbus_method_invocation_return_gerror (invocation, error); g_error_free (error); - return; + return TRUE; } ret = g_ptr_array_new (); for (item = prints; item; item = item->next) { int finger_num = GPOINTER_TO_INT (item->data); - g_ptr_array_add (ret, g_strdup (finger_num_to_name (finger_num))); + g_ptr_array_add (ret, (char *) finger_num_to_name (finger_num)); } g_ptr_array_add (ret, NULL); g_slist_free(prints); - dbus_g_method_return(context, g_ptr_array_free (ret, FALSE)); + fprint_dbus_device_complete_list_enrolled_fingers (dbus_dev, + invocation, (const gchar *const *) ret->pdata); + + return TRUE; } static void delete_enrolled_fingers(FprintDevice *rdev, const char *user) @@ -1386,78 +1403,87 @@ static void delete_enrolled_fingers(FprintDevice *rdev, const char *user) } #ifdef __linux__ -static void log_offending_client(DBusGMethodInvocation *context) +static void log_offending_client_cb (GObject *object, + GAsyncResult *res, + gpointer user_data) { - g_autofree char *sender = NULL; + GDBusConnection *connection = G_DBUS_CONNECTION (object); + g_autoptr(GVariant) ret = NULL; g_autofree char *path = NULL; g_autofree char *content = NULL; - DBusGProxy *proxy = NULL; guint pid = 0; - sender = dbus_g_method_get_sender(context); - proxy = dbus_g_proxy_new_for_name (fprintd_dbus_conn, - "org.freedesktop.DBus", - "/org/freedesktop/DBus", - "org.freedesktop.DBus"); + ret = g_dbus_connection_call_finish (connection, res, NULL); - if (!dbus_g_proxy_call(proxy, - "GetConnectionUnixProcessID", - NULL, - G_TYPE_STRING, - sender, - G_TYPE_INVALID, - G_TYPE_UINT, - &pid, - G_TYPE_INVALID)) { - goto out; - } + if (!ret) + return; + g_variant_get (ret, "(u)", &pid); path = g_strdup_printf ("/proc/%u/comm", pid); if (g_file_get_contents (path, &content, NULL, NULL)) { g_strchomp (content); g_warning ("Offending API user is %s", content); } +} -out: - g_clear_object (&proxy); +static void log_offending_client (GDBusMethodInvocation *invocation) +{ + const char *sender; + GDBusConnection *connection; + + connection = g_dbus_method_invocation_get_connection (invocation); + sender = g_dbus_method_invocation_get_sender (invocation); + + g_dbus_connection_call (connection, + "org.freedesktop.DBus", + "/org/freedesktop/DBus", + "org.freedesktop.DBus", + "GetConnectionUnixProcessID", + g_variant_new ("(s)", sender), + NULL, G_DBUS_CALL_FLAGS_NONE, + -1, NULL, log_offending_client_cb, NULL); } #endif -static void fprint_device_delete_enrolled_fingers(FprintDevice *rdev, - const char *username, - DBusGMethodInvocation *context) +static gboolean fprint_device_delete_enrolled_fingers (FprintDBusDevice *dbus_dev, + GDBusMethodInvocation *invocation, + const char *username) { + FprintDevice *rdev = FPRINT_DEVICE (dbus_dev); FprintDevicePrivate *priv = fprint_device_get_instance_private(rdev); g_autoptr(GError) error = NULL; g_autofree char *user = NULL; - char *sender; + const char *sender; gboolean opened; g_warning ("The API user should be updated to use DeleteEnrolledFingers2 method!"); #ifdef __linux__ - log_offending_client(context); + log_offending_client (invocation); #endif user = _fprint_device_check_for_username (rdev, - context, + invocation, username, NULL, &error); if (user == NULL) { - dbus_g_method_return_error (context, error); - return; + g_dbus_method_invocation_return_gerror (invocation, error); + return TRUE; } - if (_fprint_device_check_polkit_for_action (rdev, context, "net.reactivated.fprint.device.enroll", &error) == FALSE) { - dbus_g_method_return_error (context, error); - return; + if (!_fprint_device_check_polkit_for_action (rdev, invocation, + "net.reactivated.fprint.device.enroll", + &error)) { + g_dbus_method_invocation_return_gerror (invocation, error); + return TRUE; } - if (_fprint_device_check_claimed(rdev, context, &error) == FALSE) { + if (!_fprint_device_check_claimed (rdev, invocation, &error)) { /* Return error for anything but FPRINT_ERROR_CLAIM_DEVICE */ if (!g_error_matches (error, FPRINT_ERROR, FPRINT_ERROR_CLAIM_DEVICE)) { - dbus_g_method_return_error (context, error); - return; + g_dbus_method_invocation_return_gerror (invocation, + error); + return TRUE; } opened = FALSE; @@ -1465,9 +1491,8 @@ static void fprint_device_delete_enrolled_fingers(FprintDevice *rdev, opened = TRUE; } - sender = dbus_g_method_get_sender (context); + sender = g_dbus_method_invocation_get_sender (invocation); _fprint_device_add_client (rdev, sender); - g_free (sender); if (!opened && fp_device_has_storage (priv->dev)) fp_device_open_sync (priv->dev, NULL, NULL); @@ -1477,27 +1502,47 @@ static void fprint_device_delete_enrolled_fingers(FprintDevice *rdev, if (!opened && fp_device_has_storage (priv->dev)) fp_device_close_sync (priv->dev, NULL, NULL); - dbus_g_method_return(context); + fprint_dbus_device_complete_delete_enrolled_fingers (dbus_dev, + invocation); + return TRUE; } -static void fprint_device_delete_enrolled_fingers2(FprintDevice *rdev, - DBusGMethodInvocation *context) +static gboolean fprint_device_delete_enrolled_fingers2 (FprintDBusDevice *dbus_dev, + GDBusMethodInvocation *invocation) { + FprintDevice *rdev = FPRINT_DEVICE (dbus_dev); FprintDevicePrivate *priv = fprint_device_get_instance_private(rdev); g_autoptr(GError) error = NULL; - if (_fprint_device_check_claimed(rdev, context, &error) == FALSE) { - dbus_g_method_return_error (context, error); - return; + if (!_fprint_device_check_claimed (rdev, invocation, &error)) { + g_dbus_method_invocation_return_gerror (invocation, error); + return TRUE; } - if (_fprint_device_check_polkit_for_action (rdev, context, "net.reactivated.fprint.device.enroll", &error) == FALSE) { - dbus_g_method_return_error (context, error); - return; + if (!_fprint_device_check_polkit_for_action (rdev, invocation, + "net.reactivated.fprint.device.enroll", + &error)) { + g_dbus_method_invocation_return_gerror (invocation, error); + return TRUE; } delete_enrolled_fingers (rdev, priv->session->username); + fprint_dbus_device_complete_delete_enrolled_fingers2 (dbus_dev, + invocation); - dbus_g_method_return(context); + return TRUE; +} + +static void fprint_device_dbus_skeleton_iface_init (FprintDBusDeviceIface *iface) +{ + iface->handle_claim = fprint_device_claim; + iface->handle_delete_enrolled_fingers = fprint_device_delete_enrolled_fingers; + iface->handle_delete_enrolled_fingers2 = fprint_device_delete_enrolled_fingers2; + iface->handle_enroll_start = fprint_device_enroll_start; + iface->handle_enroll_stop = fprint_device_enroll_stop; + iface->handle_list_enrolled_fingers = fprint_device_list_enrolled_fingers; + iface->handle_release = fprint_device_release; + iface->handle_verify_start = fprint_device_verify_start; + iface->handle_verify_stop = fprint_device_verify_stop; } diff --git a/src/device.xml b/src/device.xml index 89fd3b5..92af74d 100644 --- a/src/device.xml +++ b/src/device.xml @@ -12,9 +12,6 @@ - - PolicyKit integration @@ -282,8 +279,6 @@ An array of strings representing the enrolled fingerprints. See Fingerprint names. - - @@ -304,8 +299,6 @@ The username for whom to delete the enrolled fingerprints. See Usernames. - - @@ -327,8 +320,6 @@ - - @@ -348,8 +339,6 @@ The username for whom to claim the device. See Usernames. - - @@ -368,8 +357,6 @@ - - @@ -390,8 +377,6 @@ A string representing the finger to verify. See Fingerprint names. - - @@ -415,8 +400,6 @@ - - @@ -486,8 +469,6 @@ Fingerprint names. Note that "any" is not a valid finger name for this method. - - @@ -511,8 +492,6 @@ - - diff --git a/src/fprintd-marshal.list b/src/fprintd-marshal.list deleted file mode 100644 index c4effb6..0000000 --- a/src/fprintd-marshal.list +++ /dev/null @@ -1 +0,0 @@ -VOID:STRING,BOOLEAN diff --git a/src/fprintd.h b/src/fprintd.h index 330523e..99ef433 100644 --- a/src/fprintd.h +++ b/src/fprintd.h @@ -20,19 +20,19 @@ #pragma once #include -#include +#include #include +#include "fprintd-dbus.h" /* General */ #define TIMEOUT 30 #define FPRINT_SERVICE_NAME "net.reactivated.Fprint" +#define FPRINT_SERVICE_PATH "/net/reactivated/Fprint" /* Errors */ GQuark fprint_error_quark(void); -GType fprint_error_get_type(void); #define FPRINT_ERROR fprint_error_quark() -#define FPRINT_TYPE_ERROR fprint_error_get_type() #define FPRINT_ERROR_DBUS_INTERFACE "net.reactivated.Fprint.Error" typedef enum { FPRINT_ERROR_CLAIM_DEVICE, /* developer didn't claim the device */ @@ -53,23 +53,18 @@ struct _FprintManager { GObject parent; }; -FprintManager *fprint_manager_new(gboolean no_timeout); +FprintManager *fprint_manager_new (GDBusConnection *connection, gboolean no_timeout); /* Device */ #define FPRINT_TYPE_DEVICE (fprint_device_get_type()) -G_DECLARE_FINAL_TYPE (FprintDevice, fprint_device, FPRINT, DEVICE, GObject) +G_DECLARE_FINAL_TYPE (FprintDevice, fprint_device, FPRINT, DEVICE, + FprintDBusDeviceSkeleton) struct _FprintDevice { - GObject parent; + FprintDBusDeviceSkeleton parent; }; FprintDevice *fprint_device_new(FpDevice *dev); guint32 _fprint_device_get_id(FprintDevice *rdev); /* Print */ /* TODO */ - -/* Binding data included in main.c through server-bindings.h which individual - * class implementations need to access. - */ -extern const DBusGObjectInfo dbus_glib_fprint_manager_object_info; -extern const DBusGObjectInfo dbus_glib_fprint_device_object_info; diff --git a/src/main.c b/src/main.c index 1ecf431..006a764 100644 --- a/src/main.c +++ b/src/main.c @@ -1,6 +1,7 @@ /* * fprint D-Bus daemon * Copyright (C) 2008 Daniel Drake + * Copyright (C) 2020 Marco Trevisan * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -23,7 +24,7 @@ #include #include -#include +#include #include #include #include @@ -37,7 +38,6 @@ fp_storage store; -DBusGConnection *fprintd_dbus_conn = NULL; static gboolean no_timeout = FALSE; static gboolean g_fatal_warnings = FALSE; @@ -139,13 +139,33 @@ static gboolean sigterm_callback(gpointer data) return FALSE; } +static void +on_name_acquired (GDBusConnection *connection, + const char *name, + gpointer user_data) +{ + g_debug ("D-Bus service launched with name: %s", name); +} + +static void +on_name_lost (GDBusConnection *connection, + const char *name, + gpointer user_data) +{ + GMainLoop *loop = user_data; + + g_warning ("Failed to get name: %s", name); + + g_main_loop_quit (loop); +} + int main(int argc, char **argv) { g_autoptr(GOptionContext) context = NULL; g_autoptr(GMainLoop) loop = NULL; g_autoptr(GError) error = NULL; - FprintManager *manager; - DBusGProxy *driver_proxy; + g_autoptr(FprintManager) manager = NULL; + g_autoptr(GDBusConnection) connection = NULL; guint32 request_name_ret; setlocale (LC_ALL, ""); @@ -170,16 +190,13 @@ int main(int argc, char **argv) g_log_set_always_fatal (fatal_mask); } - /* Obtain a connection to the session bus */ - fprintd_dbus_conn = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error); - if (fprintd_dbus_conn == NULL) { + /* Obtain a connection to the system bus */ + connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error); + if (!G_IS_DBUS_CONNECTION (connection)) { g_warning("Failed to open connection to bus: %s", error->message); return 1; } - driver_proxy = dbus_g_proxy_new_for_name(fprintd_dbus_conn, - DBUS_SERVICE_DBUS, DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS); - /* Load the configuration file, * and the default storage plugin */ if (!load_conf()) @@ -193,32 +210,23 @@ int main(int argc, char **argv) /* create the one instance of the Manager object to be shared between * all fprintd users. This blocks until all the devices are enumerated */ - manager = fprint_manager_new (no_timeout); + manager = fprint_manager_new (connection, no_timeout); /* Obtain the well-known name after the manager has been initialized. * Otherwise a client immediately enumerating the devices will not see * any. */ - if (!org_freedesktop_DBus_request_name(driver_proxy, FPRINT_SERVICE_NAME, - 0, &request_name_ret, &error)) { - g_warning("Failed to get name: %s", error->message); - g_object_unref (manager); - return 1; - } - - if (request_name_ret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) { - g_warning ("Got result code %u from requesting name", request_name_ret); - g_object_unref (manager); - return 1; - } - - g_debug("D-Bus service launched with name: %s", FPRINT_SERVICE_NAME); + request_name_ret = g_bus_own_name_on_connection (connection, + FPRINT_SERVICE_NAME, + G_BUS_NAME_OWNER_FLAGS_NONE, + on_name_acquired, + on_name_lost, + loop, NULL); g_debug("entering main loop"); g_main_loop_run(loop); + g_bus_unown_name (request_name_ret); g_debug("main loop completed"); - g_object_unref (manager); - return 0; } diff --git a/src/manager.c b/src/manager.c index 021ed44..a380409 100644 --- a/src/manager.c +++ b/src/manager.c @@ -1,6 +1,7 @@ /* * /net/reactivated/Fprint/Manager object implementation * Copyright (C) 2008 Daniel Drake + * Copyright (C) 2020 Marco Trevisan * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,7 +20,6 @@ #include #include -#include #include #include #include @@ -27,17 +27,16 @@ #include "fprintd.h" -extern DBusGConnection *fprintd_dbus_conn; - +static void fprint_manager_constructed (GObject *object); static gboolean fprint_manager_get_devices(FprintManager *manager, GPtrArray **devices, GError **error); static gboolean fprint_manager_get_default_device(FprintManager *manager, const char **device, GError **error); -#include "manager-dbus-glue.h" - typedef struct { + GDBusConnection *connection; + FprintDBusManager *dbus_manager; FpContext *context; GSList *dev_registry; gboolean no_timeout; @@ -46,28 +45,81 @@ typedef struct G_DEFINE_TYPE_WITH_CODE(FprintManager, fprint_manager, G_TYPE_OBJECT, G_ADD_PRIVATE (FprintManager)) +enum { + PROP_0, + FPRINT_MANAGER_CONNECTION, + N_PROPS +}; + +static GParamSpec *properties[N_PROPS]; + static void fprint_manager_finalize(GObject *object) { FprintManagerPrivate *priv = fprint_manager_get_instance_private (FPRINT_MANAGER (object)); + g_clear_object (&priv->dbus_manager); + g_clear_object (&priv->connection); g_clear_object (&priv->context); g_slist_free(priv->dev_registry); G_OBJECT_CLASS(fprint_manager_parent_class)->finalize(object); } +static void fprint_manager_set_property (GObject *object, guint property_id, + const GValue *value, GParamSpec *pspec) +{ + FprintManager *self = FPRINT_MANAGER (object); + FprintManagerPrivate *priv = fprint_manager_get_instance_private (self); + + switch (property_id) { + case FPRINT_MANAGER_CONNECTION: + priv->connection = g_value_dup_object (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void fprint_manager_get_property (GObject *object, guint property_id, + GValue *value, GParamSpec *pspec) +{ + FprintManager *self = FPRINT_MANAGER (object); + FprintManagerPrivate *priv = fprint_manager_get_instance_private (self); + + switch (property_id) { + case FPRINT_MANAGER_CONNECTION: + g_value_set_object (value, priv->connection); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + static void fprint_manager_class_init(FprintManagerClass *klass) { - dbus_g_object_type_install_info(FPRINT_TYPE_MANAGER, - &dbus_glib_fprint_manager_object_info); - dbus_g_error_domain_register (FPRINT_ERROR, FPRINT_ERROR_DBUS_INTERFACE, FPRINT_TYPE_ERROR); + GObjectClass *object_class = G_OBJECT_CLASS (klass); - G_OBJECT_CLASS(klass)->finalize = fprint_manager_finalize; + object_class->constructed = fprint_manager_constructed; + object_class->set_property = fprint_manager_set_property; + object_class->get_property = fprint_manager_get_property; + object_class->finalize = fprint_manager_finalize; + + properties[FPRINT_MANAGER_CONNECTION] = + g_param_spec_object ("connection", + "Connection", + "Set GDBus connection property", + G_TYPE_DBUS_CONNECTION, + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_READWRITE); + + g_object_class_install_properties (object_class, N_PROPS, properties); } static gchar *get_device_path(FprintDevice *rdev) { - return g_strdup_printf("/net/reactivated/Fprint/Device/%d", + return g_strdup_printf (FPRINT_SERVICE_PATH "/Device/%d", _fprint_device_get_id(rdev)); } @@ -106,6 +158,44 @@ fprint_manager_in_use_notified (FprintDevice *rdev, GParamSpec *spec, FprintMana priv->timeout_id = g_timeout_add_seconds (TIMEOUT, (GSourceFunc) fprint_manager_timeout_cb, manager); } +static gboolean +handle_get_devices (FprintManager *manager, GDBusMethodInvocation *invocation, + FprintDBusManager *skeleton) +{ + g_autoptr(GPtrArray) devices = NULL; + g_autoptr(GError) error = NULL; + + if (!fprint_manager_get_devices (manager, &devices, &error)) { + g_dbus_method_invocation_return_gerror (invocation, error); + return TRUE; + } + + fprint_dbus_manager_complete_get_devices (skeleton, invocation, + (const gchar *const *) + devices->pdata); + + return TRUE; +} + +static gboolean +handle_get_default_device (FprintManager *manager, + GDBusMethodInvocation *invocation, + FprintDBusManager *skeleton) +{ + const gchar *device; + g_autoptr(GError) error = NULL; + + if (!fprint_manager_get_default_device (manager, &device, &error)) { + g_dbus_method_invocation_return_gerror (invocation, error); + return TRUE; + } + + fprint_dbus_manager_complete_get_default_device (skeleton, invocation, + device); + + return TRUE; +} + static void device_added_cb (FprintManager *manager, FpDevice *device, FpContext *context) { @@ -118,8 +208,9 @@ device_added_cb (FprintManager *manager, FpDevice *device, FpContext *context) priv->dev_registry = g_slist_prepend (priv->dev_registry, rdev); path = get_device_path (rdev); - dbus_g_connection_register_g_object(fprintd_dbus_conn, path, - G_OBJECT(rdev)); + g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (rdev), + priv->connection, + path, NULL); } static void @@ -140,7 +231,8 @@ device_removed_cb (FprintManager *manager, FpDevice *device, FpContext *context) priv->dev_registry = g_slist_delete_link (priv->dev_registry, item); - dbus_g_connection_unregister_g_object(fprintd_dbus_conn, G_OBJECT(rdev)); + g_dbus_interface_skeleton_unexport ( + G_DBUS_INTERFACE_SKELETON (rdev)); g_signal_handlers_disconnect_by_data (rdev, manager); g_object_unref (rdev); @@ -154,13 +246,29 @@ device_removed_cb (FprintManager *manager, FpDevice *device, FpContext *context) fprint_manager_in_use_notified (NULL, NULL, manager); } -static void -fprint_manager_init (FprintManager *manager) +static void fprint_manager_constructed (GObject *object) { + FprintManager *manager = FPRINT_MANAGER (object); FprintManagerPrivate *priv = fprint_manager_get_instance_private (manager); + priv->dbus_manager = fprint_dbus_manager_skeleton_new (); priv->context = fp_context_new (); + g_signal_connect_object (priv->dbus_manager, + "handle-get-devices", + G_CALLBACK (handle_get_devices), + manager, + G_CONNECT_SWAPPED); + g_signal_connect_object (priv->dbus_manager, + "handle-get-default-device", + G_CALLBACK (handle_get_default_device), + manager, + G_CONNECT_SWAPPED); + + g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (priv->dbus_manager), + priv->connection, + FPRINT_SERVICE_PATH "/Manager", NULL); + /* And register the signals for initial enumeration and hotplug. */ g_signal_connect_object (priv->context, "device-added", @@ -179,16 +287,20 @@ fprint_manager_init (FprintManager *manager) */ fp_context_enumerate (priv->context); - dbus_g_connection_register_g_object(fprintd_dbus_conn, - "/net/reactivated/Fprint/Manager", G_OBJECT(manager)); + G_OBJECT_CLASS (fprint_manager_parent_class)->constructed (object); } -FprintManager *fprint_manager_new(gboolean no_timeout) +static void +fprint_manager_init (FprintManager *manager) +{ +} + +FprintManager *fprint_manager_new (GDBusConnection *connection, gboolean no_timeout) { FprintManagerPrivate *priv; GObject *object; - object = g_object_new(FPRINT_TYPE_MANAGER, NULL); + object = g_object_new (FPRINT_TYPE_MANAGER, "connection", connection, NULL); priv = fprint_manager_get_instance_private (FPRINT_MANAGER (object)); priv->no_timeout = no_timeout; @@ -213,10 +325,15 @@ static gboolean fprint_manager_get_devices(FprintManager *manager, if (num_open > 0) { for (l = elem; l != NULL; l = l->next) { - FprintDevice *rdev = l->data; - g_ptr_array_add(devs, get_device_path(rdev)); + GDBusInterfaceSkeleton *dev_skeleton = l->data; + const char *path; + + path = g_dbus_interface_skeleton_get_object_path ( + dev_skeleton); + g_ptr_array_add (devs, (char *) path); } } + g_ptr_array_add (devs, NULL); g_slist_free(elem); @@ -235,7 +352,8 @@ static gboolean fprint_manager_get_default_device(FprintManager *manager, num_open = g_slist_length(elem); if (num_open > 0) { - *device = get_device_path (g_slist_last (elem)->data); + GDBusInterfaceSkeleton *dev_skeleton = g_slist_last (elem)->data; + *device = g_dbus_interface_skeleton_get_object_path (dev_skeleton); return TRUE; } else { g_set_error (error, FPRINT_ERROR, FPRINT_ERROR_NO_SUCH_DEVICE, @@ -245,34 +363,28 @@ static gboolean fprint_manager_get_default_device(FprintManager *manager, } } -GQuark fprint_error_quark(void) +#define ERROR_ENTRY(name, dbus_name) \ + { FPRINT_ERROR_ ## name, FPRINT_ERROR_DBUS_INTERFACE "." dbus_name } +GDBusErrorEntry fprint_error_entries[] = { - static GQuark quark = 0; - if (!quark) - quark = g_quark_from_static_string("fprintd-error-quark"); - return quark; -} + ERROR_ENTRY (CLAIM_DEVICE, "ClaimDevice"), + ERROR_ENTRY (ALREADY_IN_USE, "AlreadyInUse"), + ERROR_ENTRY (INTERNAL, "Internal"), + ERROR_ENTRY (PERMISSION_DENIED, "PermissionDenied"), + ERROR_ENTRY (NO_ENROLLED_PRINTS, "NoEnrolledPrints"), + ERROR_ENTRY (NO_ACTION_IN_PROGRESS, "NoActionInProgress"), + ERROR_ENTRY (INVALID_FINGERNAME, "InvalidFingername"), + ERROR_ENTRY (NO_SUCH_DEVICE, "NoSuchDevice"), +}; -#define ENUM_ENTRY(NAME, DESC) { NAME, "" #NAME "", DESC } -GType -fprint_error_get_type (void) +GQuark fprint_error_quark (void) { - static GType etype = 0; - - if (etype == 0) { - static const GEnumValue values[] = - { - ENUM_ENTRY (FPRINT_ERROR_CLAIM_DEVICE, "ClaimDevice"), - ENUM_ENTRY (FPRINT_ERROR_ALREADY_IN_USE, "AlreadyInUse"), - ENUM_ENTRY (FPRINT_ERROR_INTERNAL, "Internal"), - ENUM_ENTRY (FPRINT_ERROR_PERMISSION_DENIED, "PermissionDenied"), - ENUM_ENTRY (FPRINT_ERROR_NO_ENROLLED_PRINTS, "NoEnrolledPrints"), - ENUM_ENTRY (FPRINT_ERROR_NO_ACTION_IN_PROGRESS, "NoActionInProgress"), - ENUM_ENTRY (FPRINT_ERROR_INVALID_FINGERNAME, "InvalidFingername"), - ENUM_ENTRY (FPRINT_ERROR_NO_SUCH_DEVICE, "NoSuchDevice"), - { 0, 0, 0 } - }; - etype = g_enum_register_static ("FprintError", values); + static volatile gsize quark = 0; + if (!quark) { + g_dbus_error_register_error_domain ("fprintd-error-quark", + &quark, + fprint_error_entries, + G_N_ELEMENTS (fprint_error_entries)); } - return etype; + return (GQuark) quark; } diff --git a/src/manager.xml b/src/manager.xml index f4a38c7..2d0ba28 100644 --- a/src/manager.xml +++ b/src/manager.xml @@ -5,8 +5,6 @@ ]> - diff --git a/src/meson.build b/src/meson.build index 4be29ff..6095961 100644 --- a/src/meson.build +++ b/src/meson.build @@ -1,30 +1,10 @@ -fprintd_marshal = gnome.genmarshal('fprintd-marshal', - prefix: 'fprintd_marshal', - sources: 'fprintd-marshal.list', - valist_marshallers: true, -) - bash = find_program('bash') -dbus_binding_tool = find_program('dbus-binding-tool') dbus_interfaces = ['Manager', 'Device'] dbus_interfaces_files = [] -dbus_server_glue_sources = [] foreach interface_name: dbus_interfaces interface = interface_name.to_lower() interface_file = interface + '.xml' - glue_name = interface + '-dbus-glue.h' - dbus_server_glue_sources += custom_target(glue_name, - input: interface_file, - output: glue_name, - command: [ - dbus_binding_tool, - '--prefix=fprint_' + interface, - '--mode=glib-server', - '--output=@OUTPUT@', - '@INPUT@', - ]) - dbus_interfaces_files += custom_target('dbus_interface_' + interface, input: interface_file, output: 'net.reactivated.Fprint.@0@.xml'.format(interface_name), @@ -34,14 +14,24 @@ foreach interface_name: dbus_interfaces ) endforeach +fprintd_dbus_sources = gnome.gdbus_codegen('fprintd-dbus', + sources: dbus_interfaces_files, + autocleanup: 'all', + interface_prefix: 'net.reactivated.Fprint.', + namespace: 'FprintDBus', +) + fprintd_deps = declare_dependency( include_directories: [ include_directories('..'), ], + sources: [ + fprintd_dbus_sources, + ], dependencies: [ - dbus_glib_dep, glib_dep, gio_dep, + gio_unix_dep, gmodule_dep, libfprint_dep, polkit_gobject_dep, @@ -58,8 +48,6 @@ libfprintd_private = static_library('fprintd-private', 'device.c', 'fprintd.h', 'manager.c', - dbus_server_glue_sources, - fprintd_marshal, ], dependencies: fprintd_deps, gnu_symbol_visibility: 'hidden', diff --git a/tests/pam/test_pam_fprintd.py b/tests/pam/test_pam_fprintd.py index 6b8ec9c..e3cfb1e 100755 --- a/tests/pam/test_pam_fprintd.py +++ b/tests/pam/test_pam_fprintd.py @@ -16,15 +16,12 @@ import unittest import sys import subprocess import dbus -import dbus.mainloop.glib import dbusmock import fcntl import os import time import pypamtest -dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) - PAM_SUCCESS = 0 PAM_AUTH_ERR = 7 PAM_AUTHINFO_UNAVAIL = 9 diff --git a/utils/delete.c b/utils/delete.c index 0c25b7b..6a2202f 100644 --- a/utils/delete.c +++ b/utils/delete.c @@ -1,6 +1,7 @@ /* * fprintd example to delete fingerprints * Copyright (C) 2008 Daniel Drake + * Copyright (C) 2020 Marco Trevisan * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,109 +21,115 @@ #include #include #include -#include -#include "manager-dbus-glue.h" -#include "device-dbus-glue.h" +#include "fprintd-dbus.h" -static DBusGProxy *manager = NULL; -static DBusGConnection *connection = NULL; +static FprintDBusManager *manager = NULL; +static GDBusConnection *connection = NULL; static void create_manager(void) { GError *error = NULL; - connection = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error); + connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error); if (connection == NULL) { g_print("Failed to connect to session bus: %s\n", error->message); exit (1); } - manager = dbus_g_proxy_new_for_name(connection, - "net.reactivated.Fprint", "/net/reactivated/Fprint/Manager", - "net.reactivated.Fprint.Manager"); -} - -static void delete_fingerprints(DBusGProxy *dev, const char *username) -{ - GError *error = NULL; - GHashTable *props; - DBusGProxy *p; - - p = dbus_g_proxy_new_from_proxy(dev, "org.freedesktop.DBus.Properties", NULL); - if (!dbus_g_proxy_call (p, "GetAll", &error, G_TYPE_STRING, "net.reactivated.Fprint.Device", G_TYPE_INVALID, - dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE), &props, G_TYPE_INVALID)) { - g_print("GetAll on the Properties interface failed: %s\n", error->message); + manager = fprint_dbus_manager_proxy_new_sync (connection, + G_DBUS_PROXY_FLAGS_NONE, + "net.reactivated.Fprint", + "/net/reactivated/Fprint/Manager", + NULL, &error); + if (manager == NULL) { + g_print ("Failed to get Fprintd manager: %s\n", error->message); exit (1); } +} - if (!net_reactivated_Fprint_Device_claim(dev, username, &error)) { +static void delete_fingerprints (FprintDBusDevice *dev, const char *username) +{ + GError *error = NULL; + + if (!fprint_dbus_device_call_claim_sync (dev, username, NULL, &error)) { g_print("failed to claim device: %s\n", error->message); exit (1); } - if (!net_reactivated_Fprint_Device_delete_enrolled_fingers2(dev, &error)) { - if (dbus_g_error_has_name (error, "net.reactivated.Fprint.Error.NoEnrolledPrints") == FALSE) { - g_print("ListEnrolledFingers failed: %s\n", error->message); + if (!fprint_dbus_device_call_delete_enrolled_fingers2_sync (dev, NULL, + &error)) { + gboolean ignore_error = FALSE; + if (g_dbus_error_is_remote_error (error)) { + g_autofree char *dbus_error = + g_dbus_error_get_remote_error (error); + if (g_str_equal (dbus_error, + "net.reactivated.Fprint.Error.NoEnrolledPrints")) { + g_print ("No fingerprints to delete on %s\n", + fprint_dbus_device_get_name (dev)); + ignore_error = TRUE; + } + } + if (!ignore_error) { + g_print("ListEnrolledFingers failed: %s\n", + error->message); exit (1); } else { - g_print ("No fingerprints to delete on %s\n", g_value_get_string (g_hash_table_lookup (props, "name"))); + g_print ("No fingerprints to delete on %s\n", + fprint_dbus_device_get_name (dev)); g_clear_error (&error); } } else { - g_print ("Fingerprints deleted on %s\n", g_value_get_string (g_hash_table_lookup (props, "name"))); + g_print ("Fingerprints deleted on %s\n", + fprint_dbus_device_get_name (dev)); } - if (!net_reactivated_Fprint_Device_release(dev, &error)) { + if (!fprint_dbus_device_call_release_sync (dev, NULL, &error)) { g_print("ReleaseDevice failed: %s\n", error->message); exit (1); } - - g_hash_table_destroy (props); - g_object_unref (p); } static void process_devices(char **argv) { GError *error = NULL; - GPtrArray *devices; + g_auto(GStrv) devices = NULL; char *path; + guint num_devices; guint i; - if (!net_reactivated_Fprint_Manager_get_devices(manager, &devices, &error)) { + if (!fprint_dbus_manager_call_get_devices_sync (manager, &devices, + NULL, &error)) { g_print("Impossible to get devices: %s\n", error->message); exit (1); } - - if (devices->len == 0) { + + num_devices = g_strv_length (devices); + if (num_devices == 0) { g_print("No devices available\n"); exit(1); } - g_print("found %d devices\n", devices->len); - for (i = 0; i < devices->len; i++) { - path = g_ptr_array_index(devices, i); + g_print ("found %u devices\n", num_devices); + for (i = 0; devices[i] != NULL; i++) { + path = devices[i]; g_print("Device at %s\n", path); } - for (i = 0; i < devices->len; i++) { + for (i = 0; devices[i] != NULL; i++) { + g_autoptr(FprintDBusDevice) dev = NULL; guint j; - DBusGProxy *dev; - path = g_ptr_array_index(devices, i); + path = devices[i]; g_print("Using device %s\n", path); - /* FIXME use for_name_owner?? */ - dev = dbus_g_proxy_new_for_name(connection, "net.reactivated.Fprint", - path, "net.reactivated.Fprint.Device"); + dev = fprint_dbus_device_proxy_new_sync (connection, + G_DBUS_PROXY_FLAGS_NONE, + "net.reactivated.Fprint", + path, NULL, &error); for (j = 1; argv[j] != NULL; j++) delete_fingerprints (dev, argv[j]); - - g_object_unref (dev); } - - g_ptr_array_foreach(devices, (GFunc) g_free, NULL); - g_ptr_array_free(devices, TRUE); } int main(int argc, char **argv) diff --git a/utils/enroll.c b/utils/enroll.c index 8bd55e9..8c32faf 100644 --- a/utils/enroll.c +++ b/utils/enroll.c @@ -1,6 +1,7 @@ /* * fprintd example to enroll right index finger * Copyright (C) 2008 Daniel Drake + * Copyright (C) 2020 Marco Trevisan * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,17 +22,14 @@ #include #include #include -#include -#include "manager-dbus-glue.h" -#include "device-dbus-glue.h" -#include "fprintd-marshal.h" +#include "fprintd-dbus.h" #define N_(x) x #define TR(x) x #include "fingerprint-strings.h" -static DBusGProxy *manager = NULL; -static DBusGConnection *connection = NULL; +static FprintDBusManager *manager = NULL; +static GDBusConnection *connection = NULL; static char *finger_name = NULL; static char **usernames = NULL; @@ -39,41 +37,54 @@ static void create_manager(void) { GError *error = NULL; - connection = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error); + connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error); if (connection == NULL) { g_print("Failed to connect to session bus: %s\n", error->message); exit (1); } - manager = dbus_g_proxy_new_for_name(connection, - "net.reactivated.Fprint", "/net/reactivated/Fprint/Manager", - "net.reactivated.Fprint.Manager"); + manager = fprint_dbus_manager_proxy_new_sync (connection, + G_DBUS_PROXY_FLAGS_NONE, + "net.reactivated.Fprint", + "/net/reactivated/Fprint/Manager", + NULL, &error); + if (manager == NULL) { + g_print ("Failed to get Fprintd manager: %s\n", error->message); + exit (1); + } } -static DBusGProxy *open_device(const char *username) +static FprintDBusDevice *open_device (const char *username) { + g_autoptr(FprintDBusDevice) dev = NULL; GError *error = NULL; gchar *path; - DBusGProxy *dev; - if (!net_reactivated_Fprint_Manager_get_default_device(manager, &path, &error)) { + if (!fprint_dbus_manager_call_get_default_device_sync (manager, &path, + NULL, &error)) { g_print("Impossible to enroll: %s\n", error->message); exit (1); } g_print("Using device %s\n", path); - /* FIXME use for_name_owner?? */ - dev = dbus_g_proxy_new_for_name(connection, "net.reactivated.Fprint", - path, "net.reactivated.Fprint.Device"); + dev = fprint_dbus_device_proxy_new_sync (connection, + G_DBUS_PROXY_FLAGS_NONE, + "net.reactivated.Fprint", + path, NULL, &error); g_free (path); - if (!net_reactivated_Fprint_Device_claim(dev, username, &error)) { + if (error) { + g_print ("failed to connect to device: %s\n", error->message); + exit (1); + } + + if (!fprint_dbus_device_call_claim_sync (dev, username, NULL, &error)) { g_print("failed to claim device: %s\n", error->message); exit (1); } - return dev; + return g_steal_pointer (&dev); } static void enroll_result(GObject *object, const char *result, gboolean done, void *user_data) @@ -84,16 +95,30 @@ static void enroll_result(GObject *object, const char *result, gboolean done, vo *enroll_completed = TRUE; } -static void do_enroll(DBusGProxy *dev) +static void proxy_signal_cb (GDBusProxy *proxy, + const gchar *sender_name, + const gchar *signal_name, + GVariant *parameters, + gpointer user_data) +{ + if (g_str_equal (signal_name, "EnrollStatus")) { + const gchar *result; + gboolean done; + + g_variant_get (parameters, "(&sb)", &result, &done); + enroll_result (G_OBJECT (proxy), result, done, user_data); + } +} + +static void do_enroll (FprintDBusDevice *dev) { GError *error = NULL; gboolean enroll_completed = FALSE; gboolean found; guint i; - dbus_g_proxy_add_signal(dev, "EnrollStatus", G_TYPE_STRING, G_TYPE_BOOLEAN, NULL); - dbus_g_proxy_connect_signal(dev, "EnrollStatus", G_CALLBACK(enroll_result), - &enroll_completed, NULL); + g_signal_connect (dev, "g-signal", G_CALLBACK (proxy_signal_cb), + &enroll_completed); found = FALSE; for (i = 0; fingers[i].dbus_name != NULL; i++) { @@ -118,7 +143,8 @@ static void do_enroll(DBusGProxy *dev) } g_print("Enrolling %s finger.\n", finger_name); - if (!net_reactivated_Fprint_Device_enroll_start(dev, finger_name, &error)) { + if (!fprint_dbus_device_call_enroll_start_sync (dev, finger_name, NULL, + &error)) { g_print("EnrollStart failed: %s\n", error->message); exit (1); } @@ -126,19 +152,18 @@ static void do_enroll(DBusGProxy *dev) while (!enroll_completed) g_main_context_iteration(NULL, TRUE); - dbus_g_proxy_disconnect_signal(dev, "EnrollStatus", - G_CALLBACK(enroll_result), &enroll_completed); + g_signal_handlers_disconnect_by_func (dev, proxy_signal_cb, &enroll_result); - if (!net_reactivated_Fprint_Device_enroll_stop(dev, &error)) { + if (!fprint_dbus_device_call_enroll_stop_sync (dev, NULL, &error)) { g_print("VerifyStop failed: %s\n", error->message); exit(1); } } -static void release_device(DBusGProxy *dev) +static void release_device (FprintDBusDevice *dev) { GError *error = NULL; - if (!net_reactivated_Fprint_Device_release(dev, &error)) { + if (!fprint_dbus_device_call_release_sync (dev, NULL, &error)) { g_print("ReleaseDevice failed: %s\n", error->message); exit (1); } @@ -152,15 +177,12 @@ static const GOptionEntry entries[] = { int main(int argc, char **argv) { + g_autoptr(FprintDBusDevice) dev = NULL; GOptionContext *context; GError *err = NULL; - DBusGProxy *dev; setlocale (LC_ALL, ""); - dbus_g_object_register_marshaller (fprintd_marshal_VOID__STRING_BOOLEAN, - G_TYPE_NONE, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_INVALID); - context = g_option_context_new ("Enroll a fingerprint"); g_option_context_add_main_entries (context, entries, NULL); @@ -175,7 +197,7 @@ int main(int argc, char **argv) create_manager(); - dev = open_device(usernames ? usernames[0] : NULL); + dev = open_device (usernames ? usernames[0] : ""); do_enroll(dev); release_device(dev); g_free(finger_name); diff --git a/utils/list.c b/utils/list.c index 54bc34b..053ab30 100644 --- a/utils/list.c +++ b/utils/list.c @@ -1,6 +1,7 @@ /* * fprintd example to list enrolled fingerprints * Copyright (C) 2008 Daniel Drake + * Copyright (C) 2020 Marco Trevisan * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,38 +21,52 @@ #include #include #include -#include -#include "manager-dbus-glue.h" -#include "device-dbus-glue.h" +#include "fprintd-dbus.h" -static DBusGProxy *manager = NULL; -static DBusGConnection *connection = NULL; +static FprintDBusManager *manager = NULL; +static GDBusConnection *connection = NULL; static void create_manager(void) { GError *error = NULL; - connection = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error); + connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error); if (connection == NULL) { g_print("Failed to connect to session bus: %s\n", error->message); exit (1); } - manager = dbus_g_proxy_new_for_name(connection, - "net.reactivated.Fprint", "/net/reactivated/Fprint/Manager", - "net.reactivated.Fprint.Manager"); + manager = fprint_dbus_manager_proxy_new_sync (connection, + G_DBUS_PROXY_FLAGS_NONE, + "net.reactivated.Fprint", + "/net/reactivated/Fprint/Manager", + NULL, &error); + if (manager == NULL) { + g_print ("Failed to get Fprintd manager: %s\n", error->message); + exit (1); + } } -static void list_fingerprints(DBusGProxy *dev, const char *username) +static void list_fingerprints (FprintDBusDevice *dev, const char *username) { GError *error = NULL; char **fingers; - GHashTable *props; - DBusGProxy *p; guint i; - if (!net_reactivated_Fprint_Device_list_enrolled_fingers(dev, username, &fingers, &error)) { - if (dbus_g_error_has_name (error, "net.reactivated.Fprint.Error.NoEnrolledPrints") == FALSE) { + if (!fprint_dbus_device_call_list_enrolled_fingers_sync (dev, username, + &fingers, NULL, + &error)) { + gboolean ignore_error = FALSE; + if (g_dbus_error_is_remote_error (error)) { + g_autofree char *dbus_error = + g_dbus_error_get_remote_error (error); + if (g_str_equal (dbus_error, + "net.reactivated.Fprint.Error.NoEnrolledPrints")) { + ignore_error = TRUE; + } + } + + if (!ignore_error) { g_print("ListEnrolledFingers failed: %s\n", error->message); exit (1); } else { @@ -60,24 +75,16 @@ static void list_fingerprints(DBusGProxy *dev, const char *username) } } - p = dbus_g_proxy_new_from_proxy(dev, "org.freedesktop.DBus.Properties", NULL); - if (!dbus_g_proxy_call (p, "GetAll", &error, G_TYPE_STRING, "net.reactivated.Fprint.Device", G_TYPE_INVALID, - dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE), &props, G_TYPE_INVALID)) { - g_print("GetAll on the Properties interface failed: %s\n", error->message); - exit (1); - } - if (fingers == NULL || g_strv_length (fingers) == 0) { - g_print("User %s has no fingers enrolled for %s.\n", username, g_value_get_string (g_hash_table_lookup (props, "name"))); + g_print ("User %s has no fingers enrolled for %s.\n", username, + fprint_dbus_device_get_name (dev)); return; } g_print("Fingerprints for user %s on %s (%s):\n", username, - g_value_get_string (g_hash_table_lookup (props, "name")), - g_value_get_string (g_hash_table_lookup (props, "scan-type"))); - g_hash_table_destroy (props); - g_object_unref (p); + fprint_dbus_device_get_name (dev), + fprint_dbus_device_get_scan_type (dev)); for (i = 0; fingers[i] != NULL; i++) { g_print(" - #%d: %s\n", i, fingers[i]); @@ -88,46 +95,45 @@ static void list_fingerprints(DBusGProxy *dev, const char *username) static void process_devices(char **argv) { + g_auto(GStrv) devices = NULL; GError *error = NULL; - GPtrArray *devices; char *path; + guint num_devices; guint i; - if (!net_reactivated_Fprint_Manager_get_devices(manager, &devices, &error)) { + if (!fprint_dbus_manager_call_get_devices_sync (manager, &devices, NULL, + &error)) { g_print("Impossible to get devices: %s\n", error->message); exit (1); } - - if (devices->len == 0) { + + num_devices = g_strv_length (devices); + if (num_devices == 0) { g_print("No devices available\n"); exit(1); } - g_print("found %d devices\n", devices->len); - for (i = 0; i < devices->len; i++) { - path = g_ptr_array_index(devices, i); + g_print ("found %u devices\n", num_devices); + for (i = 0; devices[i] != NULL; i++) { + path = devices[i]; g_print("Device at %s\n", path); } - for (i = 0; i < devices->len; i++) { + for (i = 0; devices[i] != NULL; i++) { + g_autoptr(FprintDBusDevice) dev = NULL; guint j; - DBusGProxy *dev; - path = g_ptr_array_index(devices, i); + path = devices[i]; g_print("Using device %s\n", path); - /* FIXME use for_name_owner?? */ - dev = dbus_g_proxy_new_for_name(connection, "net.reactivated.Fprint", - path, "net.reactivated.Fprint.Device"); + dev = fprint_dbus_device_proxy_new_sync (connection, + G_DBUS_PROXY_FLAGS_NONE, + "net.reactivated.Fprint", + path, NULL, &error); for (j = 1; argv[j] != NULL; j++) list_fingerprints (dev, argv[j]); - - g_object_unref (dev); } - - g_ptr_array_foreach(devices, (GFunc) g_free, NULL); - g_ptr_array_free(devices, TRUE); } int main(int argc, char **argv) diff --git a/utils/meson.build b/utils/meson.build index 63c7420..4056c79 100644 --- a/utils/meson.build +++ b/utils/meson.build @@ -1,42 +1,19 @@ -dbus_client_glue_sources = [] - -foreach interface_name: dbus_interfaces - interface = interface_name.to_lower() - interface_file = meson.source_root() / 'src' / interface + '.xml' - glue_name = interface + '-dbus-glue.h' - dbus_client_glue_sources += custom_target(glue_name, - input: interface_file, - output: glue_name, - command: [ - dbus_binding_tool, - '--prefix=fprint_' + interface, - '--mode=glib-client', - '--output=@OUTPUT@', - '@INPUT@', - ]) -endforeach - libfprintd_utils_dep = declare_dependency( include_directories: [ + include_directories('../src'), include_directories('../pam'), ], dependencies: [ glib_dep, - dbus_glib_dep, + gio_dep, + gio_unix_dep, ], sources: [ - fprintd_marshal, - dbus_client_glue_sources, + fprintd_dbus_sources, + ], + link_with: [ + libfprintd_private ], - link_with: static_library('fprintd_utils', - sources: [ - dbus_client_glue_sources, - fprintd_marshal, - ], - dependencies: [ - glib_dep, - ] - ), ) utils = [ diff --git a/utils/verify.c b/utils/verify.c index caac88e..3695cd8 100644 --- a/utils/verify.c +++ b/utils/verify.c @@ -1,6 +1,7 @@ /* * fprintd example to verify a fingerprint * Copyright (C) 2008 Daniel Drake + * Copyright (C) 2020 Marco Trevisan * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,66 +22,79 @@ #include #include #include -#include -#include "manager-dbus-glue.h" -#include "device-dbus-glue.h" -#include "fprintd-marshal.h" +#include +#include "fprintd-dbus.h" -static DBusGProxy *manager = NULL; -static DBusGConnection *connection = NULL; +static FprintDBusManager *manager = NULL; +static GDBusConnection *connection = NULL; static char *finger_name = NULL; static gboolean g_fatal_warnings = FALSE; static char **usernames = NULL; static void create_manager(void) { - GError *error = NULL; + g_autoptr(GError) error = NULL; - connection = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error); + connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error); if (connection == NULL) { g_print("Failed to connect to session bus: %s\n", error->message); exit (1); } - manager = dbus_g_proxy_new_for_name(connection, - "net.reactivated.Fprint", "/net/reactivated/Fprint/Manager", - "net.reactivated.Fprint.Manager"); + manager = fprint_dbus_manager_proxy_new_sync (connection, + G_DBUS_PROXY_FLAGS_NONE, + "net.reactivated.Fprint", + "/net/reactivated/Fprint/Manager", + NULL, &error); + if (manager == NULL) { + g_print ("Failed to get Fprintd manager: %s\n", error->message); + exit (1); + } } -static DBusGProxy *open_device(const char *username) +static FprintDBusDevice *open_device (const char *username) { + g_autoptr(FprintDBusDevice) dev = NULL; GError *error = NULL; gchar *path; - DBusGProxy *dev; - if (!net_reactivated_Fprint_Manager_get_default_device(manager, &path, &error)) { + if (!fprint_dbus_manager_call_get_default_device_sync (manager, &path, + NULL, &error)) { g_print("Impossible to verify: %s\n", error->message); exit (1); } g_print("Using device %s\n", path); - /* FIXME use for_name_owner?? */ - dev = dbus_g_proxy_new_for_name(connection, "net.reactivated.Fprint", - path, "net.reactivated.Fprint.Device"); - + dev = fprint_dbus_device_proxy_new_sync (connection, + G_DBUS_PROXY_FLAGS_NONE, + "net.reactivated.Fprint", + path, NULL, &error); + g_free (path); - if (!net_reactivated_Fprint_Device_claim(dev, username, &error)) { + if (error) { + g_print ("failed to connect to device: %s\n", error->message); + exit (1); + } + + if (!fprint_dbus_device_call_claim_sync (dev, username, NULL, &error)) { g_print("failed to claim device: %s\n", error->message); exit (1); } - return dev; + return g_steal_pointer (&dev); } -static void find_finger(DBusGProxy *dev, const char *username) +static void find_finger (FprintDBusDevice *dev, const char *username) { GError *error = NULL; char **fingers; guint i; - if (!net_reactivated_Fprint_Device_list_enrolled_fingers(dev, username, &fingers, &error)) { + if (!fprint_dbus_device_call_list_enrolled_fingers_sync (dev, username, + &fingers, + NULL, &error)) { g_print("ListEnrolledFingers failed: %s\n", error->message); exit (1); } @@ -123,19 +137,36 @@ static void verify_finger_selected(GObject *object, const char *name, void *user g_print("Verifying: %s\n", name); } -static void do_verify(DBusGProxy *dev) +static void proxy_signal_cb (GDBusProxy *proxy, + const gchar *sender_name, + const gchar *signal_name, + GVariant *parameters, + gpointer user_data) +{ + if (g_str_equal (signal_name, "VerifyStatus")) { + const gchar *result; + gboolean done; + + g_variant_get (parameters, "(&sb)", &result, &done); + verify_result (G_OBJECT (proxy), result, done, user_data); + } else if (g_str_equal (signal_name, "VerifyFingerSelected")) { + const gchar *name; + + g_variant_get (parameters, "(&s)", &name); + verify_finger_selected (G_OBJECT (proxy), name, user_data); + } +} + +static void do_verify (FprintDBusDevice *dev) { GError *error = NULL; gboolean verify_completed = FALSE; - dbus_g_proxy_add_signal(dev, "VerifyStatus", G_TYPE_STRING, G_TYPE_BOOLEAN, NULL); - dbus_g_proxy_add_signal(dev, "VerifyFingerSelected", G_TYPE_INT, NULL); - dbus_g_proxy_connect_signal(dev, "VerifyStatus", G_CALLBACK(verify_result), - &verify_completed, NULL); - dbus_g_proxy_connect_signal(dev, "VerifyFingerSelected", G_CALLBACK(verify_finger_selected), - NULL, NULL); + g_signal_connect (dev, "g-signal", G_CALLBACK (proxy_signal_cb), + &verify_completed); - if (!net_reactivated_Fprint_Device_verify_start(dev, finger_name, &error)) { + if (!fprint_dbus_device_call_verify_start_sync (dev, finger_name, NULL, + &error)) { g_print("VerifyStart failed: %s\n", error->message); exit (1); } @@ -143,19 +174,20 @@ static void do_verify(DBusGProxy *dev) while (!verify_completed) g_main_context_iteration(NULL, TRUE); - dbus_g_proxy_disconnect_signal(dev, "VerifyStatus", G_CALLBACK(verify_result), &verify_completed); - dbus_g_proxy_disconnect_signal(dev, "VerifyFingerSelected", G_CALLBACK(verify_finger_selected), NULL); - if (!net_reactivated_Fprint_Device_verify_stop(dev, &error)) { + g_signal_handlers_disconnect_by_func (dev, proxy_signal_cb, + &verify_completed); + + if (!fprint_dbus_device_call_verify_stop_sync (dev, NULL, &error)) { g_print("VerifyStop failed: %s\n", error->message); exit (1); } } -static void release_device(DBusGProxy *dev) +static void release_device (FprintDBusDevice *dev) { GError *error = NULL; - if (!net_reactivated_Fprint_Device_release(dev, &error)) { + if (!fprint_dbus_device_call_release_sync (dev, NULL, &error)) { g_print("ReleaseDevice failed: %s\n", error->message); exit (1); } @@ -170,16 +202,13 @@ static const GOptionEntry entries[] = { int main(int argc, char **argv) { + g_autoptr(FprintDBusDevice) dev = NULL; GOptionContext *context; GError *err = NULL; - DBusGProxy *dev; const char *username = NULL; setlocale (LC_ALL, ""); - dbus_g_object_register_marshaller (fprintd_marshal_VOID__STRING_BOOLEAN, - G_TYPE_NONE, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_INVALID); - context = g_option_context_new ("Verify a fingerprint"); g_option_context_add_main_entries (context, entries, NULL);