tMove agent functionnality in safe.c - 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 9d91b27b8b86983fb7383399a4eab63decae40db
(DIR) parent 6d148607abca29a784e2558bcc73639a81b20ae7
(HTM) Author: z3bra <contactatz3bradotorg>
Date: Fri, 24 May 2019 18:18:21 +0200
Move agent functionnality in safe.c
Diffstat:
M makefile | 33 +++++++++++--------------------
M mkfile | 27 +++++++++++----------------
D safe-agent.c | 167 -------------------------------
M safe.c | 76 +++++++++++++++++++++++++++++--
4 files changed, 96 insertions(+), 207 deletions(-)
---
(DIR) diff --git a/makefile b/makefile
t@@ -4,33 +4,24 @@ LD = $(CC)
PREFIX = /usr/local
MANPREFIX = ${PREFIX}/man
-CPPFLAGS = -D_XOPEN_SOURCE -I/usr/local/include
+CPPFLAGS = -I/usr/local/include
CFLAGS = -Wall -Wextra -pedantic
LDFLAGS = -L/usr/local/lib
LDLIBS = -lsodium
-all: safe safe-agent
-
-safe-agent: safe-agent.o readpassphrase.o
- $(LD) -o $@ safe-agent.o readpassphrase.o $(LDFLAGS) $(LDLIBS)
-
-safe: safe.o
- $(LD) -o $@ safe.o $(LDFLAGS) $(LDLIBS)
+safe: safe.o readpassphrase.o
clean:
- rm -f *.o safe safe-agent
+ rm -f *.o safe
-install: safe safe-agent
- mkdir -p ${DESTDIR}${PREFIX}/bin
- cp safe ${DESTDIR}${PREFIX}/bin/safe
- cp safe-agent ${DESTDIR}${PREFIX}/bin/safe-agent
- chmod 755 ${DESTDIR}${PREFIX}/bin/safe
- chmod 755 ${DESTDIR}${PREFIX}/bin/safe-agent
- mkdir -p ${DESTDIR}${MANPREFIX}/man1
- cp safe.1 ${DESTDIR}${MANPREFIX}/man1/safe.1
- chmod 644 ${DESTDIR}${MANPREFIX}/man1/safe.1
+install: safe
+ mkdir -p ${DESTDIR}${PREFIX}/bin
+ cp safe ${DESTDIR}${PREFIX}/bin/safe
+ chmod 755 ${DESTDIR}${PREFIX}/bin/safe
+ mkdir -p ${DESTDIR}${MANPREFIX}/man1
+ cp safe.1 ${DESTDIR}${MANPREFIX}/man1/safe.1
+ chmod 644 ${DESTDIR}${MANPREFIX}/man1/safe.1
uninstall::
- rm ${DESTDIR}${PREFIX}/bin/safe
- rm ${DESTDIR}${PREFIX}/bin/safe-agent
- rm ${DESTDIR}${MANPREFIX}/man1/safe.1
+ rm ${DESTDIR}${PREFIX}/bin/safe
+ rm ${DESTDIR}${MANPREFIX}/man1/safe.1
(DIR) diff --git a/mkfile b/mkfile
t@@ -4,33 +4,28 @@ LD = ${CC}
PREFIX = /usr/local
MANPREFIX = ${PREFIX}/man
-CPPFLAGS = -D_XOPEN_SOURCE
+CPPFLAGS = -I/usr/local/include
CFLAGS = -g -Wall -Wextra -pedantic
-LDFLAGS =
+LDFLAGS = -L/usr/local/lib
LDLIBS = -lsodium
-all:V: safe safe-agent
-
-safe-agent: safe-agent.o readpassphrase.o
- $LD -o $target $prereq $LDFLAGS $LDLIBS
-
-safe: safe.o
+safe: safe.o readpassphrase.o
$LD -o $target $prereq $LDFLAGS $LDLIBS
%.o: %.c
$CC $CPPFLAGS $CFLAGS -c $stem.c
clean:V:
- rm -f *.o safe safe-agent
+ rm -f *.o safe
-install:V: ${BIN}
+install:V: safe
mkdir -p ${DESTDIR}${PREFIX}/bin
- cp ${BIN} ${DESTDIR}${PREFIX}/bin/${BIN}
- chmod 755 ${DESTDIR}${PREFIX}/bin/${BIN}
+ cp safe ${DESTDIR}${PREFIX}/bin/safe
+ chmod 755 ${DESTDIR}${PREFIX}/bin/safe
mkdir -p ${DESTDIR}${MANPREFIX}/man1
- cp ${BIN}.1 ${DESTDIR}${MANPREFIX}/man1/${BIN}.1
- chmod 644 ${DESTDIR}${MANPREFIX}/man1/${BIN}.1
+ cp safe.1 ${DESTDIR}${MANPREFIX}/man1/safe.1
+ chmod 644 ${DESTDIR}${MANPREFIX}/man1/safe.1
uninstall:V:
- rm ${DESTDIR}${PREFIX}/bin/${BIN}
- rm ${DESTDIR}${MANPREFIX}/man1/${BIN}.1
+ rm ${DESTDIR}${PREFIX}/bin/safe
+ rm ${DESTDIR}${MANPREFIX}/man1/safe.1
(DIR) diff --git a/safe-agent.c b/safe-agent.c
t@@ -1,167 +0,0 @@
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <sys/un.h>
-
-#include <err.h>
-#include <limits.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <sodium.h>
-
-#include "arg.h"
-#include "readpassphrase.h"
-
-#define MDSIZ crypto_generichash_BYTES
-#define SOCKET "/tmp/safe.sock"
-
-uint8_t *passphrase;
-uint32_t pplen;
-char *argv0;
-
-void
-usage(void)
-{
- fprintf(stderr, "usage: %s [-hf] [-s socket]\n", argv0);
- exit(1);
-}
-
-ssize_t
-xread(int fd, void *buf, size_t nbytes)
-{
- uint8_t *bp = buf;
- ssize_t total = 0;
-
- while (nbytes > 0) {
- ssize_t n;
-
- n = read(fd, &bp[total], nbytes);
- if (n < 0)
- err(1, "read");
- else if (n == 0)
- return total;
- total += n;
- nbytes -= n;
- }
- return total;
-}
-
-ssize_t
-xwrite(int fd, const void *buf, size_t nbytes)
-{
- const uint8_t *bp = buf;
- ssize_t total = 0;
-
- while (nbytes > 0) {
- ssize_t n;
-
- n = write(fd, &bp[total], nbytes);
- if (n < 0)
- err(1, "write");
- else if (n == 0)
- return total;
- total += n;
- nbytes -= n;
- }
- return total;
-}
-
-void
-hash(uint8_t *buf, size_t size, uint8_t *md, size_t mdsize)
-{
- crypto_generichash(md, mdsize, buf, size, NULL, 0);
-}
-
-
-static int
-readpass(const char *prompt, uint8_t **target, uint32_t *len)
-{
- char pass[BUFSIZ], *p;
-
- p = readpassphrase(prompt, pass, sizeof(pass), RPP_ECHO_OFF);
- if (!p)
- err(1, "readpassphrase:");
-
- if (p[0] == '\0')
- return -1;
-
- *target = realloc(*target, strlen(p)); /* not null-terminated */
- if (!*target)
- err(1, "realloc:");
-
- memcpy(*target, p, strlen(p));
- *len = strlen(p);
- return 0;
-}
-
-void
-deriv(char *pw, uint8_t *salt, uint8_t *key, size_t ks)
-{
- if (crypto_pwhash(key, ks, pw, strlen(pw),
- salt, crypto_pwhash_OPSLIMIT_INTERACTIVE,
- crypto_pwhash_MEMLIMIT_INTERACTIVE,
- crypto_pwhash_ALG_DEFAULT))
- err(1, "crypto_pwhash");
-}
-
-int
-servekey(char *path)
-{
- int cfd, sfd;
- char hex[MDSIZ*2 +1];
- uint8_t md[MDSIZ];
- uint8_t salt[crypto_pwhash_SALTBYTES];
- uint8_t key[crypto_secretstream_xchacha20poly1305_KEYBYTES];
- struct sockaddr_un addr;
-
- readpass("Passphrase:", &passphrase, &pplen);
-
- hash(passphrase, pplen, md, sizeof(md));
- sodium_memzero(passphrase, pplen);
- sodium_bin2hex(hex, sizeof(hex), md, sizeof(md));
-
- sfd = socket(AF_UNIX, SOCK_STREAM, 0);
- if (sfd < 0)
- err(1, "socket: %s", path);
-
- memset(&addr, 0, sizeof(addr));
- addr.sun_family = AF_UNIX;
- strcpy(addr.sun_path, path);
-
- if (bind(sfd, (struct sockaddr *) &addr, sizeof(addr)) < 0)
- err(1, "bind: %s", path);
-
- listen(sfd, 10);
-
- while ((cfd = accept(sfd, NULL, NULL)) > 0) {
- xread(cfd, salt, sizeof(salt));
- deriv(hex, salt, key, sizeof(key));
- xwrite(cfd, key, sizeof(key));
- close(cfd);
- }
-
- close(sfd);
-
- return 0;
-}
-
-int
-main(int argc, char *argv[])
-{
- char *socket = SOCKET;
-
- ARGBEGIN {
- case 's':
- socket = EARGF(usage());
- break;
- default:
- usage();
- } ARGEND
-
- servekey(socket);
-
- return 0;
-}
(DIR) diff --git a/safe.c b/safe.c
t@@ -18,6 +18,8 @@
#include "readpassphrase.h"
#define MDSIZ crypto_generichash_BYTES
+#define SOCKDIR "/tmp/safe-XXXXXX"
+#define SOCKET "agent"
#define SAFE ".secrets"
uint8_t *passphrase;
t@@ -192,6 +194,63 @@ deriv(char *pw, uint8_t *salt, uint8_t *key, size_t ks)
}
int
+creatsock(char *sockpath)
+{
+ int sfd;
+ char path[PATH_MAX] = SOCKDIR;
+ struct sockaddr_un addr;
+
+ if (sockpath) {
+ strncpy(path, sockpath, sizeof(path));
+ } else {
+ if (!mkdtemp(path))
+ err(1, "mkdtemp: %s", path);
+
+ strncat(path, "/", 1);
+ strncat(path, SOCKET, sizeof(path));
+ }
+
+ sfd = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (sfd < 0)
+ err(1, "socket: %s", path);
+
+ memset(&addr, 0, sizeof(addr));
+ addr.sun_family = AF_UNIX;
+ strcpy(addr.sun_path, path);
+
+ if (bind(sfd, (struct sockaddr *) &addr, sizeof(addr)) < 0)
+ err(1, "bind: %s", path);
+
+ if (listen(sfd, 10) < 0)
+ err(1, "listen: %s", path);
+
+ return sfd;
+}
+
+int
+agent(char *path)
+{
+ int cfd, sfd;
+ uint8_t salt[crypto_pwhash_SALTBYTES];
+ uint8_t key[crypto_secretstream_xchacha20poly1305_KEYBYTES];
+
+ readpass("password:", &passphrase, &pplen);
+
+ sfd = creatsock(path);
+
+ while ((cfd = accept(sfd, NULL, NULL)) > 0) {
+ xread(cfd, salt, sizeof(salt));
+ deriv((char *)passphrase, salt, key, sizeof(key));
+ xwrite(cfd, key, sizeof(key));
+ close(cfd);
+ }
+
+ close(sfd);
+
+ return 0;
+}
+
+int
getkey(char *path, uint8_t *key, uint8_t *salt)
{
int sfd;
t@@ -269,13 +328,19 @@ show_secret(int fd, char *name)
int
main(int argc, char *argv[])
{
- int aflag = 0, lflag = 0;
- char *secret = NULL, *safe = SAFE;
+ int aflag = 0, dflag = 0;
+ char *secret = NULL, *sockp = NULL, *safe = SAFE;
ARGBEGIN {
case 'a':
aflag = 1;
break;
+ case 'd':
+ dflag = 1;
+ break;
+ case 'f':
+ sockp = EARGF(usage());
+ break;
case 's':
safe = EARGF(usage());
break;
t@@ -283,9 +348,14 @@ main(int argc, char *argv[])
usage();
} ARGEND
- if (argc != 1 && !lflag)
+ if (argc != 1 && !dflag)
usage();
+ if (dflag) {
+ agent(sockp);
+ return 0;
+ }
+
if (safe) {
mkdir(safe, 0700);
if (chdir(safe) < 0)