diff --git a/src/Makefile b/src/Makefile index 94f8430..9d6545e 100644 --- a/src/Makefile +++ b/src/Makefile @@ -3,7 +3,8 @@ SRC = test.c \ log.c \ xpath.c \ hal.c \ - otp.c + otp.c \ + device.c drive.c OBJ = $(SRC:.c=.o) NAME = test CC = gcc diff --git a/src/device.c b/src/device.c new file mode 100644 index 0000000..02f2101 --- /dev/null +++ b/src/device.c @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2003-2006 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 "conf.h" +#include "hal.h" +#include "log.h" +#include "otp.h" + +LibHalDrive *pusb_device_get_storage(t_pusb_options *opts, LibHalContext *ctx, + const char *udi) +{ + char *phy_udi = NULL; + char *storage_udi = NULL; + int maxloop = 0; + LibHalDrive *drive = NULL; + + log_debug("Waiting for device to come up...\n"); + while (!(phy_udi = pusb_hal_find_item(ctx, + "info.parent", udi, + "info.bus", "usb", + NULL))) + { + printf("loop\n"); + usleep(250000); + } + printf("phydev: %s\n", phy_udi); + maxloop = (10000000 / 250000); + while (maxloop > 0 && + (!(storage_udi = pusb_hal_find_item(ctx, + "storage.physical_device", phy_udi, + "info.category", "storage", + NULL)) || strstr(storage_udi, "temp"))) + { + if (storage_udi) + libhal_free_string(storage_udi); + printf("loop\n"); + printf("maxloop: %d\n", maxloop); + --maxloop; + usleep(250000); + } + printf("blockdev: %s\n", storage_udi); + libhal_free_string(phy_udi); + if (storage_udi) + { + drive = libhal_drive_from_udi(ctx, storage_udi); + printf("%s\n", storage_udi); + libhal_free_string(storage_udi); + } + return (drive); +} + +int pusb_device_check(t_pusb_options *opts) +{ + DBusConnection *dbus = NULL; + LibHalContext *ctx = NULL; + LibHalDrive *drive = NULL; + char *udi = NULL; + int retval = 0; + + if (!(dbus = pusb_hal_dbus_connect())) + return (0); + if (!(ctx = pusb_hal_init(dbus))) + { + pusb_hal_dbus_disconnect(dbus); + return (0); + } + + udi = pusb_hal_find_item(ctx, + "usb_device.serial", opts->device.serial, + "usb_device.vendor", opts->device.vendor, + "info.product", opts->device.model, + NULL); + if (!udi) + { + pusb_hal_dbus_disconnect(dbus); + libhal_ctx_free(ctx); + return (0); + } + log_debug("Valid device %s\n", udi); + if (!opts->try_otp && !opts->enforce_otp) + retval = 1; + else + { + if (!(drive = pusb_device_get_storage(opts, ctx, udi))) + retval = !opts->enforce_otp; + else + retval = pusb_otp_check(opts, ctx, drive); + } + libhal_free_string(udi); + pusb_hal_dbus_disconnect(dbus); + libhal_ctx_free(ctx); + return (retval); +} diff --git a/src/hal.c b/src/hal.c index c0feb70..aa50a96 100644 --- a/src/hal.c +++ b/src/hal.c @@ -16,14 +16,12 @@ */ #include +#include #include -#include #include -#include "conf.h" #include "log.h" -#include "otp.h" -static DBusConnection *pusb_hal_dbus_connect(void) +DBusConnection *pusb_hal_dbus_connect(void) { DBusConnection *dbus = NULL; DBusError error; @@ -39,14 +37,14 @@ static DBusConnection *pusb_hal_dbus_connect(void) return (dbus); } -static void pusb_hal_dbus_disconnect(DBusConnection *dbus) +void pusb_hal_dbus_disconnect(DBusConnection *dbus) { dbus_connection_close(dbus); dbus_connection_unref(dbus); dbus_shutdown(); } -static LibHalContext *pusb_hal_init(DBusConnection *dbus) +LibHalContext *pusb_hal_init(DBusConnection *dbus) { DBusError error; LibHalContext *ctx = NULL; @@ -72,83 +70,123 @@ static LibHalContext *pusb_hal_init(DBusConnection *dbus) return (ctx); } -static int pusb_hal_verify_model(LibHalDrive *drive, - t_pusb_options *opts) +void pusb_hal_destroy(LibHalContext *ctx) { - if (strcmp(libhal_drive_get_vendor(drive), - opts->device.vendor) != 0) - { - log_error("Vendor mismatch\n"); - return (0); - } - if (strcmp(libhal_drive_get_model(drive), - opts->device.model) != 0) + libhal_ctx_free(ctx); +} + +char *pusb_hal_get_property(LibHalContext *ctx, + const char *udi, + const char *name) +{ + DBusError error; + char *data; + + dbus_error_init(&error); + data = libhal_device_get_property_string(ctx, udi, + name, &error); + if (!data) { - log_error("Model mismatch\n"); - return (0); + log_error("Cannot retrieve device property %s for udi %s: %s\n", + name, udi, error.message); + dbus_error_free(&error); + return (NULL); } - return (1); + return (data); } -LibHalDrive *pusb_hal_find_drive(LibHalContext *ctx, - t_pusb_options *opts) +int pusb_hal_check_property(LibHalContext *ctx, + const char *udi, + const char *name, + const char *value) +{ + char *data; + int retval; + + data = pusb_hal_get_property(ctx, udi, name); + if (!data) + return (0); + retval = (strcmp(data, value) == 0); + libhal_free_string(data); + return (retval); +} + +char **pusb_hal_find_all_items(LibHalContext *ctx, + const char *property, + const char *value, + int *count) + { DBusError error; - LibHalDrive *retval = NULL; char **devices; int n_devices; dbus_error_init(&error); - if (!(devices = libhal_manager_find_device_string_match(ctx, - "storage.serial", - opts->device.serial, - &n_devices, - &error))) + *count = 0; + devices = libhal_manager_find_device_string_match(ctx, + property, + value, + &n_devices, + &error); + if (!devices) { - log_error("Unable to find device \"%s\": %s\n", opts->device.name, + log_error("Unable to find item \"%s\": %s\n", property, error.message); dbus_error_free(&error); return (NULL); } if (!n_devices) { - log_error("Device \"%s\" not connected\n", opts->device.name); libhal_free_string_array(devices); return (NULL); } - log_debug("Device \"%s\" connected (S/N: %s)\n", opts->device.name, - opts->device.serial); - retval = libhal_drive_from_udi(ctx, devices[0]); - libhal_free_string_array(devices); - if (!pusb_hal_verify_model(retval, opts)) - { - libhal_drive_free(retval); - return (NULL); - } - return (retval); + *count = n_devices; + return (devices); } -int pusb_hal_device_check(t_pusb_options *opts) +char *pusb_hal_find_item(LibHalContext *ctx, + const char *property, + const char *value, + ...) { - DBusConnection *dbus; - LibHalContext *ctx; - LibHalDrive *drive; - int retval; + char **devices; + int n_devices; + char *udi = NULL; + va_list ap; + int i; - if (!(dbus = pusb_hal_dbus_connect())) - return (0); - if (!(ctx = pusb_hal_init(dbus))) - return (0); - drive = pusb_hal_find_drive(ctx, opts); - if (!drive) + devices = pusb_hal_find_all_items(ctx, property, value, &n_devices); + if (!devices) + return (NULL); + if (!n_devices) + return (NULL); + + for (i = 0; i < n_devices; ++i) { - pusb_hal_dbus_disconnect(dbus); - libhal_ctx_free(ctx); - return (0); + char *key = NULL; + int match = 0; + + va_start(ap, value); + while ((key = va_arg(ap, char *))) + { + char *value = NULL; + + value = va_arg(ap, char *); + if (!pusb_hal_check_property(ctx, devices[i], + key, value)) + { + match = 0; + break; + } + match = 1; + } + if (match) + { + udi = strdup(devices[i]); + break; + } + va_end(ap); } - retval = pusb_otp_check(opts, ctx, drive); - libhal_drive_free(drive); - pusb_hal_dbus_disconnect(dbus); - libhal_ctx_free(ctx); - return (retval); + libhal_free_string_array(devices); + return (udi); } diff --git a/src/hal.h b/src/hal.h index 3b14aec..8ec479f 100644 --- a/src/hal.h +++ b/src/hal.h @@ -18,6 +18,20 @@ #ifndef HAL_H_ # define HAL_H_ -int pusb_hal_device_check(t_pusb_options *opts); +DBusConnection *pusb_hal_dbus_connect(void); +void pusb_hal_dbus_disconnect(DBusConnection *dbus); +LibHalContext *pusb_hal_init(DBusConnection *dbus); +void pusb_hal_destroy(LibHalContext *ctx); +char *pusb_hal_get_property(LibHalContext *ctx, + const char *udi, + const char *name); +int pusb_hal_check_property(LibHalContext *ctx, + const char *udi, + const char *name, + const char *value); +char *pusb_hal_find_item(LibHalContext *ctx, + const char *property, + const char *value, + ...); #endif /* !HAL_H_ */ diff --git a/src/otp.c b/src/otp.c index 6ae7828..cbed26e 100644 --- a/src/otp.c +++ b/src/otp.c @@ -114,7 +114,7 @@ static FILE *pusb_otp_open_system(t_pusb_options *opts, const char *mode) free(path); if (!f) { - log_error("Cannot open %s: %s\n", strerror(errno)); + log_error("Cannot open system file: %s\n", strerror(errno)); return (NULL); } return (f); @@ -158,12 +158,12 @@ static int pusb_otp_compare(t_pusb_options *opts, LibHalVolume *volume) int magic_system[1024]; int retval; - if (!(f_device = pusb_otp_open_device(opts, volume, "r"))) - return (!opts->enforce_otp); if (!(f_system = pusb_otp_open_system(opts, "r"))) + return (1); + if (!(f_device = pusb_otp_open_device(opts, volume, "r"))) { - fclose(f_device); - return (!opts->enforce_otp); + fclose(f_system); + return (0); } fread(magic_device, sizeof(int), sizeof(magic_device) / sizeof(int), f_device); fread(magic_system, sizeof(int), sizeof(magic_system) / sizeof(int), f_system); @@ -178,10 +178,18 @@ int pusb_otp_check(t_pusb_options *opts, LibHalContext *ctx, { LibHalVolume *volume = NULL; int retval; + int maxtries; + int i; - if (!opts->try_otp && !opts->enforce_otp) - return (1); - volume = pusb_otp_find_volume(opts, ctx, drive); + maxtries = (10000000 / 250000); + for (i = 0; i < maxtries; ++i) + { + printf("Waiting for volumes...\n"); + volume = pusb_otp_find_volume(opts, ctx, drive); + if (volume) + break; + usleep(250000); + } if (!volume) return (!opts->enforce_otp); log_debug("Checking one time pads... "); diff --git a/src/test.c b/src/test.c index 281cc5a..c59bedd 100644 --- a/src/test.c +++ b/src/test.c @@ -17,7 +17,6 @@ #include #include "conf.h" -#include "hal.h" #include "log.h" static void pusb_dump_conf(t_pusb_options *opts) @@ -49,6 +48,6 @@ int main(int argc, char **argv) return (0); } printf("\n"); - printf ("Access %s.\n", pusb_hal_device_check(&opts) ? "granted" : "denied"); + printf ("Access %s.\n", pusb_device_check(&opts) ? "granted" : "denied"); return (0); }