Welcome to little lamb

Code » ssp » commit 1c16e28

Ensure proper endianness in db

author Olivier Brunel
2023-12-20 21:56:52 UTC
committer Olivier Brunel
2024-01-05 10:13:12 UTC
parent 87e81bdaf679ea72e88d33c0ff3de5119fd4e0c2

Ensure proper endianness in db

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];