Make it possible to read the passphrase from a file.
This commit is contained in:
parent
270c8b4ecd
commit
a3fd6360e1
@ -12,15 +12,59 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
static void print_string(const char *const text, const size_t length)
|
static volatile int g_interrupted = 0;
|
||||||
|
|
||||||
|
static char* read_passphrase(const CHR* const file_name)
|
||||||
{
|
{
|
||||||
fputc('"', stderr);
|
const size_t buff_size = 1024U;
|
||||||
for (size_t i = 0; i < length; ++i)
|
char *const buffer = (char*) malloc(buff_size * sizeof(char));
|
||||||
|
if (!buffer)
|
||||||
{
|
{
|
||||||
fputc((text[i] >= 0x20) ? text[i] : '?', stderr);
|
return NULL;
|
||||||
}
|
}
|
||||||
fputs("\"\n\n", stderr);
|
FILE *const fin = FOPEN(file_name, T("rb"));
|
||||||
|
if (!fin)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (!fgets(buffer, (int)buff_size, fin))
|
||||||
|
{
|
||||||
|
fclose(fin);
|
||||||
|
free(buffer);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
size_t length = strlen(buffer);
|
||||||
|
while ((length > 0U) && ((buffer[length - 1U] == '\r') || (buffer[length - 1U] == '\n')))
|
||||||
|
{
|
||||||
|
buffer[--length] = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (!buffer[0U]);
|
||||||
|
fclose(fin);
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int weak_passphrase(const char *str)
|
||||||
|
{
|
||||||
|
int flags[4U] = { 0, 0, 0, 0 };
|
||||||
|
while (*str)
|
||||||
|
{
|
||||||
|
const CHR c = *str++;
|
||||||
|
if (isalpha(c))
|
||||||
|
{
|
||||||
|
flags[isupper(c) ? 0U : 1U] = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
flags[isdigit(c) ? 2U : 3U] = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const int strong = flags[0U] && flags[1U] && flags[2U] && flags[3U];
|
||||||
|
return !strong;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int open_files(FILE** const fin, FILE** const fout, const CHR* const input, const CHR* const output)
|
static int open_files(FILE** const fin, FILE** const fout, const CHR* const input, const CHR* const output)
|
||||||
@ -43,21 +87,6 @@ static int open_files(FILE** const fin, FILE** const fout, const CHR* const inpu
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int weak_passphrase(const CHR *str)
|
|
||||||
{
|
|
||||||
int flags[4U] = { 0, 0, 0, 0 };
|
|
||||||
while (*str)
|
|
||||||
{
|
|
||||||
const CHR c = *str++;
|
|
||||||
if (ISUPPER(c)) flags[0U] = 1;
|
|
||||||
else if (ISLOWER(c)) flags[1U] = 1;
|
|
||||||
else if (ISDIGIT(c)) flags[2U] = 1;
|
|
||||||
else if (ISGRAPH(c)) flags[3U] = 1;
|
|
||||||
}
|
|
||||||
const int strong = flags[0U] && flags[1U] && flags[2U] && flags[3U];
|
|
||||||
return !strong;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int encrypt(const char* const passphrase, const CHR* const input, const CHR* const output)
|
static int encrypt(const char* const passphrase, const CHR* const input, const CHR* const output)
|
||||||
{
|
{
|
||||||
mcrypt_t ctx = MCRYPT_NULL;
|
mcrypt_t ctx = MCRYPT_NULL;
|
||||||
@ -136,6 +165,11 @@ static int encrypt(const char* const passphrase, const CHR* const input, const C
|
|||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
clk_update = clk_now;
|
clk_update = clk_now;
|
||||||
}
|
}
|
||||||
|
if (g_interrupted)
|
||||||
|
{
|
||||||
|
FPUTS(T("\n\nProcess interrupted!\n\n"), stderr);
|
||||||
|
goto clean_up;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
crc_actual = crc64_finish(crc_actual);
|
crc_actual = crc64_finish(crc_actual);
|
||||||
@ -254,6 +288,11 @@ static int decrypt(const char* const passphrase, const CHR* const input, const C
|
|||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
clk_update = clk_now;
|
clk_update = clk_now;
|
||||||
}
|
}
|
||||||
|
if (g_interrupted)
|
||||||
|
{
|
||||||
|
FPUTS(T("\n\nProcess interrupted!\n\n"), stderr);
|
||||||
|
goto clean_up;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
crc_actual = crc64_finish(crc_actual);
|
crc_actual = crc64_finish(crc_actual);
|
||||||
@ -392,9 +431,16 @@ clean_up:
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void sigint_handler(const int sig)
|
||||||
|
{
|
||||||
|
g_interrupted = 1;
|
||||||
|
signal(SIGINT, sigint_handler);
|
||||||
|
}
|
||||||
|
|
||||||
int MAIN(int argc, CHR* argv[])
|
int MAIN(int argc, CHR* argv[])
|
||||||
{
|
{
|
||||||
init_terminal();
|
init_terminal();
|
||||||
|
signal(SIGINT, sigint_handler);
|
||||||
|
|
||||||
FPRINTF(stderr, T("MCrypt Utility (%") T(PRIstr) T("-%") T(PRIstr) T("), by LoRd_MuldeR <MuldeR2@GMX.de>\n"), OS_TYPE, CPU_ARCH);
|
FPRINTF(stderr, T("MCrypt Utility (%") T(PRIstr) T("-%") T(PRIstr) T("), by LoRd_MuldeR <MuldeR2@GMX.de>\n"), OS_TYPE, CPU_ARCH);
|
||||||
FPRINTF(stderr, T("Using libMCrypt v%") T(PRIstr) T(" [%") T(PRIstr) T("]\n\n"), LIBMCRYPT_VERSION, LIBMCRYPT_BUILDNO);
|
FPRINTF(stderr, T("Using libMCrypt v%") T(PRIstr) T(" [%") T(PRIstr) T("]\n\n"), LIBMCRYPT_VERSION, LIBMCRYPT_BUILDNO);
|
||||||
@ -407,6 +453,7 @@ int MAIN(int argc, CHR* argv[])
|
|||||||
const int help_requested = (argc > 1) && ((!STRICMP(argv[1U], T("/?"))) || (!STRICMP(argv[1U], T("--help"))) || (!STRICMP(argv[1U], T("--version"))));
|
const int help_requested = (argc > 1) && ((!STRICMP(argv[1U], T("/?"))) || (!STRICMP(argv[1U], T("--help"))) || (!STRICMP(argv[1U], T("--version"))));
|
||||||
if ((argc < 5) || help_requested)
|
if ((argc < 5) || help_requested)
|
||||||
{
|
{
|
||||||
|
const CHR* const program = get_file_name(argv[0U]);
|
||||||
FPUTS(T("--------------------------------------------------------------------\n"), stderr);
|
FPUTS(T("--------------------------------------------------------------------\n"), stderr);
|
||||||
FPUTS(T("This software has been released under the CC0 1.0 Universal license:\n"), stderr);
|
FPUTS(T("This software has been released under the CC0 1.0 Universal license:\n"), stderr);
|
||||||
FPUTS(T("https://creativecommons.org/publicdomain/zero/1.0/legalcode\n"), stderr);
|
FPUTS(T("https://creativecommons.org/publicdomain/zero/1.0/legalcode\n"), stderr);
|
||||||
@ -416,28 +463,20 @@ int MAIN(int argc, CHR* argv[])
|
|||||||
FPUTS(T("Error: Required argument is missing!\n\n"), stderr);
|
FPUTS(T("Error: Required argument is missing!\n\n"), stderr);
|
||||||
}
|
}
|
||||||
FPUTS(T("Usage:\n"), stderr);
|
FPUTS(T("Usage:\n"), stderr);
|
||||||
FPRINTF(stderr, T(" %") T(PRISTR) T(" --encrypt <passphrase> <input.txt> <output.enc>\n"), argv[0U]);
|
FPRINTF(stderr, T(" %") T(PRISTR) T(" --encrypt [@]<passphrase> <input.dat> <output.enc>\n"), program);
|
||||||
FPRINTF(stderr, T(" %") T(PRISTR) T(" --decrypt <passphrase> <input.enc> <output.txt>\n\n"), argv[0U]);
|
FPRINTF(stderr, T(" %") T(PRISTR) T(" --decrypt [@]<passphrase> <input.enc> <output.dat>\n\n"), program);
|
||||||
|
FPUTS(T("Note: If <passphrase> starts with an '@' symbol, the remainder specifies the\n"), stderr);
|
||||||
|
FPUTS(T("file to read the passphrase from. Only the *first* line in the file is used!\n"), stderr);
|
||||||
return help_requested ? 0 : 1;
|
return help_requested ? 0 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const CHR *const command = argv[1U], *const passphrase = argv[2U], *const input_file = argv[3U], *const output_file = argv[4U];
|
const CHR *const command = argv[1U], *const passphrase = argv[2U], *const input_file = argv[3U], *const output_file = argv[4U];
|
||||||
if (!passphrase[0U])
|
|
||||||
|
if ((!passphrase[0U]) || ((passphrase[0U] == T('@')) && (!passphrase[1U])))
|
||||||
{
|
{
|
||||||
FPUTS(T("Error: The passphrase must not be empty!\n\n"), stderr);
|
FPUTS(T("Error: The passphrase or passphrase file must not be empty!\n\n"), stderr);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
if (STRLEN(passphrase) < 12U)
|
|
||||||
{
|
|
||||||
FPUTS(T("Warning: Using a *short* passphrase; a length of 12 characters or more is recommended!\n\n"), stderr);
|
|
||||||
}
|
|
||||||
if (weak_passphrase(passphrase))
|
|
||||||
{
|
|
||||||
FPUTS(T("Warning: Using a *weak* passphrase; a mix of upper-case letters, lower-case letters, digits and 'special' characters is recommended!\n\n"), stderr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((!input_file[0U]) || (!output_file[0U]))
|
if ((!input_file[0U]) || (!output_file[0U]))
|
||||||
{
|
{
|
||||||
@ -445,23 +484,32 @@ int MAIN(int argc, CHR* argv[])
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* const passphrase_utf8 = CHR_to_utf8(passphrase);
|
char *const passphrase_buffer = (passphrase[0U] == T('@')) ? read_passphrase(passphrase + 1U) : CHR_to_utf8(passphrase);
|
||||||
if (!passphrase_utf8)
|
if (!passphrase_buffer)
|
||||||
{
|
{
|
||||||
FPUTS(T("Error: Failed to convert passphrase to the UTF-8 format!\n\n"), stderr);
|
FPUTS(T("Error: Failed to read the passphrase file!\n\n"), stderr);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (strlen(passphrase_buffer) < 12U)
|
||||||
|
{
|
||||||
|
FPUTS(T("Warning: Using a *short* passphrase; a length of 12 characters or more is recommended!\n\n"), stderr);
|
||||||
|
}
|
||||||
|
else if (weak_passphrase(passphrase_buffer))
|
||||||
|
{
|
||||||
|
FPUTS(T("Warning: Using a *weak* passphrase; a mix of upper-case letters, lower-case letters, digits and 'special' characters is recommended!\n\n"), stderr);
|
||||||
|
}
|
||||||
|
|
||||||
const clock_t clk_start = clock();
|
const clock_t clk_start = clock();
|
||||||
int result = -1;
|
int result = -1;
|
||||||
|
|
||||||
if (!STRICMP(command, T("--encrypt")))
|
if (!STRICMP(command, T("--encrypt")))
|
||||||
{
|
{
|
||||||
result = encrypt(passphrase_utf8, input_file, output_file);
|
result = encrypt(passphrase_buffer, input_file, output_file);
|
||||||
}
|
}
|
||||||
else if (!STRICMP(command, T("--decrypt")))
|
else if (!STRICMP(command, T("--decrypt")))
|
||||||
{
|
{
|
||||||
result = decrypt(passphrase_utf8, input_file, output_file);
|
result = decrypt(passphrase_buffer, input_file, output_file);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -477,10 +525,10 @@ int MAIN(int argc, CHR* argv[])
|
|||||||
|
|
||||||
exiting:
|
exiting:
|
||||||
|
|
||||||
if (passphrase_utf8)
|
if (passphrase_buffer)
|
||||||
{
|
{
|
||||||
mcrypt_bzero(passphrase_utf8, strlen(passphrase_utf8));
|
mcrypt_bzero(passphrase_buffer, strlen(passphrase_buffer));
|
||||||
free(passphrase_utf8);
|
free(passphrase_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
mcrypt_bzero((CHR*)passphrase, STRLEN(passphrase) * sizeof(CHR));
|
mcrypt_bzero((CHR*)passphrase, STRLEN(passphrase) * sizeof(CHR));
|
||||||
|
@ -55,16 +55,13 @@
|
|||||||
#define _T(X) L##X
|
#define _T(X) L##X
|
||||||
#define STRLEN(X) wcslen((X))
|
#define STRLEN(X) wcslen((X))
|
||||||
#define STRICMP(X,Y) _wcsicmp((X),(Y))
|
#define STRICMP(X,Y) _wcsicmp((X),(Y))
|
||||||
|
#define STRRCHR(X,Y) wcsrchr((X),(Y))
|
||||||
#define FPUTS(X,Y) fputws((X),(Y))
|
#define FPUTS(X,Y) fputws((X),(Y))
|
||||||
#define FPRINTF(X,Y,...) fwprintf((X),(Y),__VA_ARGS__)
|
#define FPRINTF(X,Y,...) fwprintf((X),(Y),__VA_ARGS__)
|
||||||
#define FOPEN(X,Y) _wfsopen((X),(Y),_SH_SECURE)
|
#define FOPEN(X,Y) _wfsopen((X),(Y),_SH_SECURE)
|
||||||
#define FILENO(X) _fileno((X))
|
#define FILENO(X) _fileno((X))
|
||||||
#define FSTAT64(X,Y) _fstati64((X),(Y))
|
#define FSTAT64(X,Y) _fstati64((X),(Y))
|
||||||
#define STAT64_T struct _stati64
|
#define STAT64_T struct _stati64
|
||||||
#define ISUPPER(X) iswupper((X))
|
|
||||||
#define ISLOWER(X) iswlower((X))
|
|
||||||
#define ISDIGIT(X) iswdigit((X))
|
|
||||||
#define ISGRAPH(X) iswgraph((X))
|
|
||||||
#ifdef __MINGW32__
|
#ifdef __MINGW32__
|
||||||
#define PRISTR "ls"
|
#define PRISTR "ls"
|
||||||
#define PRIstr "hs"
|
#define PRIstr "hs"
|
||||||
@ -80,16 +77,13 @@
|
|||||||
#define _T(X) X
|
#define _T(X) X
|
||||||
#define STRLEN(X) strlen((X))
|
#define STRLEN(X) strlen((X))
|
||||||
#define STRICMP(X,Y) strcasecmp((X),(Y))
|
#define STRICMP(X,Y) strcasecmp((X),(Y))
|
||||||
|
#define STRRCHR(X,Y) strrchr((X),(Y))
|
||||||
#define FPUTS(X,Y) fputs((X),(Y))
|
#define FPUTS(X,Y) fputs((X),(Y))
|
||||||
#define FPRINTF(X,Y,...) fprintf((X),(Y),__VA_ARGS__)
|
#define FPRINTF(X,Y,...) fprintf((X),(Y),__VA_ARGS__)
|
||||||
#define FOPEN(X,Y) fopen((X),(Y))
|
#define FOPEN(X,Y) fopen((X),(Y))
|
||||||
#define FILENO(X) fileno((X))
|
#define FILENO(X) fileno((X))
|
||||||
#define FSTAT64(X,Y) fstat64((X),(Y))
|
#define FSTAT64(X,Y) fstat64((X),(Y))
|
||||||
#define STAT64_T struct stat64
|
#define STAT64_T struct stat64
|
||||||
#define ISUPPER(X) isupper((X))
|
|
||||||
#define ISLOWER(X) islower((X))
|
|
||||||
#define ISDIGIT(X) isdigit((X))
|
|
||||||
#define ISGRAPH(X) isgraph((X))
|
|
||||||
#define PRISTR "s"
|
#define PRISTR "s"
|
||||||
#define PRIstr "s"
|
#define PRIstr "s"
|
||||||
#define PRIwcs "ls"
|
#define PRIwcs "ls"
|
||||||
|
@ -11,7 +11,6 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include <mcrypt.h>
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
@ -24,6 +23,14 @@
|
|||||||
#define S_IFIFO _S_IFIFO
|
#define S_IFIFO _S_IFIFO
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void init_terminal(void)
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
|
||||||
|
_setmode(_fileno(stderr), _O_U8TEXT);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
char* CHR_to_utf8(const CHR*const input)
|
char* CHR_to_utf8(const CHR*const input)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
@ -55,7 +62,7 @@ char* CHR_to_utf8(const CHR*const input)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t get_file_size(FILE *const file)
|
uint64_t get_file_size(FILE* const file)
|
||||||
{
|
{
|
||||||
STAT64_T stat;
|
STAT64_T stat;
|
||||||
if (FSTAT64(FILENO(file), &stat) != 0)
|
if (FSTAT64(FILENO(file), &stat) != 0)
|
||||||
@ -70,10 +77,16 @@ uint64_t get_file_size(FILE *const file)
|
|||||||
return 0U;
|
return 0U;
|
||||||
}
|
}
|
||||||
|
|
||||||
void init_terminal(void)
|
const CHR* get_file_name(const CHR* path)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
const CHR* ptr;
|
||||||
SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
|
while (ptr = STRRCHR(path, T('/')))
|
||||||
_setmode(_fileno(stderr), _O_U8TEXT);
|
{
|
||||||
#endif
|
path = ptr + 1U;
|
||||||
|
}
|
||||||
|
while (ptr = STRRCHR(path, T('\\')))
|
||||||
|
{
|
||||||
|
path = ptr + 1U;
|
||||||
|
}
|
||||||
|
return path;
|
||||||
}
|
}
|
||||||
|
@ -9,8 +9,9 @@
|
|||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
void init_terminal(void);
|
||||||
char* CHR_to_utf8(const CHR *const input);
|
char* CHR_to_utf8(const CHR *const input);
|
||||||
uint64_t get_file_size(FILE* const file);
|
uint64_t get_file_size(FILE* const file);
|
||||||
void init_terminal(void);
|
const CHR *get_file_name(const CHR *path);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user