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.

190 lines
5.6 KiB

13 years ago
13 years ago
13 years ago
13 years ago
13 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 <sys/utsname.h>
  18. #include <string.h>
  19. #include <errno.h>
  20. #include "mem.h"
  21. #include "conf.h"
  22. #include "xpath.h"
  23. #include "log.h"
  24. static void pusb_conf_options_get_from(t_pusb_options *opts,
  25. const char *from,
  26. xmlDoc *doc)
  27. {
  28. pusb_xpath_get_string_from(doc, from, "option[@name='hostname']",
  29. opts->hostname, sizeof(opts->hostname));
  30. pusb_xpath_get_string_from(doc, from, "option[@name='system_pad_directory']",
  31. opts->system_pad_directory,
  32. sizeof(opts->system_pad_directory));
  33. pusb_xpath_get_string_from(doc, from, "option[@name='device_pad_directory']",
  34. opts->device_pad_directory,
  35. sizeof(opts->device_pad_directory));
  36. pusb_xpath_get_bool_from(doc, from, "option[@name='debug']",
  37. &(opts->debug));
  38. pusb_xpath_get_bool_from(doc, from, "option[@name='quiet']",
  39. &(opts->quiet));
  40. pusb_xpath_get_bool_from(doc, from, "option[@name='color_log']",
  41. &(opts->color_log));
  42. pusb_xpath_get_bool_from(doc, from, "option[@name='enable']",
  43. &(opts->enable));
  44. pusb_xpath_get_bool_from(doc, from, "option[@name='one_time_pad']",
  45. &(opts->one_time_pad));
  46. pusb_xpath_get_time_from(doc, from, "option[@name='pad_expiration']",
  47. &(opts->pad_expiration));
  48. pusb_xpath_get_time_from(doc, from, "option[@name='probe_timeout']",
  49. &(opts->probe_timeout));
  50. pusb_xpath_get_bool_from(doc, from, "option[@name='deny_remote']",
  51. &(opts->deny_remote));
  52. }
  53. static int pusb_conf_parse_options(t_pusb_options *opts,
  54. xmlDoc *doc,
  55. const char *user,
  56. const char *service)
  57. {
  58. char *xpath = NULL;
  59. size_t xpath_size;
  60. int i;
  61. struct s_opt_list opt_list[] = {
  62. { CONF_DEVICE_XPATH, opts->device.name },
  63. { CONF_USER_XPATH, (char *)user },
  64. { CONF_SERVICE_XPATH, (char *)service },
  65. { NULL, NULL }
  66. };
  67. pusb_conf_options_get_from(opts, "//configuration/defaults/", doc);
  68. for (i = 0; opt_list[i].name != NULL; ++i)
  69. {
  70. xpath_size = strlen(opt_list[i].name) + strlen(opt_list[i].value) + 1;
  71. xpath = xmalloc(xpath_size);
  72. memset(xpath, 0x00, xpath_size);
  73. snprintf(xpath, xpath_size, opt_list[i].name, opt_list[i].value, "");
  74. pusb_conf_options_get_from(opts, xpath, doc);
  75. xfree(xpath);
  76. }
  77. return (1);
  78. }
  79. static int pusb_conf_device_get_property(t_pusb_options *opts,
  80. xmlDoc *doc,
  81. const char *property,
  82. char *store,
  83. size_t size)
  84. {
  85. char *xpath = NULL;
  86. size_t xpath_len;
  87. int retval;
  88. xpath_len = strlen(CONF_DEVICE_XPATH) + strlen(opts->device.name) + \
  89. strlen(property) + 1;
  90. xpath = xmalloc(xpath_len);
  91. memset(xpath, 0x00, xpath_len);
  92. snprintf(xpath, xpath_len, CONF_DEVICE_XPATH, opts->device.name,
  93. property);
  94. retval = pusb_xpath_get_string(doc, xpath, store, size);
  95. xfree(xpath);
  96. return (retval);
  97. }
  98. static int pusb_conf_parse_device(t_pusb_options *opts, xmlDoc *doc)
  99. {
  100. pusb_conf_device_get_property(opts, doc, "vendor", opts->device.vendor,
  101. sizeof(opts->device.vendor));
  102. pusb_conf_device_get_property(opts, doc, "model", opts->device.model,
  103. sizeof(opts->device.model));
  104. if (!pusb_conf_device_get_property(opts, doc, "serial", opts->device.serial,
  105. sizeof(opts->device.serial)))
  106. return (0);
  107. pusb_conf_device_get_property(opts, doc, "volume_uuid",
  108. opts->device.volume_uuid,
  109. sizeof(opts->device.volume_uuid));
  110. return (1);
  111. }
  112. int pusb_conf_init(t_pusb_options *opts)
  113. {
  114. struct utsname u;
  115. memset(opts, 0x00, sizeof(*opts));
  116. if (uname(&u) == -1)
  117. {
  118. log_error("uname: %s\n", strerror(errno));
  119. return (0);
  120. }
  121. strncpy(opts->hostname, u.nodename, sizeof(opts->hostname) - 1);
  122. if (strlen(u.nodename) > sizeof(opts->hostname))
  123. log_info("Hostname \"%s\" is too long, truncating to \"%s\".\n",
  124. u.nodename, opts->hostname);
  125. strcpy(opts->system_pad_directory, ".pamusb");
  126. strcpy(opts->device_pad_directory, ".pamusb");
  127. opts->probe_timeout = 10;
  128. opts->enable = 1;
  129. opts->debug = 0;
  130. opts->quiet = 0;
  131. opts->color_log = 1;
  132. opts->one_time_pad = 1;
  133. opts->pad_expiration = 3600;
  134. opts->deny_remote = 1;
  135. return (1);
  136. }
  137. int pusb_conf_parse(const char *file, t_pusb_options *opts,
  138. const char *user, const char *service)
  139. {
  140. xmlDoc *doc = NULL;
  141. int retval;
  142. char device_xpath[sizeof(CONF_USER_XPATH) + CONF_USER_MAXLEN + \
  143. sizeof("device")];
  144. log_debug("Parsing settings...\n",
  145. user, service);
  146. if (strlen(user) > CONF_USER_MAXLEN)
  147. {
  148. log_error("Username \"%s\" is too long (max: %d).\n", user,
  149. CONF_USER_MAXLEN);
  150. return (0);
  151. }
  152. if (!(doc = xmlReadFile(file, NULL, 0)))
  153. {
  154. log_error("Unable to parse \"%s\".\n", file);
  155. return (0);
  156. }
  157. snprintf(device_xpath, sizeof(device_xpath), CONF_USER_XPATH, user,
  158. "device");
  159. retval = pusb_xpath_get_string(doc,
  160. device_xpath,
  161. opts->device.name,
  162. sizeof(opts->device.name));
  163. if (!retval || !pusb_conf_parse_device(opts, doc))
  164. {
  165. log_error("No device configured for user \"%s\".\n", user);
  166. xmlFreeDoc(doc);
  167. xmlCleanupParser();
  168. return (0);
  169. }
  170. if (!pusb_conf_parse_options(opts, doc, user, service))
  171. {
  172. xmlFreeDoc(doc);
  173. xmlCleanupParser();
  174. return (0);
  175. }
  176. xmlFreeDoc(doc);
  177. xmlCleanupParser();
  178. return (1);
  179. }