From e3502f9054b75506dbd194b0ff6c0ae655696690 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Adrien=20Gallou=C3=ABt?= <adrien@gallouet.fr>
Date: Sun, 26 Apr 2020 20:44:54 +0000
Subject: [PATCH] Fix list and make room for a futur header
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Adrien Gallouët <adrien@gallouet.fr>
---
 README.md   |  6 +++---
 argz/argz.c |  2 +-
 secret.c    | 44 +++++++++++++++++++++++++++++---------------
 3 files changed, 33 insertions(+), 19 deletions(-)

diff --git a/README.md b/README.md
index 2778a75..7e450ea 100644
--- a/README.md
+++ b/README.md
@@ -59,20 +59,20 @@ Initialize secret for the current user:
 Add a new randomly generated secret:
 
     $ secret add test
-    Password:
+    Passphrase:
     Secret [random]:
     9{6u0ue>5&W2+z#OR:`X<@-#
 
 Show the secret:
 
     $ secret show test
-    Password:
+    Passphrase:
     9{6u0ue>5&W2+z#OR:`X<@-#
 
 Start `bash` in a trusted zone:
 
     $ secret agent bash
-    Password:
+    Passphrase:
 
 Now, the passphrase is not requested and completion fully works!
 
diff --git a/argz/argz.c b/argz/argz.c
index 28175b8..eccebe5 100644
--- a/argz/argz.c
+++ b/argz/argz.c
@@ -58,7 +58,7 @@ argz_print(struct argz *z)
     for (int i = 0; z[i].name; i++) {
         if (!argz_is_available(z, i, NULL))
             continue;
-        printf("    %-*s    %s\n", len, z[i].name, z[i].help ?: "");
+        printf("    %-*s    %s\n", len, z[i].name, z[i].help ? z[i].help : "");
     }
 }
 
diff --git a/secret.c b/secret.c
index 29c5224..349209b 100644
--- a/secret.c
+++ b/secret.c
@@ -25,6 +25,15 @@
 struct {
     char path[1024];
     int pipe[2];
+    union {
+        struct {
+            uint8_t version;
+            uint8_t master[hydro_pwhash_MASTERKEYBYTES];
+            uint8_t opslimit[8];
+            // reserved
+        };
+        uint8_t buf[S_ENTRYSIZE];
+    } hdr;
     struct {
         uint8_t key[hydro_secretbox_KEYBYTES];
         char msg[S_ENTRYSIZE - hydro_secretbox_HEADERBYTES];
@@ -144,20 +153,20 @@ s_input(unsigned char *buf, size_t size, const char *prompt)
     if (ret <= 0)
         s_exit(0);
 
-    ret--;
+    size_t len = ret - 1;
 
-    if (buf[ret] != '\n') {
+    if (buf[len] != '\n') {
         if (ret == size)
             s_fatal("Input too long!");
         s_exit(0);
     }
-    for (ssize_t i = 0; i < ret; i++) {
+    for (size_t i = 0; i < len; i++) {
         if (buf[i] < ' ')
             s_fatal("Invalid input!");
     }
 
-    memset(buf + ret, 0, size - ret);
-    return ret;
+    memset(buf + len, 0, size - len);
+    return len;
 }
 
 static int
@@ -166,7 +175,7 @@ s_open_secret(int use_tty)
     int fd = open(s.path, O_RDWR);
 
     if (fd == -1) switch (errno) {
-        case ENOENT: s_fatal("No %s", s.path);
+        case ENOENT: s_fatal("Secret store %s doesn't exist", s.path);
         default:     s_fatal("%s: %s", s.path, strerror(errno));
     }
 
@@ -178,10 +187,11 @@ s_open_secret(int use_tty)
     if (fcntl(fd, F_SETLKW, &fl))
         s_fatal("Unable to lock %s", s.path);
 
-    uint8_t master[hydro_pwhash_MASTERKEYBYTES];
+    if (s_read(fd, s.hdr.buf, sizeof(s.hdr.buf)))
+        s_fatal("Unable to read %s", s.path);
 
-    if (s_read(fd, master, sizeof(master)))
-        s_fatal("Unable to parse %s", s.path);
+    if (s.hdr.version)
+        s_fatal("Bad version!");
 
     const char *agent = getenv(S_ENV_AGENT);
     int wfd = -1, rfd = -1;
@@ -203,7 +213,9 @@ s_open_secret(int use_tty)
 
     if (hydro_pwhash_deterministic(s.x.key, sizeof(s.x.key),
                                    (char *)pass, len,
-                                   s.ctx_master, master, 100000, 0, 1))
+                                   s.ctx_master, s.hdr.master,
+                                   load64_le(s.hdr.opslimit),
+                                   0, 1))
         s_fatal("Call of the Jedi...");
 
     return fd;
@@ -217,7 +229,7 @@ s_print_keys(int use_tty)
     while (!s_read(fd, s.enc, sizeof(s.enc))) {
         if (hydro_secretbox_decrypt(s.x.msg,
                                     s.enc, sizeof(s.enc), 0,
-                                    s.ctx_master, s.x.key))
+                                    s.ctx_secret, s.x.key))
             continue;
         s_write(1, s.x.msg, strnlen(s.x.msg, sizeof(s.x.msg)));
         s_write(1, "\n", 1);
@@ -299,9 +311,10 @@ s_init(int argc, char **argv, void *data)
         default:     s_fatal("%s: %s", s.path, strerror(errno));
     }
 
-    uint8_t master[hydro_pwhash_MASTERKEYBYTES];
-    hydro_random_buf(master, sizeof(master));
-    s_write(fd, master, sizeof(master));
+    s.hdr.version = 0;
+    hydro_random_buf(s.hdr.master, sizeof(s.hdr.master));
+    store64_le(s.hdr.opslimit, 10000);
+    s_write(fd, s.hdr.buf, sizeof(s.hdr.buf));
     return 0;
 }
 
@@ -598,7 +611,8 @@ main(int argc, char **argv)
         {"show",   "Show an existing secret",         &s_show,   .alt = alts, .grp = 1},
         {"change", "Change an existing secret",       &s_change, .alt = altc, .grp = 1},
         {"agent",  "Run a process in a trusted zone", &s_agent,  .alt = altz, .grp = 1},
-        {}};
+        {NULL}
+    };
 
     if (argc == 1) {
         printf("Available commands:\n");