diff --git a/README.md b/README.md index 2924d8e..2f56f8a 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ The SlunkCypt command-line program is invoked as follows: Commands -------- -One of the following commands must be chosen: +One of the following commands **must** be chosen: - **`--encrypt` (`-e`):** Run application in ***encrypt*** mode. Reads the given *plaintext* and generates *ciphertext*. @@ -46,7 +46,7 @@ One of the following commands must be chosen: Options ------- -The following options are available: +The following command-line options are available: - **`pass:`**: * Specifies the "secret" passphrase directly on the command-line. This is considered *insecure*. @@ -62,20 +62,30 @@ The following options are available: - **``**: * Specifies the length of the passphrase to be generated. If *not* specified, defaults to 24. -### Remarks - -- If the passphrase is **not** specified on the command-line, it will be read from the `SLUNK_PASSPHRASE` environment variable. +### Remarks {.unlisted} - The same passphrase must be used for both, ***encrypt*** and ***decrypt*** mode. The decryption of the ciphertext will only be possible, if the "correct" passphrase is known. It is recommended to choose a "random" password that is at least 12 characters in length and consists of a mix of upper-case characters, lower-case characters, digits as well as special characters. -- Passing the passphrase directly on the command-line is insecure, because the command-line may be visible to other users. +- Passing the passphrase directly on the command-line is insecure, because the full command-line may be visible to other users! + +Environment +----------- + +The following environment variables may be used: + +- **`SLUNK_PASSPHRASE`**: + Specifies the "secret" passphrase. This environment variables is only evaluated, if the passphrase was **not** specified on the command-line. + Passing the passphrase via environment variable is considered more secure, because environment variables are not normally visible to other (unprivileged) users. + +- **`SLUNK_KEEP_INCOMPLETE`**: + If set to a *non-zero* value, incomplete or corrupted output files will **not** be deleted automatically. Default is `0`. Examples -------- Here are some examples on how to use the SlunkCrypt command-line application: -### Example #1 +### Example #1 {.unlisted} 1. Let's generate a new random (secure) password first: @@ -101,7 +111,7 @@ Here are some examples on how to use the SlunkCrypt command-line application: sha256sum -b plaintext.txt plaintext.out -### Example #2 +### Example #2 {.unlisted} 1. Generate a new password and store it to a text file: @@ -115,7 +125,7 @@ Here are some examples on how to use the SlunkCrypt command-line application: slunkcrypt --encrypt file:passwd.txt plaintext.txt ciphertext.enc -### Example #3 +### Example #3 {.unlisted} 1. Generate a new password directly to an environment variable: @@ -158,7 +168,7 @@ Getting started In order to use the SlunkCypt library in your C++ code, include **``** header and instantiate the appropriate SlunkCypt classes: -### Example #1 +### Example #1 {.unlisted} Here is a simple example on how to use the SlunkCrypt [**`Encryptor`**](#encryptor) class: @@ -186,7 +196,7 @@ Here is a simple example on how to use the SlunkCrypt [**`Encryptor`**](#encrypt std::cout << std::hex << slunk_encrypt.get_nonce() << std::endl; } -### Example #2 +### Example #2 {.unlisted} Here is a simple example on how to use the SlunkCrypt [**`Decryptor`**](#decryptor) class: diff --git a/frontend/src/main.c b/frontend/src/main.c index c691116..208d7d3 100644 --- a/frontend/src/main.c +++ b/frontend/src/main.c @@ -40,7 +40,9 @@ #define PW_FROM_ENV (!(argc > 4)) -static const CHR* const ENV_PASSWRD = T("SLUNK_PASSPHRASE"); +static const CHR* const ENV_PASSWORD = T("SLUNK_PASSPHRASE"); +static const CHR* const ENV_KEEPFILE = T("SLUNK_KEEP_INCOMPLETE"); + static const CHR* const PREFIX_PASS = T("pass:"); static const CHR* const PREFIX_FILE = T("file:"); @@ -107,7 +109,7 @@ 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_PASSWRD); + FPRINTF(stderr, T("Optionally, reads passphrase from the %") T(PRISTR) T(" environment variable.\n\n"), ENV_PASSWORD); } static char *copy_passphrase(const CHR *const passphrase) @@ -259,6 +261,16 @@ static int open_files(FILE **const file_in, FILE **const file_out, const CHR *co return EXIT_SUCCESS; } +static int remove_incomplete_files(void) +{ + const CHR* const keep_files = GETENV(ENV_KEEPFILE); + if (keep_files) + { + return (!STRTOUL(keep_files)); + } + return 1; +} + static void sigint_handler(const int sig) { if (sig == SIGINT) @@ -430,6 +442,13 @@ clean_up: if (file_out) { fclose(file_out); + if ((result != EXIT_SUCCESS) && remove_incomplete_files()) + { + if (REMOVE(output_path)) + { + FPUTS(T("Warning: Failed to remove incomplete output file!\n\n"), stderr); + } + } } if (file_in) @@ -620,6 +639,13 @@ clean_up: if (file_out) { fclose(file_out); + if ((result != EXIT_SUCCESS) && remove_incomplete_files()) + { + if (REMOVE(output_path)) + { + FPUTS(T("Warning: Failed to remove incomplete output file!\n\n"), stderr); + } + } } if (file_in) @@ -816,7 +842,7 @@ int MAIN(const int argc, CHR *const argv[]) goto clean_up; } - const CHR *const passphrase = PW_FROM_ENV ? GETENV(ENV_PASSWRD) : argv[2U]; + 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])) diff --git a/frontend/src/platform.h b/frontend/src/platform.h index 7f4c90a..beabe26 100644 --- a/frontend/src/platform.h +++ b/frontend/src/platform.h @@ -60,6 +60,7 @@ # define STRTOUL(X) wcstoul((X), NULL, 0) # 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) # ifdef __USE_MINGW_ANSI_STDIO # define PRISTR "ls" @@ -82,6 +83,7 @@ # define STRTOUL(X) strtoul((X), NULL, 0) # 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 PRISTR "s" # define PRIstr "s"