diff --git a/ChangeLog b/ChangeLog index 2de9d4e..f723e9e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +* 0.4.2 +- Added the pad_expiration option which tells pam_usb how often pads + should be updated in order to reduce device writing. +- Support for time options in the configuration parser (5s, 2h, 10m, etc) + * 0.4.1 - Fixed a security issue related to OpenSSH authentication - Fixed the quiet option (now it is really quiet) diff --git a/src/conf.c b/src/conf.c index 8775809..2457dad 100644 --- a/src/conf.c +++ b/src/conf.c @@ -44,7 +44,9 @@ static void pusb_conf_options_get_from(t_pusb_options *opts, &(opts->enable)); pusb_xpath_get_bool_from(doc, from, "option[@name='one_time_pad']", &(opts->one_time_pad)); - pusb_xpath_get_int_from(doc, from, "option[@name='probe_timeout']", + pusb_xpath_get_time_from(doc, from, "option[@name='pad_expiration']", + &(opts->pad_expiration)); + pusb_xpath_get_time_from(doc, from, "option[@name='probe_timeout']", &(opts->probe_timeout)); } @@ -136,6 +138,7 @@ int pusb_conf_init(t_pusb_options *opts) opts->quiet = 0; opts->color_log = 1; opts->one_time_pad = 1; + opts->pad_expiration = 86400; return (1); } diff --git a/src/conf.h b/src/conf.h index 4570048..d2dae23 100644 --- a/src/conf.h +++ b/src/conf.h @@ -24,6 +24,7 @@ # define CONF_USER_MAXLEN 32 # include # include +# include # ifndef PATH_MAX # define PATH_MAX 4096 # endif @@ -39,12 +40,13 @@ typedef struct pusb_device typedef struct pusb_options { - int probe_timeout; + time_t probe_timeout; int enable; int debug; int quiet; int color_log; int one_time_pad; + time_t pad_expiration; char hostname[32]; char system_pad_directory[PATH_MAX]; char device_pad_directory[PATH_MAX]; diff --git a/src/pad.c b/src/pad.c index 88d0fab..ff73a74 100644 --- a/src/pad.c +++ b/src/pad.c @@ -135,6 +135,49 @@ static int pusb_pad_protect(const char *user, int fd) return (1); } +static int pusb_pad_should_update(t_pusb_options *opts, const char *user) +{ + FILE *f_system = NULL; + struct stat st; + time_t now; + time_t delta; + + log_debug("Checking whether pads are expired or not..."); + if (!(f_system = pusb_pad_open_system(opts, user, "r"))) + { + log_debug("Unable to open system pad, pads must be generated.\n"); + return (1); + } + if (fstat(fileno(f_system), &st) == -1) + { + fclose(f_system); + return (1); + } + fclose(f_system); + + if (time(&now) == ((time_t)-1)) + { + log_error("Unable to fetch current time.\n"); + return (1); + } + + delta = now - st.st_mtime; + + if (delta > opts->pad_expiration) + { + log_info("Pads expired %u seconds ago, updating...\n", + delta - opts->pad_expiration); + return (1); + } + else + { + log_info("Pads were generated %u seconds ago, not updating.\n", + delta); + return (0); + } + return (1); +} + static void pusb_pad_update(t_pusb_options *opts, LibHalVolume *volume, const char *user) @@ -144,12 +187,15 @@ static void pusb_pad_update(t_pusb_options *opts, char magic[1024]; int i; + if (!pusb_pad_should_update(opts, user)) + return ; if (!(f_device = pusb_pad_open_device(opts, volume, user, "w+"))) { log_error("Unable to update pads.\n"); return ; } pusb_pad_protect(user, fileno(f_device)); + if (!(f_system = pusb_pad_open_system(opts, user, "w+"))) { log_error("Unable to update pads.\n"); @@ -157,6 +203,7 @@ static void pusb_pad_update(t_pusb_options *opts, return ; } pusb_pad_protect(user, fileno(f_system)); + log_debug("Generating %d bytes unique pad...\n", sizeof(magic)); srand(getpid() * time(NULL)); for (i = 0; i < sizeof(magic); ++i) diff --git a/src/pamusb-check.c b/src/pamusb-check.c index 6f8772f..b8b8e0b 100644 --- a/src/pamusb-check.c +++ b/src/pamusb-check.c @@ -35,7 +35,8 @@ static void pusb_check_conf_dump(t_pusb_options *opts, const char *username, fprintf(stdout, "color_log\t\t: %s\n", opts->color_log ? "true" : "false"); fprintf(stdout, "one_time_pad\t\t: %s\n", opts->one_time_pad ? "true" : "false"); - fprintf(stdout, "probe_timeout\t\t: %d\n", opts->probe_timeout); + fprintf(stdout, "pad_expiration\t\t: %u seconds\n", (unsigned int)opts->pad_expiration); + fprintf(stdout, "probe_timeout\t\t: %d seconds\n", (unsigned int)opts->probe_timeout); fprintf(stdout, "hostname\t\t: %s\n", opts->hostname); fprintf(stdout, "system_pad_directory\t: %s\n", opts->system_pad_directory); diff --git a/src/xpath.c b/src/xpath.c index cd2ffeb..27b88c8 100644 --- a/src/xpath.c +++ b/src/xpath.c @@ -179,14 +179,66 @@ int pusb_xpath_get_bool_from(xmlDocPtr doc, 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); +} + +int pusb_xpath_get_time(xmlDocPtr doc, const char *path, time_t *value) +{ + char ret[64]; + char *last; + int coef; + + if (!pusb_xpath_get_string(doc, path, ret, sizeof(ret))) + return (0); + + last = &(ret[strlen(ret) - 1]); + coef = 1; + if (*last == 's') + coef = 1; + else if (*last == 'm') + coef = 60; + else if (*last == 'h') + coef = 3600; + else if (*last == 'd') + coef = 3600 * 24; + else + if (!isdigit(*last)) + { + log_debug("Expecting a time modifier, got %c\n", *last); + return (0); + } + if (!isdigit(*last)) + *last = '\0'; + *value = atoi(ret) * coef; + + return (0); +} + +int pusb_xpath_get_time_from(xmlDocPtr doc, + const char *base, + const char *path, + time_t *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_time(doc, xpath, value); + free(xpath); return (retval); } int pusb_xpath_get_int(xmlDocPtr doc, const char *path, int *value) { - char ret[64]; /* strlen("false") + 1 */ + char ret[64]; if (!pusb_xpath_get_string(doc, path, ret, sizeof(ret))) return (0); @@ -213,7 +265,5 @@ int pusb_xpath_get_int_from(xmlDocPtr doc, snprintf(xpath, xpath_size, "%s%s", base, path); retval = pusb_xpath_get_int(doc, xpath, value); free(xpath); - if (retval) - log_debug("%s%s -> %d\n", base, path, *value); return (retval); } diff --git a/src/xpath.h b/src/xpath.h index fd6995d..1a74cbc 100644 --- a/src/xpath.h +++ b/src/xpath.h @@ -20,9 +20,11 @@ # include 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(xmlDocPtr doc, const char *path, int *value); int pusb_xpath_get_bool_from(xmlDocPtr doc, const char *base, const char *path, int *value); +int pusb_xpath_get_time(xmlDocPtr doc, const char *path, time_t *value); +int pusb_xpath_get_time_from(xmlDocPtr doc, const char *base, const char *path, time_t *value); int pusb_xpath_get_int(xmlDocPtr doc, const char *path, int *value); int pusb_xpath_get_int_from(xmlDocPtr doc, const char *base, const char *path, int *value);