diff --git a/src/device.c b/src/device.c index 332df1d..15d02ab 100644 --- a/src/device.c +++ b/src/device.c @@ -34,11 +34,9 @@ extern DBusGConnection *fprintd_dbus_conn; -static void fprint_device_set_username(FprintDevice *rdev, - const char *username, - DBusGMethodInvocation *context); static void fprint_device_claim(FprintDevice *rdev, - DBusGMethodInvocation *context); + const char *username, + DBusGMethodInvocation *context); static void fprint_device_release(FprintDevice *rdev, DBusGMethodInvocation *context); static void fprint_device_verify_start(FprintDevice *rdev, @@ -50,9 +48,11 @@ static void fprint_device_enroll_start(FprintDevice *rdev, static void fprint_device_enroll_stop(FprintDevice *rdev, DBusGMethodInvocation *context); static void fprint_device_list_enrolled_fingers(FprintDevice *rdev, - DBusGMethodInvocation *context); + const char *username, + DBusGMethodInvocation *context); static void fprint_device_delete_enrolled_fingers(FprintDevice *rdev, - DBusGMethodInvocation *context); + const char *username, + DBusGMethodInvocation *context); #include "device-dbus-glue.h" @@ -310,33 +310,65 @@ _fprint_device_check_polkit_for_actions (FprintDevice *rdev, return _fprint_device_check_polkit_for_action (rdev, context, action2, error); } -static void -fprint_device_set_username (FprintDevice *rdev, - const char *username, - DBusGMethodInvocation *context) +static char * +_fprint_device_check_for_username (FprintDevice *rdev, + DBusGMethodInvocation *context, + const char *username, + char **ret_sender, + GError **error) { - FprintDevicePrivate *priv = DEVICE_GET_PRIVATE(rdev); - GError *error = NULL; + DBusConnection *conn; + DBusError dbus_error; + char *sender; + unsigned long uid; + struct passwd *user; + char *client_username; - if (_fprint_device_check_claimed(rdev, context, &error) == FALSE) { - dbus_g_method_return_error (context, error); - return; + /* Get details about the current sender, and username/uid */ + conn = dbus_g_connection_get_connection (fprintd_dbus_conn); + sender = dbus_g_method_get_sender (context); + dbus_error_init (&dbus_error); + uid = dbus_bus_get_unix_user (conn, sender, &dbus_error); + + if (dbus_error_is_set(&dbus_error)) { + g_free (sender); + dbus_set_g_error (error, &dbus_error); + return NULL; } - if (_fprint_device_check_polkit_for_action (rdev, context, "net.reactivated.fprint.device.setusername", &error) == FALSE) { - dbus_g_method_return_error (context, error); - return; + user = getpwuid (uid); + if (user == NULL) { + g_free (sender); + g_set_error(error, FPRINT_ERROR, FPRINT_ERROR_CLAIM_DEVICE, + "Failed to get information about user UID %lu", uid); + return NULL; + } + client_username = g_strdup (user->pw_name); + + /* The current user is usually allowed to access their + * own data, this should be followed by PolicyKit checks + * anyway */ + if (username == NULL || *username == '\0' || g_str_equal (username, client_username)) { + if (ret_sender != NULL) + *ret_sender = sender; + else + g_free (sender); + return client_username; } - if (username == NULL) { - dbus_g_method_return (context); - return; + /* 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); + return NULL; } - g_free (priv->username); - priv->username = g_strdup (username); + if (ret_sender != NULL) + *ret_sender = sender; + else + g_free (sender); - dbus_g_method_return (context); + return g_strdup (username); } static void dev_open_cb(struct fp_dev *dev, int status, void *user_data) @@ -364,15 +396,12 @@ static void dev_open_cb(struct fp_dev *dev, int status, void *user_data) } static void fprint_device_claim(FprintDevice *rdev, - DBusGMethodInvocation *context) + const char *username, + DBusGMethodInvocation *context) { FprintDevicePrivate *priv = DEVICE_GET_PRIVATE(rdev); GError *error = NULL; - DBusConnection *conn; - DBusError dbus_error; - char *sender; - unsigned long uid; - struct passwd *user; + char *sender, *user; int r; /* Is it already claimed? */ @@ -383,42 +412,36 @@ static void fprint_device_claim(FprintDevice *rdev, return; } - if (_fprint_device_check_polkit_for_actions (rdev, context, - "net.reactivated.fprint.device.verify", - "net.reactivated.fprint.device.enroll", - &error) == FALSE) { - dbus_g_method_return_error (context, error); - return; - } + g_assert (priv->username == NULL); + g_assert (priv->sender == NULL); - /* 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); - - if (dbus_error_is_set(&dbus_error)) { + sender = NULL; + user = _fprint_device_check_for_username (rdev, + context, + username, + &sender, + &error); + if (user == NULL) { g_free (sender); - dbus_set_g_error (&error, &dbus_error); - dbus_g_method_return_error(context, error); + dbus_g_method_return_error (context, error); g_error_free (error); return; } - user = getpwuid (uid); - if (user == NULL) { + if (_fprint_device_check_polkit_for_actions (rdev, context, + "net.reactivated.fprint.device.verify", + "net.reactivated.fprint.device.enroll", + &error) == FALSE) { g_free (sender); - g_set_error(&error, FPRINT_ERROR, FPRINT_ERROR_CLAIM_DEVICE, - "Failed to get information about user UID %lu", uid); - dbus_g_method_return_error(context, error); + g_free (user); + dbus_g_method_return_error (context, error); return; } - priv->username = g_strdup (user->pw_name); + priv->username = user; priv->sender = sender; - g_message ("user claiming the device: %s (%ld)", priv->username, uid); - /* FIXME call polkit to check whether allowed */ + g_message ("user claiming the device: %s", priv->username); g_message("claiming device %d", priv->id); priv->session = g_slice_new0(struct session_data); @@ -478,6 +501,10 @@ static void fprint_device_release(FprintDevice *rdev, session->context_release_device = context; fp_async_dev_close(priv->dev, dev_close_cb, rdev); + g_free (priv->sender); + priv->sender = NULL; + g_free (priv->username); + priv->username = NULL; } static void verify_cb(struct fp_dev *dev, int r, struct fp_img *img, @@ -647,25 +674,37 @@ static void fprint_device_enroll_stop(FprintDevice *rdev, } static void fprint_device_list_enrolled_fingers(FprintDevice *rdev, - DBusGMethodInvocation *context) + const char *username, + DBusGMethodInvocation *context) { FprintDevicePrivate *priv = DEVICE_GET_PRIVATE(rdev); GError *error = NULL; GSList *prints; GSList *item; GArray *ret; + char *user; - if (_fprint_device_check_claimed(rdev, context, &error) == FALSE) { + g_message ("orig username: %s", username); + user = _fprint_device_check_for_username (rdev, + context, + username, + NULL, + &error); + g_message ("user: %s", user); + if (user == NULL) { dbus_g_method_return_error (context, error); + g_error_free (error); return; } if (_fprint_device_check_polkit_for_action (rdev, context, "net.reactivated.fprint.device.verify", &error) == FALSE) { + g_free (user); dbus_g_method_return_error (context, error); return; } - prints = store.discover_prints(priv->dev, priv->username); + prints = store.discover_prints(priv->ddev, user); + g_free (user); if (!prints) { g_set_error(&error, FPRINT_ERROR, FPRINT_ERROR_DISCOVER_PRINTS, "Failed to discover prints"); @@ -685,25 +724,35 @@ static void fprint_device_list_enrolled_fingers(FprintDevice *rdev, } static void fprint_device_delete_enrolled_fingers(FprintDevice *rdev, + const char *username, DBusGMethodInvocation *context) { FprintDevicePrivate *priv = DEVICE_GET_PRIVATE(rdev); GError *error = NULL; guint i; + char *user; - if (_fprint_device_check_claimed(rdev, context, &error) == FALSE) { + user = _fprint_device_check_for_username (rdev, + context, + username, + NULL, + &error); + if (user == NULL) { dbus_g_method_return_error (context, error); + g_error_free (error); return; } if (_fprint_device_check_polkit_for_action (rdev, context, "net.reactivated.fprint.device.enroll", &error) == FALSE) { + g_free (user); dbus_g_method_return_error (context, error); return; } for (i = LEFT_THUMB; i <= RIGHT_LITTLE; i++) { - store.print_data_delete(priv->dev, i, priv->username); + store.print_data_delete(priv->ddev, i, user); } + g_free (user); dbus_g_method_return(context); } diff --git a/src/device.xml b/src/device.xml index 64177db..777d57a 100644 --- a/src/device.xml +++ b/src/device.xml @@ -4,20 +4,23 @@ - - - - - - - - + + + + + + + + + + + @@ -47,11 +50,6 @@ - - - - - diff --git a/src/file_storage.c b/src/file_storage.c index 0a50980..b1d7012 100644 --- a/src/file_storage.c +++ b/src/file_storage.c @@ -78,6 +78,12 @@ static char *get_path_to_print(struct fp_dev *dev, enum fp_finger finger, char * fp_dev_get_devtype(dev), finger, base_store); } +static char *get_path_to_print_dscv(struct fp_dscv_dev *dev, enum fp_finger finger, char *base_store) +{ + return __get_path_to_print(fp_driver_get_driver_id(fp_dscv_dev_get_driver(dev)), + fp_dscv_dev_get_devtype(dev), finger, base_store); +} + static int file_storage_get_basestore_for_username(const char *username, char **base_store) { char *dirpath = FILE_STORAGE_PATH; @@ -193,7 +199,7 @@ int file_storage_print_data_load(struct fp_dev *dev, return 0; } -int file_storage_print_data_delete(struct fp_dev *dev, +int file_storage_print_data_delete(struct fp_dscv_dev *dev, enum fp_finger finger, const char *username) { int r; @@ -205,7 +211,7 @@ int file_storage_print_data_delete(struct fp_dev *dev, return r; } - gchar *path = get_path_to_print(dev, finger, base_store); + gchar *path = get_path_to_print_dscv(dev, finger, base_store); r = g_unlink(path); g_free(path); @@ -252,7 +258,7 @@ static GSList *scan_dev_storedir(char *devpath, uint16_t driver_id, return list; } -GSList *file_storage_discover_prints(struct fp_dev *dev, const char *username) +GSList *file_storage_discover_prints(struct fp_dscv_dev *dev, const char *username) { //GDir *dir; //const gchar *ent; @@ -270,12 +276,12 @@ GSList *file_storage_discover_prints(struct fp_dev *dev, const char *username) return NULL; } - storedir = get_path_to_storedir(fp_driver_get_driver_id(fp_dev_get_driver(dev)), - fp_dev_get_devtype(dev), base_store); + storedir = get_path_to_storedir(fp_driver_get_driver_id(fp_dscv_dev_get_driver(dev)), + fp_dscv_dev_get_devtype(dev), base_store); g_message("Entering %s", storedir); - list = scan_dev_storedir(storedir, fp_driver_get_driver_id(fp_dev_get_driver(dev)), - fp_dev_get_devtype(dev), list); + list = scan_dev_storedir(storedir, fp_driver_get_driver_id(fp_dscv_dev_get_driver(dev)), + fp_dscv_dev_get_devtype(dev), list); g_free(base_store); g_free(storedir); diff --git a/src/file_storage.h b/src/file_storage.h index 7ba4e4a..b0072b9 100644 --- a/src/file_storage.h +++ b/src/file_storage.h @@ -29,13 +29,13 @@ int file_storage_print_data_save(struct fp_print_data *data, int file_storage_print_data_load(struct fp_dev *dev, enum fp_finger finger, struct fp_print_data **data, const char *username); -int file_storage_print_data_delete(struct fp_dev *dev, +int file_storage_print_data_delete(struct fp_dscv_dev *dev, enum fp_finger finger, const char *username); int file_storage_init(void); int file_storage_deinit(void); -GSList *file_storage_discover_prints(struct fp_dev *dev, const char *username); +GSList *file_storage_discover_prints(struct fp_dscv_dev *dev, const char *username); #endif diff --git a/src/storage.h b/src/storage.h index 76e7acd..ce708b8 100644 --- a/src/storage.h +++ b/src/storage.h @@ -26,9 +26,9 @@ typedef int (*storage_print_data_save)(struct fp_print_data *data, enum fp_finger finger, const char *username); typedef int (*storage_print_data_load)(struct fp_dev *dev, enum fp_finger finger, struct fp_print_data **data, const char *username); -typedef int (*storage_print_data_delete)(struct fp_dev *dev, +typedef int (*storage_print_data_delete)(struct fp_dscv_dev *dev, enum fp_finger finger, const char *username); -typedef GSList *(*storage_discover_prints)(struct fp_dev *dev, const char *username); +typedef GSList *(*storage_discover_prints)(struct fp_dscv_dev *dev, const char *username); typedef int (*storage_init)(void); typedef int (*storage_deinit)(void); diff --git a/tests/Makefile.am b/tests/Makefile.am index 0ddd29e..9ea58a9 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -2,7 +2,7 @@ BUILT_SOURCES = manager-dbus-glue.h device-dbus-glue.h noinst_HEADERS = $(BUILT_SOURCES) CLEANFILES = $(BUILT_SOURCES) -bin_PROGRAMS = verify enroll +bin_PROGRAMS = verify enroll list verify_SOURCES = verify.c verify_CFLAGS = $(AM_CFLAGS) $(GLIB_CFLAGS) @@ -12,6 +12,10 @@ enroll_SOURCES = enroll.c enroll_CFLAGS = $(AM_CFLAGS) $(GLIB_CFLAGS) enroll_LDADD = $(GLIB_LIBS) +list_SOURCES = list.c +list_CFLAGS = $(AM_CFLAGS) $(GLIB_CFLAGS) +list_LDADD = $(GLIB_LIBS) + manager-dbus-glue.h: ../src/manager.xml dbus-binding-tool --prefix=fprint_manager --mode=glib-client $< --output=$@ diff --git a/tests/enroll.c b/tests/enroll.c index 1aa92a0..c924388 100644 --- a/tests/enroll.c +++ b/tests/enroll.c @@ -83,7 +83,7 @@ static void create_manager(void) "net.reactivated.Fprint.Manager"); } -static DBusGProxy *open_device(void) +static DBusGProxy *open_device(const char *username) { GError *error = NULL; GPtrArray *devices; @@ -115,7 +115,7 @@ static DBusGProxy *open_device(void) g_ptr_array_foreach(devices, (GFunc) g_free, NULL); g_ptr_array_free(devices, TRUE); - if (!net_reactivated_Fprint_Device_claim(dev, &error)) + if (!net_reactivated_Fprint_Device_claim(dev, username, &error)) g_error("failed to claim device: %s", error->message); return dev; } @@ -158,30 +158,20 @@ static void release_device(DBusGProxy *dev) g_error("ReleaseDevice failed: %s", error->message); } -static gboolean set_username(DBusGProxy *dev, const char *username) -{ - GError *error = NULL; - if (!net_reactivated_Fprint_Device_set_username(dev, username, &error)) { - g_error("SetUsename failed: %s", error->message); - return FALSE; - } - return TRUE; -} - int main(int argc, char **argv) { GMainLoop *loop; DBusGProxy *dev; + char *username; g_type_init(); loop = g_main_loop_new(NULL, FALSE); create_manager(); - dev = open_device(); - if (argc == 2) { - if (set_username(dev, argv[1]) == FALSE) - return 1; - } + username = NULL; + if (argc == 2) + username = argv[1]; + dev = open_device(username); do_enroll(dev); release_device(dev); return 0; diff --git a/tests/list.c b/tests/list.c new file mode 100644 index 0000000..b916b4f --- /dev/null +++ b/tests/list.c @@ -0,0 +1,165 @@ +/* + * fprintd example to verify a fingerprint + * Copyright (C) 2008 Daniel Drake + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include +#include +#include "manager-dbus-glue.h" +#include "device-dbus-glue.h" + +static DBusGProxy *manager = NULL; +static DBusGConnection *connection = NULL; + +enum fp_finger { + LEFT_THUMB = 1, /** thumb (left hand) */ + LEFT_INDEX, /** index finger (left hand) */ + LEFT_MIDDLE, /** middle finger (left hand) */ + LEFT_RING, /** ring finger (left hand) */ + LEFT_LITTLE, /** little finger (left hand) */ + RIGHT_THUMB, /** thumb (right hand) */ + RIGHT_INDEX, /** index finger (right hand) */ + RIGHT_MIDDLE, /** middle finger (right hand) */ + RIGHT_RING, /** ring finger (right hand) */ + RIGHT_LITTLE, /** little finger (right hand) */ +}; + +static const char *fingerstr(guint32 fingernum) +{ + switch (fingernum) { + case LEFT_THUMB: + return "Left thumb"; + case LEFT_INDEX: + return "Left index finger"; + case LEFT_MIDDLE: + return "Left middle finger"; + case LEFT_RING: + return "Left ring finger"; + case LEFT_LITTLE: + return "Left little finger"; + case RIGHT_THUMB: + return "Right thumb"; + case RIGHT_INDEX: + return "Right index finger"; + case RIGHT_MIDDLE: + return "Right middle finger"; + case RIGHT_RING: + return "Right ring finger"; + case RIGHT_LITTLE: + return "Right little finger"; + default: + return "Unknown finger"; + } +} + +static void create_manager(void) +{ + GError *error = NULL; + + connection = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error); + if (connection == NULL) + g_error("Failed to connect to session bus: %s", error->message); + + manager = dbus_g_proxy_new_for_name(connection, + "net.reactivated.Fprint", "/net/reactivated/Fprint/Manager", + "net.reactivated.Fprint.Manager"); +} + +static DBusGProxy *open_device(void) +{ + GError *error = NULL; + GPtrArray *devices; + gchar *path; + DBusGProxy *dev; + guint i; + + if (!net_reactivated_Fprint_Manager_get_devices(manager, &devices, &error)) + g_error("list_devices failed: %s", error->message); + + if (devices->len == 0) { + g_print("No devices found\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("Device at %s\n", path); + } + + path = g_ptr_array_index(devices, 0); + 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"); + + g_ptr_array_foreach(devices, (GFunc) g_free, NULL); + g_ptr_array_free(devices, TRUE); + + return dev; +} + +static void list_fingerprints(DBusGProxy *dev, const char *username) +{ + GError *error = NULL; + GArray *fingers; + guint i; + int fingernum; + + if (!net_reactivated_Fprint_Device_list_enrolled_fingers(dev, username, &fingers, &error)) + g_error("ListEnrolledFingers failed: %s", error->message); + + if (fingers->len == 0) { + g_print("User %s has no fingers enrolled for this device.\n", username); + return; + } + + g_print("Fingerprints for user %s:\n", username); + for (i = 0; i < fingers->len; i++) { + fingernum = g_array_index(fingers, guint32, i); + g_print(" - #%d: %s\n", fingernum, fingerstr(fingernum)); + } + + fingernum = g_array_index(fingers, guint32, 0); + g_array_free(fingers, TRUE); +} + +int main(int argc, char **argv) +{ + GMainLoop *loop; + DBusGProxy *dev; + guint32 i; + + g_type_init(); + loop = g_main_loop_new(NULL, FALSE); + create_manager(); + + if (argc < 2) { + g_print ("Usage: %s [usernames...]\n", argv[0]); + return 1; + } + + dev = open_device(); + for (i = 1; argv[i] != NULL; i++) { + list_fingerprints (dev, argv[i]); + } + + return 0; +} + diff --git a/tests/verify.c b/tests/verify.c index fed0d4e..8c20427 100644 --- a/tests/verify.c +++ b/tests/verify.c @@ -109,7 +109,7 @@ static void create_manager(void) "net.reactivated.Fprint.Manager"); } -static DBusGProxy *open_device(void) +static DBusGProxy *open_device(const char *username) { GError *error = NULL; GPtrArray *devices; @@ -141,19 +141,19 @@ static DBusGProxy *open_device(void) g_ptr_array_foreach(devices, (GFunc) g_free, NULL); g_ptr_array_free(devices, TRUE); - if (!net_reactivated_Fprint_Device_claim(dev, &error)) + if (!net_reactivated_Fprint_Device_claim(dev, username, &error)) g_error("failed to claim device: %s", error->message); return dev; } -static guint32 find_finger(DBusGProxy *dev) +static guint32 find_finger(DBusGProxy *dev, const char *username) { GError *error = NULL; GArray *fingers; guint i; int fingernum; - if (!net_reactivated_Fprint_Device_list_enrolled_fingers(dev, &fingers, &error)) + if (!net_reactivated_Fprint_Device_list_enrolled_fingers(dev, username, &fingers, &error)) g_error("ListEnrolledFingers failed: %s", error->message); if (fingers->len == 0) { @@ -211,32 +211,23 @@ static void release_device(DBusGProxy *dev) g_error("ReleaseDevice failed: %s", error->message); } -static gboolean set_username(DBusGProxy *dev, const char *username) -{ - GError *error = NULL; - if (!net_reactivated_Fprint_Device_set_username(dev, username, &error)) { - g_error("SetUsename failed: %s", error->message); - return FALSE; - } - return TRUE; -} - int main(int argc, char **argv) { GMainLoop *loop; DBusGProxy *dev; guint32 finger_num; + char *username; g_type_init(); loop = g_main_loop_new(NULL, FALSE); create_manager(); - dev = open_device(); - if (argc == 2) { - if (set_username(dev, argv[1]) == FALSE) - return 1; - } - finger_num = find_finger(dev); + username = NULL; + if (argc == 2) + username = argv[1]; + + dev = open_device(username); + finger_num = find_finger(dev, username); do_verify(dev, finger_num); release_device(dev); return 0;