aboutsummaryrefslogtreecommitdiffstats
path: root/src/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.c')
-rw-r--r--src/main.c470
1 files changed, 12 insertions, 458 deletions
diff --git a/src/main.c b/src/main.c
index 1b33323..22e9eb8 100644
--- a/src/main.c
+++ b/src/main.c
@@ -20,21 +20,12 @@
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
-#include <getopt.h>
-#include <dirent.h>
-#include <libgen.h>
-#include <stdarg.h>
#include <errno.h>
#include <sys/stat.h>
-#include <sys/wait.h>
-#include <fcntl.h>
#include "constants.h"
-#include "easydir.h"
-#include "xstd.h"
-#include "implementation.h"
#include "exec-cmd.h"
-#include "tree.h"
+#include "xstd.h"
struct cmd_struct {
const char *cmd;
@@ -53,438 +44,6 @@ static struct cmd_struct commands[] = {
{ NULL, NULL }
};
-int cmd_init(int argc, char *argv[])
-{
- const char description[] = "init gpg-key\n";
- char *gpg_key = argv[2];
- if(gpg_key == NULL)
- usageprint("%s", description);
-
- // create .gpg-key in storage
- FILE *filekey = fopen(GPGKEY_FILE, "w");
- if(!filekey)
- errprint(1, "fopen() failed");
-
- fputs(gpg_key, filekey);
- fclose(filekey);
-
- printf("LockPassword initialized for %s\n", gpg_key);
- return 0;
-}
-
-int cmd_insert(int argc, char *argv[])
-{
- const char description[] = "insert [-ecf] passname\n";
- 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, "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: usageprint("%s", description);
- }
- }
-
- if(optind < argc) optind++; // for skip "insert"
- dbgprint("passname: %s\n", argv[optind]);
-
- char *path = argv[optind];
- if(path == NULL)
- usageprint("%s", description);
-
- result = check_sneaky_paths(path);
- if(result)
- errprint(1, "You have used forbidden paths\n");
-
- if(file_exist(path) == F_ISFILE) {
- if(!flag_force) {
- if(overwrite_answer(path) != 'y')
- return 1;
- }
- }
-
- char *f_pass;
- if(!flag_echo) {
- char *s_pass;
- visible_enter(0);
-
- fputs("Type your password: ", stdout);
- f_pass = get_input(minlen_pass, maxlen_pass);
- fputs("\n", stdout);
- if(f_pass == NULL) {
- visible_enter(1);
- errprint(1, "Incorrect password");
- }
-
- fputs("Type your password again: ", stdout);
- s_pass = get_input(minlen_pass, maxlen_pass);
- fputs("\n", stdout);
- visible_enter(1);
- if(s_pass == NULL) {
- free(f_pass);
- errprint(1, "Incorrect password");
- }
-
- if(strcmp(f_pass, s_pass) != 0) {
- free(f_pass);
- free(s_pass);
- errprint(1, "Password do not match");
- }
- free(s_pass);
- }
- else {
- fputs("Type your password: ", stdout);
- f_pass = get_input(minlen_pass, maxlen_pass);
- if(f_pass == NULL)
- errprint(1, "Incorrect password");
- }
-
- result = insert_pass(path, f_pass);
- if(result) {
- free(f_pass);
- errprint(1, "Can't add password to LockPassword");
- }
- if(flag_copy)
- copy_outside(f_pass);
-
- printf("Password added successfully for %s\n", path);
- free(f_pass);
- return 0;
-}
-
-int cmd_edit(int argc, char *argv[])
-{
- const char description[] = "edit passname\n";
- 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);
-
- result = check_sneaky_paths(path);
- if(result)
- errprint(1, "You have used forbidden paths\n");
-
- editor = getenv("EDITOR");
- if(!editor)
- editor = STD_TEXT_EDITOR;
-
- password = get_password(path);
- if(password == NULL)
- errprint(1, "Decrypt password failed\n");
-
- 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");
- }
-
- // 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);
-
- fd = open(path_tmpfile, O_RDONLY);
- if(fd == -1) {
- unlink(path_tmpfile);
- perror("open");
- return 1;
- }
-
- 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);
-
- // encrypt
- result = insert_pass(path, password);
- free(password);
- if(result)
- errprint(1, "Can't add password to LockPassword\n");
-
- return 0;
-}
-
-int cmd_generate(int argc, char *argv[])
-{
- const char description[] = "generate [-l=pass-length] [-f] passname\n";
- int pass_length = stdlen_pass;
- int 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: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: usageprint("%s", description);
- }
- }
-
- if(optind < argc) optind++; // for skip "generate"
- dbgprint("passname: %s\n", argv[optind]);
-
- char *path = argv[optind];
- if(path == NULL)
- usageprint("%s", description);
-
- if(pass_length < minlen_pass || pass_length > maxlen_pass)
- errprint(1, "You typed an incorrect length\n");
-
- result = check_sneaky_paths(path);
- if(result)
- errprint(1, "You have used forbidden paths\n");
-
- result = file_exist(path);
- if(result == F_ISFILE) {
- if(!flag_force) {
- if(overwrite_answer(path) != 'y')
- return 1;
- }
- }
- else if(result == F_ISDIR)
- errprint(1, "You can't generate password for directory\n");
-
- // generate password
- char *g_pass;
- g_pass = gen_password(pass_length);
-
- result = insert_pass(path, g_pass);
- if(result) {
- free(g_pass);
- errprint(1, "Can't add password to LockPassword");
- }
-
- if(flag_copy)
- copy_outside(g_pass);
- else
- printf("Generated password: %s\n", g_pass);
- printf("Password added successfully for %s\n", path);
- free(g_pass);
- return 0;
-}
-
-int cmd_remove(int argc, char *argv[])
-{
- const char description[] = "rm passname\n";
- int result;
- char *path = argv[2];
- if(!path)
- usageprint("%s", description);
-
- 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");
- if(result == F_ISDIR) {
- if(count_dir_entries(path) != 0)
- errprint(1, "Directory not empty\n");
- }
-
- remove(path);
- return 0;
-}
-
-int cmd_move(int argc, char *argv[])
-{
- /* we have a two situation:
- 1) mv file file
- 2) mv file directory */
-
- const char description[] = "mv [-f] old-path new-path\n";
- const struct option long_options[] = {
- {"force", no_argument, NULL, 'f'},
- {NULL, 0, NULL, 0}
- };
-
- int result, flag_force = 0;
- while((result = getopt_long(argc, argv, "f", long_options, NULL)) != -1) {
- switch(result) {
- case 'f': { flag_force = 1; break; }
- default: usageprint("%s", description);
- }
- }
-
- if(optind < argc) optind++; // for skip "move"
- if(!argv[optind] || !argv[optind+1])
- usageprint("%s", description);
-
- char *old_path = argv[optind];
- char *new_path = argv[optind+1];
- dbgprint("old-path = %s\n", old_path);
- dbgprint("new-path = %s\n", new_path);
-
- result = check_sneaky_paths(old_path);
- if(result)
- errprint(1, "You have used forbidden paths\n");
- result = file_exist(old_path);
- if(result == F_NOEXIST)
- errprint(1, "No such file exists\n");
-
- result = check_sneaky_paths(new_path);
- if(result)
- errprint(1, "You have used forbidden paths\n");
- result = file_exist(new_path);
- if(result != F_NOEXIST) {
- if(!flag_force) {
- if(overwrite_answer(new_path) != 'y')
- return 1;
- }
- }
-
- if(rename(old_path, new_path))
- perror("rename");
- return 0;
-}
-
-int cmd_help(int argc, char *argv[])
-{
- printf("Synopsis:\n"
- "\tlpass [command] [arguments] ...\n"
-
- "Commands:\n"
- "\tinit gpg-key\n"
- "\t\tInitialize the password manager using the passed gpg-key.\n"
- "\tinsert [-e, --echo] [-c, --copy] [-f, --force] passname\n"
- "\t\tAdd the specified passname to the password manager.\n"
- "\tedit [-t, --text-editor=text-editor] passname\n"
- "\t\tOpen the specified passname in a text editor, waiting for changes.\n"
- "\tgenerate [-l, --length=pass-length] [-c, --copy] [-f, --force] passname\n"
- "\t\tGenerate a random password and write it in passname.\n"
- "\tmv [-f, --force] old-path new-path\n"
- "\t\tMove/rename old-path to new-path.\n"
- "\trm passname\n"
- "\t\tRemove the passname you specified from the password manager.\n"
- "\thelp\n"
- "\t\tPrint help information about commands and the application itself.\n"
- "\tversion\n"
- "\t\tPrint version information.\n"
-
- "\nMore information may be found in the lpass(1) man page.\n");
- return 0;
-}
-
-int cmd_version(int argc, char *argv[])
-{
- printf("LockPassword v%s\n"
- "Release date: %s\n\n"
- "Copyright (C) 2020-2021 Aleksandr D. Goncharov (Joursoir)\n"
- "License: GNU GPL version 3\n"
- "This is free software: you are free to change and redistribute it.\n"
- "This program comes with ABSOLUTELY NO WARRANTY.\n",
- VERSION, DATE_RELEASE);
- return 0;
-}
-
-int cmd_showtree(int argc, char *argv[])
-{
- const char description[] = "[-c] [passname]\n";
- int flag_copy = 0, result;
- char *path;
- const struct option long_options[] = {
- {"copy", no_argument, NULL, 'c'},
- {NULL, 0, NULL, 0}
- };
-
- while((result = getopt_long(argc, argv, "c", long_options, NULL)) != -1) {
- switch(result) {
- case 'c': { flag_copy = 1; break; }
- default: usageprint("%s", description);
- }
- }
-
- if(argv[optind]) {
- result = check_sneaky_paths(argv[optind]);
- if(result)
- errprint(1, "You have used forbidden paths\n");
- path = malloc(sizeof(char) * (strlen(argv[optind]) + 1));
- strcpy(path, argv[optind]);
- }
- else {
- path = malloc(sizeof(char) * 2);
- strcpy(path, ".");
- }
-
- result = file_exist(path);
- if(result == F_ISDIR)
- {
- if(flag_copy)
- errprint(1, "You must type a passname, not a directory\n");
-
- if(strcmp(path, ".") == 0) printf("Password Manager\n");
- else printf("Password Manager/%s\n", path);
- tree(path, "");
- }
- else if(result == F_ISFILE)
- {
- char *pass = get_password(path);
- if(pass == NULL) {
- free(path);
- errprint(1, "Decrypt password failed\n");
- }
- if(flag_copy)
- copy_outside(pass);
- else
- printf("%s\n", pass);
-
- free(pass);
- }
- else {
- free(path);
- errprint(1, "This path is not in the password storage\n");
- }
-
- free(path);
- return 0;
-}
-
static struct cmd_struct *get_cmd(const char *name)
{
struct cmd_struct *ptr;
@@ -497,41 +56,36 @@ static struct cmd_struct *get_cmd(const char *name)
static int goto_maindir()
{
- int ret = 0;
+ int retval = 0, result;
char *rootdir = xstrcat(getenv("HOME"), LOCKPASS_DIR, "/");
if(chdir(rootdir)) // failed
{
// create main directory:
- int res = mkdir(rootdir, S_IRWXU);
- if(res) {
- if(errno != EEXIST) {
- perror("mkdir");
- ret = 1;
- }
+ result = mkdir(rootdir, S_IRWXU);
+ if(result) {
+ if(errno != EEXIST)
+ errprint_ptr(&retval, 1, "%s", strerror(errno));
}
else // try again:
- ret = chdir(rootdir);
+ retval = chdir(rootdir);
}
free(rootdir);
- return ret;
+ return retval;
}
int main(int argc, char *argv[])
{
if(!isatty(STDIN_FILENO))
- errprint(1, "Please, use a terminal to run this application\n");
+ errprint_r(1, "Please, use a terminal to run this application\n");
if(goto_maindir())
- perror("chdir");
+ errprint_r(1, "%s", strerror(errno));
- int ret = 0;
char *cmd = (argv[1] != NULL) ? argv[1] : "";
struct cmd_struct *ptr;
if((ptr = get_cmd(cmd)))
- ret = ptr->func(argc, argv);
- else
- ret = cmd_showtree(argc, argv);
+ return ptr->func(argc, argv);
- return ret;
+ return cmd_showtree(argc, argv);
} \ No newline at end of file