mirror of
https://github.com/Yubico/yubico-pam.git
synced 2025-02-27 06:54:15 +01:00
add a username switch to ykpamcfg, creating file for different user
also refactor to use a tempfile when writing a new challenge file so we rename it to the correct name as the last operation. fixes #113
This commit is contained in:
parent
6ef497da42
commit
340386f640
@ -8,7 +8,7 @@ YKPAMCFG(1)
|
|||||||
ykpamcfg - Manage user settings for the Yubico PAM module
|
ykpamcfg - Manage user settings for the Yubico PAM module
|
||||||
|
|
||||||
== SYNOPSIS
|
== SYNOPSIS
|
||||||
*ykmapcfg* [-1 | -2] [-A] [-p] [-i] [-v] [-V] [-h]
|
*ykmapcfg* [-1 | -2] [-A] [-p] [-i] [-u] [-v] [-V] [-h]
|
||||||
|
|
||||||
== OPTIONS
|
== OPTIONS
|
||||||
*-1*::
|
*-1*::
|
||||||
@ -26,6 +26,9 @@ specify output directory, default is ~/.yubico/
|
|||||||
*-i* _iterations_::
|
*-i* _iterations_::
|
||||||
number of iterations to use for pbkdf2 of expected response
|
number of iterations to use for pbkdf2 of expected response
|
||||||
|
|
||||||
|
*-u* _username_::
|
||||||
|
username to use for created file, defaults to current user
|
||||||
|
|
||||||
*-v*::
|
*-v*::
|
||||||
enable verbose mode.
|
enable verbose mode.
|
||||||
|
|
||||||
|
81
ykpamcfg.c
81
ykpamcfg.c
@ -46,6 +46,8 @@
|
|||||||
#define ACTION_ADD_HMAC_CHALRESP "add_hmac_chalresp"
|
#define ACTION_ADD_HMAC_CHALRESP "add_hmac_chalresp"
|
||||||
#define ACTION_MAX_LEN 1024
|
#define ACTION_MAX_LEN 1024
|
||||||
|
|
||||||
|
#define TMPFILE_SUFFIX ".XXXXXX"
|
||||||
|
|
||||||
const char *usage =
|
const char *usage =
|
||||||
"Usage: ykpamcfg [options]\n"
|
"Usage: ykpamcfg [options]\n"
|
||||||
"\n"
|
"\n"
|
||||||
@ -55,7 +57,8 @@ const char *usage =
|
|||||||
"\t-2 Send challenge to slot 2.\n"
|
"\t-2 Send challenge to slot 2.\n"
|
||||||
"\t-A action What to do.\n"
|
"\t-A action What to do.\n"
|
||||||
"\t-p path Specify an output path for the challenge file.\n"
|
"\t-p path Specify an output path for the challenge file.\n"
|
||||||
"\t-i iters Number of iterations to use for pbkdf2 (defaults to 10000)\n"
|
"\t-i iters Number of iterations to use for pbkdf2 (defaults to 10000).\n"
|
||||||
|
"\t-u user Specify a username to create for (defaults to current user).\n"
|
||||||
"\n"
|
"\n"
|
||||||
"\t-v Increase verbosity\n"
|
"\t-v Increase verbosity\n"
|
||||||
"\t-V Show version and exit\n"
|
"\t-V Show version and exit\n"
|
||||||
@ -67,7 +70,7 @@ const char *usage =
|
|||||||
"\n"
|
"\n"
|
||||||
"\n"
|
"\n"
|
||||||
;
|
;
|
||||||
const char *optstring = "12A:p:i:vVh";
|
const char *optstring = "12A:p:i:u:vVh";
|
||||||
|
|
||||||
static void
|
static void
|
||||||
report_yk_error(void)
|
report_yk_error(void)
|
||||||
@ -90,7 +93,7 @@ static int
|
|||||||
parse_args(int argc, char **argv,
|
parse_args(int argc, char **argv,
|
||||||
int *slot, bool *verbose,
|
int *slot, bool *verbose,
|
||||||
char **action, char **output_dir,
|
char **action, char **output_dir,
|
||||||
unsigned int *iterations)
|
unsigned int *iterations, char **username)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
@ -118,6 +121,9 @@ parse_args(int argc, char **argv,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'u':
|
||||||
|
*username = optarg;
|
||||||
|
break;
|
||||||
case 'v':
|
case 'v':
|
||||||
*verbose = true;
|
*verbose = true;
|
||||||
break;
|
break;
|
||||||
@ -135,25 +141,31 @@ parse_args(int argc, char **argv,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
do_add_hmac_chalresp(YK_KEY *yk, uint8_t slot, bool verbose, char *output_dir, unsigned int iterations, int *exit_code)
|
do_add_hmac_chalresp(YK_KEY *yk, uint8_t slot, bool verbose, char *output_dir, unsigned int iterations, char *username, int *exit_code)
|
||||||
{
|
{
|
||||||
char buf[CR_RESPONSE_SIZE + 16];
|
char buf[CR_RESPONSE_SIZE + 16];
|
||||||
CR_STATE state;
|
CR_STATE state;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
unsigned int response_len;
|
unsigned int response_len;
|
||||||
char *fn;
|
char *fn = NULL;
|
||||||
|
char *tmp_fn = NULL;
|
||||||
struct passwd *p;
|
struct passwd *p;
|
||||||
FILE *f = NULL;
|
FILE *f = NULL;
|
||||||
|
int fd;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
|
||||||
state.iterations = iterations;
|
state.iterations = iterations;
|
||||||
state.slot = slot;
|
state.slot = slot;
|
||||||
*exit_code = 1;
|
*exit_code = 1;
|
||||||
|
|
||||||
p = getpwuid (getuid ());
|
if (username) {
|
||||||
|
p = getpwnam (username);
|
||||||
|
} else {
|
||||||
|
p = getpwuid (getuid ());
|
||||||
|
}
|
||||||
|
|
||||||
if (! p) {
|
if (! p) {
|
||||||
fprintf (stderr, "Who am I???");
|
fprintf (stderr, "User not found.\n");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -237,14 +249,50 @@ do_add_hmac_chalresp(YK_KEY *yk, uint8_t slot, bool verbose, char *output_dir, u
|
|||||||
|
|
||||||
umask(077);
|
umask(077);
|
||||||
|
|
||||||
f = fopen (fn, "w");
|
tmp_fn = malloc(strlen(fn) + 1 + strlen(TMPFILE_SUFFIX));
|
||||||
if (! f) {
|
if (! tmp_fn) {
|
||||||
fprintf (stderr, "Failed opening '%s' for writing : %s\n", fn, strerror (errno));
|
fprintf (stderr, "Failed allocating memory.\n");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! write_chalresp_state (f, &state))
|
strcpy(tmp_fn, fn);
|
||||||
|
strcat(tmp_fn, TMPFILE_SUFFIX);
|
||||||
|
|
||||||
|
fd = mkstemp(tmp_fn);
|
||||||
|
if (fd < 0) {
|
||||||
|
fprintf (stderr, "Failed opening temporary file '%s' (%s)\n", tmp_fn, strerror(errno));
|
||||||
goto out;
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (username) {
|
||||||
|
if (fchown(fd, p->pw_uid, p->pw_gid) != 0) {
|
||||||
|
fprintf(stderr, "Failed changing ownership of '%s' to user '%s'\n", tmp_fn, username);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
f = fdopen (fd, "w");
|
||||||
|
if (! f) {
|
||||||
|
close(fd);
|
||||||
|
fprintf (stderr, "Failed opening '%s' for writing : %s\n", tmp_fn, strerror (errno));
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! write_chalresp_state (f, &state)) {
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fclose (f) < 0) {
|
||||||
|
fprintf(stderr, "Failed closing file '%s'\n", tmp_fn);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
f = NULL;
|
||||||
|
|
||||||
|
if (rename (tmp_fn, fn) != 0) {
|
||||||
|
fprintf(stderr, "Failed renaming '%s' to '%s'\n", tmp_fn, fn);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
printf ("Stored initial challenge and expected response in '%s'.\n", fn);
|
printf ("Stored initial challenge and expected response in '%s'.\n", fn);
|
||||||
|
|
||||||
@ -255,6 +303,12 @@ do_add_hmac_chalresp(YK_KEY *yk, uint8_t slot, bool verbose, char *output_dir, u
|
|||||||
if (f)
|
if (f)
|
||||||
fclose (f);
|
fclose (f);
|
||||||
|
|
||||||
|
if (tmp_fn)
|
||||||
|
free (tmp_fn);
|
||||||
|
|
||||||
|
if (fn)
|
||||||
|
free (fn);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -272,6 +326,7 @@ main(int argc, char **argv)
|
|||||||
char *output_dir = NULL;
|
char *output_dir = NULL;
|
||||||
int slot = 1;
|
int slot = 1;
|
||||||
unsigned int iterations = CR_DEFAULT_ITERATIONS;
|
unsigned int iterations = CR_DEFAULT_ITERATIONS;
|
||||||
|
char *username = NULL;
|
||||||
|
|
||||||
ykp_errno = 0;
|
ykp_errno = 0;
|
||||||
yk_errno = 0;
|
yk_errno = 0;
|
||||||
@ -281,7 +336,7 @@ main(int argc, char **argv)
|
|||||||
if (! parse_args(argc, argv,
|
if (! parse_args(argc, argv,
|
||||||
&slot, &verbose,
|
&slot, &verbose,
|
||||||
&ptr, &output_dir,
|
&ptr, &output_dir,
|
||||||
&iterations))
|
&iterations, &username))
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
exit_code = 1;
|
exit_code = 1;
|
||||||
@ -296,7 +351,7 @@ main(int argc, char **argv)
|
|||||||
if (! check_firmware_version(yk, verbose, false, stdout))
|
if (! check_firmware_version(yk, verbose, false, stdout))
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
if (! do_add_hmac_chalresp (yk, slot, verbose, output_dir, iterations, &exit_code))
|
if (! do_add_hmac_chalresp (yk, slot, verbose, output_dir, iterations, username, &exit_code))
|
||||||
goto err;
|
goto err;
|
||||||
} else {
|
} else {
|
||||||
fprintf (stderr, "Unknown action '%s'\n", action);
|
fprintf (stderr, "Unknown action '%s'\n", action);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user