Browse Source

port to udisks2

master
Luka Novsak 9 years ago
parent
commit
1ccae6671c
11 changed files with 266 additions and 557 deletions
  1. +2
    -3
      Makefile
  2. +49
    -28
      src/device.c
  3. +1
    -0
      src/device.h
  4. +0
    -345
      src/hal.c
  5. +0
    -31
      src/hal.h
  6. +16
    -8
      src/pad.c
  7. +3
    -1
      src/pad.h
  8. +130
    -95
      src/volume.c
  9. +12
    -3
      src/volume.h
  10. +32
    -21
      tools/pamusb-agent
  11. +21
    -22
      tools/pamusb-conf

+ 2
- 3
Makefile View File

@ -7,16 +7,15 @@ LIBDIR ?= lib
# compiler/linker options # compiler/linker options
CC := gcc CC := gcc
CFLAGS := $(CFLAGS) -Wall -fPIC `pkg-config --cflags libxml-2.0` \ 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` \ LIBS := `pkg-config --libs libxml-2.0` \
`pkg-config --libs dbus-1`
`pkg-config --libs udisks2`
# common source files # common source files
SRCS := src/conf.c \ SRCS := src/conf.c \
src/mem.c \ src/mem.c \
src/log.c \ src/log.c \
src/xpath.c \ src/xpath.c \
src/hal.c \
src/pad.c \ src/pad.c \
src/volume.c \ src/volume.c \
src/local.c \ src/local.c \


+ 49
- 28
src/device.c View File

@ -1,4 +1,7 @@
/* -*- mode: c; c-file-style: "bsd"; indent-tabs-mode: t; -*- */
/* /*
* Copyright (c) 2016 Luka Novsak <lnovsak@gmail.com>
* Copyright (c) 2003-2007 Andrea Luzzardi <scox@sig11.org> * Copyright (c) 2003-2007 Andrea Luzzardi <scox@sig11.org>
* *
* This file is part of the pam_usb project. pam_usb is free software; * This file is part of the pam_usb project. pam_usb is free software;
@ -18,56 +21,74 @@
#include <unistd.h> #include <unistd.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <dbus/dbus.h>
#include "mem.h"
#include <udisks/udisks.h>
#include "conf.h" #include "conf.h"
#include "hal.h"
#include "log.h" #include "log.h"
#include "pad.h" #include "pad.h"
#include "device.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", log_debug("Searching for \"%s\" in the hardware database...\n",
opts->device.name); 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); return (0);
} }
if (opts->one_time_pad) if (opts->one_time_pad)
{ {
log_info("Performing one time pad verification...\n"); log_info("Performing one time pad verification...\n");
retval = pusb_pad_check(opts, dbus, user);
retval = pusb_pad_check(opts, udisks, user);
} }
else else
{ {
@ -75,6 +96,6 @@ int pusb_device_check(t_pusb_options *opts,
retval = 1; retval = 1;
} }
pusb_hal_dbus_disconnect(dbus);
g_object_unref(udisks);
return (retval); return (retval);
} }

+ 1
- 0
src/device.h View File

@ -17,6 +17,7 @@
#ifndef PUSB_DEVICE_H_ #ifndef PUSB_DEVICE_H_
# define PUSB_DEVICE_H_ # define PUSB_DEVICE_H_
# include "conf.h"
int pusb_device_check(t_pusb_options *opts, const char *user); int pusb_device_check(t_pusb_options *opts, const char *user);


+ 0
- 345
src/hal.c View File

@ -1,345 +0,0 @@
/*
* Copyright (c) 2003-2007 Andrea Luzzardi <scox@sig11.org>
*
* 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 <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <unistd.h>
#include <sys/types.h>
#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);
}

+ 0
- 31
src/hal.h View File

@ -1,31 +0,0 @@
/*
* Copyright (c) 2003-2007 Andrea Luzzardi <scox@sig11.org>
*
* 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 <dbus/dbus.h>
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_ */

+ 16
- 8
src/pad.c View File

@ -1,4 +1,7 @@
/* -*- mode: c; c-file-style: "bsd"; indent-tabs-mode: t; -*- */
/* /*
* Copyright (c) 2016 Luka Novsak <lnovsak@gmail.com>
* Copyright (c) 2003-2007 Andrea Luzzardi <scox@sig11.org> * Copyright (c) 2003-2007 Andrea Luzzardi <scox@sig11.org>
* *
* This file is part of the pam_usb project. pam_usb is free software; * 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 * Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
#include "pad.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -25,10 +30,10 @@
#include <fcntl.h> #include <fcntl.h>
#include <pwd.h> #include <pwd.h>
#include <time.h> #include <time.h>
#include "conf.h" #include "conf.h"
#include "log.h" #include "log.h"
#include "volume.h" #include "volume.h"
#include "pad.h"
static FILE *pusb_pad_open_device(t_pusb_options *opts, static FILE *pusb_pad_open_device(t_pusb_options *opts,
const char *mnt_point, const char *mnt_point,
@ -262,20 +267,23 @@ static int pusb_pad_compare(t_pusb_options *opts, const char *volume,
return (retval == 0); 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) 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) if (!volume)
return (0); return (0);
retval = pusb_pad_compare(opts, volume, user);
retval = pusb_pad_compare(opts, volume->mount_point, user);
if (retval) if (retval)
pusb_pad_update(opts, volume, user);
pusb_pad_update(opts, volume->mount_point, user);
else else
log_error("Pad checking failed !\n");
log_error("Pad checking failed!\n");
pusb_volume_destroy(volume); pusb_volume_destroy(volume);
return (retval); return (retval);
} }

+ 3
- 1
src/pad.h View File

@ -17,7 +17,9 @@
#ifndef PUSB_OTP_H_ #ifndef PUSB_OTP_H_
# define PUSB_OTP_H_ # define PUSB_OTP_H_
# include <udisks/udisks.h>
# 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_ */ #endif /* !PUSB_OTP_H_ */

+ 130
- 95
src/volume.c View File

@ -1,4 +1,7 @@
/* -*- mode: c; c-file-style: "bsd"; indent-tabs-mode: t; -*- */
/* /*
* Copyright (c) 2016 Luka Novsak <lnovsak@gmail.com>
* Copyright (c) 2003-2007 Andrea Luzzardi <scox@sig11.org> * Copyright (c) 2003-2007 Andrea Luzzardi <scox@sig11.org>
* *
* This file is part of the pam_usb project. pam_usb is free software; * This file is part of the pam_usb project. pam_usb is free software;
@ -24,145 +27,177 @@
#ifndef __GNU__ #ifndef __GNU__
#include <sys/mount.h> #include <sys/mount.h>
#endif #endif
#include "mem.h" #include "mem.h"
#include "conf.h" #include "conf.h"
#include "log.h" #include "log.h"
#include "hal.h"
#include "volume.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)) if (!*(opts->device.volume_uuid))
{ {
log_debug("No UUID configured for device\n");
log_debug("No UUID configured for device.\n");
return (NULL); 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) for (i = 0; i < maxtries; ++i)
{ {
char *udi = NULL;
blocks = udisks_client_get_block_for_uuid(udisks, opts->device.volume_uuid);
if (i == 1) if (i == 1)
log_info("Probing volume (this could take a while)...\n"); 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); 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 (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);
} }

+ 12
- 3
src/volume.h View File

@ -17,9 +17,18 @@
#ifndef VOLUME_H_ #ifndef VOLUME_H_
# define VOLUME_H_ # define VOLUME_H_
# include "hal.h"
# include <udisks/udisks.h>
# 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_ */ #endif /* !VOLUME_H_ */

+ 32
- 21
tools/pamusb-agent View File

@ -20,10 +20,13 @@ import sys
import pwd import pwd
import getopt import getopt
import syslog 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: try:
# Python 2.5 # Python 2.5
import xml.etree.ElementTree as et import xml.etree.ElementTree as et
@ -39,41 +42,46 @@ class HotPlugDevice:
self.__udi = None self.__udi = None
self.__serial = serial self.__serial = serial
self.__callbacks = [] self.__callbacks = []
self.__bus = dbus.SystemBus()
self.__running = False self.__running = False
def run(self): def run(self):
self.__scanDevices() self.__scanDevices()
self.__registerSignals() self.__registerSignals()
self.__running = True self.__running = True
gobject.MainLoop().run()
GLib.MainLoop().run()
print 'signals registered' print 'signals registered'
def addCallback(self, callback): def addCallback(self, callback):
self.__callbacks.append(callback) self.__callbacks.append(callback)
def __scanDevices(self): 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): 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): def __deviceAdded(self, udi):
if self.__udi is not None: if self.__udi is not None:
return 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 return
self.__udi = udi self.__udi = udi
if self.__running: if self.__running:
@ -197,6 +205,9 @@ def authChangeCallback(event):
logger.info('Authentication failed for device %s. ' \ logger.info('Authentication failed for device %s. ' \
'Keeping user "%s" locked down.' % (deviceName, username)) 'Keeping user "%s" locked down.' % (deviceName, username))
udisks = UDisks.Client.new_sync()
udisksObjectManager = udisks.get_object_manager()
hpDev = HotPlugDevice(serial) hpDev = HotPlugDevice(serial)
hpDev.addCallback(authChangeCallback) hpDev.addCallback(authChangeCallback)


+ 21
- 22
tools/pamusb-conf View File

@ -15,40 +15,41 @@
# this program; if not, write to the Free Software Foundation, Inc., 59 Temple # this program; if not, write to the Free Software Foundation, Inc., 59 Temple
# Place, Suite 330, Boston, MA 02111-1307 USA # Place, Suite 330, Boston, MA 02111-1307 USA
import dbus
import sys import sys
import os import os
import gi
gi.require_version('UDisks', '2.0')
from gi.repository import UDisks
from xml.dom import minidom from xml.dom import minidom
class Device: class Device:
def __init__(self, udi): def __init__(self, udi):
self.__udi = 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) # Workaround for removable devices with fixed media (such as SD cards)
if not "mmcblk" in udi: if not "mmcblk" in udi:
raise Exception, 'Not a removable device' 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: if len(self.volumes()) < 1:
raise Exception, 'Device does not contain any volume' raise Exception, 'Device does not contain any volume'
def volumes(self): def volumes(self):
vols = [] 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 continue
if deviceProperties.Get('org.freedesktop.UDisks.Device', 'PartitionSlave') != self.__udi:
if not obj.get_filesystem():
continue 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 return vols
def __repr__(self): def __repr__(self):
@ -143,7 +144,7 @@ def addUser(options):
def addDevice(options): def addDevice(options):
devices = [] 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: try:
if options['verbose']: if options['verbose']:
print 'Inspecting %s' % udi print 'Inspecting %s' % udi
@ -259,10 +260,8 @@ if options['deviceName'] is None and options['userName'] is None:
usage() usage()
if options['deviceName'] is not None: 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: try:
addDevice(options) addDevice(options)
except KeyboardInterrupt: except KeyboardInterrupt:


Loading…
Cancel
Save