Hardware authentication for Linux using ordinary USB Flash Drives.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

201 lines
4.8 KiB

8 years ago
13 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
  1. /*
  2. * Copyright (c) 2003-2007 Andrea Luzzardi <scox@sig11.org>
  3. *
  4. * This file is part of the pam_usb project. pam_usb is free software;
  5. * you can redistribute it and/or modify it under the terms of the GNU General
  6. * Public License version 2, as published by the Free Software Foundation.
  7. *
  8. * pam_usb is distributed in the hope that it will be useful, but WITHOUT ANY
  9. * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  10. * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
  11. * details.
  12. *
  13. * You should have received a copy of the GNU General Public License along with
  14. * this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
  15. * Street, Fifth Floor, Boston, MA 02110-1301 USA
  16. */
  17. #include <stdio.h>
  18. #include <string.h>
  19. #include <errno.h>
  20. #include <unistd.h>
  21. #include <stdlib.h>
  22. #include <sys/types.h>
  23. #ifndef __GNU__
  24. #include <sys/mount.h>
  25. #endif
  26. #include "mem.h"
  27. #include "conf.h"
  28. #include "log.h"
  29. #include "volume.h"
  30. static int pusb_volume_mount(t_pusb_volume *volume)
  31. {
  32. GError *error = NULL;
  33. GVariant *options = NULL;
  34. GVariantBuilder builder;
  35. int retval = 0;
  36. const gchar *const *mount_points = NULL;
  37. g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT);
  38. options = g_variant_builder_end(&builder);
  39. log_debug("Attempting to mount device %s.\n", volume->device);
  40. udisks_filesystem_call_mount_sync(volume->filesystem,
  41. options,
  42. &volume->mount_point,
  43. NULL,
  44. &error);
  45. if (!error)
  46. {
  47. volume->unmount = 1;
  48. retval = 1;
  49. log_debug("Mounted device %s to %s.\n",
  50. volume->device, volume->mount_point);
  51. }
  52. else if (error->code == UDISKS_ERROR_ALREADY_MOUNTED)
  53. {
  54. g_main_context_iteration(NULL, FALSE);
  55. mount_points = udisks_filesystem_get_mount_points(volume->filesystem);
  56. volume->mount_point = xstrdup(*mount_points);
  57. retval = 1;
  58. log_debug("Device %s mounted in between our probe and mount.\n",
  59. volume->device);
  60. }
  61. else
  62. {
  63. log_error("Failed to mount device %s.\n", volume->device);
  64. }
  65. if (error)
  66. g_error_free(error);
  67. return (retval);
  68. }
  69. static t_pusb_volume *pusb_volume_probe(t_pusb_options *opts,
  70. UDisksClient *udisks)
  71. {
  72. t_pusb_volume *volume = NULL;
  73. int maxtries = (opts->probe_timeout * 1000000) / 100000;
  74. int i;
  75. int j;
  76. GList *blocks = NULL;
  77. UDisksBlock *block = NULL;
  78. UDisksObject *object = NULL;
  79. const gchar *const *mount_points = NULL;
  80. if (!*(opts->device.volume_uuid))
  81. {
  82. log_debug("No UUID configured for device.\n");
  83. return (NULL);
  84. }
  85. log_debug("Searching for volume with uuid %s.\n",
  86. opts->device.volume_uuid);
  87. for (i = 0; i < maxtries; ++i)
  88. {
  89. blocks = udisks_client_get_block_for_uuid(udisks, opts->device.volume_uuid);
  90. if (i == 1)
  91. log_info("Probing volume (this could take a while)...\n");
  92. for (j = 0; j < g_list_length(blocks); ++j)
  93. {
  94. block = UDISKS_BLOCK(g_list_nth(blocks, j)->data);
  95. object = UDISKS_OBJECT(g_dbus_interface_get_object(G_DBUS_INTERFACE(block)));
  96. if (udisks_object_peek_filesystem(object))
  97. {
  98. volume = xmalloc(sizeof(t_pusb_volume));
  99. volume->filesystem = udisks_object_get_filesystem(object);
  100. volume->unmount = 0;
  101. volume->device = xstrdup(udisks_block_get_device(block));
  102. volume->mount_point = NULL;
  103. mount_points = udisks_filesystem_get_mount_points(volume->filesystem);
  104. log_debug("Found mount points: %s\n", *mount_points);
  105. if (mount_points && *mount_points)
  106. volume->mount_point = xstrdup(*mount_points);
  107. break;
  108. }
  109. }
  110. g_list_foreach (blocks, (GFunc) g_object_unref, NULL);
  111. g_list_free (blocks);
  112. if (volume)
  113. {
  114. log_debug("Found volume %s.\n", opts->device.volume_uuid);
  115. break;
  116. }
  117. usleep(100000);
  118. g_main_context_iteration(NULL, FALSE);
  119. }
  120. if (!volume)
  121. log_debug("Could not find volume %s.\n",
  122. opts->device.volume_uuid);
  123. return (volume);
  124. }
  125. t_pusb_volume *pusb_volume_get(t_pusb_options *opts, UDisksClient *udisks)
  126. {
  127. t_pusb_volume *volume = pusb_volume_probe(opts, udisks);
  128. if (!volume)
  129. return (NULL);
  130. if (volume->mount_point)
  131. {
  132. log_debug("Volume %s is already mounted.\n",
  133. opts->device.volume_uuid);
  134. return (volume);
  135. }
  136. if(!pusb_volume_mount(volume))
  137. {
  138. pusb_volume_destroy(volume);
  139. return (NULL);
  140. }
  141. return (volume);
  142. }
  143. void pusb_volume_destroy(t_pusb_volume *volume)
  144. {
  145. GVariantBuilder builder;
  146. GVariant *options;
  147. int ret;
  148. if (volume->unmount)
  149. {
  150. g_variant_builder_init(&builder, G_VARIANT_TYPE_VARDICT);
  151. options = g_variant_builder_end(&builder);
  152. log_debug("Attempting to unmount %s from %s.\n",
  153. volume->device, volume->mount_point);
  154. ret = udisks_filesystem_call_unmount_sync(volume->filesystem,
  155. options,
  156. NULL,
  157. NULL);
  158. if (!ret)
  159. log_error("Unable to unmount %s from %s\n",
  160. volume->device, volume->mount_point);
  161. log_debug("Unmount succeeded.\n");
  162. }
  163. g_object_unref(volume->filesystem);
  164. xfree(volume->device);
  165. xfree(volume->mount_point);
  166. xfree(volume);
  167. }