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.

192 lines
4.8 KiB

  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., 59 Temple
  15. * Place, Suite 330, Boston, MA 02111-1307 USA
  16. */
  17. #include <libxml/xpath.h>
  18. #include <string.h>
  19. #include "xpath.h"
  20. #include "log.h"
  21. static xmlXPathObject *pusb_xpath_match(xmlDocPtr doc, const char *path)
  22. {
  23. xmlXPathContext *context = NULL;
  24. xmlXPathObject *result = NULL;
  25. context = xmlXPathNewContext(doc);
  26. if (context == NULL)
  27. {
  28. log_error("Unable to create XML context\n");
  29. return (NULL);
  30. }
  31. result = xmlXPathEvalExpression((xmlChar *)path, context);
  32. xmlXPathFreeContext(context);
  33. if (result == NULL)
  34. {
  35. log_error("Error in xmlXPathEvalExpression\n");
  36. return (NULL);
  37. }
  38. if (xmlXPathNodeSetIsEmpty(result->nodesetval))
  39. {
  40. xmlXPathFreeObject(result);
  41. return (NULL);
  42. }
  43. return (result);
  44. }
  45. int pusb_xpath_get_string(xmlDocPtr doc, const char *path,
  46. char *value, size_t size)
  47. {
  48. xmlXPathObject *result = NULL;
  49. xmlNode *node = NULL;
  50. xmlChar *result_string = NULL;
  51. if (!(result = pusb_xpath_match(doc, path)))
  52. return (0);
  53. if (result->nodesetval->nodeNr > 1)
  54. {
  55. xmlXPathFreeObject(result);
  56. log_debug("Syntax error: %s: more than one record found\n", path);
  57. return (0);
  58. }
  59. node = result->nodesetval->nodeTab[0]->xmlChildrenNode;
  60. result_string = xmlNodeListGetString(doc, node, 1);
  61. if (!result_string)
  62. {
  63. xmlXPathFreeObject(result);
  64. log_debug("Empty value for %s\n", path);
  65. return (0);
  66. }
  67. if (strlen((const char *)result_string) + 1 > size)
  68. {
  69. xmlFree(result_string);
  70. xmlXPathFreeObject(result);
  71. log_debug("Result for %s (%s) is too long (max: %d)\n",
  72. path, (const char *)result_string, size);
  73. return (0);
  74. }
  75. memset(value, '\0', size);
  76. strncpy(value, (const char *)result_string, size);
  77. xmlFree(result_string);
  78. xmlXPathFreeObject(result);
  79. return (1);
  80. }
  81. int pusb_xpath_get_string_from(xmlDocPtr doc,
  82. const char *base,
  83. const char *path,
  84. char *value, size_t size)
  85. {
  86. char *xpath = NULL;
  87. size_t xpath_size;
  88. int retval;
  89. xpath_size = strlen(base) + strlen(path) + 1;
  90. if (!(xpath = malloc(xpath_size)))
  91. {
  92. log_error("malloc error !\n");
  93. return (0);
  94. }
  95. memset(xpath, 0x00, xpath_size);
  96. snprintf(xpath, xpath_size, "%s%s", base, path);
  97. retval = pusb_xpath_get_string(doc, xpath, value, size);
  98. if (retval)
  99. log_debug("%s%s -> %s\n", base, path, value);
  100. free(xpath);
  101. return (retval);
  102. }
  103. int pusb_xpath_get_bool(xmlDocPtr doc, const char *path, int *value)
  104. {
  105. char ret[6]; /* strlen("false") + 1 */
  106. if (!pusb_xpath_get_string(doc, path, ret, sizeof(ret)))
  107. return (0);
  108. if (!strcmp(ret, "true"))
  109. {
  110. *value = 1;
  111. return (1);
  112. }
  113. if (!strcmp(ret, "false"))
  114. {
  115. *value = 0;
  116. return (1);
  117. }
  118. log_debug("Expecting a boolean, got %s\n", ret);
  119. return (0);
  120. }
  121. int pusb_xpath_get_bool_from(xmlDocPtr doc,
  122. const char *base,
  123. const char *path,
  124. int *value)
  125. {
  126. char *xpath = NULL;
  127. size_t xpath_size;
  128. int retval;
  129. xpath_size = strlen(base) + strlen(path) + 1;
  130. if (!(xpath = malloc(xpath_size)))
  131. {
  132. log_error("malloc error!\n");
  133. return (0);
  134. }
  135. memset(xpath, 0x00, xpath_size);
  136. snprintf(xpath, xpath_size, "%s%s", base, path);
  137. retval = pusb_xpath_get_bool(doc, xpath, value);
  138. free(xpath);
  139. if (retval)
  140. log_debug("%s%s -> %s\n", base, path, *value ? "true" : "false");
  141. return (retval);
  142. }
  143. int pusb_xpath_get_int(xmlDocPtr doc, const char *path, int *value)
  144. {
  145. char ret[64]; /* strlen("false") + 1 */
  146. if (!pusb_xpath_get_string(doc, path, ret, sizeof(ret)))
  147. return (0);
  148. *value = atoi(ret);
  149. return (1);
  150. }
  151. int pusb_xpath_get_int_from(xmlDocPtr doc,
  152. const char *base,
  153. const char *path,
  154. int *value)
  155. {
  156. char *xpath = NULL;
  157. size_t xpath_size;
  158. int retval;
  159. xpath_size = strlen(base) + strlen(path) + 1;
  160. if (!(xpath = malloc(xpath_size)))
  161. {
  162. log_error("malloc error!\n");
  163. return (0);
  164. }
  165. memset(xpath, 0x00, xpath_size);
  166. snprintf(xpath, xpath_size, "%s%s", base, path);
  167. retval = pusb_xpath_get_int(doc, xpath, value);
  168. free(xpath);
  169. if (retval)
  170. log_debug("%s%s -> %d\n", base, path, *value);
  171. return (retval);
  172. }