Don't require environment variable to start with "pass:" prefix + some code clean-up.

This commit is contained in:
LoRd_MuldeR 2021-03-26 01:21:29 +01:00
parent c8cd0fc699
commit bdab06cd80
Signed by: mulder
GPG Key ID: 2B5913365F57E03F

View File

@ -25,22 +25,25 @@
#include <signal.h>
#include <assert.h>
/* Const */
// ==========================================================================
// Constants
// ==========================================================================
#define BUFFER_SIZE 4096U
/* Op-mode */
#define SLUNK_MODE_HELP 0
#define SLUNK_MODE_VERS 1
#define SLUNK_MODE_ENCR 2
#define SLUNK_MODE_DECR 3
#define SLUNK_MODE_PASS 4
#define SLUNK_MODE_TEST 5
#define MODE_HELP 0
#define MODE_VERS 1
#define MODE_ENCR 2
#define MODE_DECR 3
#define MODE_PASS 4
#define MODE_TEST 5
#define PW_FROM_ENV (!(argc > 4))
static const CHR* const ENV_PASSWRD = T("SLUNK_PASSPHRASE");
static const CHR* const PREFIX_PASS = T("pass:");
static const CHR* const PREFIX_FILE = T("file:");
static const CHR* const ENV_PASSWD_NAME = T("SLUNK_PASSPHRASE");
static const char PASSWD_SYMBOLS[] =
{
'!', '#', '$', '%', '&', '(', ')', '*', '+', ',', '-', '.', '/', '0', '1',
@ -51,42 +54,44 @@ static const char PASSWD_SYMBOLS[] =
'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~'
};
static const size_t RCMD_PWDLEN_LENGTH = 12U;
static const size_t DFLT_PWDLEN_LENGTH = 20U;
static const uint64_t MAGIC_NUMBER = 0x243F6A8885A308D3ull;
// ==========================================================================
// Auxiliary functions
// ==========================================================================
static int parse_mode(const CHR* const command)
static int parse_slunk_mode(const CHR* const command)
{
if ((!STRICMP(command, T("-h"))) || (!STRICMP(command, T("/?"))) || (!STRICMP(command, T("--help"))))
{
return SLUNK_MODE_HELP;
return MODE_HELP;
}
else if ((!STRICMP(command, T("-v"))) || (!STRICMP(command, T("--version"))))
{
return SLUNK_MODE_VERS;
return MODE_VERS;
}
else if ((!STRICMP(command, T("-e"))) || (!STRICMP(command, T("--encrypt"))))
{
return SLUNK_MODE_ENCR;
return MODE_ENCR;
}
else if ((!STRICMP(command, T("-d"))) || (!STRICMP(command, T("--decrypt"))))
{
return SLUNK_MODE_DECR;
return MODE_DECR;
}
else if ((!STRICMP(command, T("-p"))) || (!STRICMP(command, T("--make-pw"))))
{
return SLUNK_MODE_PASS;
return MODE_PASS;
}
else if ((!STRICMP(command, T("-t"))) || (!STRICMP(command, T("--self-test"))))
{
return SLUNK_MODE_TEST;
return MODE_TEST;
}
else
{
FPRINTF(stderr, T("Error: The specified command \"%") T(PRISTR) T("\" is unknown!\n\n"), command);
exit(EXIT_FAILURE);
return -1; /*invalid command*/
}
}
@ -100,22 +105,29 @@ static void print_manpage(const CHR *const program)
FPRINTF(stderr, T(" %") T(PRISTR) T(" --encrypt [pass:<pass>|file:<file>] <input.txt> <output.enc>\n"), program);
FPRINTF(stderr, T(" %") T(PRISTR) T(" --decrypt [pass:<pass>|file:<file>] <input.enc> <output.txt>\n"), program);
FPRINTF(stderr, T(" %") T(PRISTR) T(" --make-pw [<length>]\n\n"), program);
FPRINTF(stderr, T("Optionally, reads passphrase from the %") T(PRISTR) T(" environment variable.\n\n"), ENV_PASSWD_NAME);
FPRINTF(stderr, T("Optionally, reads passphrase from the %") T(PRISTR) T(" environment variable.\n\n"), ENV_PASSWRD);
}
static char *duplicate_string(const CHR *const passphrase)
static char *copy_passphrase(const CHR *const passphrase)
{
if ((!passphrase) || (!passphrase[0U]))
{
FPUTS(T("Error: The passphrase input string must not be empty!\n\n"), stderr);
return NULL;
}
char *const buffer = CHR_to_utf8(passphrase);
if (!buffer)
{
FPUTS(T("Error: Failed to allocate the string buffer!\n\n"), stderr);
}
return buffer;
}
static char *read_passphrase(const CHR* const file_name)
static char *read_passphrase(const CHR *const file_name)
{
if (file_name && (!file_name[0U]))
if ((!file_name) || (!file_name[0U]))
{
FPUTS(T("Error: The passphrase input file name must not be empty!\n\n"), stderr);
return NULL;
@ -133,7 +145,7 @@ static char *read_passphrase(const CHR* const file_name)
FILE *const file_in = use_stdin ? stdin : FOPEN(file_name, T("rb"));
if (!file_in)
{
FPRINTF(stderr, T("Error: Failed to open file \"%") T(PRISTR) T("\" for reading!\n\n"), file_name);
FPRINTF(stderr, T("Error: Failed to open input file \"%") T(PRISTR) T("\" for reading!\n\n"), file_name);
free(buffer);
return NULL;
}
@ -225,20 +237,20 @@ clean_up:
return result;
}
static int open_files(FILE **const file_in, FILE **const file_out, const CHR* const input_path, const CHR* const output_path)
static int open_files(FILE **const file_in, FILE **const file_out, const CHR *const input_path, const CHR *const output_path)
{
*file_in = FOPEN(input_path, T("rb"));
if (!(*file_in))
if (!(*file_in = FOPEN(input_path, T("rb"))))
{
FPRINTF(stderr, T("Error: Failed to open 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"), input_path);
*file_out = NULL;
return EXIT_FAILURE;
}
*file_out = FOPEN(output_path, T("wb"));
if (!(*file_out))
if (!(*file_out = FOPEN(output_path, T("wb"))))
{
FPRINTF(stderr, T("Error: Failed to open 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"), output_path);
fclose(*file_in);
*file_in = NULL;
return EXIT_FAILURE;
}
@ -763,20 +775,26 @@ int MAIN(const int argc, CHR *const argv[])
goto clean_up;
}
const int mode = parse_mode(argv[1U]);
switch (mode)
const int slunk_mode = parse_slunk_mode(argv[1U]);
switch (slunk_mode)
{
case SLUNK_MODE_HELP:
case MODE_HELP:
print_manpage(get_file_name(argv[0U]));
case SLUNK_MODE_VERS:
case MODE_VERS:
result = EXIT_SUCCESS;
goto clean_up;
case SLUNK_MODE_PASS:
result = generate_passphrase((argc > 2) ? STRTOUL(argv[2U]) : 24U);
case MODE_ENCR:
case MODE_DECR:
break; /*fallthrough*/
case MODE_PASS:
result = generate_passphrase((argc > 2) ? STRTOUL(argv[2U]) : DFLT_PWDLEN_LENGTH);
goto clean_up;
case SLUNK_MODE_TEST:
case MODE_TEST:
result = run_self_test();
goto clean_up;
default:
FPRINTF(stderr, T("Error: The specified command \"%") T(PRISTR) T("\" is unknown!\n\n"), argv[1U]);
goto clean_up;
}
if (argc < 4)
@ -785,8 +803,8 @@ int MAIN(const int argc, CHR *const argv[])
goto clean_up;
}
const CHR *const passphrase = (argc > 4) ? argv[2U] : GETENV(ENV_PASSWD_NAME);
const CHR *const input_file = argv[(argc > 4) ? 3U : 2U], *const output_file = argv[(argc > 4) ? 4U : 3U];
const CHR *const passphrase = PW_FROM_ENV ? GETENV(ENV_PASSWRD) : 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]))
{
@ -794,10 +812,13 @@ int MAIN(const int argc, CHR *const argv[])
goto clean_up;
}
if (STRICMP(passphrase, T("-")) && (!STARTS_WITH(passphrase, PREFIX_PASS)) && (!STARTS_WITH(passphrase, PREFIX_FILE)))
if ((!PW_FROM_ENV) && STRICMP(passphrase, T("-")))
{
FPRINTF(stderr, T("Error: The passphrase must start with a '%") T(PRISTR) T("' or '%") T(PRISTR) T("' prefix!\n\n"), PREFIX_PASS, PREFIX_FILE);
goto clean_up;
if ((!STARTS_WITH(passphrase, PREFIX_PASS)) && (!STARTS_WITH(passphrase, PREFIX_FILE)))
{
FPRINTF(stderr, T("Error: The passphrase must start with a '%") T(PRISTR) T("' or '%") T(PRISTR) T("' prefix!\n\n"), PREFIX_PASS, PREFIX_FILE);
goto clean_up;
}
}
if ((!input_file[0U]) || (!output_file[0U]))
@ -810,9 +831,9 @@ int MAIN(const int argc, CHR *const argv[])
/* Initialize passphrase */
/* ----------------------------------------------------- */
passphrase_buffer = STARTS_WITH(passphrase, PREFIX_PASS) ? duplicate_string(passphrase + STRLEN(PREFIX_PASS)) :
(STARTS_WITH(passphrase, PREFIX_FILE) ? read_passphrase(passphrase + STRLEN(PREFIX_FILE)) : read_passphrase(NULL));
if (!passphrase_buffer)
if (!(passphrase_buffer = PW_FROM_ENV ? copy_passphrase(passphrase) :
(STARTS_WITH(passphrase, PREFIX_PASS) ? copy_passphrase(passphrase + STRLEN(PREFIX_PASS)) :
(STARTS_WITH(passphrase, PREFIX_FILE) ? read_passphrase(passphrase + STRLEN(PREFIX_FILE)) : read_passphrase(T("-"))))))
{
goto clean_up;
}
@ -822,18 +843,18 @@ int MAIN(const int argc, CHR *const argv[])
const size_t passphrase_len = strlen(passphrase_buffer);
if (passphrase_len < SLUNKCRYPT_PWDLEN_MIN)
{
FPRINTF(stderr, T("Error: Passphrase must be at least %") T(PRIu64) T(" characters in length!\n\n"), (uint64_t)SLUNKCRYPT_PWDLEN_MIN);
FPRINTF(stderr, T("Error: Passphrase must be at least %u characters in length!\n\n"), (unsigned)SLUNKCRYPT_PWDLEN_MIN);
goto clean_up;
}
else if (passphrase_len > SLUNKCRYPT_PWDLEN_MAX)
{
FPRINTF(stderr, T("Error: Passphrase must be at most %") T(PRIu64) T(" characters in length!\n\n"), (uint64_t)SLUNKCRYPT_PWDLEN_MAX);
FPRINTF(stderr, T("Error: Passphrase must be at most %u characters in length!\n\n"), (unsigned)SLUNKCRYPT_PWDLEN_MAX);
goto clean_up;
}
if (passphrase_len < 12U)
if (passphrase_len < RCMD_PWDLEN_LENGTH)
{
FPUTS(T("Warning: Using a *short* passphrase; a length of 12 characters or more is recommended!\n\n"), stderr);
FPRINTF(stderr, T("Warning: Using a *short* passphrase; a length of %u characters or more is recommended!\n\n"), (unsigned)RCMD_PWDLEN_LENGTH);
}
else if (weak_passphrase(passphrase_buffer))
{
@ -846,12 +867,12 @@ int MAIN(const int argc, CHR *const argv[])
const clock_t clk_start = clock();
switch (mode)
switch (slunk_mode)
{
case SLUNK_MODE_ENCR:
case MODE_ENCR:
result = encrypt(passphrase_buffer, input_file, output_file);
break;
case SLUNK_MODE_DECR:
case MODE_DECR:
result = decrypt(passphrase_buffer, input_file, output_file);
break;
default: