From bdab06cd80417438893da7b2e72a5bd755284efb Mon Sep 17 00:00:00 2001 From: LoRd_MuldeR Date: Fri, 26 Mar 2021 01:21:29 +0100 Subject: [PATCH] Don't require environment variable to start with "pass:" prefix + some code clean-up. --- frontend/src/main.c | 127 ++++++++++++++++++++++++++------------------ 1 file changed, 74 insertions(+), 53 deletions(-) diff --git a/frontend/src/main.c b/frontend/src/main.c index 0783f6b..0981bce 100644 --- a/frontend/src/main.c +++ b/frontend/src/main.c @@ -25,22 +25,25 @@ #include #include -/* 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:|file:] \n"), program); FPRINTF(stderr, T(" %") T(PRISTR) T(" --decrypt [pass:|file:] \n"), program); FPRINTF(stderr, T(" %") T(PRISTR) T(" --make-pw []\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: