-
Notifications
You must be signed in to change notification settings - Fork 85
port to udisks2 #31
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
port to udisks2 #31
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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> | ||
* | ||
* This file is part of the pam_usb project. pam_usb is free software; | ||
|
@@ -18,63 +21,81 @@ | |
#include <unistd.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
#include <dbus/dbus.h> | ||
#include "mem.h" | ||
|
||
#include <udisks/udisks.h> | ||
|
||
#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); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No extra space between function name and |
||
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 | ||
{ | ||
log_debug("One time pad is disabled, no more verifications to do.\n"); | ||
retval = 1; | ||
} | ||
|
||
pusb_hal_dbus_disconnect(dbus); | ||
g_object_unref(udisks); | ||
return (retval); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,6 +17,7 @@ | |
|
||
#ifndef PUSB_DEVICE_H_ | ||
# define PUSB_DEVICE_H_ | ||
# include "conf.h" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is this required here? Shouldn't it be in |
||
|
||
int pusb_device_check(t_pusb_options *opts, const char *user); | ||
|
||
|
This file was deleted.
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,7 @@ | ||
/* -*- mode: c; c-file-style: "bsd"; indent-tabs-mode: t; -*- */ | ||
|
||
/* | ||
* Copyright (c) 2016 Luka Novsak <lnovsak@gmail.com> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Copyrights shouldn't be updated on file changes. Git already tracks who contributed to the file. It's perfectly legitimate to take credit for all the amazing work you've done here, so maybe add an Or I'd be okay with removing the entire copyright notice altogether if you prefer. Appending names would get messy over time and also at this point doesn't reflect the tens of people who contributed to those files already. |
||
* Copyright (c) 2003-2007 Andrea Luzzardi <scox@sig11.org> | ||
* | ||
* 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" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why was By convention, local inclusion ( |
||
|
||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
|
@@ -25,10 +30,10 @@ | |
#include <fcntl.h> | ||
#include <pwd.h> | ||
#include <time.h> | ||
|
||
#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); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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> | ||
* | ||
* This file is part of the pam_usb project. pam_usb is free software; | ||
|
@@ -24,145 +27,177 @@ | |
#ifndef __GNU__ | ||
#include <sys/mount.h> | ||
#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); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why this sleep? |
||
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); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@luka-n, could you remove those? They are editor specific and I don't think they belong in the source file.