vipre-cryptor/vipre-manager.h

330 lines
9.8 KiB
C

/*
* vipre-manager.h
*
* Copyright 2025
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*
*
*/
#if (!defined(_DATA_VIPRE_H_PARSER))
#define _DATA_VIPRE_H_PARSER
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <string.h>
#define VERSION "1.0"
#define ERROR_FILE_OUT "unnamed_out_file.csv"
#define bool unsigned char
#define true 1
#define false 0
typedef FILE* file_t;
void _put_vipre_help(void) {
puts (
"Vipre Console Cryptor V " VERSION "\n"
" Crypt files" "\n"
"Create user and encrypt file: " "\n"
" vipre-cryptor key_file.sig --create-user user_name.bin --file input_file" "\n"
"Create signature:" "\n"
" vipre-cryptor --sig key_file.sig" "\n"
"Format for decryption:" "\n"
" vipre-cryptor key_file.sig --user user_name.bin --file out_file" "\n"
"Options: " "\n"
" -h, --help - show this help" "\n"
" -v, --version - show version" "\0"
);
}
void _file_read_error(void) {
puts("\033[1mvipre-cryptor: \033[91mFile read error!\033[0m");
}
#define DATA_RAND_MAX (ULONG_MAX / 2)
static unsigned long int next = 1;
int _str_rand(void)
{
next = next * 1103515245 + 12345;
return (unsigned long)(next/65536) % (DATA_RAND_MAX + 1);
}
void _str_srand(unsigned long seed)
{
next = seed;
}
unsigned long __generate_hash(char* str) {
size_t pos = 0;
unsigned long ret = 0;
size_t max = strlen(str);
while (pos < max) {
ret += (unsigned char)str[pos]*pos;
if (ret > (unsigned long)ULONG_MAX - 10) ret = 32;
pos ++;
}
if (ret == 0) ret ++;
return ret;
}
signed short int __find_arr_index(char val, char* arr, size_t len) {
size_t pos = 0;
while (pos < len) {
if (arr[pos] == val) return pos;
pos ++;
}
return -1;
}
void __refresh_dt(char* arr, size_t sz) {
sz --;
char save_dt = arr[sz];
unsigned int pos = sz - 1;
while (true) {
arr[pos + 1] = arr[pos];
if (pos) pos --;
else break;
}
arr[0] = save_dt;
}
void __refresh_data(char* arr, size_t sz, unsigned int to) {
while (to != 0) {
__refresh_dt(arr, sz);
to --;
}
}
int __create_sig(char* file) {
size_t arr_len = abs(CHAR_MIN) + abs(CHAR_MAX) + 1;
char* arr = (char*)malloc(arr_len * sizeof(char));
size_t str_dt = 0;
while (str_dt < arr_len) {
arr[str_dt] = 0;
str_dt ++;
}
char key[32] = "";
fputs("Signature key: ", stdout);
if (!scanf("%32[^\n]", key)) puts("\033[1mvipre-cryptor: \033[91mKey read error!\033[0m");
file_t fp = fopen(file, "wb");
if (fp == NULL) { _file_read_error(); free(arr); return EXIT_FAILURE; }
_str_srand(__generate_hash(key));
unsigned short int pos = 0;
while (true) {
if (pos == arr_len) break;
char val = (_str_rand() % arr_len) - CHAR_MIN;
while (__find_arr_index(val, arr, pos) != (-1)) {
val = (_str_rand() % arr_len) - CHAR_MIN;
}
arr[pos] = val;
pos ++;
}
size_t count = fwrite(arr, sizeof(char), (unsigned long)arr_len, fp);
if (count != arr_len) {
_file_read_error();
free(arr);
return EXIT_FAILURE;
}
fclose(fp);
free(arr);
return EXIT_SUCCESS;
}
int __create_user(char* file, char* user_file, char* cry_file) {
file_t fp = fopen(file, "rb");
file_t wp = fopen(user_file, "wb");
file_t fw = fopen(cry_file, "rb");
if (fp == NULL || wp == NULL || fw == NULL) { _file_read_error(); return EXIT_FAILURE; }
size_t arr_len = abs(CHAR_MIN) + abs(CHAR_MAX) + 1;
char* arr = (char*)malloc(arr_len * sizeof(char));
if (fread(arr, sizeof(char), arr_len, fp) != arr_len) {
_file_read_error();
free(arr);
return EXIT_FAILURE;
}
char user_login[32];
char password[32];
fputs("Login: ", stdout);
int c;
size_t cnt = 0;
while((c=getchar())!=EOF && cnt < 31 && c != '\n') {
user_login[cnt] = c;
cnt ++;
}
fputs("Password: ", stdout);
cnt = 0;
while((c=getchar())!=EOF && cnt < 31 && c != '\n') {
password[cnt] = c;
cnt ++;
}
size_t cnt_save = cnt;
password[cnt] = '\0';
fputs("Repeat password: ", stdout);
cnt = 0;
while((c=getchar())!=EOF && cnt < 31 && c != '\n') {
if (password[cnt] != c) {
puts("\033[1mvipre-cryptor: \033[91mThe password was repeated incorrectly!\033[0m");
free(arr);
return EXIT_FAILURE;
}
cnt ++;
}
if (cnt != cnt_save) {
puts("\033[1mvipre-cryptor: \033[91mThe password was repeated incorrectly!\033[0m");
free(arr);
return EXIT_FAILURE;
}
fputs(user_login, wp); putc('\n', wp);
fputs(password, wp); putc('\n', wp);
fseek(fw, 0, SEEK_END);
unsigned long file_size = ftell(fw);
rewind(fw);
unsigned long count = 0;
while (count < file_size) {
c = (char)getc(fw);
c = arr[(unsigned char)c];
putc(c, wp);
__refresh_data(arr, arr_len, abs(arr[0]));
count ++;
}
free(arr);
fclose(fp);
fclose(wp);
fclose(fw);
return EXIT_SUCCESS;
}
int __read_user(char* file, char* user_file, char* cry_file) {
file_t fp = fopen(file, "rb");
file_t up = fopen(user_file, "rb");
file_t fw = fopen(cry_file, "wb");
size_t arr_len = abs(CHAR_MIN) + abs(CHAR_MAX) + 1;
if (fp == NULL || up == NULL || fw == NULL) { _file_read_error(); return EXIT_FAILURE; }
char* arr = (char*)malloc(arr_len * sizeof(char));
if (fread(arr, sizeof(char), arr_len, fp) != arr_len) {
_file_read_error();
free(arr);
return EXIT_FAILURE;
}
char user_login[32];
char correct_login[32];
char password[32];
char correct_password[32];
fputs("Login: ", stdout);
char* res;
res = fgets(user_login, 32, stdin);
res = fgets(correct_login, 32, up);
fputs("Password: ", stdout);
res = fgets(password, 32, stdin);
res = fgets(correct_password, 32, up);
if (res);
if (!(strcmp(user_login, correct_login) == 0 && strcmp(password, correct_password) == 0)) {
puts("\033[1mvipre-cryptor: \033[91mThe password or login is incorrect!\033[0m");
free(arr);
return EXIT_FAILURE;
}
unsigned long save_pos = ftell(up);
fseek(up, 0, SEEK_END);
unsigned long data_size = ftell(up) - save_pos;
fseek(up, save_pos, SEEK_SET);
unsigned long pos = 0;
int c;
while (pos < data_size) {
c = getc(up);
c = __find_arr_index(c, arr, arr_len);
__refresh_data(arr, arr_len, abs(arr[0]));
putc(c, fw);
pos ++;
}
fclose(fp);
fclose(up);
fclose(fw);
free(arr);
return EXIT_SUCCESS;
}
int parse_file_data(int argc, char** argv) {
unsigned int n = 1;
bool read_out_file_name = false;
char* file = NULL;
char* out_file = NULL;
bool create_user = false;
bool create_sig = false;
bool read_user = false;
char* cry_file = NULL;
bool read_cry_file = false;
while (n < argc) {
char* str = argv[n];
bool val = false;
if (str[0] == '-') {
if (str[1] == '-') val = true;
switch (str[val + 1]) {
case 'h':
_put_vipre_help();
return EXIT_SUCCESS;
case 'v':
puts(VERSION);
return EXIT_SUCCESS;
case 'u':
read_out_file_name = true;
read_user = true;
break;
case 'c':
create_user = true;
read_out_file_name = true;
break;
case 's':
create_sig = true;
break;
case 'f':
read_cry_file = true;
break;
default:
printf("\033[1mvipre-cryptor: \033[91mUnknown option \"%s\"!\033[0m\n", str);
return EXIT_FAILURE;
}
} else {
if (read_out_file_name) out_file = str;
else if (read_cry_file) cry_file = str;
else file = str;
read_out_file_name = false;
read_cry_file = false;
}
n ++;
}
if (file == NULL) {
puts("\033[1mvipre-cryptor: \033[91mNo input file!\033[0m");
return EXIT_FAILURE;
}
if (create_sig) return __create_sig(file);
if (create_user) return __create_user(file, out_file, cry_file);
if (read_user) return __read_user(file, out_file, cry_file);
puts("\033[1mvipre-cryptor: \033[91mNo input option!\033[0m");
return EXIT_FAILURE;
}
#undef VERSION
#undef bool
#undef true
#undef false
#endif