From 9c55e81bbbd0e5e977ea048abd784da9b266de85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dag-Erling=20Sm=C3=B8rgrav?= Date: Wed, 22 Oct 2014 10:03:14 +0000 Subject: [PATCH] Add a calc command that prints the current code. git-svn-id: svn+ssh://svn.openpam.org/svn/openpam/trunk@827 185d5e19-27fe-0310-9dcf-9bff6b9f3609 --- bin/oathkey/oathkey.1 | 12 ++++--- bin/oathkey/oathkey.c | 75 +++++++++++++++++++++++++++++++++++-------- 2 files changed, 70 insertions(+), 17 deletions(-) diff --git a/bin/oathkey/oathkey.1 b/bin/oathkey/oathkey.1 index 59701a3..a7407d9 100644 --- a/bin/oathkey/oathkey.1 +++ b/bin/oathkey/oathkey.1 @@ -28,7 +28,7 @@ .\" .\" $Id$ .\" -.Dd October 8, 2014 +.Dd October 22, 2014 .Dt OATHKEY 1 .Os .Sh NAME @@ -67,6 +67,10 @@ Enable writeback mode (see below). .Pp The commands are: .Bl -tag -width 6n +.It Cm calc +Compute and display the current code for the given key. +If writeback mode is enabled, the user's keyfile is updated to prevent +reuse. .It Cm genkey Generate a new key. If writeback mode is enabled, the user's key is set; otherwise, it is @@ -77,14 +81,14 @@ Print the user's key. Print the user's key in otpauth URI form. .It Cm setkey Ar uri Set the user's key to the given otpauth URI. +.It Cm uri +Deprecated synonym for +.Cm geturi . .It Cm verify Ar code Verify that the given code is the correct current response for the user's key. If writeback mode is enabled and the response matched, the user's keyfile is updated to prevent reuse. -.It Cm uri -Deprecated synonym for -.Cm geturi . .El .Sh SEE ALSO .Xr oath_hotp 3 , diff --git a/bin/oathkey/oathkey.c b/bin/oathkey/oathkey.c index 8f5b22c..f915ac0 100644 --- a/bin/oathkey/oathkey.c +++ b/bin/oathkey/oathkey.c @@ -91,6 +91,24 @@ oathkey_print_uri(struct oath_key *key) return (RET_SUCCESS); } +/* + * Load key from file + */ +static int +oathkey_load(struct oath_key **key) +{ + + if (verbose) + warnx("loading key from %s", keyfile); + if ((*key = oath_key_from_file(keyfile)) == NULL) { + warn("%s", keyfile); + if (errno == EACCES || errno == EPERM) + return (RET_UNAUTH); + return (RET_ERROR); + } + return (RET_SUCCESS); +} + /* * Save key to file * XXX liboath should take care of this for us @@ -183,10 +201,8 @@ oathkey_getkey(int argc, char *argv[]) (void)argv; if (!isroot && !issameuser) return (RET_UNAUTH); - if (verbose) - warnx("loading key from %s", keyfile); - if ((key = oath_key_from_file(keyfile)) == NULL) - return (RET_ERROR); + if ((ret = oathkey_load(&key)) != RET_SUCCESS) + return (ret); ret = oathkey_print_hex(key); oath_key_free(key); return (ret); @@ -206,10 +222,8 @@ oathkey_geturi(int argc, char *argv[]) (void)argv; if (!isroot && !issameuser) return (RET_UNAUTH); - if (verbose) - warnx("loading key from %s", keyfile); - if ((key = oath_key_from_file(keyfile)) == NULL) - return (RET_ERROR); + if ((ret = oathkey_load(&key)) != RET_SUCCESS) + return (ret); ret = oathkey_print_uri(key); oath_key_free(key); return (ret); @@ -228,10 +242,8 @@ oathkey_verify(int argc, char *argv[]) if (argc < 1) return (RET_USAGE); - if (verbose) - warnx("loading key from %s", keyfile); - if ((key = oath_key_from_file(keyfile)) == NULL) - return (RET_ERROR); + if ((ret = oathkey_load(&key)) != RET_SUCCESS) + return (ret); response = strtoul(*argv, &end, 10); if (end == *argv || *end != '\0') response = ULONG_MAX; /* never valid */ @@ -256,6 +268,40 @@ oathkey_verify(int argc, char *argv[]) return (ret); } +/* + * Compute the current code + */ +static int +oathkey_calc(int argc, char *argv[]) +{ + struct oath_key *key; + unsigned int current; + int ret; + + if (argc != 0) + return (RET_USAGE); + (void)argv; + if ((ret = oathkey_load(&key)) != RET_SUCCESS) + return (ret); + if (key->mode == om_totp) + current = oath_totp_current(key); + else if (key->mode == om_hotp) + current = oath_hotp_current(key); + else + current = -1; + if (current == (unsigned int)-1) { + warnx("OATH error"); + ret = RET_ERROR; + } else { + printf("%.*d\n", (int)key->digits, current); + ret = RET_SUCCESS; + if (writeback) + ret = oathkey_save(key); + } + oath_key_free(key); + return (ret); +} + /* * Print usage string and exit. */ @@ -266,6 +312,7 @@ usage(void) "usage: oathkey [-hvw] [-u user] [-k keyfile] \n" "\n" "Commands:\n" + " calc Print the current code\n" " genkey Generate a new key\n" " getkey Print the key in hexadecimal form\n" " geturi Print the key in otpauth URI form\n" @@ -354,10 +401,12 @@ main(int argc, char *argv[]) */ if (strcmp(cmd, "help") == 0) ret = RET_USAGE; + else if (strcmp(cmd, "calc") == 0) + ret = oathkey_calc(argc, argv); else if (strcmp(cmd, "genkey") == 0) ret = oathkey_genkey(argc, argv); else if (strcmp(cmd, "getkey") == 0) - ret = oathkey_getkey(argc, argv); + ret = oathkey_getkey(argc, argv); else if (strcmp(cmd, "geturi") == 0 || strcmp(cmd, "uri") == 0) ret = oathkey_geturi(argc, argv); else if (strcmp(cmd, "setkey") == 0)