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.

257 lines
5.7 KiB

17 years ago
13 years ago
13 years ago
13 years ago
13 years ago
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 <libxml/xpath.h>
  18. #include <ctype.h>
  19. #include <string.h>
  20. #include "mem.h"
  21. #include "xpath.h"
  22. #include "log.h"
  23. static xmlXPathObject *pusb_xpath_match(xmlDocPtr doc, const char *path)
  24. {
  25. xmlXPathContext *context = NULL;
  26. xmlXPathObject *result = NULL;
  27. context = xmlXPathNewContext(doc);
  28. if (context == NULL)
  29. {
  30. log_error("Unable to create XML context\n");
  31. return (NULL);
  32. }
  33. result = xmlXPathEvalExpression((xmlChar *)path, context);
  34. xmlXPathFreeContext(context);
  35. if (result == NULL)
  36. {
  37. log_error("Error in xmlXPathEvalExpression\n");
  38. return (NULL);
  39. }
  40. if (xmlXPathNodeSetIsEmpty(result->nodesetval))
  41. {
  42. xmlXPathFreeObject(result);
  43. return (NULL);
  44. }
  45. return (result);
  46. }
  47. static int pusb_xpath_strip_string(char *dest, const char *src,
  48. size_t size)
  49. {
  50. int first_char = -1;
  51. int last_char = -1;
  52. int i;
  53. for (i = 0; src[i]; ++i)
  54. {
  55. if (isspace(src[i]))
  56. continue ;
  57. if (first_char == -1)
  58. first_char = i;
  59. last_char = i;
  60. }
  61. if (first_char == -1 || last_char == -1)
  62. return (0);
  63. if ((last_char - first_char) > (size - 1))
  64. {
  65. log_error("Device name is too long: %s", src);
  66. return (0);
  67. }
  68. memset(dest, 0x0, size);
  69. strncpy(dest, &(src[first_char]), last_char - first_char + 1);
  70. return (1);
  71. }
  72. int pusb_xpath_get_string(xmlDocPtr doc, const char *path,
  73. char *value, size_t size)
  74. {
  75. xmlXPathObject *result = NULL;
  76. xmlNode *node = NULL;
  77. xmlChar *result_string = NULL;
  78. if (!(result = pusb_xpath_match(doc, path)))
  79. return (0);
  80. if (result->nodesetval->nodeNr > 1)
  81. {
  82. xmlXPathFreeObject(result);
  83. log_debug("Syntax error: %s: more than one record found\n", path);
  84. return (0);
  85. }
  86. node = result->nodesetval->nodeTab[0]->xmlChildrenNode;
  87. result_string = xmlNodeListGetString(doc, node, 1);
  88. if (!result_string)
  89. {
  90. xmlXPathFreeObject(result);
  91. log_debug("Empty value for %s\n", path);
  92. return (0);
  93. }
  94. if (!pusb_xpath_strip_string(value, (const char *)result_string, size))
  95. {
  96. xmlFree(result_string);
  97. xmlXPathFreeObject(result);
  98. log_debug("Result for %s (%s) is too long (max: %d)\n",
  99. path, (const char *)result_string, size);
  100. return (0);
  101. }
  102. xmlFree(result_string);
  103. xmlXPathFreeObject(result);
  104. return (1);
  105. }
  106. int pusb_xpath_get_string_from(xmlDocPtr doc,
  107. const char *base,
  108. const char *path,
  109. char *value, size_t size)
  110. {
  111. char *xpath = NULL;
  112. size_t xpath_size;
  113. int retval;
  114. xpath_size = strlen(base) + strlen(path) + 1;
  115. xpath = xmalloc(xpath_size);
  116. memset(xpath, 0x00, xpath_size);
  117. snprintf(xpath, xpath_size, "%s%s", base, path);
  118. retval = pusb_xpath_get_string(doc, xpath, value, size);
  119. if (retval)
  120. log_debug("%s%s -> %s\n", base, path, value);
  121. xfree(xpath);
  122. return (retval);
  123. }
  124. int pusb_xpath_get_bool(xmlDocPtr doc, const char *path, int *value)
  125. {
  126. char ret[6]; /* strlen("false") + 1 */
  127. if (!pusb_xpath_get_string(doc, path, ret, sizeof(ret)))
  128. return (0);
  129. if (!strcmp(ret, "true"))
  130. {
  131. *value = 1;
  132. return (1);
  133. }
  134. if (!strcmp(ret, "false"))
  135. {
  136. *value = 0;
  137. return (1);
  138. }
  139. log_debug("Expecting a boolean, got %s\n", ret);
  140. return (0);
  141. }
  142. int pusb_xpath_get_bool_from(xmlDocPtr doc,
  143. const char *base,
  144. const char *path,
  145. int *value)
  146. {
  147. char *xpath = NULL;
  148. size_t xpath_size;
  149. int retval;
  150. xpath_size = strlen(base) + strlen(path) + 1;
  151. xpath = xmalloc(xpath_size);
  152. memset(xpath, 0x00, xpath_size);
  153. snprintf(xpath, xpath_size, "%s%s", base, path);
  154. retval = pusb_xpath_get_bool(doc, xpath, value);
  155. xfree(xpath);
  156. return (retval);
  157. }
  158. int pusb_xpath_get_time(xmlDocPtr doc, const char *path, time_t *value)
  159. {
  160. char ret[64];
  161. char *last;
  162. int coef;
  163. if (!pusb_xpath_get_string(doc, path, ret, sizeof(ret)))
  164. return (0);
  165. last = &(ret[strlen(ret) - 1]);
  166. coef = 1;
  167. if (*last == 's')
  168. coef = 1;
  169. else if (*last == 'm')
  170. coef = 60;
  171. else if (*last == 'h')
  172. coef = 3600;
  173. else if (*last == 'd')
  174. coef = 3600 * 24;
  175. else
  176. if (!isdigit(*last))
  177. {
  178. log_debug("Expecting a time modifier, got %c\n", *last);
  179. return (0);
  180. }
  181. if (!isdigit(*last))
  182. *last = '\0';
  183. *value = atoi(ret) * coef;
  184. return (0);
  185. }
  186. int pusb_xpath_get_time_from(xmlDocPtr doc,
  187. const char *base,
  188. const char *path,
  189. time_t *value)
  190. {
  191. char *xpath = NULL;
  192. size_t xpath_size;
  193. int retval;
  194. xpath_size = strlen(base) + strlen(path) + 1;
  195. xpath = xmalloc(xpath_size);
  196. memset(xpath, 0x00, xpath_size);
  197. snprintf(xpath, xpath_size, "%s%s", base, path);
  198. retval = pusb_xpath_get_time(doc, xpath, value);
  199. xfree(xpath);
  200. return (retval);
  201. }
  202. int pusb_xpath_get_int(xmlDocPtr doc, const char *path, int *value)
  203. {
  204. char ret[64];
  205. if (!pusb_xpath_get_string(doc, path, ret, sizeof(ret)))
  206. return (0);
  207. *value = atoi(ret);
  208. return (1);
  209. }
  210. int pusb_xpath_get_int_from(xmlDocPtr doc,
  211. const char *base,
  212. const char *path,
  213. int *value)
  214. {
  215. char *xpath = NULL;
  216. size_t xpath_size;
  217. int retval;
  218. xpath_size = strlen(base) + strlen(path) + 1;
  219. xpath = xmalloc(xpath_size);
  220. memset(xpath, 0x00, xpath_size);
  221. snprintf(xpath, xpath_size, "%s%s", base, path);
  222. retval = pusb_xpath_get_int(doc, xpath, value);
  223. xfree(xpath);
  224. return (retval);
  225. }