From 1ccae6671c2570d46db35e8d11aecfc8ebb5926c Mon Sep 17 00:00:00 2001 From: Luka Novsak Date: Sun, 7 Feb 2016 13:30:41 +0100 Subject: [PATCH] port to udisks2 --- Makefile | 5 +- src/device.c | 77 ++++++---- src/device.h | 1 + src/hal.c | 345 --------------------------------------------- src/hal.h | 31 ---- src/pad.c | 24 ++-- src/pad.h | 4 +- src/volume.c | 225 ++++++++++++++++------------- src/volume.h | 15 +- tools/pamusb-agent | 53 ++++--- tools/pamusb-conf | 43 +++--- 11 files changed, 266 insertions(+), 557 deletions(-) delete mode 100644 src/hal.c delete mode 100644 src/hal.h diff --git a/Makefile b/Makefile index 16273a1..14a8c97 100644 --- a/Makefile +++ b/Makefile @@ -7,16 +7,15 @@ LIBDIR ?= lib # compiler/linker options CC := gcc CFLAGS := $(CFLAGS) -Wall -fPIC `pkg-config --cflags libxml-2.0` \ - `pkg-config --cflags dbus-1` + `pkg-config --cflags udisks2` LIBS := `pkg-config --libs libxml-2.0` \ - `pkg-config --libs dbus-1` + `pkg-config --libs udisks2` # common source files SRCS := src/conf.c \ src/mem.c \ src/log.c \ src/xpath.c \ - src/hal.c \ src/pad.c \ src/volume.c \ src/local.c \ diff --git a/src/device.c b/src/device.c index dfe9ae0..fdab4ff 100644 --- a/src/device.c +++ b/src/device.c @@ -1,4 +1,7 @@ +/* -*- mode: c; c-file-style: "bsd"; indent-tabs-mode: t; -*- */ + /* + * Copyright (c) 2016 Luka Novsak * Copyright (c) 2003-2007 Andrea Luzzardi * * This file is part of the pam_usb project. pam_usb is free software; @@ -18,56 +21,74 @@ #include #include #include -#include -#include "mem.h" + +#include + #include "conf.h" -#include "hal.h" #include "log.h" #include "pad.h" #include "device.h" -static int pusb_device_connected(t_pusb_options *opts, DBusConnection *dbus) +static int pusb_device_connected(t_pusb_options *opts, UDisksClient *udisks) { - char *udi = NULL; + GDBusObjectManager *manager = udisks_client_get_object_manager(udisks); + GList *objects = g_dbus_object_manager_get_objects(manager); + int retval = 0; + int i; + UDisksObject *object = NULL; + UDisksDrive *drive = NULL; + + manager = udisks_client_get_object_manager(udisks); + objects = g_dbus_object_manager_get_objects(manager); log_debug("Searching for \"%s\" in the hardware database...\n", opts->device.name); - udi = pusb_hal_find_item(dbus, - "DriveSerial", opts->device.serial, - "DriveVendor", opts->device.vendor, - "DriveModel", opts->device.model, - NULL); - if (!udi) + + for (i = 0; i < g_list_length(objects); ++i) { - log_error("Device \"%s\" is not connected.\n", - opts->device.name); - return (0); + object = UDISKS_OBJECT(g_list_nth(objects, i)->data); + if (udisks_object_peek_drive(object)) + { + drive = udisks_object_get_drive(object); + retval = strcmp(udisks_drive_get_serial(drive), opts->device.serial) == 0 && + strcmp(udisks_drive_get_vendor(drive), opts->device.vendor) == 0 && + strcmp(udisks_drive_get_model(drive), opts->device.model) == 0; + g_object_unref(drive); + if (retval) + break; + } } - xfree(udi); - log_info("Device \"%s\" is connected (good).\n", opts->device.name); - return (1); + + if (retval) + log_info("Device \"%s\" is connected (good).\n", + opts->device.name); + else + log_error("Device \"%s\" is not connected (bad).\n", + opts->device.name); + + g_list_foreach (objects, (GFunc) g_object_unref, NULL); + g_list_free (objects); + + return (retval); } -int pusb_device_check(t_pusb_options *opts, - const char *user) +int pusb_device_check(t_pusb_options *opts, const char *user) { - DBusConnection *dbus = NULL; - int retval = 0; + UDisksClient *udisks = NULL; + int retval = 0; - log_debug("Connecting to HAL...\n"); - if (!(dbus = pusb_hal_dbus_connect())) - return (0); + udisks = udisks_client_new_sync(NULL, NULL); - if (!pusb_device_connected(opts, dbus)) + if (!pusb_device_connected(opts, udisks)) { - pusb_hal_dbus_disconnect(dbus); + g_object_unref(udisks); return (0); } if (opts->one_time_pad) { log_info("Performing one time pad verification...\n"); - retval = pusb_pad_check(opts, dbus, user); + retval = pusb_pad_check(opts, udisks, user); } else { @@ -75,6 +96,6 @@ int pusb_device_check(t_pusb_options *opts, retval = 1; } - pusb_hal_dbus_disconnect(dbus); + g_object_unref(udisks); return (retval); } diff --git a/src/device.h b/src/device.h index e9a3851..6d97d99 100644 --- a/src/device.h +++ b/src/device.h @@ -17,6 +17,7 @@ #ifndef PUSB_DEVICE_H_ # define PUSB_DEVICE_H_ +# include "conf.h" int pusb_device_check(t_pusb_options *opts, const char *user); diff --git a/src/hal.c b/src/hal.c deleted file mode 100644 index f951792..0000000 --- a/src/hal.c +++ /dev/null @@ -1,345 +0,0 @@ -/* - * Copyright (c) 2003-2007 Andrea Luzzardi - * - * This file is part of the pam_usb project. pam_usb is free software; - * you can redistribute it and/or modify it under the terms of the GNU General - * Public License version 2, as published by the Free Software Foundation. - * - * pam_usb 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., 59 Temple - * Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include -#include -#include -#include "mem.h" -#include "log.h" -#include "hal.h" - -DBusConnection *pusb_hal_dbus_connect(void) -{ - DBusConnection *dbus = NULL; - DBusError error; - - dbus_error_init(&error); - if (!(dbus = dbus_bus_get(DBUS_BUS_SYSTEM, &error))) - { - /* Workaround for https://bugs.freedesktop.org/show_bug.cgi?id=11876 */ - uid_t ruid; - uid_t euid; - - if (!(euid = geteuid()) && (ruid = getuid())) - { - dbus_error_free(&error); - setreuid(euid, euid); - dbus = dbus_bus_get(DBUS_BUS_SYSTEM, &error); - setreuid(ruid, euid); - } - if (!dbus) - { - log_error("Cannot connect to system bus: %s\n", - error.message); - dbus_error_free(&error); - return (NULL); - } - } - return (dbus); -} - -void pusb_hal_dbus_disconnect(DBusConnection *dbus) -{ - dbus_connection_unref(dbus); -} - -void pusb_hal_free_string_array(char **str_array, int length) -{ - int i; - - if (str_array == NULL) - return ; - - for (i = 0; i < length; ++i) - xfree(str_array[i]); - xfree(str_array); -} - -char **pusb_hal_get_string_array_from_iter(DBusMessageIter *iter, int *num_elements) -{ - int count; - char **buffer; - - count = 0; - buffer = (char **)xmalloc(sizeof(char *) * 8); - - buffer[0] = NULL; - while (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_STRING || - dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_OBJECT_PATH) - { - const char *value; - - if ((count % 8) == 0 && count != 0) { - buffer = xrealloc(buffer, sizeof (char *) * (count + 8)); - } - - dbus_message_iter_get_basic(iter, &value); - buffer[count] = xstrdup(value); - - dbus_message_iter_next(iter); - count++; - } - - if (num_elements != NULL) - *num_elements = count; - return buffer; -} - - - -DBusMessage *pusb_hal_get_raw_property(DBusConnection *dbus, - const char *udi, - const char *name) -{ - DBusMessage *message; - DBusMessage *reply; - DBusMessageIter iter; - DBusError error; - char *iface = "org.freedesktop.UDisks.Device"; - - message = dbus_message_new_method_call("org.freedesktop.UDisks", udi, - "org.freedesktop.DBus.Properties", - "Get"); - if (message == NULL) { - log_error("Could not allocate D-BUS message\n"); - return (NULL); - } - dbus_message_iter_init_append(message, &iter); - dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &iface); - dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &name); - - dbus_error_init(&error); - reply = dbus_connection_send_with_reply_and_block(dbus, - message, -1, - &error); - dbus_message_unref(message); - if (dbus_error_is_set(&error)) { - log_error("Error communicating with D-BUS\n"); - return (NULL); - } - dbus_error_free(&error); - return (reply); -} - -char *pusb_hal_get_string_property(DBusConnection *dbus, - const char *udi, - const char *name) -{ - DBusMessage *reply; - DBusMessageIter reply_iter; - char *data; - char *dbus_str; - - reply = pusb_hal_get_raw_property(dbus, udi, name); - if (reply == NULL) { - return (NULL); - } - - dbus_message_iter_init(reply, &reply_iter); - - if (dbus_message_iter_get_arg_type(&reply_iter) != DBUS_TYPE_VARIANT) - { - dbus_message_unref(reply); - return (NULL); - } - - DBusMessageIter subiter; - dbus_message_iter_recurse(&reply_iter, &subiter); - dbus_message_iter_get_basic(&subiter, &dbus_str); - if (dbus_str != NULL) - data = xstrdup(dbus_str); - dbus_message_unref(reply); - return (data); -} - -char **pusb_hal_get_string_array_property(DBusConnection *dbus, - const char *udi, - const char *name, - int *n_items) -{ - DBusMessage *reply; - DBusMessageIter reply_iter; - char **items; - - reply = pusb_hal_get_raw_property(dbus, udi, name); - if (reply == NULL) { - return (NULL); - } - - dbus_message_iter_init(reply, &reply_iter); - - if (dbus_message_iter_get_arg_type(&reply_iter) != DBUS_TYPE_VARIANT) - { - dbus_message_unref(reply); - return (NULL); - } - - DBusMessageIter subiter, subsubiter; - dbus_message_iter_recurse(&reply_iter, &subiter); - dbus_message_iter_recurse(&subiter, &subsubiter); - items = pusb_hal_get_string_array_from_iter(&subsubiter, n_items); - dbus_message_unref(reply); - if (!*n_items) - { - pusb_hal_free_string_array(items, *n_items); - return (NULL); - } - return (items); -} - - - -int pusb_hal_get_bool_property(DBusConnection *dbus, - const char *udi, - const char *name, - dbus_bool_t *value) -{ - DBusMessage *reply; - DBusMessageIter reply_iter; - - reply = pusb_hal_get_raw_property(dbus, udi, name); - if (reply == NULL) { - return (0); - } - - dbus_message_iter_init(reply, &reply_iter); - - if (dbus_message_iter_get_arg_type(&reply_iter) != - DBUS_TYPE_VARIANT) - { - dbus_message_unref(reply); - return (0); - } - - DBusMessageIter subiter; - dbus_message_iter_recurse(&reply_iter, &subiter); - dbus_message_iter_get_basic(&subiter, value); - dbus_message_unref(reply); - return (1); -} - -int pusb_hal_check_property(DBusConnection *dbus, - const char *udi, - const char *name, - const char *value) -{ - char *data; - int retval; - - data = pusb_hal_get_string_property(dbus, udi, name); - if (!data) - return (0); - retval = (strcmp(data, value) == 0); - xfree(data); - return (retval); -} - -char **pusb_hal_find_all_items(DBusConnection *dbus, int *count) -{ - DBusError error; - DBusMessage *message; - DBusMessage *reply; - DBusMessageIter iter_array, reply_iter; - char **devices; - int n_devices; - - *count = 0; - message = dbus_message_new_method_call("org.freedesktop.UDisks", - "/org/freedesktop/UDisks", - "org.freedesktop.UDisks", - "EnumerateDevices"); - if (message == NULL) - { - log_error("Couldn't allocate D-BUS message\n"); - return (NULL); - } - dbus_error_init(&error); - reply = dbus_connection_send_with_reply_and_block(dbus, - message, -1, - &error); - dbus_message_unref(message); - if (dbus_error_is_set(&error)) { - log_error("Error communicating with D-BUS\n"); - return (NULL); - } - if (reply == NULL) { - return (NULL); - } - dbus_message_iter_init(reply, &reply_iter); - if (dbus_message_iter_get_arg_type(&reply_iter) != DBUS_TYPE_ARRAY) { - log_error("Malformed D-BUS reply"); - return (NULL); - } - dbus_message_iter_recurse(&reply_iter, &iter_array); - devices = pusb_hal_get_string_array_from_iter(&iter_array, &n_devices); - dbus_message_unref(reply); - if (!n_devices) - { - pusb_hal_free_string_array(devices, n_devices); - return (NULL); - } - *count = n_devices; - return (devices); -} - -char *pusb_hal_find_item(DBusConnection *dbus, - ...) -{ - char **devices; - int n_devices; - char *udi = NULL; - va_list ap; - int i; - - devices = pusb_hal_find_all_items(dbus, &n_devices); - if (!devices) - return (NULL); - if (!n_devices) - return (NULL); - - for (i = 0; i < n_devices; ++i) - { - char *key = NULL; - int match = 1; - - va_start(ap, dbus); - while ((key = va_arg(ap, char *))) - { - char *value = NULL; - - value = va_arg(ap, char *); - if (!value || *value == 0x0) - continue ; - if (!pusb_hal_check_property(dbus, devices[i], - key, value)) - { - match = 0; - break; - } - } - if (match) - { - udi = xstrdup(devices[i]); - break; - } - va_end(ap); - } - pusb_hal_free_string_array(devices, n_devices); - return (udi); -} diff --git a/src/hal.h b/src/hal.h deleted file mode 100644 index 78cbd0b..0000000 --- a/src/hal.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2003-2007 Andrea Luzzardi - * - * This file is part of the pam_usb project. pam_usb is free software; - * you can redistribute it and/or modify it under the terms of the GNU General - * Public License version 2, as published by the Free Software Foundation. - * - * pam_usb 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., 59 Temple - * Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef PUSB_HAL_H_ -# define PUSB_HAL_H_ -# include - -DBusConnection *pusb_hal_dbus_connect(void); -void pusb_hal_dbus_disconnect(DBusConnection *dbus); -char *pusb_hal_get_string_property(DBusConnection *dbus, const char *udi, const char *name); -int pusb_hal_get_bool_property(DBusConnection *dbus, const char *udi, const char *name, dbus_bool_t *value); -char **pusb_hal_get_string_array_property(DBusConnection *dbus, const char *udi, const char *name, int *n_items); -int pusb_hal_check_property(DBusConnection *dbus, const char *udi, const char *name, const char *value); -char *pusb_hal_find_item(DBusConnection *dbus, ...); -void pusb_hal_free_string_array(char **str_array, int length); - -#endif /* !PUSB_HAL_H_ */ diff --git a/src/pad.c b/src/pad.c index b1b54d1..c5c7699 100644 --- a/src/pad.c +++ b/src/pad.c @@ -1,4 +1,7 @@ +/* -*- mode: c; c-file-style: "bsd"; indent-tabs-mode: t; -*- */ + /* + * Copyright (c) 2016 Luka Novsak * Copyright (c) 2003-2007 Andrea Luzzardi * * This file is part of the pam_usb project. pam_usb is free software; @@ -15,6 +18,8 @@ * Place, Suite 330, Boston, MA 02111-1307 USA */ +#include "pad.h" + #include #include #include @@ -25,10 +30,10 @@ #include #include #include + #include "conf.h" #include "log.h" #include "volume.h" -#include "pad.h" static FILE *pusb_pad_open_device(t_pusb_options *opts, const char *mnt_point, @@ -262,20 +267,23 @@ static int pusb_pad_compare(t_pusb_options *opts, const char *volume, return (retval == 0); } -int pusb_pad_check(t_pusb_options *opts, DBusConnection *dbus, +int pusb_pad_check(t_pusb_options *opts, + UDisksClient *udisks, const char *user) { - char *volume = NULL; - int retval = 0; + t_pusb_volume *volume = NULL; + int retval = 0; - volume = pusb_volume_get(opts, dbus); + volume = pusb_volume_get(opts, udisks); if (!volume) return (0); - retval = pusb_pad_compare(opts, volume, user); + + retval = pusb_pad_compare(opts, volume->mount_point, user); if (retval) - pusb_pad_update(opts, volume, user); + pusb_pad_update(opts, volume->mount_point, user); else - log_error("Pad checking failed !\n"); + log_error("Pad checking failed!\n"); + pusb_volume_destroy(volume); return (retval); } diff --git a/src/pad.h b/src/pad.h index 6491c71..f161d90 100644 --- a/src/pad.h +++ b/src/pad.h @@ -17,7 +17,9 @@ #ifndef PUSB_OTP_H_ # define PUSB_OTP_H_ +# include +# include "conf.h" -int pusb_pad_check(t_pusb_options *opts, DBusConnection *dbus, const char *user); +int pusb_pad_check(t_pusb_options *opts, UDisksClient *udisks, const char *user); #endif /* !PUSB_OTP_H_ */ diff --git a/src/volume.c b/src/volume.c index c5a55e6..74555d9 100644 --- a/src/volume.c +++ b/src/volume.c @@ -1,4 +1,7 @@ +/* -*- mode: c; c-file-style: "bsd"; indent-tabs-mode: t; -*- */ + /* + * Copyright (c) 2016 Luka Novsak * Copyright (c) 2003-2007 Andrea Luzzardi * * This file is part of the pam_usb project. pam_usb is free software; @@ -24,145 +27,177 @@ #ifndef __GNU__ #include #endif + #include "mem.h" #include "conf.h" #include "log.h" -#include "hal.h" #include "volume.h" -static int pusb_volume_mount(t_pusb_options *opts, char *udi, - DBusConnection *dbus) +static int pusb_volume_mount(t_pusb_volume *volume) { - char command[1024]; - char tempname[32]; - const char *devname; + GError *error = NULL; + GVariant *options = NULL; + GVariantBuilder builder; + int retval = 0; + const gchar *const *mount_points = NULL; - snprintf(tempname, sizeof(tempname), "pam_usb%d", getpid()); - if (!(devname = pusb_hal_get_string_property(dbus, udi, "DeviceFile"))) - { - log_error("Unable to retrieve device filename\n"); - return (0); - } - log_debug("Attempting to mount device %s with label %s\n", - devname, tempname); - snprintf(command, sizeof(command), "pmount -A -s %s %s", - devname, tempname); - log_debug("Executing \"%s\"\n", command); - if (system(command) != 0) - { - log_error("Mount failed\n"); - return (0); - } + g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT); + options = g_variant_builder_end(&builder); - log_debug("Mount succeeded.\n"); - return (1); -} + log_debug("Attempting to mount device %s.\n", volume->device); -static char *pusb_volume_mount_path(t_pusb_options *opts, char *udi, DBusConnection* dbus) -{ - dbus_bool_t is_mounted; - if (!pusb_hal_get_bool_property(dbus, udi, "DeviceIsMounted", &is_mounted)) - { - return (NULL); - } - if (is_mounted != TRUE) + udisks_filesystem_call_mount_sync(volume->filesystem, + options, + &volume->mount_point, + NULL, + &error); + + if (!error) { - log_debug("Device %s is not mounted\n", udi); - return (NULL); + volume->unmount = 1; + retval = 1; + log_debug("Mounted device %s to %s.\n", + volume->device, volume->mount_point); } - - int n_mount; - char **mount_pathes = pusb_hal_get_string_array_property(dbus, udi, "DeviceMountPaths", &n_mount); - if (!mount_pathes) + else if (error->code == UDISKS_ERROR_ALREADY_MOUNTED) { - log_debug("Failed to retrieve device %s mount path\n", udi); - return (NULL); + g_main_context_iteration(NULL, FALSE); + mount_points = udisks_filesystem_get_mount_points(volume->filesystem); + volume->mount_point = xstrdup(*mount_points); + retval = 1; + log_debug("Device %s mounted in between our probe and mount.\n", + volume->device); } - if (n_mount > 1) + else { - log_debug("Device %s is mounted more than once\n", udi); + log_error("Failed to mount device %s.\n", volume->device); } - char *mount_path = xstrdup(mount_pathes[0]); - pusb_hal_free_string_array(mount_pathes, n_mount); - log_debug("Device %s is mounted on %s\n", udi, mount_path); - return (mount_path); + + if (error) + g_error_free(error); + + return (retval); } -static char *pusb_volume_probe(t_pusb_options *opts, - DBusConnection *dbus) +static t_pusb_volume *pusb_volume_probe(t_pusb_options *opts, + UDisksClient *udisks) { - int maxtries = 0; - int i; + t_pusb_volume *volume = NULL; + int maxtries = (opts->probe_timeout * 1000000) / 250000; + int i; + int j; + GList *blocks = NULL; + UDisksBlock *block = NULL; + UDisksObject *object = NULL; + const gchar *const *mount_points = NULL; if (!*(opts->device.volume_uuid)) { - log_debug("No UUID configured for device\n"); + log_debug("No UUID configured for device.\n"); return (NULL); } - log_debug("Searching for volume with uuid %s\n", opts->device.volume_uuid); - maxtries = ((opts->probe_timeout * 1000000) / 250000); + + log_debug("Searching for volume with uuid %s.\n", + opts->device.volume_uuid); + for (i = 0; i < maxtries; ++i) { - char *udi = NULL; + blocks = udisks_client_get_block_for_uuid(udisks, opts->device.volume_uuid); if (i == 1) log_info("Probing volume (this could take a while)...\n"); - udi = pusb_hal_find_item(dbus, - "IdUuid", opts->device.volume_uuid, - NULL); - if (!udi) + + for (j = 0; j < g_list_length(blocks); ++j) { - usleep(250000); - continue; + block = UDISKS_BLOCK(g_list_nth(blocks, j)->data); + object = UDISKS_OBJECT(g_dbus_interface_get_object(G_DBUS_INTERFACE(block))); + + if (udisks_object_peek_filesystem(object)) + { + volume = xmalloc(sizeof(t_pusb_volume)); + volume->filesystem = udisks_object_get_filesystem(object); + volume->unmount = 0; + volume->device = xstrdup(udisks_block_get_device(block)); + volume->mount_point = NULL; + + mount_points = udisks_filesystem_get_mount_points(volume->filesystem); + if (mount_points && *mount_points) + volume->mount_point = xstrdup(*mount_points); + + break; + } + } + + g_list_foreach (blocks, (GFunc) g_object_unref, NULL); + g_list_free (blocks); + + if (volume) + { + log_debug("Found volume %s.\n", opts->device.volume_uuid); + break; } - return (udi); + + usleep(250000); + g_main_context_iteration(NULL, FALSE); } - return (NULL); + + if (!volume) + log_debug("Could not find volume %s.\n", + opts->device.volume_uuid); + + return (volume); } -char *pusb_volume_get(t_pusb_options *opts, DBusConnection *dbus) +t_pusb_volume *pusb_volume_get(t_pusb_options *opts, UDisksClient *udisks) { - char *volume_udi; - char *mount_point; + t_pusb_volume *volume = pusb_volume_probe(opts, udisks); - if (!(volume_udi = pusb_volume_probe(opts, dbus))) + if (!volume) return (NULL); - log_debug("Found volume %s\n", opts->device.volume_uuid); - mount_point = pusb_volume_mount_path(opts, volume_udi, dbus); - if (mount_point) - { - log_debug("Volume is already mounted.\n"); - return (mount_point); - } - if (!pusb_volume_mount(opts, volume_udi, dbus)) + + if (volume->mount_point) { - xfree(volume_udi); - return (NULL); + log_debug("Volume %s is already mounted.\n", + opts->device.volume_uuid); + return (volume); } - mount_point = pusb_volume_mount_path(opts, volume_udi, dbus); - if (!mount_point) + + if(!pusb_volume_mount(volume)) { - log_error("Unable to retrieve %s mount point\n", volume_udi); - pusb_volume_destroy(mount_point); + pusb_volume_destroy(volume); return (NULL); } - return (mount_point); + + return (volume); } -void pusb_volume_destroy(char *mntpoint) +void pusb_volume_destroy(t_pusb_volume *volume) { - if (mntpoint && strstr(mntpoint, "pam_usb")) + GVariantBuilder builder; + GVariant *options; + int ret; + + if (volume->unmount) { - char command[1024]; - - log_debug("Attempting to umount %s\n", - mntpoint); - snprintf(command, sizeof(command), "pumount %s", mntpoint); - log_debug("Executing \"%s\"\n", command); - if (!system(command)) - log_debug("Umount succeeded.\n"); - else - log_error("Unable to umount %s\n", mntpoint); + g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT); + options = g_variant_builder_end(&builder); + + log_debug("Attempting to unmount %s from %s.\n", + volume->device, volume->mount_point); + + ret = udisks_filesystem_call_unmount_sync(volume->filesystem, + options, + NULL, + NULL); + if (!ret) + log_error("Unable to unmount %s from %s\n", + volume->device, volume->mount_point); + + log_debug("Unmount succeeded.\n"); } - xfree(mntpoint); + + g_object_unref(volume->filesystem); + xfree(volume->device); + xfree(volume->mount_point); + xfree(volume); } diff --git a/src/volume.h b/src/volume.h index f7c2fe0..3f83ef4 100644 --- a/src/volume.h +++ b/src/volume.h @@ -17,9 +17,18 @@ #ifndef VOLUME_H_ # define VOLUME_H_ -# include "hal.h" +# include +# include "conf.h" -char *pusb_volume_get(t_pusb_options *opts, DBusConnection *dbus); -void pusb_volume_destroy(char *mntpoint); +typedef struct pusb_volume +{ + UDisksFilesystem *filesystem; + int unmount; + char *device; + char *mount_point; +} t_pusb_volume; + +t_pusb_volume *pusb_volume_get(t_pusb_options *opts, UDisksClient *udisks); +void pusb_volume_destroy(t_pusb_volume *volume); #endif /* !VOLUME_H_ */ diff --git a/tools/pamusb-agent b/tools/pamusb-agent index ffb6b3d..c2f2144 100755 --- a/tools/pamusb-agent +++ b/tools/pamusb-agent @@ -20,10 +20,13 @@ import sys import pwd import getopt import syslog -import gobject -import dbus -if getattr(dbus, 'version', (0,0,0)) >= (0,41,0): - import dbus.glib +import gi + +gi.require_version('UDisks', '2.0') + +from gi.repository import GLib +from gi.repository import UDisks + try: # Python 2.5 import xml.etree.ElementTree as et @@ -39,41 +42,46 @@ class HotPlugDevice: self.__udi = None self.__serial = serial self.__callbacks = [] - self.__bus = dbus.SystemBus() self.__running = False def run(self): self.__scanDevices() self.__registerSignals() self.__running = True - gobject.MainLoop().run() + GLib.MainLoop().run() print 'signals registered' def addCallback(self, callback): self.__callbacks.append(callback) def __scanDevices(self): - halService = self.__bus.get_object('org.freedesktop.UDisks', - '/org/freedesktop/UDisks') - halManager = dbus.Interface(halService, 'org.freedesktop.UDisks') - for udi in halManager.EnumerateDevices(): - self.__deviceAdded(udi) + for udi in udisksObjectManager.get_objects(): + if udi.get_block(): + device = udisks.get_drive_for_block(udi.get_block()) + if device: + self.__deviceAdded(device) def __registerSignals(self): - halService = self.__bus.get_object('org.freedesktop.UDisks', - '/org/freedesktop/UDisks') - halManager = dbus.Interface(halService, 'org.freedesktop.UDisks') - for signal, callback in (('DeviceAdded', self.__deviceAdded), - ('DeviceRemoved', self.__deviceRemoved)): - halManager.connect_to_signal(signal, callback) + for signal, callback in (('object-added', self.__objectAdded), + ('object-removed', self.__objectRemoved)): + udisksObjectManager.connect(signal, callback) + + def __objectAdded(self, _, udi): + if udi.get_block(): + device = udisks.get_drive_for_block(udi.get_block()) + if device: + self.__deviceAdded(device) + + def __objectRemoved(self, _, udi): + if udi.get_block(): + device = udisks.get_drive_for_block(udi.get_block()) + if device: + self.__deviceRemoved(device) def __deviceAdded(self, udi): if self.__udi is not None: return - deviceObj = self.__bus.get_object('org.freedesktop.UDisks', - udi) - deviceProperties = dbus.Interface(deviceObj, dbus.PROPERTIES_IFACE) - if deviceProperties.Get('org.freedesktop.UDisks.Device', 'DriveSerial') != self.__serial: + if udi.get_property('serial') != self.__serial: return self.__udi = udi if self.__running: @@ -197,6 +205,9 @@ def authChangeCallback(event): logger.info('Authentication failed for device %s. ' \ 'Keeping user "%s" locked down.' % (deviceName, username)) +udisks = UDisks.Client.new_sync() +udisksObjectManager = udisks.get_object_manager() + hpDev = HotPlugDevice(serial) hpDev.addCallback(authChangeCallback) diff --git a/tools/pamusb-conf b/tools/pamusb-conf index 14cfe73..64aabda 100755 --- a/tools/pamusb-conf +++ b/tools/pamusb-conf @@ -15,40 +15,41 @@ # this program; if not, write to the Free Software Foundation, Inc., 59 Temple # Place, Suite 330, Boston, MA 02111-1307 USA - -import dbus import sys import os +import gi + +gi.require_version('UDisks', '2.0') + +from gi.repository import UDisks from xml.dom import minidom class Device: def __init__(self, udi): self.__udi = udi - deviceObj = bus.get_object('org.freedesktop.UDisks', - udi) - deviceProperties = dbus.Interface(deviceObj, dbus.PROPERTIES_IFACE) - if deviceProperties.Get('org.freedesktop.UDisks.Device', 'DeviceIsRemovable') != 1: + deviceObj = udisksObjectManager.get_object(udi) + driveObj = deviceObj.get_drive() + if not driveObj.get_property('removable'): # Workaround for removable devices with fixed media (such as SD cards) if not "mmcblk" in udi: raise Exception, 'Not a removable device' - self.vendor = deviceProperties.Get('org.freedesktop.UDisks.Device', 'DriveVendor') - self.product = deviceProperties.Get('org.freedesktop.UDisks.Device', 'DriveModel') - self.serialNumber = deviceProperties.Get('org.freedesktop.UDisks.Device', 'DriveSerial') + self.vendor = driveObj.get_property('vendor') + self.product = driveObj.get_property('model') + self.serialNumber = driveObj.get_property('serial') if len(self.volumes()) < 1: raise Exception, 'Device does not contain any volume' def volumes(self): vols = [] - for udi in halManager.get_dbus_method('EnumerateDevices')(): - deviceObj = bus.get_object('org.freedesktop.UDisks', - udi) - deviceProperties = dbus.Interface(deviceObj, dbus.PROPERTIES_IFACE) - if deviceProperties.Get('org.freedesktop.UDisks.Device', 'DeviceIsPartition') != 1: + for udi in [o.get_object_path() for o in udisksObjectManager.get_objects() if o.get_block()]: + obj = udisks.get_object(udi) + blockObj = obj.get_block() + if blockObj.get_property('drive') != self.__udi: continue - if deviceProperties.Get('org.freedesktop.UDisks.Device', 'PartitionSlave') != self.__udi: + if not obj.get_filesystem(): continue - vols.append({'uuid' : deviceProperties.Get('org.freedesktop.UDisks.Device', 'IdUuid'), - 'device' : deviceProperties.Get('org.freedesktop.UDisks.Device', 'DeviceFile')}) + vols.append({'uuid' : blockObj.get_property('id-uuid'), + 'device' : blockObj.get_property('device')}) return vols def __repr__(self): @@ -143,7 +144,7 @@ def addUser(options): def addDevice(options): devices = [] - for udi in halManager.get_dbus_method('EnumerateDevices')(): + for udi in [o.get_object_path() for o in udisksObjectManager.get_objects() if o.get_drive()]: try: if options['verbose']: print 'Inspecting %s' % udi @@ -259,10 +260,8 @@ if options['deviceName'] is None and options['userName'] is None: usage() if options['deviceName'] is not None: - bus = dbus.SystemBus() - halService = bus.get_object('org.freedesktop.UDisks', - '/org/freedesktop/UDisks') - halManager = dbus.Interface(halService, 'org.freedesktop.UDisks') + udisks = UDisks.Client.new_sync() + udisksObjectManager = udisks.get_object_manager() try: addDevice(options) except KeyboardInterrupt: