@ -0,0 +1,17 @@ | |||
SRC = test.c \ | |||
conf.c \ | |||
log.c \ | |||
xpath.c \ | |||
hal.c | |||
OBJ = $(SRC:.c=.o) | |||
NAME = test | |||
CC = gcc | |||
CFLAGS = -Wall `pkg-config --cflags hal` `pkg-config --cflags libxml-2.0` | |||
LDFLAGS = `pkg-config --libs hal` `pkg-config --libs libxml-2.0` | |||
all : $(NAME) | |||
$(NAME) : $(OBJ) | |||
$(CC) -o $(NAME) $(LDFLAGS) $(OBJ) | |||
clean : | |||
rm -f $(OBJ) |
@ -0,0 +1,169 @@ | |||
/* | |||
* Copyright (c) 2003-2006 Andrea Luzzardi <scox@sig11.org> | |||
* | |||
* 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 <unistd.h> | |||
#include <string.h> | |||
#include <errno.h> | |||
#include "conf.h" | |||
#include "xpath.h" | |||
#include "log.h" | |||
static void pusb_conf_options_get_from(t_pusb_options *opts, | |||
const char *from, | |||
xmlDoc *doc) | |||
{ | |||
pusb_xpath_get_string_from(doc, from, "option[@name='hostname']", | |||
opts->hostname, sizeof(opts->hostname)); | |||
pusb_xpath_get_bool_from(doc, from, "option[@name='debug']", | |||
&(opts->debug)); | |||
pusb_xpath_get_bool_from(doc, from, "option[@name='enable']", | |||
&(opts->enable)); | |||
pusb_xpath_get_bool_from(doc, from, "option[@name='try_otp']", | |||
&(opts->try_otp)); | |||
pusb_xpath_get_bool_from(doc, from, "option[@name='enforce_otp']", | |||
&(opts->enforce_otp)); | |||
} | |||
static int pusb_conf_parse_options(t_pusb_options *opts, | |||
xmlDoc *doc, | |||
const char *user, | |||
const char *service) | |||
{ | |||
char *xpath = NULL; | |||
size_t xpath_size; | |||
int i; | |||
struct s_opt_list opt_list[] = { | |||
{ CONF_DEVICE_XPATH, opts->device.name }, | |||
{ CONF_USER_XPATH, (char *)user }, | |||
{ CONF_SERVICE_XPATH, (char *)service }, | |||
{ NULL, NULL } | |||
}; | |||
pusb_conf_options_get_from(opts, "//configuration/defaults/", doc); | |||
for (i = 0; opt_list[i].name != NULL; ++i) | |||
{ | |||
xpath_size = strlen(opt_list[i].name) + strlen(opt_list[i].value) + 1; | |||
if (!(xpath = malloc(xpath_size))) | |||
{ | |||
log_error("malloc error\n"); | |||
return (0); | |||
} | |||
memset(xpath, 0x00, xpath_size); | |||
snprintf(xpath, xpath_size, opt_list[i].name, opt_list[i].value, ""); | |||
pusb_conf_options_get_from(opts, xpath, doc); | |||
free(xpath); | |||
} | |||
return (1); | |||
} | |||
static int pusb_conf_device_get_property(t_pusb_options *opts, | |||
xmlDoc *doc, | |||
const char *property, | |||
char *store, | |||
size_t size) | |||
{ | |||
char *xpath = NULL; | |||
size_t xpath_len; | |||
int retval; | |||
xpath_len = strlen(CONF_DEVICE_XPATH) + strlen(opts->device.name) + \ | |||
strlen(property) + 1; | |||
if (!(xpath = malloc(xpath_len))) | |||
{ | |||
log_error("malloc error!\n"); | |||
return (0); | |||
} | |||
memset(xpath, 0x00, xpath_len); | |||
snprintf(xpath, xpath_len, CONF_DEVICE_XPATH, opts->device.name, | |||
property); | |||
retval = pusb_xpath_get_string(doc, xpath, store, size); | |||
free(xpath); | |||
return (retval); | |||
} | |||
static int pusb_conf_parse_device(t_pusb_options *opts, xmlDoc *doc) | |||
{ | |||
log_debug("Parsing settings...\n"); | |||
if (!pusb_conf_device_get_property(opts, doc, "vendor", opts->device.vendor, | |||
sizeof(opts->device.vendor))) | |||
return (0); | |||
if (!pusb_conf_device_get_property(opts, doc, "model", opts->device.model, | |||
sizeof(opts->device.model))) | |||
return (0); | |||
if (!pusb_conf_device_get_property(opts, doc, "serial", opts->device.serial, | |||
sizeof(opts->device.serial))) | |||
return (0); | |||
return (1); | |||
} | |||
int pusb_conf_init(t_pusb_options *opts) | |||
{ | |||
memset(opts, 0x00, sizeof(*opts)); | |||
if (gethostname(opts->hostname, sizeof(opts->hostname)) == -1) | |||
{ | |||
log_error("gethostname: %s\n", strerror(errno)); | |||
return (0); | |||
} | |||
opts->enable = 1; | |||
opts->try_otp = 1; | |||
opts->enforce_otp = 0; | |||
opts->debug = 0; | |||
return (1); | |||
} | |||
int pusb_conf_parse(const char *file, t_pusb_options *opts, | |||
const char *user, const char *service) | |||
{ | |||
xmlDoc *doc = NULL; | |||
int retval; | |||
char device_xpath[sizeof(CONF_USER_XPATH) + CONF_USER_MAXLEN + \ | |||
sizeof("device")]; | |||
if (strlen(user) > CONF_USER_MAXLEN) | |||
{ | |||
log_error("Username \"%s\" is too long (max: %d)\n", user, | |||
CONF_USER_MAXLEN); | |||
return (0); | |||
} | |||
if (!(doc = xmlReadFile(file, NULL, 0))) | |||
{ | |||
log_error("Unable to parse \"%s\"\n", file); | |||
return (0); | |||
} | |||
snprintf(device_xpath, sizeof(device_xpath), CONF_USER_XPATH, user, | |||
"device"); | |||
retval = pusb_xpath_get_string(doc, | |||
device_xpath, | |||
opts->device.name, | |||
sizeof(opts->device.name)); | |||
if (!retval || !pusb_conf_parse_device(opts, doc)) | |||
{ | |||
log_error("No device found for user \"%s\"\n", user); | |||
xmlFreeDoc(doc); | |||
xmlCleanupParser(); | |||
return (0); | |||
} | |||
if (!pusb_conf_parse_options(opts, doc, user, service)) | |||
{ | |||
xmlFreeDoc(doc); | |||
xmlCleanupParser(); | |||
return (0); | |||
} | |||
xmlFreeDoc(doc); | |||
xmlCleanupParser(); | |||
return (1); | |||
} |
@ -0,0 +1,53 @@ | |||
/* | |||
* Copyright (c) 2003-2006 Andrea Luzzardi <scox@sig11.org> | |||
* | |||
* 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 | |||
*/ | |||
#ifndef PUSB_CONF_H_ | |||
# define PUSB_CONF_H_ | |||
# define CONF_DEVICE_XPATH "//configuration/devices/device[@id='%s']/%s" | |||
# define CONF_USER_XPATH "//configuration/users/user[@id='%s']/%s" | |||
# define CONF_SERVICE_XPATH "//configuration/services/service[@id='%s']/%s" | |||
# define CONF_USER_MAXLEN 32 | |||
typedef struct pusb_device | |||
{ | |||
char name[32]; | |||
char vendor[32]; | |||
char model[32]; | |||
char serial[64]; | |||
} t_pusb_device; | |||
typedef struct pusb_options | |||
{ | |||
int enable; | |||
int try_otp; | |||
int enforce_otp; | |||
int debug; | |||
char hostname[32]; | |||
t_pusb_device device; | |||
} t_pusb_options; | |||
struct s_opt_list | |||
{ | |||
char *name; | |||
char *value; | |||
}; | |||
int pusb_conf_init(t_pusb_options *opts); | |||
int pusb_conf_parse(const char *file, t_pusb_options *opts, | |||
const char *user, const char *service); | |||
#endif /* !PUSB_CONF_H_ */ |
@ -0,0 +1,42 @@ | |||
<configuration> | |||
<defaults> | |||
<option name="hostname">foobar</option> | |||
<option name="debug">true</option> | |||
<option name="try_otp">true</option> | |||
<option name="enforce_otp">false</option> | |||
</defaults> | |||
<devices> | |||
<device id="foobar"> | |||
<vendor>SanDisk Corp.</vendor> | |||
<model>Cruzer Titanium</model> | |||
<serial>SNDKB882652FC4A03701</serial> | |||
</device> | |||
</devices> | |||
<users> | |||
<user id="scox"> | |||
<device>foobar</device> | |||
</user> | |||
<user id="root"> | |||
<device>foobar</device> | |||
<option name="enforce_otp">true</option> | |||
</user> | |||
</users> | |||
<services> | |||
<!-- Disable pam_usb for sshd (nonsense) --> | |||
<service id="ssh"> | |||
<option name="enable">false</option> | |||
</service> | |||
<!-- Speed up 'login' authentication by disabling one time pads. | |||
This setting will not affect user 'root' as he/she is | |||
enforcing one time pads (enforce_otp). | |||
--> | |||
<service id="login"> | |||
<option name="try_otp">false</option> | |||
</service> | |||
</services> | |||
</configuration> |
@ -0,0 +1,159 @@ | |||
/* | |||
* Copyright (c) 2003-2006 Andrea Luzzardi <scox@sig11.org> | |||
* | |||
* 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 <string.h> | |||
#include <dbus/dbus.h> | |||
#include <libhal.h> | |||
#include "conf.h" | |||
#include "log.h" | |||
static DBusConnection *pusb_hal_dbus_connect(void) | |||
{ | |||
DBusConnection *dbus = NULL; | |||
DBusError error; | |||
dbus_error_init(&error); | |||
if (!(dbus = dbus_bus_get(DBUS_BUS_SYSTEM, &error))) | |||
{ | |||
log_error("Cannot connect to system bus: %s\n", | |||
error.message); | |||
dbus_error_free(&error); | |||
return (NULL); | |||
} | |||
return (dbus); | |||
} | |||
static void pusb_hal_dbus_disconnect(DBusConnection *dbus) | |||
{ | |||
dbus_connection_close(dbus); | |||
dbus_connection_unref(dbus); | |||
dbus_shutdown(); | |||
} | |||
static LibHalContext *pusb_hal_init(DBusConnection *dbus) | |||
{ | |||
DBusError error; | |||
LibHalContext *ctx = NULL; | |||
dbus_error_init(&error); | |||
if (!(ctx = libhal_ctx_new())) | |||
{ | |||
log_error("Failed to create a HAL context\n"); | |||
return (NULL); | |||
} | |||
if (!libhal_ctx_set_dbus_connection(ctx, dbus)) | |||
{ | |||
log_error("Failed to attach dbus connection to hal\n"); | |||
libhal_ctx_free(ctx); | |||
return (NULL); | |||
} | |||
if (!libhal_ctx_init(ctx, &error)) | |||
{ | |||
log_error("libhal_ctx_init: %s\n", error.name, error.message); | |||
libhal_ctx_free(ctx); | |||
return (NULL); | |||
} | |||
return (ctx); | |||
} | |||
static int pusb_hal_verify_model(LibHalContext *ctx, | |||
t_pusb_options *opts, | |||
const char *udi) | |||
{ | |||
DBusError error; | |||
char *data; | |||
int i; | |||
struct s_opt_list check_list[] = { | |||
{ "usb_device.vendor", opts->device.vendor }, | |||
{ "info.product", opts->device.model }, | |||
{ NULL, NULL } | |||
}; | |||
log_debug("Verifying model...\n"); | |||
dbus_error_init(&error); | |||
for (i = 0; check_list[i].name; ++i) | |||
{ | |||
data = libhal_device_get_property_string(ctx, udi, | |||
check_list[i].name, | |||
&error); | |||
if (!data) | |||
{ | |||
log_error("Cannot retrieve device %s: %s\n", | |||
check_list[i].name, | |||
error.message); | |||
dbus_error_free(&error); | |||
return (0); | |||
} | |||
if (strcmp(data, check_list[i].value) != 0) | |||
{ | |||
log_error("[KO]\t%s -> %s\n", check_list[i].name, data); | |||
libhal_free_string(data); | |||
return (0); | |||
} | |||
log_debug("[OK]\t%s -> %s \n", check_list[i].name, data); | |||
libhal_free_string(data); | |||
} | |||
return (1); | |||
} | |||
static int pusb_hal_find_device(LibHalContext *ctx, | |||
t_pusb_options *opts) | |||
{ | |||
DBusError error; | |||
char **devices; | |||
int n_devices; | |||
int retval = 0; | |||
dbus_error_init(&error); | |||
if (!(devices = libhal_manager_find_device_string_match(ctx, | |||
"usb_device.serial", | |||
opts->device.serial, | |||
&n_devices, | |||
&error))) | |||
{ | |||
log_error("Unable to find device \"%s\": %s\n", opts->device.name, | |||
error.message); | |||
dbus_error_free(&error); | |||
return (0); | |||
} | |||
if (n_devices > 0) | |||
{ | |||
log_debug("Device \"%s\" connected (S/N: %s)\n", opts->device.name, | |||
opts->device.serial); | |||
retval = pusb_hal_verify_model(ctx, opts, devices[0]); | |||
} | |||
else | |||
log_error("Device \"%s\" not connected\n", opts->device.name); | |||
libhal_free_string_array(devices); | |||
return (retval); | |||
} | |||
int pusb_hal_device_check(t_pusb_options *opts) | |||
{ | |||
DBusConnection *dbus; | |||
LibHalContext *ctx; | |||
int retval; | |||
if (!(dbus = pusb_hal_dbus_connect())) | |||
return (0); | |||
if (!(ctx = pusb_hal_init(dbus))) | |||
return (0); | |||
retval = pusb_hal_find_device(ctx, opts); | |||
pusb_hal_dbus_disconnect(dbus); | |||
libhal_ctx_free(ctx); | |||
return (retval); | |||
} |
@ -0,0 +1,23 @@ | |||
/* | |||
* Copyright (c) 2003-2006 Andrea Luzzardi <scox@sig11.org> | |||
* | |||
* 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 | |||
*/ | |||
#ifndef HAL_H_ | |||
# define HAL_H_ | |||
int pusb_hal_device_check(t_pusb_options *opts); | |||
#endif /* !HAL_H_ */ |
@ -0,0 +1,47 @@ | |||
/* | |||
* Copyright (c) 2003-2006 Andrea Luzzardi <scox@sig11.org> | |||
* | |||
* 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 <stdio.h> | |||
#include <stdarg.h> | |||
#include "log.h" | |||
void log_debug(const char *fmt, ...) | |||
{ | |||
va_list ap; | |||
va_start(ap, fmt); | |||
vfprintf(stderr, fmt, ap); | |||
va_end(ap); | |||
} | |||
void log_error(const char *fmt, ...) | |||
{ | |||
va_list ap; | |||
va_start(ap, fmt); | |||
vfprintf(stderr, fmt, ap); | |||
va_end(ap); | |||
} | |||
void log_verbose(const char *fmt, ...) | |||
{ | |||
va_list ap; | |||
va_start(ap, fmt); | |||
vfprintf(stderr, fmt, ap); | |||
va_end(ap); | |||
} |
@ -0,0 +1,25 @@ | |||
/* | |||
* Copyright (c) 2003-2006 Andrea Luzzardi <scox@sig11.org> | |||
* | |||
* 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 | |||
*/ | |||
#ifndef LOG_H_ | |||
# define LOG_H_ | |||
void log_debug(const char *fmt, ...); | |||
void log_error(const char *fmt, ...); | |||
void log_verbose(const char *fmt, ...); | |||
#endif /* !LOG_H_ */ |
@ -0,0 +1,54 @@ | |||
/* | |||
* Copyright (c) 2003-2006 Andrea Luzzardi <scox@sig11.org> | |||
* | |||
* 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 <stdio.h> | |||
#include "conf.h" | |||
#include "hal.h" | |||
#include "log.h" | |||
static void pusb_dump_conf(t_pusb_options *opts) | |||
{ | |||
printf("\nConfiguration dump:\n"); | |||
printf("enable:\t\t%d\n", opts->enable); | |||
printf("try_otp:\t%d\n", opts->try_otp); | |||
printf("enforce_otp:\t%d\n", opts->enforce_otp); | |||
printf("debug:\t\t%d\n", opts->debug); | |||
printf("hostname:\t%s\n", opts->hostname); | |||
} | |||
int main(int argc, char **argv) | |||
{ | |||
t_pusb_options opts; | |||
if (argc < 3) | |||
{ | |||
printf("Usage: %s <username> <service>\n", argv[0]); | |||
return (1); | |||
} | |||
pusb_conf_init(&opts); | |||
if (!pusb_conf_parse("conf.xml", &opts, argv[1], argv[2])) | |||
return (0); | |||
pusb_dump_conf(&opts); | |||
if (!opts.enable) | |||
{ | |||
printf("not enabled, exiting\n"); | |||
return (0); | |||
} | |||
printf("\n"); | |||
printf ("Access %s.\n", pusb_hal_device_check(&opts) ? "granted" : "denied"); | |||
return (0); | |||
} |
@ -0,0 +1,152 @@ | |||
/* | |||
* Copyright (c) 2003-2006 Andrea Luzzardi <scox@sig11.org> | |||
* | |||
* 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 <libxml/xpath.h> | |||
#include <string.h> | |||
#include "xpath.h" | |||
#include "log.h" | |||
static xmlXPathObject *pusb_xpath_match(xmlDocPtr doc, const char *path) | |||
{ | |||
xmlXPathContext *context = NULL; | |||
xmlXPathObject *result = NULL; | |||
context = xmlXPathNewContext(doc); | |||
if (context == NULL) | |||
{ | |||
log_error("Unable to create XML context\n"); | |||
return (NULL); | |||
} | |||
result = xmlXPathEvalExpression((xmlChar *)path, context); | |||
xmlXPathFreeContext(context); | |||
if (result == NULL) | |||
{ | |||
log_error("Error in xmlXPathEvalExpression\n"); | |||
return (NULL); | |||
} | |||
if (xmlXPathNodeSetIsEmpty(result->nodesetval)) | |||
{ | |||
xmlXPathFreeObject(result); | |||
return (NULL); | |||
} | |||
return (result); | |||
} | |||
int pusb_xpath_get_string(xmlDocPtr doc, const char *path, | |||
char *value, size_t size) | |||
{ | |||
xmlXPathObject *result = NULL; | |||
xmlNode *node = NULL; | |||
xmlChar *result_string = NULL; | |||
if (!(result = pusb_xpath_match(doc, path))) | |||
return (0); | |||
if (result->nodesetval->nodeNr > 1) | |||
{ | |||
xmlXPathFreeObject(result); | |||
log_debug("Syntax error: %s: more than one record found\n", path); | |||
return (0); | |||
} | |||
node = result->nodesetval->nodeTab[0]->xmlChildrenNode; | |||
result_string = xmlNodeListGetString(doc, node, 1); | |||
if (strlen((const char *)result_string) + 1 > size) | |||
{ | |||
xmlFree(result_string); | |||
xmlXPathFreeObject(result); | |||
log_debug("Result for %s (%s) is too long (max: %d)\n", | |||
path, (const char *)result_string, size); | |||
return (0); | |||
} | |||
memset(value, '\0', size); | |||
strncpy(value, (const char *)result_string, size); | |||
xmlFree(result_string); | |||
xmlXPathFreeObject(result); | |||
return (1); | |||
} | |||
int pusb_xpath_get_string_from(xmlDocPtr doc, | |||
const char *base, | |||
const char *path, | |||
char *value, size_t size) | |||
{ | |||
char *xpath = NULL; | |||
size_t xpath_size; | |||
int retval; | |||
xpath_size = strlen(base) + strlen(path) + 1; | |||
if (!(xpath = malloc(xpath_size))) | |||
{ | |||
log_error("malloc error !\n"); | |||
return (0); | |||
} | |||
memset(xpath, 0x00, xpath_size); | |||
snprintf(xpath, xpath_size, "%s%s", base, path); | |||
retval = pusb_xpath_get_string(doc, xpath, value, size); | |||
if (retval) | |||
log_debug("%s%s -> %s\n", base, path, value); | |||
free(xpath); | |||
return (retval); | |||
} | |||
int pusb_xpath_get_bool(xmlDocPtr doc, const char *path, int *value) | |||
{ | |||
char ret[6]; /* strlen("false") + 1 */ | |||
if (!pusb_xpath_get_string(doc, path, ret, sizeof(ret))) | |||
return (0); | |||
if (!strcmp(ret, "true")) | |||
{ | |||
*value = 1; | |||
return (1); | |||
} | |||
if (!strcmp(ret, "false")) | |||
{ | |||
*value = 0; | |||
return (1); | |||
} | |||
log_debug("Expecting a boolean, got %s\n", ret); | |||
return (0); | |||
} | |||
int pusb_xpath_get_bool_from(xmlDocPtr doc, | |||
const char *base, | |||
const char *path, | |||
int *value) | |||
{ | |||
char *xpath = NULL; | |||
size_t xpath_size; | |||
int retval; | |||
xpath_size = strlen(base) + strlen(path) + 1; | |||
if (!(xpath = malloc(xpath_size))) | |||
{ | |||
log_error("malloc error!\n"); | |||
return (0); | |||
} | |||
memset(xpath, 0x00, xpath_size); | |||
snprintf(xpath, xpath_size, "%s%s", base, path); | |||
retval = pusb_xpath_get_bool(doc, xpath, value); | |||
free(xpath); | |||
if (retval) | |||
log_debug("%s%s -> %s\n", base, path, *value ? "true" : "false"); | |||
return (retval); | |||
} |
@ -0,0 +1,29 @@ | |||
/* | |||
* Copyright (c) 2003-2006 Andrea Luzzardi <scox@sig11.org> | |||
* | |||
* 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 | |||
*/ | |||
#ifndef PUSB_XPATH_H_ | |||
# define PUSB_XPATH_H_ | |||
# include <libxml/parser.h> | |||
int pusb_xpath_get_string(xmlDocPtr doc, const char *path, char *value, | |||
size_t size); | |||
int pusb_xpath_get_bool(xmlDocPtr doc, const char *path, int *value); | |||
int pusb_xpath_get_string_from(xmlDocPtr doc, const char *base, | |||
const char *path, char *value, size_t size); | |||
int pusb_xpath_get_bool_from(xmlDocPtr doc, const char *base, const char *path, | |||
int *value); | |||
#endif /* !PUSB_XPATH_H_ */ |