Implement keyfile writeback.
git-svn-id: svn+ssh://svn.openpam.org/svn/openpam/trunk@784 185d5e19-27fe-0310-9dcf-9bff6b9f3609
This commit is contained in:
parent
ebdefa45ca
commit
38622bad18
|
@ -36,7 +36,7 @@
|
||||||
.Nd OATH key management tool
|
.Nd OATH key management tool
|
||||||
.Sh SYNOPSIS
|
.Sh SYNOPSIS
|
||||||
.Nm
|
.Nm
|
||||||
.Op Fl hv
|
.Op Fl hvw
|
||||||
.Op Fl u Ar user
|
.Op Fl u Ar user
|
||||||
.Op Fl k Ar keyfile
|
.Op Fl k Ar keyfile
|
||||||
.Ar command
|
.Ar command
|
||||||
|
@ -61,12 +61,16 @@ The default is the current user.
|
||||||
Only root may operate on other users.
|
Only root may operate on other users.
|
||||||
.It Fl v
|
.It Fl v
|
||||||
Enable verbose mode.
|
Enable verbose mode.
|
||||||
|
.It Fl w
|
||||||
|
Enable writeback mode (see below).
|
||||||
.El
|
.El
|
||||||
.Pp
|
.Pp
|
||||||
The commands are:
|
The commands are:
|
||||||
.Bl -tag -width 6n
|
.Bl -tag -width 6n
|
||||||
.It Cm genkey
|
.It Cm genkey
|
||||||
Generate a new key.
|
Generate a new key.
|
||||||
|
If writeback mode is enabled, the user's key is set; otherwise, it is
|
||||||
|
printed to standard output.
|
||||||
.It Cm setkey Ar uri
|
.It Cm setkey Ar uri
|
||||||
Set the user's key to the given otpauth URI.
|
Set the user's key to the given otpauth URI.
|
||||||
.It Cm uri
|
.It Cm uri
|
||||||
|
@ -74,6 +78,8 @@ Print the user's key in otpauth URI form.
|
||||||
.It Cm verify Ar code
|
.It Cm verify Ar code
|
||||||
Verify that the given code is the correct current response for the
|
Verify that the given code is the correct current response for the
|
||||||
user's key.
|
user's key.
|
||||||
|
If writeback mode is enabled and the response matched, the user's
|
||||||
|
keyfile is updated to prevent reuse.
|
||||||
.El
|
.El
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr oath_hotp 3 ,
|
.Xr oath_hotp 3 ,
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
|
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
@ -54,10 +55,60 @@ enum { RET_SUCCESS, RET_FAILURE, RET_ERROR, RET_USAGE, RET_UNAUTH };
|
||||||
static char *user;
|
static char *user;
|
||||||
static char *keyfile;
|
static char *keyfile;
|
||||||
static int verbose;
|
static int verbose;
|
||||||
|
static int writeback;
|
||||||
|
|
||||||
static int isroot; /* running as root */
|
static int isroot; /* running as root */
|
||||||
static int issameuser; /* real user same as target user */
|
static int issameuser; /* real user same as target user */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Print key in otpauth URI form
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
oathkey_print(struct oath_key *key)
|
||||||
|
{
|
||||||
|
char *keyuri;
|
||||||
|
|
||||||
|
if ((keyuri = oath_key_to_uri(key)) == NULL) {
|
||||||
|
warnx("failed to convert key to otpauth URI");
|
||||||
|
return (RET_ERROR);
|
||||||
|
}
|
||||||
|
printf("%s\n", keyuri);
|
||||||
|
free(keyuri);
|
||||||
|
return (RET_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Save key to file
|
||||||
|
* XXX liboath should take care of this for us
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
oathkey_save(struct oath_key *key)
|
||||||
|
{
|
||||||
|
char *keyuri;
|
||||||
|
int fd, len, ret;
|
||||||
|
|
||||||
|
keyuri = NULL;
|
||||||
|
len = 0;
|
||||||
|
fd = ret = -1;
|
||||||
|
if ((keyuri = oath_key_to_uri(key)) == NULL) {
|
||||||
|
warnx("failed to convert key to otpauth URI");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
len = strlen(keyuri);
|
||||||
|
if ((fd = open(keyfile, O_WRONLY|O_CREAT|O_TRUNC, 0600)) < 0 ||
|
||||||
|
write(fd, keyuri, len) != len || write(fd, "\n", 1) != 1) {
|
||||||
|
warn("%s", keyfile);
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
ret = 0;
|
||||||
|
done:
|
||||||
|
if (fd >= 0)
|
||||||
|
close(fd);
|
||||||
|
if (keyuri != NULL)
|
||||||
|
free(keyuri);
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Generate a new key
|
* Generate a new key
|
||||||
*/
|
*/
|
||||||
|
@ -65,6 +116,7 @@ static int
|
||||||
oathkey_genkey(int argc, char *argv[])
|
oathkey_genkey(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
struct oath_key *key;
|
struct oath_key *key;
|
||||||
|
int ret;
|
||||||
|
|
||||||
/* XXX add parameters later */
|
/* XXX add parameters later */
|
||||||
if (argc != 0)
|
if (argc != 0)
|
||||||
|
@ -77,10 +129,9 @@ oathkey_genkey(int argc, char *argv[])
|
||||||
|
|
||||||
if ((key = oath_key_create(user, om_totp, oh_undef, NULL, 0)) == NULL)
|
if ((key = oath_key_create(user, om_totp, oh_undef, NULL, 0)) == NULL)
|
||||||
return (RET_ERROR);
|
return (RET_ERROR);
|
||||||
/* XXX should save to file, not print */
|
ret = writeback ? oathkey_save(key) : oathkey_print(key);
|
||||||
printf("%s\n", oath_key_to_uri(key));
|
|
||||||
oath_key_free(key);
|
oath_key_free(key);
|
||||||
return (RET_SUCCESS);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -90,6 +141,7 @@ static int
|
||||||
oathkey_setkey(int argc, char *argv[])
|
oathkey_setkey(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
struct oath_key *key;
|
struct oath_key *key;
|
||||||
|
int ret;
|
||||||
|
|
||||||
/* XXX add parameters later */
|
/* XXX add parameters later */
|
||||||
if (argc != 1)
|
if (argc != 1)
|
||||||
|
@ -102,10 +154,9 @@ oathkey_setkey(int argc, char *argv[])
|
||||||
|
|
||||||
if ((key = oath_key_from_uri(argv[0])) == NULL)
|
if ((key = oath_key_from_uri(argv[0])) == NULL)
|
||||||
return (RET_ERROR);
|
return (RET_ERROR);
|
||||||
/* XXX should save to file, not print */
|
ret = oathkey_save(key);
|
||||||
printf("%s\n", oath_key_to_uri(key));
|
|
||||||
oath_key_free(key);
|
oath_key_free(key);
|
||||||
return (RET_SUCCESS);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -115,6 +166,7 @@ static int
|
||||||
oathkey_uri(int argc, char *argv[])
|
oathkey_uri(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
struct oath_key *key;
|
struct oath_key *key;
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (argc != 0)
|
if (argc != 0)
|
||||||
return (RET_USAGE);
|
return (RET_USAGE);
|
||||||
|
@ -126,9 +178,9 @@ oathkey_uri(int argc, char *argv[])
|
||||||
|
|
||||||
if ((key = oath_key_from_file(keyfile)) == NULL)
|
if ((key = oath_key_from_file(keyfile)) == NULL)
|
||||||
return (RET_ERROR);
|
return (RET_ERROR);
|
||||||
printf("%s\n", oath_key_to_uri(key));
|
ret = oathkey_print(key);
|
||||||
oath_key_free(key);
|
oath_key_free(key);
|
||||||
return (RET_SUCCESS);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -140,7 +192,7 @@ oathkey_verify(int argc, char *argv[])
|
||||||
struct oath_key *key;
|
struct oath_key *key;
|
||||||
unsigned long response;
|
unsigned long response;
|
||||||
char *end;
|
char *end;
|
||||||
int match;
|
int match, ret;
|
||||||
|
|
||||||
if (argc < 1)
|
if (argc < 1)
|
||||||
return (RET_USAGE);
|
return (RET_USAGE);
|
||||||
|
@ -163,11 +215,11 @@ oathkey_verify(int argc, char *argv[])
|
||||||
if (verbose)
|
if (verbose)
|
||||||
warnx("response: %lu %s", response,
|
warnx("response: %lu %s", response,
|
||||||
match ? "matched" : "did not match");
|
match ? "matched" : "did not match");
|
||||||
if (match) {
|
ret = match ? RET_SUCCESS : RET_FAILURE;
|
||||||
/* XXX write key back! */
|
if (match && writeback)
|
||||||
}
|
ret = oathkey_save(key);
|
||||||
oath_key_free(key);
|
oath_key_free(key);
|
||||||
return (match ? RET_SUCCESS : RET_FAILURE);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -177,7 +229,7 @@ static void
|
||||||
usage(void)
|
usage(void)
|
||||||
{
|
{
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"usage: oathkey [-hv] [-u user] [-k keyfile] <command>\n"
|
"usage: oathkey [-hvw] [-u user] [-k keyfile] <command>\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Commands:\n"
|
"Commands:\n"
|
||||||
" genkey Generate a new key\n"
|
" genkey Generate a new key\n"
|
||||||
|
@ -198,7 +250,7 @@ main(int argc, char *argv[])
|
||||||
/*
|
/*
|
||||||
* Parse command-line options
|
* Parse command-line options
|
||||||
*/
|
*/
|
||||||
while ((opt = getopt(argc, argv, "hk:u:v")) != -1)
|
while ((opt = getopt(argc, argv, "hk:u:vw")) != -1)
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case 'k':
|
case 'k':
|
||||||
keyfile = optarg;
|
keyfile = optarg;
|
||||||
|
@ -209,6 +261,9 @@ main(int argc, char *argv[])
|
||||||
case 'v':
|
case 'v':
|
||||||
++verbose;
|
++verbose;
|
||||||
break;
|
break;
|
||||||
|
case 'w':
|
||||||
|
++writeback;
|
||||||
|
break;
|
||||||
case 'h':
|
case 'h':
|
||||||
default:
|
default:
|
||||||
usage();
|
usage();
|
||||||
|
|
Loading…
Reference in New Issue