Port pamusb-agent and pamusb-conf to UDisks.
[pam_usb.git] / src / conf.c
blobf349a84e9e9af8c13c1b551f2f659bebffa1394f
1 /*
2 * Copyright (c) 2003-2007 Andrea Luzzardi <scox@sig11.org>
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.
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.
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
18 #include <sys/utsname.h>
19 #include <string.h>
20 #include <errno.h>
21 #include "conf.h"
22 #include "xpath.h"
23 #include "log.h"
25 static void pusb_conf_options_get_from(t_pusb_options *opts,
26 const char *from,
27 xmlDoc *doc)
29 pusb_xpath_get_string_from(doc, from, "option[@name='hostname']",
30 opts->hostname, sizeof(opts->hostname));
31 pusb_xpath_get_string_from(doc, from, "option[@name='system_pad_directory']",
32 opts->system_pad_directory,
33 sizeof(opts->system_pad_directory));
34 pusb_xpath_get_string_from(doc, from, "option[@name='device_pad_directory']",
35 opts->device_pad_directory,
36 sizeof(opts->device_pad_directory));
37 pusb_xpath_get_bool_from(doc, from, "option[@name='debug']",
38 &(opts->debug));
39 pusb_xpath_get_bool_from(doc, from, "option[@name='quiet']",
40 &(opts->quiet));
41 pusb_xpath_get_bool_from(doc, from, "option[@name='color_log']",
42 &(opts->color_log));
43 pusb_xpath_get_bool_from(doc, from, "option[@name='enable']",
44 &(opts->enable));
45 pusb_xpath_get_bool_from(doc, from, "option[@name='one_time_pad']",
46 &(opts->one_time_pad));
47 pusb_xpath_get_time_from(doc, from, "option[@name='pad_expiration']",
48 &(opts->pad_expiration));
49 pusb_xpath_get_time_from(doc, from, "option[@name='probe_timeout']",
50 &(opts->probe_timeout));
53 static int pusb_conf_parse_options(t_pusb_options *opts,
54 xmlDoc *doc,
55 const char *user,
56 const char *service)
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 }
68 pusb_conf_options_get_from(opts, "//configuration/defaults/", doc);
69 for (i = 0; opt_list[i].name != NULL; ++i)
71 xpath_size = strlen(opt_list[i].name) + strlen(opt_list[i].value) + 1;
72 if (!(xpath = malloc(xpath_size)))
74 log_error("malloc error\n");
75 return (0);
77 memset(xpath, 0x00, xpath_size);
78 snprintf(xpath, xpath_size, opt_list[i].name, opt_list[i].value, "");
79 pusb_conf_options_get_from(opts, xpath, doc);
80 free(xpath);
82 return (1);
85 static int pusb_conf_device_get_property(t_pusb_options *opts,
86 xmlDoc *doc,
87 const char *property,
88 char *store,
89 size_t size)
91 char *xpath = NULL;
92 size_t xpath_len;
93 int retval;
95 xpath_len = strlen(CONF_DEVICE_XPATH) + strlen(opts->device.name) + \
96 strlen(property) + 1;
97 if (!(xpath = malloc(xpath_len)))
99 log_error("malloc error!\n");
100 return (0);
102 memset(xpath, 0x00, xpath_len);
103 snprintf(xpath, xpath_len, CONF_DEVICE_XPATH, opts->device.name,
104 property);
105 retval = pusb_xpath_get_string(doc, xpath, store, size);
106 free(xpath);
107 return (retval);
110 static int pusb_conf_parse_device(t_pusb_options *opts, xmlDoc *doc)
112 pusb_conf_device_get_property(opts, doc, "vendor", opts->device.vendor,
113 sizeof(opts->device.vendor));
114 pusb_conf_device_get_property(opts, doc, "model", opts->device.model,
115 sizeof(opts->device.model));
116 if (!pusb_conf_device_get_property(opts, doc, "serial", opts->device.serial,
117 sizeof(opts->device.serial)))
118 return (0);
119 pusb_conf_device_get_property(opts, doc, "volume_uuid",
120 opts->device.volume_uuid,
121 sizeof(opts->device.volume_uuid));
122 return (1);
125 int pusb_conf_init(t_pusb_options *opts)
127 struct utsname u;
129 memset(opts, 0x00, sizeof(*opts));
130 if (uname(&u) == -1)
132 log_error("uname: %s\n", strerror(errno));
133 return (0);
135 strncpy(opts->hostname, u.nodename, sizeof(opts->hostname) - 1);
136 if (strlen(u.nodename) > sizeof(opts->hostname))
137 log_info("Hostname \"%s\" is too long, truncating to \"%s\".\n",
138 u.nodename, opts->hostname);
139 strcpy(opts->system_pad_directory, ".pamusb");
140 strcpy(opts->device_pad_directory, ".pamusb");
141 opts->probe_timeout = 10;
142 opts->enable = 1;
143 opts->debug = 0;
144 opts->quiet = 0;
145 opts->color_log = 1;
146 opts->one_time_pad = 1;
147 opts->pad_expiration = 3600;
148 return (1);
151 int pusb_conf_parse(const char *file, t_pusb_options *opts,
152 const char *user, const char *service)
154 xmlDoc *doc = NULL;
155 int retval;
156 char device_xpath[sizeof(CONF_USER_XPATH) + CONF_USER_MAXLEN + \
157 sizeof("device")];
159 log_debug("Parsing settings...\n",
160 user, service);
161 if (strlen(user) > CONF_USER_MAXLEN)
163 log_error("Username \"%s\" is too long (max: %d).\n", user,
164 CONF_USER_MAXLEN);
165 return (0);
167 if (!(doc = xmlReadFile(file, NULL, 0)))
169 log_error("Unable to parse \"%s\".\n", file);
170 return (0);
172 snprintf(device_xpath, sizeof(device_xpath), CONF_USER_XPATH, user,
173 "device");
174 retval = pusb_xpath_get_string(doc,
175 device_xpath,
176 opts->device.name,
177 sizeof(opts->device.name));
178 if (!retval || !pusb_conf_parse_device(opts, doc))
180 log_error("No device configured for user \"%s\".\n", user);
181 xmlFreeDoc(doc);
182 xmlCleanupParser();
183 return (0);
185 if (!pusb_conf_parse_options(opts, doc, user, service))
187 xmlFreeDoc(doc);
188 xmlCleanupParser();
189 return (0);
191 xmlFreeDoc(doc);
192 xmlCleanupParser();
193 return (1);