vipre-cryptor/vipre-manager.h
2025-12-28 19:43:22 +04:00

435 lines
13 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 LIB_TRUE 1
#define LIB_FALSE 0
#define VERSION "1.0"
#define ERROR_FILE_OUT "unnamed_out_file.csv"
#define bool unsigned char
#define true 1
#define false 0
char* __YEFWHD_api_login = NULL;
char* __YEFWHD_api_password = NULL;
char* __YEFWHD_api_datakey = NULL;
char __YEFWHD_data_type = '\0';
bool __YEFWHD_users = false;
#define VIPRE_API_MODE 'A'
typedef FILE* file_t;
void __api_detach(void) {
__YEFWHD_data_type = '\0';
}
void __set_api_mode(char* login, char* password, char* data_key) {
__YEFWHD_api_login = login;
__YEFWHD_api_password = password;
__YEFWHD_api_datakey = data_key;
__YEFWHD_data_type = VIPRE_API_MODE;
}
void __use_users(bool is_use_users) {
__YEFWHD_users = is_use_users;
}
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 - 8) 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] = "";
file_t fp = fopen(file, "wb");
if (fp == NULL) { _file_read_error(); free(arr); return EXIT_FAILURE; }
if (__YEFWHD_data_type != VIPRE_API_MODE) {
fputs("Signature key: ", stdout);
if (!scanf("%32[^\n]", key)) puts("\033[1mvipre-cryptor: \033[91mKey read error!\033[0m");
} else {
strncpy(key, __YEFWHD_api_datakey, 31);
key[31] = '\0';
}
_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;
}
static void __nl_del(char* user_login) {
if (user_login[strlen(user_login) - 1] == '\n') user_login[strlen(user_login) - 1] = '\0';
}
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];
int c;
if (__YEFWHD_data_type != VIPRE_API_MODE && __YEFWHD_users == true) {
fputs("Login: ", stdout);
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;
}
} else {
if (__YEFWHD_users == false) {
strcpy(user_login, "admin");
strcpy(password, "1234");
} else {
strncpy(user_login, __YEFWHD_api_login, 31);
strncpy(password, __YEFWHD_api_password, 31);
user_login[31] = '\0';
password[31] = '\0';
}
}
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;
unsigned char crc = 0xFF;
while (count < file_size) {
crc ^= (unsigned char)getc(fw);
unsigned short int i = 0;
while (i < 8) {
crc = crc & 0x80 ? (crc << 1) ^ 0x31 : crc << 1;
i ++;
}
count ++;
}
putc((char)crc, wp);
fprintf(wp, "%lu\n", count);
rewind(fw);
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];
char* res;
unsigned char crc_file = 0xFF;
res = fgets(correct_login, 32, up);
res = fgets(correct_password, 32, up);
crc_file = (unsigned char)fgetc(up);
unsigned long read_sum = 0;
res = (char*)(unsigned long int)fscanf(up, "%lu\n", &read_sum);
if (__YEFWHD_data_type != VIPRE_API_MODE && __YEFWHD_users == true) {
fputs("Login: ", stdout);
res = fgets(user_login, 32, stdin);
fputs("Password: ", stdout);
res = fgets(password, 32, stdin);
} else {
if (__YEFWHD_users == false) {
strcpy(user_login, "admin");
strcpy(password, "1234");
} else {
strncpy(user_login, __YEFWHD_api_login, 31);
strncpy(password, __YEFWHD_api_password, 31);
user_login[31] = '\0';
password[31] = '\0';
}
}
if (res == NULL) {
puts("\033[1mvipre-cryptor: \033[91mThe file is in the wrong format!\033[0m");
free(arr);
return EXIT_FAILURE;
};
__nl_del(user_login); __nl_del(password);
__nl_del(correct_login); __nl_del(correct_password);
if (user_login[strlen(user_login) - 1] == '\n') user_login[strlen(user_login) - 1] = '\0';
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;
unsigned char crc = 0xFF;
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 ++;
crc ^= (unsigned char)c;
unsigned short int i = 0;
while (i < 8) {
crc = crc & 0x80 ? (crc << 1) ^ 0x31 : crc << 1;
i ++;
}
}
if (crc != crc_file || read_sum != pos) {
puts("\033[1mvipre-cryptor: \033[91mVerification error! Request the data again.\033[0m");
free(arr);
return EXIT_FAILURE;
}
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;
bool users = 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;
case 't':
users = 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 ++;
}
__YEFWHD_users = users;
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