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);