Sun, 08 Aug 2021 12:45:31 +0200
implement secretstore unlock command
dav/config.c | file | annotate | diff | comparison | revisions | |
dav/main.c | file | annotate | diff | comparison | revisions | |
dav/pwd.c | file | annotate | diff | comparison | revisions | |
dav/pwd.h | file | annotate | diff | comparison | revisions | |
libidav/utils.c | file | annotate | diff | comparison | revisions | |
libidav/utils.h | file | annotate | diff | comparison | revisions |
--- a/dav/config.c Sun Aug 08 11:45:36 2021 +0200 +++ b/dav/config.c Sun Aug 08 12:45:31 2021 +0200 @@ -574,6 +574,10 @@ int load_secretstore(const xmlNode *node) { // currently only one secretstore is supported + if(!pstore) { + return 0; + } + node = node->children; int error = 0; while(node) { @@ -581,9 +585,9 @@ char *value = util_xml_get_text(node); if(value) { if(xstreq(node->name, "unlock-command")) { - secretstore_unlock_cmd = strdup(value); + pstore->unlock_cmd = strdup(value); } else if(xstreq(node->name, "lock-command")) { - secretstore_lock_cmd = strdup(value); + pstore->lock_cmd = strdup(value); } } }
--- a/dav/main.c Sun Aug 08 11:45:36 2021 +0200 +++ b/dav/main.c Sun Aug 08 12:45:31 2021 +0200 @@ -466,10 +466,35 @@ return 1; } - char *ps_password = util_password_input("Master password: "); + char *ps_password = NULL; + if(secrets->unlock_cmd && strlen(secrets->unlock_cmd) > 0) { + UcxBuffer *cmd_out = ucx_buffer_new(NULL, 128, UCX_BUFFER_AUTOEXTEND); + if(!util_exec_command(secrets->unlock_cmd, cmd_out)) { + // command successful, get first line from output without newline + // and use that as password for the secretstore + size_t len = 0; + for(size_t i=0;i<=cmd_out->size;i++) { + if(i == cmd_out->size || cmd_out->space[i] == '\n') { + len = i; + break; + } + } + if(len > 0) { + ps_password = malloc(len + 1); + memcpy(ps_password, cmd_out->space, len); + ps_password[len] = 0; + } + } + ucx_buffer_free(cmd_out); + } + if(!ps_password) { - return 1; + ps_password = util_password_input("Master password: "); + if(!ps_password) { + return 1; + } } + if(pwdstore_setpassword(secrets, ps_password)) { fprintf(stderr, "Error: cannot create key from password\n"); return 1;
--- a/dav/pwd.c Sun Aug 08 11:45:36 2021 +0200 +++ b/dav/pwd.c Sun Aug 08 12:45:31 2021 +0200 @@ -62,6 +62,8 @@ p->index = ucx_map_new(16); p->content = buf; p->key = NULL; + p->unlock_cmd = NULL; + p->lock_cmd = NULL; p->encoffset = PWDS_HEADER_SIZE; p->isdecrypted = 0;
--- a/dav/pwd.h Sun Aug 08 11:45:36 2021 +0200 +++ b/dav/pwd.h Sun Aug 08 12:45:31 2021 +0200 @@ -115,6 +115,16 @@ DavKey *key; /* + * optional shell command, that is used for getting the master password + */ + char *unlock_cmd; + + /* + * optional shell command, that is exected when the secretstore is closed + */ + char *lock_cmd; + + /* * start offset of the encrypted buffer */ uint32_t encoffset;
--- a/libidav/utils.c Sun Aug 08 11:45:36 2021 +0200 +++ b/libidav/utils.c Sun Aug 08 12:45:31 2021 +0200 @@ -44,6 +44,9 @@ #define IS_PATH_SEPARATOR(c) (c == '/' || c == '\\') #define PATH_SEPARATOR '\\' #else +#include <unistd.h> +#include <spawn.h> +#include <sys/wait.h> #include <termios.h> #define getpasswordchar() getchar() #define IS_PATH_SEPARATOR(c) (c == '/') @@ -1114,6 +1117,55 @@ return str; } +int util_exec_command(char *command, UcxBuffer *outbuf) { +#ifdef _WIN32 + fprintf(stderr, "util_exec_command unsupported\n"); + return NULL; +#endif + + int pout[2]; + if(pipe(pout)) { + perror("pipe"); + return 1; + } + + int ret = 0; + + // close stdin and stderr, use pipe for stdout + posix_spawn_file_actions_t actions; + posix_spawn_file_actions_init(&actions); + posix_spawn_file_actions_addclose(&actions, 0); + posix_spawn_file_actions_adddup2(&actions, pout[1], 1); + posix_spawn_file_actions_addclose(&actions, 2); + + char *args[4]; + args[0] = "sh"; + args[1] = "-c"; + args[2] = command; + args[3] = NULL; + + pid_t pid; // child pid + ret = posix_spawn(&pid, "/bin/sh", &actions, NULL, args, NULL); + + close(pout[1]); + + if(!ret) { + ssize_t r; + char buf[1024]; + while((r = read(pout[0], buf, 1024)) > 0) { + ucx_buffer_write(buf, 1, r, outbuf); + } + } + + // wait for child process + ret = 1; + waitpid(pid, &ret, 0); + + posix_spawn_file_actions_destroy(&actions); + close(pout[0]); + + return ret; +} char* util_hexstr(const unsigned char *data, size_t len) { size_t buflen = 2*len + 4;
--- a/libidav/utils.h Sun Aug 08 11:45:36 2021 +0200 +++ b/libidav/utils.h Sun Aug 08 12:45:31 2021 +0200 @@ -37,6 +37,7 @@ #include <sys/types.h> #include <libxml/tree.h> #include <ucx/string.h> +#include <ucx/buffer.h> #include <sys/stat.h> #include <inttypes.h> @@ -116,6 +117,8 @@ sstr_t util_readline(FILE *stream); char* util_password_input(char *prompt); +int util_exec_command(char *command, UcxBuffer *outbuf); + char* util_hexstr(const unsigned char *data, size_t len); void util_remove_trailing_pathseparator(char *path);