OSDN Git Service

Make it possible to read the passphrase from a file.
authorLoRd_MuldeR <mulder2@gmx.de>
Wed, 14 Oct 2020 14:36:17 +0000 (16:36 +0200)
committerLoRd_MuldeR <mulder2@gmx.de>
Sat, 20 Mar 2021 20:18:13 +0000 (21:18 +0100)
frontend/src/main.c
frontend/src/platform.h
frontend/src/utils.c
frontend/src/utils.h

index 6fb8eb7..efec490 100644 (file)
 #include <time.h>
 #include <inttypes.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)
+{
+       const size_t buff_size = 1024U;
+       char *const buffer = (char*) malloc(buff_size * sizeof(char));
+       if (!buffer)
+       {
+               return NULL;
+       }
+       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)
 {
-       fputc('"', stderr);
-       for (size_t i = 0; i < length; ++i)
+       int flags[4U] = { 0, 0, 0, 0 };
+       while (*str)
        {
-               fputc((text[i] >= 0x20) ? text[i] : '?', stderr);
+               const CHR c = *str++;
+               if (isalpha(c))
+               {
+                       flags[isupper(c) ? 0U : 1U] = 1;
+               }
+               else 
+               {
+                       flags[isdigit(c) ? 2U : 3U] = 1;
+               }
        }
-       fputs("\"\n\n", stderr);
+       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)
@@ -43,21 +87,6 @@ static int open_files(FILE** const fin, FILE** const fout, const CHR* const inpu
        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)
 {
        mcrypt_t ctx = MCRYPT_NULL;
@@ -136,6 +165,11 @@ static int encrypt(const char* const passphrase, const CHR* const input, const C
                        fflush(stderr);
                        clk_update = clk_now;
                }
+               if (g_interrupted)
+               {
+                       FPUTS(T("\n\nProcess interrupted!\n\n"), stderr);
+                       goto clean_up;
+               }
        }
 
        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);
                        clk_update = clk_now;
                }
+               if (g_interrupted)
+               {
+                       FPUTS(T("\n\nProcess interrupted!\n\n"), stderr);
+                       goto clean_up;
+               }
        }
 
        crc_actual = crc64_finish(crc_actual);
@@ -392,9 +431,16 @@ clean_up:
        return result;
 }
 
+static void sigint_handler(const int sig)
+{
+       g_interrupted = 1;
+       signal(SIGINT, sigint_handler);
+}
+
 int MAIN(int argc, CHR* argv[])
 {
        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("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"))));
        if ((argc < 5) || help_requested)
        {
+               const CHR* const program = get_file_name(argv[0U]);
                FPUTS(T("--------------------------------------------------------------------\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);
@@ -416,28 +463,20 @@ int MAIN(int argc, CHR* argv[])
                        FPUTS(T("Error: Required argument is missing!\n\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(" --decrypt <passphrase> <input.enc> <output.txt>\n\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.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;
        }
 
        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;
        }
-       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]))
        {
@@ -445,23 +484,32 @@ int MAIN(int argc, CHR* argv[])
                return 1;
        }
 
-       char* const passphrase_utf8 = CHR_to_utf8(passphrase);
-       if (!passphrase_utf8)
+       char *const passphrase_buffer = (passphrase[0U] == T('@')) ? read_passphrase(passphrase + 1U) : CHR_to_utf8(passphrase);
+       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;
        }
 
+       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();
        int result = -1;
 
        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")))
        {
-               result = decrypt(passphrase_utf8, input_file, output_file);
+               result = decrypt(passphrase_buffer, input_file, output_file);
        }
        else
        {
@@ -477,10 +525,10 @@ int MAIN(int argc, CHR* argv[])
 
 exiting:
        
-       if (passphrase_utf8)
+       if (passphrase_buffer)
        {
-               mcrypt_bzero(passphrase_utf8, strlen(passphrase_utf8));
-               free(passphrase_utf8);
+               mcrypt_bzero(passphrase_buffer, strlen(passphrase_buffer));
+               free(passphrase_buffer);
        }
 
        mcrypt_bzero((CHR*)passphrase, STRLEN(passphrase) * sizeof(CHR));
index 0ce1508..f122442 100644 (file)
 #define _T(X) L##X
 #define STRLEN(X) wcslen((X))
 #define STRICMP(X,Y) _wcsicmp((X),(Y))
+#define STRRCHR(X,Y) wcsrchr((X),(Y))
 #define FPUTS(X,Y) fputws((X),(Y))
 #define FPRINTF(X,Y,...) fwprintf((X),(Y),__VA_ARGS__)
 #define FOPEN(X,Y) _wfsopen((X),(Y),_SH_SECURE)
 #define FILENO(X) _fileno((X))
 #define FSTAT64(X,Y) _fstati64((X),(Y))
 #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__
 #define PRISTR "ls"
 #define PRIstr "hs"
 #define _T(X) X
 #define STRLEN(X) strlen((X))
 #define STRICMP(X,Y) strcasecmp((X),(Y))
+#define STRRCHR(X,Y) strrchr((X),(Y))
 #define FPUTS(X,Y) fputs((X),(Y))
 #define FPRINTF(X,Y,...) fprintf((X),(Y),__VA_ARGS__)
 #define FOPEN(X,Y) fopen((X),(Y))
 #define FILENO(X) fileno((X))
 #define FSTAT64(X,Y) fstat64((X),(Y))
 #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 PRIwcs "ls"
index 3602102..9237b12 100644 (file)
@@ -11,7 +11,6 @@
 #endif
 
 #include "utils.h"
-#include <mcrypt.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 
 #define S_IFIFO _S_IFIFO
 #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)
 {
 #ifdef _WIN32
@@ -55,7 +62,7 @@ char* CHR_to_utf8(const CHR*const input)
 #endif
 }
 
-uint64_t get_file_size(FILE *const file)
+uint64_t get_file_size(FILEconst file)
 {
        STAT64_T stat;
        if (FSTAT64(FILENO(file), &stat) != 0)
@@ -70,10 +77,16 @@ uint64_t get_file_size(FILE *const file)
        return 0U;
 }
 
-void init_terminal(void)
+const CHR* get_file_name(const CHR* path)
 {
-#ifdef _WIN32
-       SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
-       _setmode(_fileno(stderr), _O_U8TEXT);
-#endif
+       const CHR* ptr;
+       while (ptr = STRRCHR(path, T('/')))
+       {
+               path = ptr + 1U;
+       }
+       while (ptr = STRRCHR(path, T('\\')))
+       {
+               path = ptr + 1U;
+       }
+       return path;
 }
index 1d3b764..d7523c1 100644 (file)
@@ -9,8 +9,9 @@
 #include "platform.h"
 #include <stdint.h>
 
+void init_terminal(void);
 char* CHR_to_utf8(const CHR *const input);
 uint64_t get_file_size(FILE* const file);
-void init_terminal(void);
+const CHR *get_file_name(const CHR *path);
 
 #endif