1
0
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:
Klas Lindfors 2017-01-03 09:39:12 +01:00
parent 6ef497da42
commit 340386f640
No known key found for this signature in database
GPG Key ID: BCA00FD4B2168C0A
2 changed files with 73 additions and 15 deletions

View File

@ -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.

View File

@ -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);