From 8a48afccb97462b0dc261e8c99c0825295ebc019 Mon Sep 17 00:00:00 2001 From: Joursoir Date: Wed, 3 Mar 2021 20:10:05 +0000 Subject: cmd 'edit' has become more secure --- src/constants.h | 1 + src/easydir.c | 34 ----------------- src/easydir.h | 1 - src/main.c | 114 ++++++++++++++++++++++++++++++++------------------------ 4 files changed, 66 insertions(+), 84 deletions(-) (limited to 'src') diff --git a/src/constants.h b/src/constants.h index 1df4898..2168883 100644 --- a/src/constants.h +++ b/src/constants.h @@ -24,6 +24,7 @@ #define LOCKPASS_DIR ".lock-password/" #define GPGKEY_FILE ".gpg-key" +#define STD_TEXT_EDITOR "vi" #define errprint(RET, ...) \ do { \ diff --git a/src/easydir.c b/src/easydir.c index c94b944..cf10110 100644 --- a/src/easydir.c +++ b/src/easydir.c @@ -54,37 +54,3 @@ int count_dir_entries(const char *path) closedir(dir); return counter; } - -char *fileCropLineFeed(char *path, char *text, int maxlen) -{ - FILE *file = fopen(path, "r+"); - if(file == NULL) callError(130); - - int symbol; - int pos = 0; - char *str = (char *) malloc(sizeof(char) * maxlen); - while((symbol = fgetc(file))) - { - switch(symbol) - { - case '\n': - case EOF: { - str[pos] = '\0'; - pos = -1; // for break while - break; - } - default: { - str[pos] = symbol; - pos++; - break; - } - } - if(pos == -1) break; - if(pos > maxlen-1) { str[pos-1] = '\0'; break; } - } - fclose(file); - - strcpy(text, str); - free(str); - return text; -} diff --git a/src/easydir.h b/src/easydir.h index cfd4494..292002e 100644 --- a/src/easydir.h +++ b/src/easydir.h @@ -27,6 +27,5 @@ enum status_file { int file_exist(const char *path); int count_dir_entries(const char *path); -char *fileCropLineFeed(char *path, char *text, int maxlen); #endif \ No newline at end of file diff --git a/src/main.c b/src/main.c index d38b84a..4b19e82 100644 --- a/src/main.c +++ b/src/main.c @@ -26,6 +26,8 @@ #include #include #include +#include +#include #include "constants.h" #include "easydir.h" @@ -159,71 +161,85 @@ int cmd_insert(int argc, char *argv[]) int cmd_edit(int argc, char *argv[]) { - usageprint("Temporarily unavailable :(\n"); - -/* const char description[] = "edit passname\n"; - int result; + int result, fd, pid, len_pass, save_errno; + /* We expect tmpfs to be mounted at /dev/shm */ + char path_tmpfile[] = "/dev/shm/lpass.XXXXXX"; + char *editor, *password; char *path = argv[2]; if(!path) usageprint("%s", description); - dbgprint("passname: %s\n", path); result = check_sneaky_paths(path); if(result) errprint(1, "You have used forbidden paths\n"); - result = file_exist(path); - if(result == F_NOEXIST) - errprint(1, "No such file exists\n"); - else if(result == F_ISDIR) - errprint(1, "It is a directory\n"); - - // configure text editor file - char text_editor[MAXLEN_TEXTEDITOR]; - FILE *f_texteditor = fopen(TEXTEDITOR_FILE, "r"); - if(f_texteditor == NULL) { - f_texteditor = fopen(TEXTEDITOR_FILE, "w"); - if(f_texteditor == NULL) - errprint(1, "fopen() failed"); - fputs(STANDARD_TEXTEDITOR, f_texteditor); // in file - strcpy(text_editor, STANDARD_TEXTEDITOR); // in variable - } - else { - if(!fgets(text_editor, sizeof(char)*MAXLEN_TEXTEDITOR, f_texteditor)) - errprint(1, "fgets() failed"); - } - fclose(f_texteditor); - - dbgprint("text editor: %s\n", text_editor); - // end configure + editor = getenv("EDITOR"); + if(!editor) + editor = STD_TEXT_EDITOR; - // decryption - char *public_gpgkey = get_pubkey(); + password = get_password(path); + if(password == NULL) + errprint(1, "Decrypt password failed\n"); - char *decrypt_arg[] = {"gpg", "-d", "--quiet", "-r", public_gpgkey, "-o", path, gPath_pass, NULL}; - easyFork("gpg", decrypt_arg); + fd = mkstemp(path_tmpfile); + if(fd == -1) { + free(password); + errprint(1, "mkstemp() failed\n"); + } + dbgprint("tmp file: %s\n", path_tmpfile); + + len_pass = strlen(password); + result = write(fd, password, len_pass); + free(password); + close(fd); + if(result != len_pass) { + unlink(path_tmpfile); + errprint(1, "Write password to temporary file failed\n"); + } - // start vim/etc for edit passowrd - char *editor_arg[] = {text_editor, path, NULL}; - easyFork(text_editor, editor_arg); + // fork for text editor + char *editor_arg[] = {editor, path_tmpfile, NULL}; + pid = fork(); + if(pid == -1) { + unlink(path_tmpfile); + errprint(1, "%s fork() failed\n", editor); + } + if(pid == 0) { /* new process */ + execvp(editor, editor_arg); + perror(editor); + exit(1); + } + wait(&pid); - // delete '\n' and paste good pass - char password[maxlen_pass]; - fileCropLineFeed(path, password, maxlen_pass); + fd = open(path_tmpfile, O_RDONLY); + if(fd == -1) { + unlink(path_tmpfile); + perror("open"); + return 1; + } - FILE *file = fopen(path, "w"); - if(file == NULL) callError(108); - fputs(password, file); - fclose(file); + password = malloc(sizeof(char) * (maxlen_pass + 1)); + len_pass = read(fd, password, maxlen_pass); + save_errno = errno; + close(fd); + unlink(path_tmpfile); + if(len_pass < minlen_pass) { + free(password); + if(len_pass == -1) + errprint(1, "Read temporary file: %s\n", strerror(save_errno)); + else + errprint(1, "Min. password length is %d\n", minlen_pass); + } + password[len_pass-1] = '\0'; + dbgprint("new pass: %s\n", password); - // encryption - char *encrypt_arg[] = {"gpg", "--quiet", "--yes", "-r", public_gpgkey, "-e", path, NULL}; - easyFork("gpg", encrypt_arg); + // encrypt + result = insert_pass(path, password); + free(password); + if(result) + errprint(1, "Can't add password to LockPassword\n"); - remove(path); - free(public_gpgkey); -*/ return 0; } -- cgit v1.2.3-18-g5258