Welcome to little lamb

Code » ssp » commit 57f99a8

Refactoring

author Olivier Brunel
2023-04-19 07:46:55 UTC
committer Olivier Brunel
2023-04-19 07:47:48 UTC
parent d23d9287ff6191b08ce77e9f1462b445e7b0d615

Refactoring

src/ssp/database.c +54 -25

diff --git a/src/ssp/database.c b/src/ssp/database.c
index d923fb2..ec67982 100644
--- a/src/ssp/database.c
+++ b/src/ssp/database.c
@@ -98,11 +98,11 @@ open_db(struct ssp *ctx)
     return 1;
 }
 
-void
-rebuild_db(const char *oldkey, const char *newkey, const struct otp *otp, struct ssp *ctx)
+int
+rebuild_cdb(cdbmaker_sa *mkr, const char *oldkey, const char *newkey,
+            const struct otp *otp, struct ssp *ctx)
 {
     size_t olen = 0, nlen = 0, vlen = 0;
-    cdbmaker_sa mkr;
     int r = 0;
 
     /* oldkey & newkey  : renaming/editing an entry
@@ -117,12 +117,12 @@ rebuild_db(const char *oldkey, const char *newkey, const struct otp *otp, struct
     }
     if (oldkey) olen = strlen(oldkey) + 1;
 
-    if (!cdbmaker_sa_start(&mkr))
-        diefusys(EX_TEMPFAIL, "save database");
+    if (!cdbmaker_sa_start(mkr))
+        return 0;
     /* new file? */
     if (!ctx->cdb.map) {
-        if (nlen && !cdbmaker_sa_add(&mkr, newkey, nlen, (char *) otp, vlen))
-            diefusys(EX_TEMPFAIL, "save database");
+        if (nlen && !cdbmaker_sa_add(mkr, newkey, nlen, (char *) otp, vlen))
+            return 0;
     } else {
         int a = !nlen;
         db_reset(ctx);
@@ -130,14 +130,15 @@ rebuild_db(const char *oldkey, const char *newkey, const struct otp *otp, struct
             /* existing newkey isn't allowed when adding or renaming */
             if (nlen == ctx->key.len && !strcmp(newkey, ctx->key.s)
                     && (!olen || strcmp(oldkey, newkey))) {
-                diefu(EX_DATA_ERR, "add entry ", ESC, newkey, ESC, ": Already exists");
+                warnu("add entry ", ESC, newkey, ESC, ": Entry already exists");
+                return (errno = EINVAL, 0);
             } else {
                 /* Note the use of strcoll() here to ensure we order entries
                  * using locale-specific rules. */
                 if (!a && strcoll(ctx->key.s, newkey) > 0) {
                     /* insert otp at the right place */
-                    if (!cdbmaker_sa_add(&mkr, newkey, nlen, (char *) otp, vlen))
-                        diefusys(EX_TEMPFAIL, "save database");
+                    if (!cdbmaker_sa_add(mkr, newkey, nlen, (char *) otp, vlen))
+                        return 0;
                     a = 1;
                 }
                 /* if current entry isn't the old one nor the new one, re-add */
@@ -145,35 +146,46 @@ rebuild_db(const char *oldkey, const char *newkey, const struct otp *otp, struct
                         && !(nlen == ctx->key.len && !strcmp(newkey, ctx->key.s))
                         && !cdbmaker_sa_add(mkr, ctx->key.s, ctx->key.len,
                                             ctx->val.s, ctx->val.len))
-                    diefusys(EX_TEMPFAIL, "save database");
+                    return 0;
             }
         }
-        if (r < 0) diefu(EX_DATA_ERR, "read database: file corrupted");
+        if (r < 0) {
+            warnu("read database: file corrupted");
+            return (errno = EINVAL, 0);
+        }
         if (!a) {
             /* insert last */
-            if (!cdbmaker_sa_add(&mkr, newkey, nlen, (char *) otp, vlen))
-                diefusys(EX_TEMPFAIL, "save database");
+            if (!cdbmaker_sa_add(mkr, newkey, nlen, (char *) otp, vlen))
+                return 0;
         }
     }
-    if (!cdbmaker_sa_finish(&mkr))
-        diefusys(EX_TEMPFAIL, "save database");
+    if (!cdbmaker_sa_finish(mkr))
+        return 0;
 
+    return 1;
+}
+
+int
+write_db(char *data, size_t dlen, struct ssp *ctx)
+{
     char salt[SALT_LEN];
-    char enckey[KEY_LEN];
+    char key[KEY_LEN];
     char nonce[NONCE_LEN] = { 0 };
 
     /* each time we save the db, we generate a new key to encrypt it */
     random_buf(salt, sizeof(salt));
-    if (!get_key(enckey, salt, "Enter new database password: ", ctx))
-        diefusys(EX_DATA_ERR, "save database: cannot read password");
+    if (!get_key(key, salt, "Enter new database password: ", ctx)) {
+        warnusys("read password");
+        return (errno = EINVAL, 0);
+    }
 
     u32 magic_int = SSP_MAGIC_INT;
     u32p_be(&magic_int);
 
     chacha20_ctx chacha;
-    chacha20_init(enckey, nonce, &chacha);
+    chacha20_init(key, nonce, &chacha);
     chacha20_crypt(&magic_int, &magic_int, sizeof(magic_int), &chacha);
-    chacha20_crypt(mkr.sa.s, mkr.sa.s, mkr.sa.len, &chacha);
+    chacha20_crypt(data, data, dlen, &chacha);
     chacha20_clear(&chacha);
 
 
@@ -187,11 +199,28 @@ rebuild_db(const char *oldkey, const char *newkey, const struct otp *otp, struct
     v[1].iov_len = sizeof(salt);
     v[2].iov_base = &magic_int;
     v[2].iov_len = sizeof(magic_int);
-    v[3].iov_base = mkr.sa.s;
-    v[3].iov_len = mkr.sa.len;
+    v[3].iov_base = data;
+    v[3].iov_len = dlen;
+
+    if (!openwritevnclose(db_file(ctx), v, 4)) {
+        warnusys("write database to ", ESC, db_file(ctx), ESC);
+        return 0;
+    }
+
+    return 1;
+}
+
+void
+rebuild_db(const char *oldkey, const char *newkey, const struct otp *otp, struct ssp *ctx)
+{
+    cdbmaker_sa mkr;
+
+    if (!rebuild_cdb(&mkr, oldkey, newkey, otp, ctx))
+        diefu(exitcode_from_errno(errno), "save database",
+              (errno == ENOMEM) ? ": Out of memory" : NULL);
 
-    if (!openwritevnclose(db_file(ctx), v, 4))
-        diefusys(EX_CANTCREAT, "save database to ", ESC, db_file(ctx), ESC);
+    if (!write_db(mkr.sa.s, mkr.sa.len, ctx))
+        diefusys((errno == EINVAL) ? EX_DATA_ERR : EX_CANTCREAT, "save database");
 
     cdbmaker_sa_free(&mkr);
     out("Database saved to ", ESC, db_file(ctx), ESC);