tagent: Only watch POLLOUT when key is loaded - 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 cb5cd138e476c31fdc7436f797b095b2e460bdf5
 (DIR) parent fc777644442cd8bf8742e916aef145e281ae1b01
 (HTM) Author: Willy Goiffon <dev@z3bra.org>
       Date:   Fri, 23 Aug 2019 13:50:46 +0200
       
       agent: Only watch POLLOUT when key is loaded
       
       This fix a bug where you cannot send the key to the agent.
       
       POLLOUT event will always be present in the case of a unix domain socket,
       and is ready right when the session is established, before any data can
       be received.
       
       It means that when the key is not in memory, and the client connects to
       send it, POLLOUT will be ready while POLLIN is not. As the key is not in
       memory, the agent simply closes the connection before the client could
       send the key.
       
       As a side effect, once the key is in memory, you cannot overwrite the
       in-memory key by simply sending some data again (which is good!).
       To do so, one must first kill -USR1 the agent to make it forget the key,
       tthen send it again.
       
       Diffstat:
         M safe-agent.c                        |      24 +++++++++++++-----------
       
       1 file changed, 13 insertions(+), 11 deletions(-)
       ---
 (DIR) diff --git a/safe-agent.c b/safe-agent.c
       t@@ -170,17 +170,22 @@ servekey(int timeout)
        
                for (;;) {
                        pfd.fd = accept(sfd, NULL, NULL);
       -                pfd.events = POLLIN|POLLOUT|POLLERR;
       +                pfd.revents = 0;
       +                pfd.events = POLLIN;
       +
       +                if (s.loaded)
       +                        pfd.events |= POLLOUT;
        
                        if (pfd.fd < 0)
                                err(1, "%s", sockp);
        
       -                if ((r = poll(&pfd, 1, 0)) < 1)
       +                if ((r = poll(&pfd, 1, 100)) < 0)
                                return r;
        
                        if (pfd.revents & POLLIN) {
                                if (verbose)
       -                                fprintf(stderr, "reading key from client\n");
       +                                fprintf(stderr, "reading key from client fd %d\n", pfd.fd);
       +
                                n = xread(pfd.fd, s.saltkey, sizeof(s.saltkey));
                                if (n == sizeof(s.saltkey)) {
                                        s.loaded = 1;
       t@@ -196,15 +201,12 @@ servekey(int timeout)
                                                fprintf(stderr, "failed to load key in memory\n");
                                }
                        } else if (pfd.revents & POLLOUT) {
       -                        if (s.loaded) {
       -                                if (verbose)
       -                                        fprintf(stderr, "sending key to client\n");
       -                                xwrite(pfd.fd, s.saltkey, sizeof(s.saltkey));
       -                        } else {
       -                                if (verbose)
       -                                        fprintf(stderr, "no key loaded in memory\n");
       -                        }
       +                        if (verbose)
       +                                fprintf(stderr, "sending key to client fd %d\n", pfd.fd);
       +
       +                        xwrite(pfd.fd, s.saltkey, sizeof(s.saltkey));
                        }
       +
                        close(pfd.fd);
                }