author | Olivier Brunel
<jjk@jjacky.com> 2023-12-20 21:56:52 UTC |
committer | Olivier Brunel
<jjk@jjacky.com> 2024-01-05 10:13:12 UTC |
parent | 87e81bdaf679ea72e88d33c0ff3de5119fd4e0c2 |
src/include/ssp.h | +3 | -9 |
src/ssp/add.c | +3 | -3 |
src/ssp/database.c | +21 | -3 |
src/ssp/edit.c | +5 | -8 |
src/ssp/get.c | +13 | -13 |
src/ssp/import.c | +2 | -2 |
src/ssp/show.c | +4 | -4 |
diff --git a/src/include/ssp.h b/src/include/ssp.h index df7041e..7579d58 100644 --- a/src/include/ssp.h +++ b/src/include/ssp.h @@ -44,21 +44,15 @@ enum { struct otp { - size_t slen; /* length of secret within data; or offset to comments */ - union { - u64 c; - struct { - u64 precision : 6; - u64 unused : 58; - } t; - }; + u64 slen; /* length of secret within data; or offset to comments */ + u64 n; /* next counter or time precision */ u8 algo; u8 type; u8 digits; char data[]; }; -#define OTP_DEFAULT { .slen = 0, .c = 1, .algo = ALGO_SHA1, .type = TYPE_COUNTER, .digits = 6 } +#define OTP_DEFAULT { .slen = 0, .n = 1, .algo = ALGO_SHA1, .type = TYPE_COUNTER, .digits = 6 } /* ssp.c */ int exitcode_from_errno(int e); diff --git a/src/ssp/add.c b/src/ssp/add.c index 1054b39..f2411e6 100644 --- a/src/ssp/add.c +++ b/src/ssp/add.c @@ -124,7 +124,7 @@ parse_cmdline(int argc, const char *argv[], const char usage[], struct add *ctx) ctx->cmtoff = LO_OFF(&lo); break; case 'c': - if (validate_counter(&ctx->otp.c, LO_ARG(&lo), strlen(LO_ARG(&lo))) < 0) + if (validate_counter(&ctx->otp.n, LO_ARG(&lo), strlen(LO_ARG(&lo))) < 0) diecmdusage(EX_USAGE, usage, &command_add); ctx->otp.type = TYPE_COUNTER; break; @@ -136,12 +136,12 @@ parse_cmdline(int argc, const char *argv[], const char usage[], struct add *ctx) break; case 't': if (!LO_ARG(&lo)) { - ctx->otp.t.precision = 30; + ctx->otp.n = 30; } else { r = validate_precision(LO_ARG(&lo), strlen(LO_ARG(&lo))); if (r < 0) diecmdusage(EX_USAGE, usage, &command_add); - ctx->otp.t.precision = r; + ctx->otp.n = r; } ctx->otp.type = TYPE_TIME; break; diff --git a/src/ssp/database.c b/src/ssp/database.c index a3bcad7..01f8f6f 100644 --- a/src/ssp/database.c +++ b/src/ssp/database.c @@ -8,6 +8,7 @@ #include <limb/bytestr.h> #include <limb/cdb.h> #include <limb/cdbmake.h> +#include <limb/endian.h> #include <limb/exitcode.h> #include <limb/hasher.h> #include <limb/output.h> @@ -89,6 +90,14 @@ open_db(struct ssp *ctx, int is_needed) cdb_init_frommem(&ctx->cdb, ctx->sa.s + off, ctx->sa.len - off); dbg("initialized cdb [off=", PMUINT(off), " size=", PMUINT(ctx->cdb.size), "]"); +#if ! LIMB_IS_LE + db_reset(ctx); + while (db_next(ctx) == 1) { + u64p_le(&((struct otp *) db_otp(ctx))->slen); + u64p_le(&((struct otp *) db_otp(ctx))->n); + } +#endif + return 1; } @@ -128,12 +137,21 @@ rebuild_cdb(cdbmaker_sa *mkr, const char *oldkey, const char *newkey, dbg("oldkey=", ESC, oldkey, ESC, " newkey=", ESC, newkey, ESC, " vlen=", PMUINT(vlen)); +#if LIMB_IS_LE + char *data = (char *) otp; +#else + char data[vlen]; + memcpy(data, otp, vlen); + u64p_le(&((struct otp *) data)->slen); + u64p_le(&((struct otp *) data)->n); +#endif + if (!cdbmaker_sa_start(mkr)) return -1; /* new file? */ if (!ctx->cdb.map) { dbg("new file, adding newkey"); - if (nlen && !cdbmaker_sa_add(mkr, newkey, nlen, (char *) otp, vlen)) + if (nlen && !cdbmaker_sa_add(mkr, newkey, nlen, data, vlen)) return -1; ++n; } else { @@ -153,7 +171,7 @@ rebuild_cdb(cdbmaker_sa *mkr, const char *oldkey, const char *newkey, if (!a && strcoll(ctx->key.s, newkey) > 0) { dbg("inserting newkey before"); /* insert otp at the right place */ - if (!cdbmaker_sa_add(mkr, newkey, nlen, (char *) otp, vlen)) + if (!cdbmaker_sa_add(mkr, newkey, nlen, data, vlen)) return -1; ++n; a = 1; @@ -176,7 +194,7 @@ rebuild_cdb(cdbmaker_sa *mkr, const char *oldkey, const char *newkey, if (!a) { dbg("inserting newkey last"); /* insert last */ - if (!cdbmaker_sa_add(mkr, newkey, nlen, (char *) otp, vlen)) + if (!cdbmaker_sa_add(mkr, newkey, nlen, data, vlen)) return -1; ++n; } diff --git a/src/ssp/edit.c b/src/ssp/edit.c index 01d8209..807d1b1 100644 --- a/src/ssp/edit.c +++ b/src/ssp/edit.c @@ -77,9 +77,9 @@ parse_cmdline(int argc, const char *argv[], const char usage[], struct edit *ctx break; case 'c': if (!LO_ARG(&lo)) { - ctx->otp.c = 1; + ctx->otp.n = 1; } else { - if (validate_counter(&ctx->otp.c, LO_ARG(&lo), strlen(LO_ARG(&lo))) < 0) + if (validate_counter(&ctx->otp.n, LO_ARG(&lo), strlen(LO_ARG(&lo))) < 0) diecmdusage(EX_USAGE, usage, &command_edit); } ctx->otp.type = TYPE_COUNTER; @@ -98,12 +98,12 @@ parse_cmdline(int argc, const char *argv[], const char usage[], struct edit *ctx break; case 't': if (!LO_ARG(&lo)) { - ctx->otp.t.precision = 30; + ctx->otp.n = 30; } else { r = validate_precision(LO_ARG(&lo), strlen(LO_ARG(&lo))); if (r < 0) diecmdusage(EX_USAGE, usage, &command_edit); - ctx->otp.t.precision = r; + ctx->otp.n = r; } ctx->otp.type = TYPE_TIME; break; @@ -171,10 +171,7 @@ edit_main(int argc, const char *argv[], const char *env[], const char usage[], v p->algo = (ctx.otp.algo != ALGO_UNKNOWN) ? ctx.otp.algo : cur->algo; p->type = (ctx.otp.type != TYPE_UNKNOWN) ? ctx.otp.type : cur->type; p->digits = (ctx.otp.digits) ? ctx.otp.digits : cur->digits; - if (p->type == TYPE_COUNTER) - p->c = (ctx.otp.type != TYPE_UNKNOWN) ? ctx.otp.c : cur->c; - else - p->t.precision = (ctx.otp.type != TYPE_UNKNOWN) ? ctx.otp.t.precision : cur->t.precision; + p->n = (ctx.otp.type != TYPE_UNKNOWN) ? ctx.otp.n : cur->n; p->slen = slen; if (ctx.secret) diff --git a/src/ssp/get.c b/src/ssp/get.c index 9c5176c..1a80e48 100644 --- a/src/ssp/get.c +++ b/src/ssp/get.c @@ -80,13 +80,13 @@ parse_cmdline(int argc, const char *argv[], const char usage[], struct get *ctx) /* fall through */ case 'c': if (!LO_ARG(&lo)) { - ctx->otp.c = 1; + ctx->otp.n = 1; } else { - if (validate_counter(&ctx->otp.c, LO_ARG(&lo), strlen(LO_ARG(&lo))) < 0) + if (validate_counter(&ctx->otp.n, LO_ARG(&lo), strlen(LO_ARG(&lo))) < 0) diecmdusage(EX_USAGE, usage, &command_get); } ctx->otp.type = TYPE_COUNTER; - dbg("setting to HOTP with counter=", PMUINT(ctx->otp.c)); + dbg("setting to HOTP with counter=", PMUINT(ctx->otp.n)); break; case 'd': r = validate_digits(LO_ARG(&lo), strlen(LO_ARG(&lo))); @@ -139,15 +139,15 @@ parse_cmdline(int argc, const char *argv[], const char usage[], struct get *ctx) break; case 't': if (!LO_ARG(&lo)) { - ctx->otp.t.precision = 30; + ctx->otp.n = 30; } else { r = validate_precision(LO_ARG(&lo), strlen(LO_ARG(&lo))); if (r < 0) diecmdusage(EX_USAGE, usage, &command_get); - ctx->otp.t.precision = r; + ctx->otp.n = r; } ctx->otp.type = TYPE_TIME; - dbg("setting to TOTP with precision=", PMUINT(ctx->otp.t.precision)); + dbg("setting to TOTP with precision=", PMUINT(ctx->otp.n)); break; case -1: @@ -197,17 +197,17 @@ get_main(int argc, const char *argv[], const char *env[], const char usage[], vo case ALGO_BLAKE3: hr = blake3; break; } - u64 c; + u64 n; if (ctx.otp.type == TYPE_TIME) { if (ctx.ts == (u64) -1) ctx.ts = time(NULL); - c = ctx.ts / ctx.otp.t.precision; + n = ctx.ts / ctx.otp.n; } else { - c = ctx.otp.c; + n = ctx.otp.n; } - dbg("calculating HOTP c=", PMUINT(c), " digits=", PMUINT(ctx.otp.digits)); - int r = hotp(hr, ctx.secret, ctx.otp.slen, c, ctx.otp.digits); + dbg("calculating HOTP n=", PMUINT(n), " digits=", PMUINT(ctx.otp.digits)); + int r = hotp(hr, ctx.secret, ctx.otp.slen, n, ctx.otp.digits); add((ctx.otp.type == TYPE_COUNTER) ? "H" : "T", "OTP: "); char buf[ctx.otp.digits + 1]; buf[u32_0fmt(buf, r, sizeof(buf) - 1)] = 0; @@ -219,8 +219,8 @@ get_main(int argc, const char *argv[], const char *env[], const char usage[], vo /* make sure the entry is also in COUNTER mode */ && db_otp(ssp)->type == TYPE_COUNTER) { struct otp *e = (struct otp *) db_otp(ssp); - e->c = ++ctx.otp.c; - dbg("updating entry's counter to ", PMUINT(e->c)); + e->n = ++ctx.otp.n; + dbg("updating entry's counter to ", PMUINT(e->n)); if (!write_db(ssp->sa.s + ssp->cdboff, ssp->cdb.size, ssp)) diefusys((errno == EINVAL) ? EX_DATA_ERR : EX_CANTCREAT, "save database"); diff --git a/src/ssp/import.c b/src/ssp/import.c index ea21b9e..d8527d5 100644 --- a/src/ssp/import.c +++ b/src/ssp/import.c @@ -191,7 +191,7 @@ import_main(int argc, const char *argv[], const char *env[], const char usage[], if (r < 0) goto err; otp.digits = r; } else if (copa_nlen(&copa) == 7 && !strncmp(copa_name(&copa), "counter", 7)) { - if (validate_counter(&otp.c, copa_value(&copa), copa_vlen(&copa)) < 0) + if (validate_counter(&otp.n, copa_value(&copa), copa_vlen(&copa)) < 0) goto err; } else if (copa_nlen(&copa) == 4 && !strncmp(copa_name(&copa), "time", 4)) { if (copa_vlen(&copa) == 1 && copa_value(&copa)[0] == '1') @@ -206,7 +206,7 @@ import_main(int argc, const char *argv[], const char *env[], const char usage[], && !strncmp(copa_name(&copa), "precision", 9)) { r = validate_precision(copa_value(&copa), copa_vlen(&copa)); if (r < 0) goto err; - otp.t.precision = r; + otp.n = r; } else if (copa_nlen(&copa) == 6 && !strncmp(copa_name(&copa), "secret", 6)) { slen = base32_scan(NULL, copa_value(&copa), copa_vlen(&copa), 0); if (slen < 0) diff --git a/src/ssp/show.c b/src/ssp/show.c index 9c9fa90..b085a1f 100644 --- a/src/ssp/show.c +++ b/src/ssp/show.c @@ -86,9 +86,9 @@ show_entry(unsigned options, struct ssp *ctx) out(" Algo: ", algos[otp->algo]); add(" ", types[otp->type], "-based; "); if (otp->type == TYPE_COUNTER) - out("Counter: ", PMUINT(otp->c)); + out("Counter: ", PMUINT(otp->n)); else /* TYPE_TIME */ - out("Precision: ", PMUINT(otp->t.precision), "s"); + out("Precision: ", PMUINT(otp->n), "s"); out(" Digits: ", PMUINT(otp->digits)); if (options & OPT_SECRET) { size_t l = base32_fmt(NULL, otp->data, otp->slen, 0); @@ -119,9 +119,9 @@ show_entry_ini(unsigned options, struct ssp *ctx) out("digits=", PMUINT(otp->digits)); if (otp->type == TYPE_TIME) { out("time=1"); - out("precision=", PMUINT(otp->t.precision)); + out("precision=", PMUINT(otp->n)); } else { - out("counter=", PMUINT(otp->c)); + out("counter=", PMUINT(otp->n)); } size_t l = base32_fmt(NULL, otp->data, otp->slen, 1); char buf[l + 1];