435 lines
13 KiB
C
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
|