Changeset 842 in openpam


Ignore:
Timestamp:
Nov 12, 2014, 5:30:38 PM (6 years ago)
Author:
Dag-Erling Smørgrav
Message:

Implement HOTP resynchronization: the user provides two consecutive codes
from their token. If the first code is found within the synchronization
window (currently hardcoded to 99) and the second is the next code in the
sequence, the counter is reset to one past the second code.

Location:
trunk/bin/oathkey
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/bin/oathkey/oathkey.1

    r841 r842  
    8383.It Cm geturi
    8484Print the user's key in otpauth URI form.
     85.It Cm resync Ar code1 Ar code2
     86Resynchronize an event-mode token that has moved too far ahead of the
     87validation server.
     88The codes provided must be two consecutive codes within the
     89resynchronization window.
    8590.It Cm setkey Ar uri
    8691Set the user's key to the given otpauth URI.
  • trunk/bin/oathkey/oathkey.c

    r841 r842  
    237237{
    238238        struct oath_key *key;
    239         unsigned long response;
     239        unsigned long counter, response;
    240240        char *end;
    241241        int match, ret;
     
    248248        if (end == *argv || *end != '\0')
    249249                response = ULONG_MAX; /* never valid */
    250         if (key->mode == om_totp)
     250        switch (key->mode) {
     251        case om_totp:
    251252                match = oath_totp_match(key, response, 3 /* XXX window */);
    252         else if (key->mode == om_hotp)
     253                break;
     254        case om_hotp:
     255                counter = key->counter;
    253256                match = oath_hotp_match(key, response, 17 /* XXX window */);
    254         else
     257                if (verbose && match > 0 && key->counter > counter + 1)
     258                        warnx("skipped %lu codes", key->counter - counter - 1);
     259                break;
     260        default:
    255261                match = -1;
     262        }
    256263        /* oath_*_match() return -1 on error, 0 on failure, 1 on success */
    257264        if (match < 0) {
     
    300307
    301308/*
     309 * Resynchronize
     310 */
     311static int
     312oathkey_resync(int argc, char *argv[])
     313{
     314        struct oath_key *key;
     315        unsigned long counter, response[2];
     316        char *end;
     317        int i, match, ret;
     318
     319        if (argc != 2)
     320                return (RET_USAGE);
     321        for (i = 0; i < argc; ++i) {
     322                response[i] = strtoul(argv[i], &end, 10);
     323                if (end == argv[i] || *end != '\0')
     324                        response[i] = ULONG_MAX; /* never valid */
     325        }
     326        if ((ret = oathkey_load(&key)) != RET_SUCCESS)
     327                return (ret);
     328        switch (key->mode) {
     329        case om_hotp:
     330                counter = key->counter;
     331                match = oath_hotp_match(key, response[0], 99 /* XXX window */);
     332                if (match > 0)
     333                        match = oath_hotp_match(key, response[1], 1);
     334                if (verbose && match > 0)
     335                        warnx("skipped %lu codes", key->counter - counter - 1);
     336                break;
     337        case om_totp:
     338                match = 1;
     339                break;
     340        default:
     341                match = -1;
     342        }
     343        if (match < 0) {
     344                warnx("OATH error");
     345                match = 0;
     346        }
     347        if (verbose)
     348                warnx("resynchronization %s", match ? "succeeded" : "failed");
     349        ret = match ? readonly ? RET_SUCCESS : oathkey_save(key) : RET_FAILURE;
     350        oath_key_free(key);
     351        return (ret);
     352}
     353
     354/*
    302355 * Print usage string and exit.
    303356 */
     
    313366            "    getkey      Print the key in hexadecimal form\n"
    314367            "    geturi      Print the key in otpauth URI form\n"
     368            "    resync      Resynchronize an HOTP token\n"
    315369            "    setkey      Generate a new key\n"
    316370            "    verify <response>\n"
     
    409463        else if (strcmp(cmd, "geturi") == 0 || strcmp(cmd, "uri") == 0)
    410464                ret = oathkey_geturi(argc, argv);
     465        else if (strcmp(cmd, "resync") == 0)
     466                ret = oathkey_resync(argc, argv);
    411467        else if (strcmp(cmd, "setkey") == 0)
    412468                ret = oathkey_setkey(argc, argv);
Note: See TracChangeset for help on using the changeset viewer.