1
0
Fork 0

Compare commits

...

4 Commits

6 changed files with 156 additions and 74 deletions

View File

@ -20,6 +20,7 @@
#include <inttypes.h>
#include <ctype.h>
#include <assert.h>
#include <errno.h>
// ==========================================================================
// Constants
@ -37,14 +38,14 @@ static int open_files(FILE **const file_in, FILE **const file_out, const CHR *co
{
if (!(*file_in = FOPEN(input_path, T("rb"))))
{
FPRINTF(stderr, T("Error: Failed to open input file \"%") T(PRISTR) T("\" for reading!\n\n"), input_path);
FPRINTF(stderr, T("Error: Failed to open input file \"%") T(PRISTR) T("\" for reading!\n\n%") T(PRISTR) T("\n\n"), input_path, STRERROR(errno));
*file_out = NULL;
return EXIT_FAILURE;
}
if (!(*file_out = FOPEN(output_path, T("wb"))))
{
FPRINTF(stderr, T("Error: Failed to open output file \"%") T(PRISTR) T("\" for writing!\n\n"), output_path);
FPRINTF(stderr, T("Error: Failed to open output file \"%") T(PRISTR) T("\" for writing!\n\n%") T(PRISTR) T("\n\n"), output_path, STRERROR(errno));
return EXIT_FAILURE;
}
@ -66,7 +67,7 @@ int encrypt(const char *const passphrase, const CHR *const input_path, const CHR
goto clean_up;
}
const uint64_t file_size = get_file_size(file_in);
const uint64_t file_size = get_size(file_in);
if (file_size == UINT64_MAX)
{
FPUTS(T("I/O error: Failed to determine size of input file!\n\n"), stderr);
@ -251,7 +252,7 @@ int decrypt(const char *const passphrase, const CHR *const input_path, const CHR
goto clean_up;
}
const uint64_t file_size = get_file_size(file_in);
const uint64_t file_size = get_size(file_in);
if (file_size == UINT64_MAX)
{
FPUTS(T("I/O error: Failed to determine size of input file!\n\n"), stderr);

View File

@ -144,10 +144,12 @@ static void sigint_handler(const int sig)
int MAIN(const int argc, CHR *const argv[])
{
int result = EXIT_FAILURE;
const CHR *input_file = NULL, *output_file = NULL;
char *passphrase_buffer = NULL;
init_terminal();
setup_signal_handler(SIGINT, sigint_handler);
int result = EXIT_FAILURE;
char *passphrase_buffer = NULL;
FPRINTF(stderr, T("SlunkCrypt Utility (%") T(PRIstr) T("-%") T(PRIstr) T("), by LoRd_MuldeR <MuldeR2@GMX.de>\n"), OS_TYPE, CPU_ARCH);
FPRINTF(stderr, T("Using libSlunkCrypt v%u.%u.%u [%") T(PRIstr) T("]\n\n"), SLUNKCRYPT_VERSION_MAJOR, SLUNKCRYPT_VERSION_MINOR, SLUNKCRYPT_VERSION_PATCH, SLUNKCRYPT_BUILD);
@ -203,8 +205,6 @@ int MAIN(const int argc, CHR *const argv[])
check_excess_arguments(argc, 5);
const CHR *const passphrase = PW_FROM_ENV ? GETENV(ENV_PASSWORD) : argv[2U];
const CHR *const input_file = argv[PW_FROM_ENV ? 2U : 3U], *const output_file = argv[PW_FROM_ENV ? 3U : 4U];
if ((!passphrase) || (!passphrase[0U]))
{
FPUTS(T("Error: The passphrase must be specified, directly or indirectly!\n\n"), stderr);
@ -220,9 +220,23 @@ int MAIN(const int argc, CHR *const argv[])
}
}
if ((!input_file[0U]) || (!output_file[0U]))
input_file = argv[PW_FROM_ENV ? 2U : 3U];
if (!input_file[0U])
{
FPUTS(T("Error: The input file and/or output file must not be empty!\n\n"), stderr);
FPUTS(T("Error: The specified input file name must not be empty!\n\n"), stderr);
goto clean_up;
}
output_file = argv[PW_FROM_ENV ? 3U : 4U];
if (!output_file[0U])
{
FPUTS(T("Error: The specified output file name must not be empty!\n\n"), stderr);
goto clean_up;
}
if (same_file(input_file, output_file) > 0)
{
FPUTS(T("Error: The input and output files must not be the same!\n\n"), stderr);
goto clean_up;
}

View File

@ -58,10 +58,12 @@
# define STRNICMP(X,Y,Z) _wcsnicmp((X),(Y),(Z))
# define STRRCHR(X,Y) wcsrchr((X),(Y))
# define STRTOUL(X) wcstoul((X), NULL, 0)
# define STRDUP(X) _wcsdup((X))
# define FPUTS(X,Y) fputws((X),(Y))
# define FPRINTF(X,Y,...) fwprintf((X),(Y),__VA_ARGS__)
# define REMOVE(X) _wremove((X))
# define FOPEN(X,Y) _wfsopen((X),(Y),_SH_SECURE)
# define STRERROR(X) _wcserror((X))
# ifdef __USE_MINGW_ANSI_STDIO
# define PRISTR "ls"
# define PRIstr "hs"
@ -81,10 +83,12 @@
# define STRNICMP(X,Y,Z) strncasecmp((X),(Y),(Z))
# define STRRCHR(X,Y) strrchr((X),(Y))
# define STRTOUL(X) strtoul((X), NULL, 0)
# define STRDUP(X) strdup((X))
# define FPUTS(X,Y) fputs((X),(Y))
# define FPRINTF(X,Y,...) fprintf((X),(Y),__VA_ARGS__)
# define REMOVE(X) remove((X))
# define FOPEN(X,Y) fopen((X),(Y))
# define STRERROR(X) strerror((X))
# define PRISTR "s"
# define PRIstr "s"
# define PRIwcs "ls"

View File

@ -16,6 +16,7 @@
/* CRT */
#include <ctype.h>
#include <errno.h>
// ==========================================================================
// Constants
@ -37,51 +38,63 @@ static const char PASSWD_SYMBOLS[] =
// Read passphrase from file
// ==========================================================================
#define PASSPHRASE_BUFFSIZE (SLUNKCRYPT_PWDLEN_MAX + 2U)
static void trim_end_of_line(char *const buffer)
{
size_t length;
for (length = strlen(buffer); length > 0U; --length)
{
const char last = buffer[length - 1U];
if ((last != '\r') && (last != '\n') && (last != '\f'))
{
break;
}
}
buffer[length] = '\0';
}
char *read_passphrase(const CHR *const file_name)
{
FILE *passphrase_file = NULL;
char *buffer = NULL;
if ((!file_name) || (!file_name[0U]))
{
FPUTS(T("Error: The passphrase input file name must not be empty!\n\n"), stderr);
return NULL;
goto finish;
}
const size_t max_len = SLUNKCRYPT_PWDLEN_MAX + 2U;
char *const buffer = (char*) malloc(max_len * sizeof(char));
passphrase_file = STRICMP(file_name, T("-")) ? FOPEN(file_name, T("rb")) : stdin;
if (!passphrase_file)
{
FPRINTF(stderr, T("Error: Failed to open passphrase file \"%") T(PRISTR) T("\" for reading!\n\n%") T(PRISTR) T("\n\n"), file_name, STRERROR(errno));
goto finish;
}
buffer = (char*) calloc(PASSPHRASE_BUFFSIZE, sizeof(char));
if (!buffer)
{
FPUTS(T("Error: Failed to allocate the passphrase buffer!\n\n"), stderr);
return NULL;
}
const int use_stdin = (!file_name) || (!STRICMP(file_name, T("-")));
FILE *const file_in = use_stdin ? stdin : FOPEN(file_name, T("rb"));
if (!file_in)
{
FPRINTF(stderr, T("Error: Failed to open input file \"%") T(PRISTR) T("\" for reading!\n\n"), file_name);
free(buffer);
return NULL;
goto finish;
}
do
{
if (!fgets(buffer, (int)max_len, file_in))
if (!fgets(buffer, (int)PASSPHRASE_BUFFSIZE, passphrase_file))
{
buffer[0U] = '\0';
goto finish;
}
size_t length = strlen(buffer);
while ((length > 0U) && ((buffer[length - 1U] == '\r') || (buffer[length - 1U] == '\n')))
{
buffer[--length] = '\0';
}
trim_end_of_line(buffer);
}
while (!buffer[0U]);
finish:
if ((!use_stdin) && file_in)
if (passphrase_file && (passphrase_file != stdin))
{
fclose(file_in);
fclose(passphrase_file);
}
return buffer;

View File

@ -19,6 +19,7 @@
#include <sys/types.h>
#include <time.h>
#include <signal.h>
#include <stdarg.h>
/* Platform support */
#ifdef _WIN32
@ -26,6 +27,7 @@
# include <io.h>
# include <fcntl.h>
# define STAT_T struct _stati64
# define STAT(X,Y) _wstati64((X),(Y))
# define FSTAT(X,Y) _fstati64((X),(Y))
# define FILENO(X) _fileno((X))
# define S_IFMT _S_IFMT
@ -35,11 +37,14 @@
# define _O_U8TEXT 0x40000
# endif
#else
# include <unistd.h>
# if defined(__USE_LARGEFILE64) && (__USE_LARGEFILE64)
# define STAT_T struct stat64
# define STAT(X,Y) stat64((X),(Y))
# define FSTAT(X,Y) fstat64((X),(Y))
# else
# define STAT_T struct stat
# define STAT(X,Y) stat((X),(Y))
# define FSTAT(X,Y) fstat((X),(Y))
# endif
# define FILENO(X) fileno((X))
@ -105,6 +110,41 @@ void setup_signal_handler(const int signo, signal_handler_t* const handler)
#endif
}
// ==========================================================================
// String functions
// ==========================================================================
char* CHR_to_utf8(const CHR *const input)
{
#ifdef _WIN32
char *buffer = NULL;
DWORD buffer_size = 0U, result = 0U;
buffer_size = input ? WideCharToMultiByte(CP_UTF8, 0, input, -1, NULL, 0, NULL, NULL) : 0U;
if (buffer_size < 1U)
{
return NULL;
}
buffer = (char*)malloc(sizeof(char) * buffer_size);
if (!buffer)
{
return NULL;
}
result = WideCharToMultiByte(CP_UTF8, 0, input, -1, (LPSTR)buffer, buffer_size, NULL, NULL);
if ((result > 0U) && (result <= buffer_size))
{
return buffer;
}
free(buffer);
return NULL;
#else
return strdup(input); /*simple string copy*/
#endif
}
// ==========================================================================
// Time functions
// ==========================================================================
@ -149,41 +189,6 @@ uint64_t clock_read(void)
return 0U;
}
// ==========================================================================
// Character set conversion
// ==========================================================================
char* CHR_to_utf8(const CHR *const input)
{
#ifdef _WIN32
char *buffer = NULL;
DWORD buffer_size = 0U, result = 0U;
buffer_size = input ? WideCharToMultiByte(CP_UTF8, 0, input, -1, NULL, 0, NULL, NULL) : 0U;
if (buffer_size < 1U)
{
return NULL;
}
buffer = (char*) malloc(sizeof(char) * buffer_size);
if (!buffer)
{
return NULL;
}
result = WideCharToMultiByte(CP_UTF8, 0, input, -1, (LPSTR)buffer, buffer_size, NULL, NULL);
if ((result > 0U) && (result <= buffer_size))
{
return buffer;
}
free(buffer);
return NULL;
#else
return strdup(input); /*simple string copy*/
#endif
}
// ==========================================================================
// Byte-order support
// ==========================================================================
@ -233,16 +238,59 @@ size_t fread_ui64(uint64_t *const value, FILE *const stream)
// File functions
// ==========================================================================
uint64_t get_file_size(FILE* const file)
typedef struct
{
STAT_T stat;
if (FSTAT(FILENO(file), &stat) == 0)
uint64_t dev;
uint64_t ino;
}
file_uid_t;
static int get_file_unique_id(const CHR *const path, file_uid_t *const file_id)
{
int retval = -1;
#ifdef _WIN32
const HANDLE handle = CreateFileW(path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0U, NULL);
if (handle != INVALID_HANDLE_VALUE)
{
const uint16_t file_type = stat.st_mode & S_IFMT;
if ((file_type != S_IFDIR) && (file_type != S_IFIFO))
BY_HANDLE_FILE_INFORMATION file_info;
if ((retval = (!GetFileInformationByHandle(handle, &file_info))) == 0)
{
const int64_t ssize = stat.st_size;
return (ssize >= 0) ? ((uint64_t)ssize) : 0U;
file_id->dev = file_info.dwVolumeSerialNumber;
file_id->ino = (((uint64_t)file_info.nFileIndexHigh) << 32) | file_info.nFileIndexLow;
}
CloseHandle(handle);
}
#else
STAT_T file_info;
if ((retval = STAT(path, &file_info)) == 0)
{
file_id->dev = file_info.st_dev;
file_id->ino = file_info.st_ino;
}
#endif
return retval;
}
int same_file(const CHR *const path0, const CHR *const path1)
{
file_uid_t file_id0, file_id1;
if ((get_file_unique_id(path0, &file_id0) == 0) && (get_file_unique_id(path1, &file_id1) == 0))
{
return (file_id0.dev == file_id1.dev) && (file_id0.ino == file_id1.ino);
}
return -1;
}
uint64_t get_size(FILE *const file)
{
STAT_T file_info;
if (FSTAT(FILENO(file), &file_info) == 0)
{
const unsigned ftype = file_info.st_mode & S_IFMT;
if ((ftype != S_IFDIR) && (ftype != S_IFIFO))
{
const int64_t size = file_info.st_size;
return (size >= 0) ? ((uint64_t)size) : 0U;
}
return 0U;
}

View File

@ -23,7 +23,9 @@ size_t fwrite_ui64(const uint64_t value, FILE *const stream);
size_t fread_ui64(uint64_t *const value, FILE *const stream);
char* CHR_to_utf8(const CHR *const input);
uint64_t get_file_size(FILE* const file);
int same_file(const CHR*const path0, const CHR*const path1);
uint64_t get_size(FILE *const file);
const CHR *get_file_name(const CHR *path);
uint64_t round_down(const uint64_t value, const uint64_t base);