From 38a3be4a3eeacec75a534fef6951b9484b4d7098 Mon Sep 17 00:00:00 2001 From: Joursoir Date: Wed, 28 Oct 2020 14:12:54 +0000 Subject: feature: copy password to clipboard --- Makefile | 10 +++++++--- implementation.c | 27 ++++++++++++++++++++++----- implementation.h | 6 +++--- lpass_copy.sh | 24 ++++++++++++++++++++++++ main.c | 48 ++++++++++++++++++++++++------------------------ 5 files changed, 80 insertions(+), 35 deletions(-) create mode 100755 lpass_copy.sh diff --git a/Makefile b/Makefile index d4520b3..5122e69 100755 --- a/Makefile +++ b/Makefile @@ -3,6 +3,7 @@ CC = gcc CFLAGS = -Wall -g SOURCES = easydir.c handerror.c implementation.c main.c OBJECTS = $(SOURCES:.c=.o) +BASH = lpass_copy.sh EXECUTABLE = lpass .PHONY: all clean install uninstall @@ -19,10 +20,13 @@ $(EXECUTABLE): $(OBJECTS) @$(CC) $(CFLAGS) -o $(EXECUTABLE) $(OBJECTS) install: all - @echo installing file to $(PREFIX) + @echo installing files to $(PREFIX) @install $(EXECUTABLE) $(PREFIX) @chmod 755 $(PREFIX)/$(EXECUTABLE) + @install $(BASH) $(PREFIX) + @chmod 755 $(PREFIX)/$(BASH) uninstall: - @echo removing file from $(PREFIX) - @rm -rf $(PREFIX)/$(EXECUTABLE) \ No newline at end of file + @echo removing files from $(PREFIX) + @rm -rf $(PREFIX)/$(EXECUTABLE) + @rm -rf $(PREFIX)/$(BASH) \ No newline at end of file diff --git a/implementation.c b/implementation.c index 04af102..3ba2be7 100644 --- a/implementation.c +++ b/implementation.c @@ -13,11 +13,24 @@ /* define in implementation.h */ // GPG_PUBLICKEY_MAXLENGTH 1025 +#define BASH_EXEC_COPY "lpass_copy.sh" + // == global var == extern char *gPath_rootdir; // /home/[username]/.lockpassword/ extern char *gPath_subdir; // example: programming/github.com extern char *gPath_pass; // example: programming/github.com/joursoir.gpg +static void copyText(char *password) +{ + size_t size = (strlen(password) + strlen(BASH_EXEC_COPY) + 1) * sizeof(char); + char *command = malloc(size); + + snprintf(command, size, "%s %s", BASH_EXEC_COPY, password); + system(command); + + free(command); +} + void checkForbiddenPaths(char *path) // check two dot in path { int firstdot = 0; @@ -45,7 +58,7 @@ char *getGPGKey(char *dest, size_t size) return dest; } -char* getPassword(char *path_pass, char *password, size_t size) +char* getPassword(char *path_pass, char *password, size_t size, int flag_copy) { int size_gpgkey = sizeof(char) * GPG_PUBLICKEY_MAXLENGTH; char *secret_gpgkey = (char *) malloc(size_gpgkey); @@ -62,6 +75,8 @@ char* getPassword(char *path_pass, char *password, size_t size) } fclose(filePass); + if(flag_copy) copyText(password); + remove(path_pass); free(secret_gpgkey); return password; @@ -80,7 +95,7 @@ void nonvisibleEnter(int status) tcsetattr(0, TCSANOW, &term_settings); } -void insertPass(char *add_path, char *password) +void insertPass(char *add_path, char *password, int flag_copy) { /* gPath_rootdir = /home/[username]/.lock-password/ add_path = banks/france/[number] @@ -103,6 +118,8 @@ void insertPass(char *add_path, char *password) fputs(password, filePass); fclose(filePass); + if(flag_copy) copyText(password); + // encryption char *arguments2[] = {"gpg", "--quiet", "--yes", "-r", secret_gpgkey, "-e", add_path, NULL}; easyFork("gpg", arguments2); @@ -137,7 +154,7 @@ char *typePass(char *text, char *dest, int minlen, int maxlen) return dest; } -int userEnterPassword(int minlen, int maxlen, char *path_insert, int flag_echo) +int userEnterPassword(int minlen, int maxlen, char *path_insert, int flag_echo, int flag_copy) { char *pass_one = (char *) malloc(sizeof(char) * maxlen); int rvalue = 0; @@ -150,14 +167,14 @@ int userEnterPassword(int minlen, int maxlen, char *path_insert, int flag_echo) nonvisibleEnter(0); if(strcmp(pass_one, pass_two) == 0) { - insertPass(path_insert, pass_one); + insertPass(path_insert, pass_one, flag_copy); rvalue = 1; } free(pass_two); } else { typePass("Type your password: ", pass_one, minlen, maxlen); - insertPass(path_insert, pass_one); + insertPass(path_insert, pass_one, flag_copy); rvalue = 1; } diff --git a/implementation.h b/implementation.h index 7ede6be..f41cc4a 100644 --- a/implementation.h +++ b/implementation.h @@ -5,11 +5,11 @@ void checkForbiddenPaths(char *path); char *getGPGKey(char *dest, size_t size); -char* getPassword(char *path_pass, char *password, size_t size); +char* getPassword(char *path_pass, char *password, size_t size, int flag_copy); void nonvisibleEnter(int status); -void insertPass(char *add_path, char *password); +void insertPass(char *add_path, char *password, int flag_copy); char *typePass(char *text, char *dest, int minlen, int maxlen); -int userEnterPassword(int minlen, int maxlen, char *path_insert, int flag_echo); +int userEnterPassword(int minlen, int maxlen, char *path_insert, int flag_echo, int flag_copy); char *generatePassword(char *dest, int amount, int max_len); unsigned long hash(char *str); int getOverwriteAnswer(char *path); diff --git a/lpass_copy.sh b/lpass_copy.sh new file mode 100755 index 0000000..9499dec --- /dev/null +++ b/lpass_copy.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash + +error() { + echo "$@" + exit 1 +} + +if [[ -z $1 ]]; then + error "Error: nothing to copy" +fi + +if [[ -n $WAYLAND_DISLPLAY ]]; then + command=(wl-copy) + if [[ $X_SELECTION == primary ]]; then + command+=( --primary ) + fi +elif [[ -n $DISPLAY ]]; then + command=(xclip -selection clipboard) +else + error "Error: X11 or Wayland display were not detected" +fi + +echo "$1" | "${command[@]}" || error "Error: failed to copy data to clipboard" +echo "Password copied to clipboard." \ No newline at end of file diff --git a/main.c b/main.c index 4848606..06154ec 100644 --- a/main.c +++ b/main.c @@ -35,7 +35,6 @@ #define HASH_INIT 6385337657 #define HASH_HELP 6385292014 #define HASH_VERSION 229486327000139 -#define HASH_COPY 6385123360 #define HASH_EDIT 6385183019 #define HASH_MV 5863624 #define HASH_MOVE 249844339311324255 @@ -52,7 +51,7 @@ #define STR_EDITUSE "Use: lpass edit [-t=text-editor] passname\n" #define STR_GENERATEUSE "Use: lpass generate [-l=pass-length] [-f] passname\n" #define STR_REMOVEUSE "Use: lpass remove/rm/delete passname\n" -#define STR_MOVEUSE "Use: lpass move/mv [-f] old-path new-path" +#define STR_MOVEUSE "Use: lpass move/mv [-f] old-path new-path\n" // == global var == char *gPath_rootdir; // /home/[username]/.lockpassword/ @@ -105,11 +104,6 @@ static void cmd_init(int argc, char *argv[]) printf("LockPassword initialized for %s\n", gpg_key); } -static void cmd_copy(int argc, char *argv[]) -{ - printf("Coming soon...\n"); -} - static void cmd_edit(int argc, char *argv[]) { const struct option long_options[] = { @@ -258,18 +252,20 @@ static void cmd_move(int argc, char *argv[]) static void cmd_generate(int argc, char *argv[]) { - int pass_length = STANDARD_AMOUNT_GENERATE_SYMBOLS, flag_force = 0, result; + int pass_length = STANDARD_AMOUNT_GENERATE_SYMBOLS, flag_force = 0, flag_copy = 0, result; const struct option long_options[] = { {"length", required_argument, NULL, 'l'}, {"force", no_argument, NULL, 'f'}, + {"copy", no_argument, NULL, 'c'}, {NULL, 0, NULL, 0} }; - while((result = getopt_long(argc, argv, "l:f", long_options, NULL)) != -1) { + while((result = getopt_long(argc, argv, "l:fc", long_options, NULL)) != -1) { switch(result) { // if optarg - incorrect number, atoi return 0 case 'l': { pass_length = atoi(optarg); break; } case 'f': { flag_force = 1; break; } + case 'c': { flag_copy = 1; break; } default: printError(STR_GENERATEUSE); } } @@ -301,24 +297,26 @@ static void cmd_generate(int argc, char *argv[]) char gpass[MAXLEN_PASSWORD]; generatePassword(gpass, pass_length, MAXLEN_PASSWORD); - insertPass(path_to_password, gpass); - printf("Generated password: %s\n", gpass); + insertPass(path_to_password, gpass, flag_copy); + if(!flag_copy) printf("Generated password: %s\n", gpass); printf("Password added successfully for %s\n", path_to_password); } static void cmd_insert(int argc, char *argv[]) { - int flag_echo = 0, flag_force = 0, result; + int flag_echo = 0, flag_force = 0, flag_copy = 0, result; const struct option long_options[] = { {"echo", no_argument, NULL, 'e'}, {"force", no_argument, NULL, 'f'}, + {"copy", no_argument, NULL, 'c'}, {NULL, 0, NULL, 0} }; - while((result = getopt_long(argc, argv, "ef", long_options, NULL)) != -1) { + while((result = getopt_long(argc, argv, "efc", long_options, NULL)) != -1) { switch(result) { case 'e': { flag_echo = 1; break; } case 'f': { flag_force = 1; break; } + case 'c': { flag_copy = 1; break; } default: printError(STR_INSERTUSE); } } @@ -343,8 +341,9 @@ static void cmd_insert(int argc, char *argv[]) } } - if(userEnterPassword(MINLEN_PASSWORD, MAXLEN_PASSWORD, path_to_password, flag_echo) == 1) + if(userEnterPassword(MINLEN_PASSWORD, MAXLEN_PASSWORD, path_to_password, flag_echo, flag_copy) == 1) { printf("Password added successfully for %s\n", path_to_password); + } else printf("Passwords do not match\n"); } @@ -370,28 +369,30 @@ static void cmd_showtree(int argc, char *argv[]) int flag_copy = 0, result; char *path; const struct option long_options[] = { - {"copy", required_argument, NULL, 'c'}, + {"copy", no_argument, NULL, 'c'}, {NULL, 0, NULL, 0} }; - while((result = getopt_long(argc, argv, "c:", long_options, NULL)) != -1) { + while((result = getopt_long(argc, argv, "c", long_options, NULL)) != -1) { switch(result) { - case 'c': { flag_copy = 1; path = optarg; break; } + case 'c': { flag_copy = 1; break; } default: printError(STR_SHOWTREEUSE); } } #if defined(DEBUG) for(int i=0; i < argc; i++) printf("arg: %s\n", argv[i]); + printf("passname: %s\n", argv[optind]); #endif - - if(!flag_copy) { - if(argv[1] == NULL) { + + if(argv[optind] == NULL) { + if(flag_copy) printError(STR_SHOWTREEUSE); + else { path = (char *) malloc(sizeof(char) * 2); strcpy(path, "."); } - else path = argv[1]; } + else path = argv[optind]; checkForbiddenPaths(path); if(opendir(path) != NULL) // if it's directory @@ -419,8 +420,8 @@ static void cmd_showtree(int argc, char *argv[]) if(checkFileExist(gPath_pass) == 1) // exist { char password[MAXLEN_PASSWORD]; - getPassword(path, password, sizeof(char)*MAXLEN_PASSWORD); - printf("%s\n", password); + getPassword(path, password, sizeof(char)*MAXLEN_PASSWORD, flag_copy); + if(!flag_copy) printf("%s\n", password); } else printf("Error: %s is not in the password storage\n", path); } @@ -468,7 +469,6 @@ int main(int argc, char *argv[]) switch(ihash) { case HASH_INIT: { cmd_init(argc, argv); break; } - case HASH_COPY: { cmd_copy(argc, argv); break; } case HASH_EDIT: { cmd_edit(argc, argv); break; } case HASH_MV: case HASH_MOVE: { cmd_move(argc, argv); break; } -- cgit v1.2.3-18-g5258