tInterpret empty agent response has "No key in memory" - safe - password protected secret keeper
 (HTM) git clone git://git.z3bra.org/safe.git
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 91a51b83db319c0421378197ce9998a1d71a6cfc
 (DIR) parent 23350b3136fc4edcf2fa40975e466a8e70d27a7c
 (HTM) Author: Willy Goiffon <dev@z3bra.org>
       Date:   Mon, 24 Jun 2019 12:32:40 +0200
       
       Interpret empty agent response has "No key in memory"
       
       Whenever the agent replies to a socket read with a zero byte message,
       tthe client will assume that this is because the agent does not have the
       key in memory, and will thus prompt the user for the master password.
       
       Diffstat:
         M safe.c                              |      34 +++++++++++++++++++++++--------
       
       1 file changed, 26 insertions(+), 8 deletions(-)
       ---
 (DIR) diff --git a/safe.c b/safe.c
       t@@ -183,22 +183,36 @@ int
        readkey(struct safe *s, char *path)
        {
                int sfd;
       +        ssize_t n;
                struct sockaddr_un addr;
        
                addr.sun_family = AF_UNIX;
                strcpy(addr.sun_path, path);
        
       -        if ((sfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
       +        if ((sfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
       +                err(1, "%s", path);
                        return -1;
       +        }
        
       -        if (connect(sfd, (struct sockaddr *)&addr, sizeof(addr)) < 0)
       +        if (connect(sfd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
       +                err(1, "%s", path);
       +                return -1;
       +        }
       +
       +        if ((n = xread(sfd, s->salt, sizeof(s->salt), NULL)) < 0) {
       +                err(1, "%s", path);
                        return -1;
       +        }
        
       -        if (xread(sfd, s->salt, sizeof(s->salt), NULL) < 0)
       +        if (!n) {
       +                close(sfd);
                        return -1;
       +        }
        
       -        if (xread(sfd, s->key, sizeof(s->key), NULL) < 0)
       +        if (xread(sfd, s->key, sizeof(s->key), NULL) < 0) {
       +                err(1, "%s", path);
                        return -1;
       +        }
        
                close(sfd);
        
       t@@ -316,7 +330,7 @@ readsecret(struct safe *s, int in, int out)
        int
        main(int argc, char *argv[])
        {
       -        int fd, aflag = 0, pflag = 0;
       +        int fd, haskey = 0, aflag = 0, pflag = 0;
                char *secret = NULL, *sockp = NULL, *safe = SAFE;
                struct safe s;
        
       t@@ -354,9 +368,11 @@ main(int argc, char *argv[])
                        err(1, "%s", MASTER);
        
                if (sockp && !pflag) {
       -                if (readkey(&s, sockp) < 0)
       -                        err(1, "%s", sockp);
       -        } else {
       +                if (!readkey(&s, sockp))
       +                        haskey = 1;
       +        }
       +
       +        if (!haskey) {
                        readpass("password:", &passphrase, &pplen);
        
                        /* write master password entry if not present */
       t@@ -374,6 +390,8 @@ main(int argc, char *argv[])
                                xread(fd, s.salt, sizeof(s.salt), NULL);
                                deriv((char *)passphrase, &s);
                        }
       +
       +                haskey = 1;
                }
        
                /* try to decrypt master password first, to ensure passphrase match */