mirror of
https://github.com/Yubico/yubico-pam.git
synced 2024-12-01 15:24:12 +01:00
Use a temporary file to ensure we always have a challenge
If we use ftruncate we might end up in the situation that we do not have a challenge on disk, leading to the user being unable to log in. By using a temporary file, fsync and rename we avoid this problem.
This commit is contained in:
parent
e2968a1bf8
commit
1130d47bb2
29
pam_yubico.c
29
pam_yubico.c
@ -356,7 +356,7 @@ struct cfg
|
||||
static int
|
||||
do_challenge_response(struct cfg *cfg, const char *username)
|
||||
{
|
||||
char *userfile = NULL;
|
||||
char *userfile = NULL, *tmpfile = NULL;
|
||||
FILE *f = NULL;
|
||||
unsigned char buf[CR_RESPONSE_SIZE + 16], response_hex[CR_RESPONSE_SIZE * 2 + 1];
|
||||
int ret;
|
||||
@ -391,11 +391,16 @@ do_challenge_response(struct cfg *cfg, const char *username)
|
||||
D(("Loading challenge from file %s", userfile));
|
||||
|
||||
/* XXX should drop root privileges before opening file in user's home directory */
|
||||
f = fopen(userfile, "r+");
|
||||
f = fopen(userfile, "r");
|
||||
|
||||
if (! load_chalresp_state(f, &state))
|
||||
goto out;
|
||||
|
||||
if (fclose(f) < 0) {
|
||||
f = NULL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (! challenge_response(yk, state.slot, state.challenge, state.challenge_len,
|
||||
true, flags, false,
|
||||
buf, sizeof(buf), &response_len)) {
|
||||
@ -443,8 +448,27 @@ do_challenge_response(struct cfg *cfg, const char *username)
|
||||
memcpy (state.response, buf, response_len);
|
||||
state.response_len = response_len;
|
||||
|
||||
/* Write out the new file */
|
||||
tmpfile = malloc(strlen(userfile) + 1 + 4);
|
||||
if (! tmpfile)
|
||||
goto out;
|
||||
strcpy(tmpfile, userfile);
|
||||
strcat(tmpfile, ".tmp");
|
||||
|
||||
f = fopen(tmpfile, "w");
|
||||
if (! f)
|
||||
goto out;
|
||||
|
||||
if (! write_chalresp_state (f, &state))
|
||||
goto out;
|
||||
if (fclose(f) < 0) {
|
||||
f = NULL;
|
||||
goto out;
|
||||
}
|
||||
f = NULL;
|
||||
if (rename(tmpfile, userfile) < 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
D(("Challenge-response success!"));
|
||||
|
||||
@ -469,6 +493,7 @@ do_challenge_response(struct cfg *cfg, const char *username)
|
||||
fclose(f);
|
||||
|
||||
free(userfile);
|
||||
free(tmpfile);
|
||||
return ret;
|
||||
}
|
||||
#undef USERFILE
|
||||
|
Loading…
Reference in New Issue
Block a user