329 lines
9.8 KiB
C
329 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];
|
|
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 |