aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoursoir <chat@joursoir.net>2020-09-28 15:37:00 +0300
committerJoursoir <chat@joursoir.net>2020-09-28 15:37:00 +0300
commitac79cbd424d2339ff34112e142d289a51f90d3a6 (patch)
treefb049fa112bb6ec224f5dbadf0e4dd37c7aed8fc
downloadlock-password-ac79cbd424d2339ff34112e142d289a51f90d3a6.tar.gz
lock-password-ac79cbd424d2339ff34112e142d289a51f90d3a6.tar.bz2
lock-password-ac79cbd424d2339ff34112e142d289a51f90d3a6.zip
init project
-rw-r--r--.gitignore3
-rw-r--r--LICENSE.md24
-rwxr-xr-xcompulation4
-rw-r--r--easydir.c113
-rw-r--r--easydir.h3
-rw-r--r--handerror.c15
-rw-r--r--handerror.h2
-rw-r--r--main.c398
8 files changed, 562 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..d28ca88
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+documentation/
+*.o
+lpass \ No newline at end of file
diff --git a/LICENSE.md b/LICENSE.md
new file mode 100644
index 0000000..00d2e13
--- /dev/null
+++ b/LICENSE.md
@@ -0,0 +1,24 @@
+This is free and unencumbered software released into the public domain.
+
+Anyone is free to copy, modify, publish, use, compile, sell, or
+distribute this software, either in source code form or as a compiled
+binary, for any purpose, commercial or non-commercial, and by any
+means.
+
+In jurisdictions that recognize copyright laws, the author or authors
+of this software dedicate any and all copyright interest in the
+software to the public domain. We make this dedication for the benefit
+of the public at large and to the detriment of our heirs and
+successors. We intend this dedication to be an overt act of
+relinquishment in perpetuity of all present and future rights to this
+software under copyright law.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+For more information, please refer to <http://unlicense.org/> \ No newline at end of file
diff --git a/compulation b/compulation
new file mode 100755
index 0000000..614c238
--- /dev/null
+++ b/compulation
@@ -0,0 +1,4 @@
+#!/bin/bash
+
+gcc -c -Wall -g *.c
+gcc -Wall -g -o lpass *.o \ No newline at end of file
diff --git a/easydir.c b/easydir.c
new file mode 100644
index 0000000..a4ece76
--- /dev/null
+++ b/easydir.c
@@ -0,0 +1,113 @@
+#include <malloc.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <errno.h>
+
+#include "handerror.h"
+
+/* Buff size: source == path = file
+splitPath thinks, that in end path always stay FILE, not directory */
+char* splitPath(char *source, char *path, char *file)
+{
+ int fSymbol = 0, f = 0;
+
+ char *main_path = malloc(sizeof(char) * strlen(source) + 1);
+ char *file_path = malloc(sizeof(char) * strlen(source) + 1);
+
+ for(int i=0; i < strlen(source); i++)
+ {
+ if(fSymbol == 1)
+ {
+ switch(source[i])
+ {
+ case '/':
+ {
+ fSymbol = 0;
+ f = 0;
+
+ strcat(main_path, file_path);
+ strcat(main_path, "/");
+ file_path[0] = '\0';
+ break;
+ }
+ default:
+ {
+ file_path[f] = source[i];
+ file_path[f+1] = '\0';
+ f++;
+
+ break;
+ }
+
+ }
+ }
+ else // if it's beginning of string
+ {
+ // handling first symbol
+ switch(source[i])
+ {
+ case '.':
+ case '\\':
+ case '/':
+ {
+ print_error("[Error] You can't use these symbol at the beginning: '.', '/', '\\' \n");
+ break;
+ }
+ default:
+ fSymbol = 1;
+
+ // enter first symbol
+ file_path[0] = source[i];
+ file_path[1] = '\0';
+ f++;
+
+ break;
+ }
+ }
+ }
+
+ strcpy(path, main_path);
+ strcpy(file, file_path);
+ free(main_path);
+ free(file_path);
+
+ if(*file) return file;
+ return NULL;
+}
+
+int delete_file(char *file_path)
+{
+ int pid;
+ pid = fork();
+ if(pid == -1) call_error(112);
+ if(pid == 0) { /* new process */
+ execlp("rm", "rm", file_path, NULL);
+ perror("rm");
+ exit(4);
+ }
+ wait(&pid);
+
+ return 1;
+}
+
+int delete_emptydir(char *dir_path)
+{
+ int pid;
+ pid = fork();
+ if(pid == -1) call_error(113);
+ if(pid == 0) { /* new process */
+ #if defined(DEBUG)
+ execlp("rmdir", "rmdir", "-p", dir_path, NULL);
+ #else
+ execlp("rmdir", "rmdir", "-p", "--ignore-fail-on-non-empty", dir_path, NULL);
+ #endif
+ perror("rmdir");
+ exit(4);
+ }
+ wait(&pid);
+
+ return 1;
+}
diff --git a/easydir.h b/easydir.h
new file mode 100644
index 0000000..ed62da7
--- /dev/null
+++ b/easydir.h
@@ -0,0 +1,3 @@
+char* splitPath(char *source, char *path, char *file);
+int delete_file(char *file_path);
+int delete_emptydir(char *dir_path); \ No newline at end of file
diff --git a/handerror.c b/handerror.c
new file mode 100644
index 0000000..482b467
--- /dev/null
+++ b/handerror.c
@@ -0,0 +1,15 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+void call_error(int num)
+{
+ fprintf(stderr, "Sorry, there was an error in the program [#%d]\n", num);
+ exit(3);
+}
+
+void print_error(char *text)
+{
+ fprintf(stderr, "%s", text);
+ exit(4);
+}
+
diff --git a/handerror.h b/handerror.h
new file mode 100644
index 0000000..d4137a9
--- /dev/null
+++ b/handerror.h
@@ -0,0 +1,2 @@
+void call_error(int num);
+void print_error(char *text); \ No newline at end of file
diff --git a/main.c b/main.c
new file mode 100644
index 0000000..5d579cd
--- /dev/null
+++ b/main.c
@@ -0,0 +1,398 @@
+#include <stdio.h>
+#include <termios.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <getopt.h>
+#include <errno.h>
+#include <dirent.h>
+#include <time.h>
+
+#include "easydir.h"
+#include "handerror.h"
+
+//#define DEBUG
+#define MAXLEN_PASSWORD 128
+#define FULLNAMEFILE "/.lock-password/Password-Bank"
+#define TREENAMEFILE "/.lock-password"
+#define ADDNAMETOFULL "/Password-Bank"
+#define NAMEFILE "Password-Bank"
+
+static char* get_password(char *path, char *password)
+{
+ FILE *filePass;
+ filePass = fopen(path, "r");
+ if(filePass == NULL) {
+ call_error(110);
+ }
+
+ char sign[MAXLEN_PASSWORD];
+ if(!fgets(sign, sizeof(sign), filePass)) {
+ call_error(111);
+ }
+
+ strcpy(password, sign);
+ fclose(filePass);
+ return password;
+}
+
+static void show_tree(char *path)
+{
+ if(opendir(path) != NULL) { // if it's directory
+ int pid;
+ pid = fork();
+ if(pid == -1) call_error(101);
+ if(pid == 0) { /* new process */
+ execlp("tree", "tree", "-C", "--noreport", path, NULL);
+ perror("tree");
+ exit(4);
+ }
+ wait(&pid);
+ }
+ else {
+ char password[MAXLEN_PASSWORD];
+ get_password(path, password);
+ printf("%s\n", password);
+ }
+}
+
+static void changePass(char *root_path, char *add_path, char *password)
+{
+ /* root_path = /home/[username]/
+ add_path = banks/france/[number]
+ main_path = banks/france
+ file_path = [number] */
+
+ char *main_path = malloc(sizeof(char) * strlen(add_path) + 1);
+ char *file_path = malloc(sizeof(char) * strlen(add_path) + 1);
+
+ if(splitPath(add_path, main_path, file_path) == NULL) {
+ print_error("[Error] The path you specified is incorrect\n");
+ }
+
+ int pass_buf = strlen(root_path) + strlen(add_path);
+ char *final_path = (char*) malloc(sizeof(char) * pass_buf + 1);
+
+ strcpy(final_path, root_path);
+ strcat(final_path, "/");
+ strcat(final_path, main_path);
+
+ if(chdir(final_path) != 0) {
+ call_error(107);
+ }
+
+ FILE *filePass;
+ filePass = fopen(file_path, "r+");
+ if(filePass == NULL) {
+ if(errno == ENOENT) { // file doesn't exist
+ print_error("Error: No such file exists\n");
+ }
+ call_error(114);
+ }
+ fputs(password, filePass);
+
+ free(main_path);
+ free(file_path);
+ fclose(filePass);
+}
+
+static void insertPass(char *root_path, char *add_path, char *password)
+{
+ /* root_path = /home/[username]/
+ add_path = banks/france/[number]
+ main_path = banks/france
+ file_path = [number] */
+
+ char *main_path = malloc(sizeof(char) * strlen(add_path) + 1);
+ char *file_path = malloc(sizeof(char) * strlen(add_path) + 1);
+
+ if(splitPath(add_path, main_path, file_path) == NULL) {
+ print_error("[Error] The path you specified is incorrect\n");
+ }
+
+ int pass_buf = strlen(root_path) + strlen(add_path);
+ char *final_path = (char*) malloc(sizeof(char) * pass_buf + 1);
+
+ strcpy(final_path, root_path);
+ strcat(final_path, "/");
+ strcat(final_path, main_path);
+
+ int pid = fork();
+ if(pid == -1) call_error(103);
+ if(pid == 0) { /* new process */
+ execlp("mkdir", "mkdir", "-p", main_path, NULL);
+ perror("mkdir");
+ exit(4);
+ }
+ wait(&pid);
+
+ if(chdir(final_path) != 0) {
+ call_error(107);
+ }
+
+ // create file, copy password there
+ FILE *filePass;
+ filePass = fopen(file_path, "w");
+ if(filePass == NULL) {
+ call_error(108);
+ }
+ fputs(password, filePass);
+
+ free(main_path);
+ free(file_path);
+ fclose(filePass);
+}
+
+static char *generate_password(char *dest, int amount)
+{
+ char allowed_symbols[] = {
+ 'A','E','I','J','O','U','B','C','D','F','G','H',
+ 'K','L','M','N','P','Q','R','S','T','V','W','X',
+ 'Y','Z','a','e','i','j','o','u','b','c','d','f',
+ 'g','h','k','l','m','n','p','q','r','s','t','v',
+ 'w','x','y','z','1','2','3','4','5','6','7','8',
+ '9','0','!','#','$',';','%','^',':','&','?','*',
+ '(',')','-','_','+','=','<', '>'
+ };
+ int max = sizeof(allowed_symbols);
+ srand(time(NULL));
+
+ char password[MAXLEN_PASSWORD];
+ for(int i=0; i < amount; i++)
+ {
+ char c = allowed_symbols[rand() % max];
+
+ password[i] = c;
+ password[i+1] = '\0';
+ }
+
+ strcpy(dest, password);
+ return dest;
+}
+
+static void nonvisible_enter(int status)
+{
+ struct termios term_settings;
+ tcgetattr(0, &term_settings); // get current settings
+ if(status == 1) {
+ term_settings.c_lflag &= ~ECHO; // flag reset
+ }
+ else {
+ term_settings.c_lflag |= ECHO;
+ }
+ tcsetattr(0, TCSANOW, &term_settings);
+}
+
+int main(int argc, char *argv[])
+{
+ if(!isatty(0)) { // stdin
+ print_error("Please, use a terminal to run this program\n");
+ }
+
+ #if defined(DEBUG)
+ char* short_options = "c:e:g:i:R:t";
+ #else
+ char* short_options = "c:e:g:i:R:";
+ #endif
+
+ struct option long_options[] = {
+ {"init", no_argument, NULL, 'I'},
+ {NULL, 0, NULL, 0}
+ };
+
+ int rootBuf = strlen(getenv("HOME")) + strlen(FULLNAMEFILE);
+ char *rootPath = (char *) malloc(sizeof(char) * rootBuf + 1); // +1 for '\0'
+
+ int path_init = 0;
+ strcpy(rootPath, getenv("HOME"));
+ strcat(rootPath, TREENAMEFILE);
+
+ if(chdir(rootPath) == 0) path_init = 1;
+
+ int option_index = -1, result = -1;
+ result = getopt_long(argc, argv, short_options, long_options, &option_index);
+ if(!path_init) {
+ if(result != 'I') // if doesn't init
+ {
+ if(errno == ENOENT) { // file doesn't exist
+ print_error("Before starting work, you must initialize LockPassword\n\
+ Use: lpass --init\n");
+ }
+ call_error(102);
+ }
+ }
+ else {
+ if(result == 'I') {
+ print_error("You already initialized LockPassword\n");
+ }
+ else if(result != -1)
+ {
+ strcat(rootPath, ADDNAMETOFULL); // complements to full path
+ if(chdir(rootPath) != 0) {
+ call_error(112);
+ }
+ }
+ }
+
+ if(result != -1)
+ {
+ switch(result) {
+ case 'c': {
+ printf("Coming soon...\n");
+ break;
+ }
+ case 'e': {
+ nonvisible_enter(1); /* change terminal work */
+
+ /* enter password */
+ char pass_one[MAXLEN_PASSWORD], pass_two[MAXLEN_PASSWORD];
+
+ printf("Please type your new password: ");
+ if(!fgets(pass_one, sizeof(pass_one), stdin)) {
+ nonvisible_enter(0);
+ print_error("Unexpected end of file\n");
+ }
+ printf("\n");
+
+ printf("Please type your new password again: ");
+ if(!fgets(pass_two, sizeof(pass_two), stdin)) {
+ nonvisible_enter(0);
+ print_error("Unexpected end of file\n");
+ }
+ printf("\n");
+
+ nonvisible_enter(0);
+
+ if(strcmp(pass_one, pass_two) == 0) {
+ printf("Password correct\n");
+
+ changePass(rootPath, optarg, pass_one);
+ printf("Password updated successfully for %s\n", optarg);
+ }
+ else printf("Passwords do not match\n");
+
+ break;
+ }
+ case 'g': {
+ int n_symbols = 0;
+ if(strcmp(optarg, argv[argc-1]) == 0)
+ n_symbols = 8;
+ else n_symbols = atoi(optarg);
+
+
+ if(n_symbols < 1 || n_symbols > 127) {
+ print_error("Error: you typed an incorrect number");
+ }
+
+ /* generate password */
+ char gpass[MAXLEN_PASSWORD];
+ generate_password(gpass, n_symbols);
+
+ insertPass(rootPath, argv[argc-1], gpass);
+ printf("Generated password: %s\n", gpass);
+ printf("Password added successfully for %s\n", argv[argc-1]);
+
+ break;
+ }
+ case 'i': {
+ nonvisible_enter(1); /* change terminal work */
+
+ /* enter password */
+ char pass_one[MAXLEN_PASSWORD], pass_two[MAXLEN_PASSWORD];
+
+ printf("Please type your password: ");
+ if(!fgets(pass_one, sizeof(pass_one), stdin)) {
+ nonvisible_enter(0);
+ print_error("Unexpected end of file\n");
+ }
+ printf("\n");
+
+ printf("Please type your password again: ");
+ if(!fgets(pass_two, sizeof(pass_two), stdin)) {
+ nonvisible_enter(0);
+ print_error("Unexpected end of file\n");
+ }
+ printf("\n");
+
+ nonvisible_enter(0);
+
+ if(strcmp(pass_one, pass_two) == 0) {
+ printf("Password correct\n");
+
+ insertPass(rootPath, optarg, pass_one);
+ printf("Password added successfully for %s\n", optarg);
+ }
+ else printf("Passwords do not match\n");
+
+ break;
+ }
+ case 'R': {
+ char *main_path = malloc(sizeof(char) * strlen(optarg) + 1);
+ char *file_path = malloc(sizeof(char) * strlen(optarg) + 1);
+
+ if(splitPath(optarg, main_path, file_path) == NULL) { // check correct input
+ print_error("[Error] The path you specified is incorrect\n");
+ }
+
+ if(delete_file(optarg)) {
+ delete_emptydir(main_path);
+ }
+
+ free(main_path);
+ free(file_path);
+ break;
+ }
+ case 'I': {
+ int pid;
+
+ // create direction:
+ pid = fork();
+ if(pid == -1) call_error(100);
+ if(pid == 0) { /* new process */
+ execlp("mkdir", "mkdir", "-vp", rootPath, NULL);
+ perror("mkdir");
+ exit(4);
+ }
+ wait(&pid);
+ printf("LockPassword initialized\n");
+ break;
+ }
+
+ #if defined(DEBUG)
+ case 't':
+ {
+ char *main_path = malloc(sizeof(char) * strlen(optarg) + 1);
+ char *file_path = malloc(sizeof(char) * strlen(optarg) + 1);
+
+ if(splitPath(optarg, main_path, file_path) == NULL)
+ printf("NULL\n");
+ break;
+ }
+ #endif
+
+ default: break;
+
+ }
+ }
+ else
+ {
+ char *ptr;
+ if(strcmp(argv[argc-1], argv[0]) == 0) {
+ ptr = malloc(sizeof(char) * strlen(NAMEFILE) + 1);
+ strcpy(ptr, NAMEFILE);
+ }
+ else {
+ int buff_tree = strlen(NAMEFILE) + strlen(argv[argc-1]);
+ ptr = malloc(sizeof(char) * buff_tree + 1 + 1);
+ strcpy(ptr, NAMEFILE);
+ strcat(ptr, "/");
+ strcat(ptr, argv[argc-1]);
+ }
+ show_tree(ptr);
+
+ free(ptr);
+ }
+
+ return 0;
+} \ No newline at end of file