Require the user to specify the OATH mode (HOTP or TOTP) when generating

a new key.

Allow resynchronizing with three keys instead of two, increasing the
resynchronization window from 100 keys to 1000 keys.


git-svn-id: svn+ssh://svn.openpam.org/svn/openpam/trunk@847 185d5e19-27fe-0310-9dcf-9bff6b9f3609
This commit is contained in:
Dag-Erling Smørgrav 2014-12-11 14:06:59 +00:00
parent c7a5aa489f
commit 2f686b73cb
2 changed files with 27 additions and 20 deletions

View File

@ -28,7 +28,7 @@
.\" .\"
.\" $Id$ .\" $Id$
.\" .\"
.Dd November 11, 2014 .Dd December 11, 2014
.Dt OATHKEY 1 .Dt OATHKEY 1
.Os .Os
.Sh NAME .Sh NAME
@ -74,19 +74,21 @@ The commands are:
Compute and display the current code for the given key. Compute and display the current code for the given key.
If writeback mode is enabled, the user's keyfile is updated to prevent If writeback mode is enabled, the user's keyfile is updated to prevent
reuse. reuse.
.It Cm genkey .It Cm genkey Ar hotp | totp
Generate a new key. Generate a new key for the specified OATH mode.
If writeback mode is enabled, the user's key is set; otherwise, it is If writeback mode is enabled, the user's key is set; otherwise, it is
printed to standard output. printed to standard output.
.It Cm getkey .It Cm getkey
Print the user's key. Print the user's key.
.It Cm geturi .It Cm geturi
Print the user's key in otpauth URI form. Print the user's key in otpauth URI form.
.It Cm resync Ar code1 Ar code2 .It Cm resync Ar code1 Ar code2 Op Ar code3
Resynchronize an event-mode token that has moved too far ahead of the Resynchronize an event-mode token that has moved too far ahead of the
validation server. validation server.
The codes provided must be two consecutive codes within the The codes provided must be consecutive codes within the
resynchronization window. resynchronization window.
The resynchronization window is 100 if two codes are provided and 1000
if three codes are provided.
.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

View File

@ -150,15 +150,16 @@ static int
oathkey_genkey(int argc, char *argv[]) oathkey_genkey(int argc, char *argv[])
{ {
struct oath_key *key; struct oath_key *key;
enum oath_mode mode;
int ret; int ret;
/* XXX add parameters later */ if (argc != 1)
if (argc != 0) return (RET_USAGE);
if ((mode = oath_mode(argv[0])) == om_undef)
return (RET_USAGE); return (RET_USAGE);
(void)argv;
if (!isroot && !issameuser) if (!isroot && !issameuser)
return (RET_UNAUTH); return (RET_UNAUTH);
if ((key = oath_key_create(user, om_totp, oh_undef, NULL, 0)) == NULL) if ((key = oath_key_create(user, mode, oh_undef, NULL, 0)) == NULL)
return (RET_ERROR); return (RET_ERROR);
ret = readonly ? oathkey_print_uri(key) : oathkey_save(key); ret = readonly ? oathkey_print_uri(key) : oathkey_save(key);
oath_key_free(key); oath_key_free(key);
@ -312,25 +313,27 @@ static int
oathkey_resync(int argc, char *argv[]) oathkey_resync(int argc, char *argv[])
{ {
struct oath_key *key; struct oath_key *key;
unsigned long counter, response[2]; unsigned long counter, response[3];
char *end; char *end;
int i, match, ret; int i, match, n, ret, w;
if (argc != 2) if (argc < 2 || argc > 3)
return (RET_USAGE); return (RET_USAGE);
for (i = 0; i < argc; ++i) { n = argc;
for (i = 0, w = 1; i < n; ++i) {
response[i] = strtoul(argv[i], &end, 10); response[i] = strtoul(argv[i], &end, 10);
if (end == argv[i] || *end != '\0') if (end == argv[i] || *end != '\0')
response[i] = ULONG_MAX; /* never valid */ response[i] = ULONG_MAX; /* never valid */
w = w * 10;
} }
if ((ret = oathkey_load(&key)) != RET_SUCCESS) if ((ret = oathkey_load(&key)) != RET_SUCCESS)
return (ret); return (ret);
switch (key->mode) { switch (key->mode) {
case om_hotp: case om_hotp:
counter = key->counter; counter = key->counter;
match = oath_hotp_match(key, response[0], 99 /* XXX window */); match = oath_hotp_match(key, response[0], w);
if (match > 0) for (i = 1; i < n && match > 0; ++i)
match = oath_hotp_match(key, response[1], 1); match = oath_hotp_match(key, response[i], 1);
if (verbose && match > 0) if (verbose && match > 0)
warnx("skipped %lu codes", key->counter - counter - 1); warnx("skipped %lu codes", key->counter - counter - 1);
break; break;
@ -362,13 +365,15 @@ usage(void)
"\n" "\n"
"Commands:\n" "Commands:\n"
" calc Print the current code\n" " calc Print the current code\n"
" genkey Generate a new key\n" " genkey <mode>\n"
" Generate a new key\n"
" getkey Print the key in hexadecimal form\n" " getkey Print the key in hexadecimal form\n"
" geturi Print the key in otpauth URI form\n" " geturi Print the key in otpauth URI form\n"
" resync Resynchronize an HOTP token\n" " resync <code1> <code2> [<code3>]\n"
" Resynchronize an HOTP token\n"
" setkey Generate a new key\n" " setkey Generate a new key\n"
" verify <response>\n" " verify <code>\n"
" Verify a response\n"); " Verify an HOTP or TOTP code\n");
exit(1); exit(1);
} }