/*** This file is part of LockPassword Copyright (C) 2020-2021 Aleksandr D. Goncharov (Joursoir) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . ***/ #include #include #include #include #include #include #include #include #include #include "routines.h" #include "constants.h" #include "easydir.h" #include "r-gpgme.h" #if defined(DISPLAY) #include "r-x11.h" #endif #include "output.h" #define NUMBER_ALLOWED_CHARS (10+26+26+8) int copy_outside(char *password) { #if defined(DISPLAY) int pid; pid = fork(); if(pid == -1) { print_error("Error: X11 fork() failed\n"); return 1; } if(pid == 0) /* new process */ exit(run_clipboard(password)); return 0; #else if(getenv("WAYLAND_DISPLAY") != NULL) { char * const wl_copy[] = {"wl-copy", password, NULL}; int pid; pid = fork(); if(pid == -1) { print_error("Error: Wayland fork() failed\n"); return 1; } if(pid == 0) { /* new process */ execvp("wl-copy", wl_copy); perror("wl-copy"); exit(1); } return 0; } print_error("Error: You didn't have x11 or wayland when app builded\n"); return 1; #endif } int check_sneaky_paths(const char *path) { int length = strlen(path), i; for(i = 1; i < length; i++) { if(path[i-1] == '.' && path[i] == '.') { print_error("Error: A double dot is found in the path.\n"); return 1; } } return 0; } char *get_pubkey() { char *pubkey; FILE *fileGPG = fopen(".gpg-key", "r"); if(fileGPG == NULL) { if(errno == ENOENT) print_error("Error: No GPG key exists. Use \"lpass init\"\n"); else print_error("Error: %s\n", strerror(errno)); return NULL; } pubkey = malloc(sizeof(char) * (maxlen_fingerprint + 1)); if (!pubkey) { print_error("Unable to allocate space for the public key.\n"); fclose(fileGPG); return NULL; } if(fgets(pubkey, maxlen_fingerprint + 1, fileGPG) == NULL) { print_error("Error: %s\n", strerror(errno)); free(pubkey); pubkey = NULL; } fclose(fileGPG); return pubkey; } char *get_password(const char *path) { return decrypt_data(path); } void visible_enter(int status) { struct termios term_settings; tcgetattr(0, &term_settings); // get current settings if(status == 1) term_settings.c_lflag |= ECHO; else term_settings.c_lflag &= ~ECHO; tcsetattr(0, TCSANOW, &term_settings); } static void mkdir_recursive(const char *path) { char *subpath, *fullpath; fullpath = strdup(path); subpath = dirname(fullpath); if(subpath[0] != '.') mkdir_recursive(subpath); mkdir(path, S_IRWXU); free(fullpath); } int insert_pass(const char *path, const char *password) { char *public_gpgkey = get_pubkey(); if(public_gpgkey == NULL) return 1; // create directories char *tmp, *dirs_path; tmp = strdup(path); dirs_path = dirname(tmp); if(dirs_path[0] != '.') mkdir_recursive(dirs_path); free(tmp); int ret = ecnrypt_data(path, password, public_gpgkey); free(public_gpgkey); return ret; } char *get_input(int minlen, int maxlen) { int len; char *pass = malloc(sizeof(char) * (maxlen + 1)); if (!pass) { print_error("Unable to allocate space for the password.\n"); return NULL; } if(fgets(pass, maxlen + 1, stdin) == NULL) { print_error("Error: %s\n", strerror(errno)); free(pass); return NULL; } len = strlen(pass); if(len < minlen) { free(pass); return NULL; } if(pass[len-1] == '\n') pass[len-1] = '\0'; return pass; } char *gen_password(int length) { int i; char allowed_chars[NUMBER_ALLOWED_CHARS] = "abcdefghijklmnoqprstuvwyzx" "ABCDEFGHIJKLMNOQPRSTUYWVZX" "0123456789" "!@#$^&*?"; char *password = malloc(sizeof(char) * (length + 1)); if (!password) { print_error("Unable to allocate space for the password.\n"); return NULL; } srand(time(NULL)); for(i = 0; i < length; i++) password[i] = allowed_chars[rand() % NUMBER_ALLOWED_CHARS]; password[i] = '\0'; return password; } static void clear_stdin() { int garbage; while( (garbage = fgetc(stdin)) != '\n' && garbage != EOF ) ; } int overwrite_answer(const char *path) { int answer; printf("Password for \"%s\" exists. Overwrite? (Y/N)\n", path); while((answer = fgetc(stdin))) { clear_stdin(); switch(answer) { case 'Y': case 'y': return 'y'; case 'N': case 'n': case EOF: return 'n'; default: { printf("Overwrite? (Y/N) "); break; } } } return 'n'; }