Refactored passphrase generator into a separate file.
This commit is contained in:
parent
46dc28f3ca
commit
b7e32f5f0a
@ -45,6 +45,7 @@
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\blake2.c" />
|
||||
<ClCompile Include="src\crypt.c" />
|
||||
<ClCompile Include="src\pwgen.c" />
|
||||
<ClCompile Include="src\selftest.c" />
|
||||
<ClCompile Include="src\test_data.c" />
|
||||
<ClCompile Include="src\main.c" />
|
||||
@ -54,6 +55,7 @@
|
||||
<ClInclude Include="src\blake2.h" />
|
||||
<ClInclude Include="src\crypt.h" />
|
||||
<ClInclude Include="src\platform.h" />
|
||||
<ClInclude Include="src\pwgen.h" />
|
||||
<ClInclude Include="src\selftest.h" />
|
||||
<ClInclude Include="src\test_data.h" />
|
||||
<ClInclude Include="src\utils.h" />
|
||||
|
@ -33,6 +33,9 @@
|
||||
<ClCompile Include="src\selftest.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\pwgen.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="src\utils.h">
|
||||
@ -53,6 +56,9 @@
|
||||
<ClInclude Include="src\selftest.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\pwgen.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Manifest Include="res\compatibility.manifest">
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include <slunkcrypt.h>
|
||||
#include "utils.h"
|
||||
#include "crypt.h"
|
||||
#include "pwgen.h"
|
||||
#include "selftest.h"
|
||||
|
||||
/* CRT */
|
||||
@ -33,7 +34,8 @@
|
||||
#define MODE_PASS 4
|
||||
#define MODE_TEST 5
|
||||
|
||||
#define PW_FROM_ENV (!(argc > 4))
|
||||
static const size_t RCMD_PWDLEN_LENGTH = 12U;
|
||||
static const size_t DFLT_PWDLEN_LENGTH = 20U;
|
||||
|
||||
static const CHR* const ENV_PASSWORD = T("SLUNK_PASSPHRASE");
|
||||
static const CHR* const ENV_KEEPFILE = T("SLUNK_KEEP_INCOMPLETE");
|
||||
@ -41,23 +43,12 @@ 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:");
|
||||
|
||||
static const char PASSWD_SYMBOLS[] =
|
||||
{
|
||||
'!', '#', '$', '%', '&', '(', ')', '*', '+', ',', '-', '.', '/', '0', '1',
|
||||
'2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', '@',
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
|
||||
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', ']', '^', '_',
|
||||
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
|
||||
'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;
|
||||
|
||||
// ==========================================================================
|
||||
// Auxiliary functions
|
||||
// ==========================================================================
|
||||
|
||||
#define PW_FROM_ENV (!(argc > 4))
|
||||
|
||||
static int parse_slunk_mode(const CHR* const command)
|
||||
{
|
||||
if ((!STRICMP(command, T("-h"))) || (!STRICMP(command, T("/?"))) || (!STRICMP(command, T("--help"))))
|
||||
@ -120,118 +111,6 @@ static char *copy_passphrase(const CHR *const passphrase)
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static char *read_passphrase(const CHR *const file_name)
|
||||
{
|
||||
if ((!file_name) || (!file_name[0U]))
|
||||
{
|
||||
FPUTS(T("Error: The passphrase input file name must not be empty!\n\n"), stderr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const size_t max_len = SLUNKCRYPT_PWDLEN_MAX + 2U;
|
||||
char *const buffer = (char*) malloc(max_len * sizeof(char));
|
||||
if (!buffer)
|
||||
{
|
||||
FPUTS(T("Error: Failed to allocate the passphrase buffer!\n\n"), stderr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const int use_stdin = (!file_name) || (!STRICMP(file_name, T("-")));
|
||||
FILE *const file_in = use_stdin ? stdin : FOPEN(file_name, T("rb"));
|
||||
if (!file_in)
|
||||
{
|
||||
FPRINTF(stderr, T("Error: Failed to open input file \"%") T(PRISTR) T("\" for reading!\n\n"), file_name);
|
||||
free(buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
if (!fgets(buffer, (int)max_len, file_in))
|
||||
{
|
||||
buffer[0U] = '\0';
|
||||
goto finish;
|
||||
}
|
||||
size_t length = strlen(buffer);
|
||||
while ((length > 0U) && ((buffer[length - 1U] == '\r') || (buffer[length - 1U] == '\n')))
|
||||
{
|
||||
buffer[--length] = '\0';
|
||||
}
|
||||
}
|
||||
while (!buffer[0U]);
|
||||
|
||||
finish:
|
||||
|
||||
if ((!use_stdin) && file_in)
|
||||
{
|
||||
fclose(file_in);
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static int weak_passphrase(const char *str)
|
||||
{
|
||||
int flags[4U] = { 0, 0, 0, 0 };
|
||||
while (*str)
|
||||
{
|
||||
const int 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 generate_passphrase(const size_t length)
|
||||
{
|
||||
int result = EXIT_FAILURE;
|
||||
const size_t passwd_len = BOUND(SLUNKCRYPT_PWDLEN_MIN, length, SLUNKCRYPT_PWDLEN_MAX);
|
||||
|
||||
char *const buffer = (char*) malloc((passwd_len + 1U) * sizeof(char));
|
||||
if (!buffer)
|
||||
{
|
||||
FPUTS(T("Error: Failed to allocate memory buffer!\n\n"), stderr);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
for (size_t i = 0U; i < passwd_len; ++i)
|
||||
{
|
||||
uint64_t value;
|
||||
if (slunkcrypt_generate_nonce(&value) != SLUNKCRYPT_SUCCESS)
|
||||
{
|
||||
FPUTS(T("Error: Failed to generate next random number!\n\n"), stderr);
|
||||
goto clean_up;
|
||||
}
|
||||
buffer[i] = PASSWD_SYMBOLS[value % ARRAY_SIZE(PASSWD_SYMBOLS)];
|
||||
}
|
||||
buffer[passwd_len] = '\0';
|
||||
}
|
||||
while ((!isalpha((int)buffer[0U])) || (!isalnum((int)buffer[passwd_len - 1U])) || weak_passphrase(buffer));
|
||||
|
||||
FPRINTF(stdout, T("%") T(PRIstr) T("\n\n"), buffer);
|
||||
fflush(stdout);
|
||||
result = EXIT_SUCCESS;
|
||||
|
||||
clean_up:
|
||||
|
||||
if (buffer)
|
||||
{
|
||||
slunkcrypt_bzero(buffer, passwd_len * sizeof(char));
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int keep_incomplete_files(void)
|
||||
{
|
||||
const CHR *const keep_files = GETENV(ENV_KEEPFILE);
|
||||
@ -372,7 +251,7 @@ int MAIN(const int argc, CHR *const argv[])
|
||||
}
|
||||
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);
|
||||
FPUTS(T("Warning: Using a *weak* passphrase; a mix of upper-case letters, lower-case letters, digits and other characters is recommended!\n\n"), stderr);
|
||||
}
|
||||
|
||||
fflush(stderr);
|
||||
|
151
frontend/src/pwgen.c
Normal file
151
frontend/src/pwgen.c
Normal file
@ -0,0 +1,151 @@
|
||||
/******************************************************************************/
|
||||
/* SlunkCrypt, by LoRd_MuldeR <MuldeR2@GMX.de> */
|
||||
/* This work has been released under the CC0 1.0 Universal license! */
|
||||
/******************************************************************************/
|
||||
|
||||
#ifdef _WIN32
|
||||
# define _CRT_SECURE_NO_WARNINGS 1
|
||||
#else
|
||||
# define _GNU_SOURCE 1
|
||||
#endif
|
||||
|
||||
/* Internal */
|
||||
#include "pwgen.h"
|
||||
#include <slunkcrypt.h>
|
||||
#include "utils.h"
|
||||
|
||||
/* CRT */
|
||||
#include <ctype.h>
|
||||
|
||||
// ==========================================================================
|
||||
// Constants
|
||||
// ==========================================================================
|
||||
|
||||
static const char PASSWD_SYMBOLS[] =
|
||||
{
|
||||
'!', '#', '$', '%', '&', '(', ')', '*', '+', ',', '-', '.', '/', '0', '1',
|
||||
'2', '3', '4', '5', '6', '7', '8', '9', ':', ';', '<', '=', '>', '?', '@',
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
|
||||
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', ']', '^', '_',
|
||||
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
|
||||
'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '{', '|', '}', '~'
|
||||
};
|
||||
|
||||
// ==========================================================================
|
||||
// Read passphrase from file
|
||||
// ==========================================================================
|
||||
|
||||
char *read_passphrase(const CHR *const file_name)
|
||||
{
|
||||
if ((!file_name) || (!file_name[0U]))
|
||||
{
|
||||
FPUTS(T("Error: The passphrase input file name must not be empty!\n\n"), stderr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const size_t max_len = SLUNKCRYPT_PWDLEN_MAX + 2U;
|
||||
char *const buffer = (char*) malloc(max_len * sizeof(char));
|
||||
if (!buffer)
|
||||
{
|
||||
FPUTS(T("Error: Failed to allocate the passphrase buffer!\n\n"), stderr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const int use_stdin = (!file_name) || (!STRICMP(file_name, T("-")));
|
||||
FILE *const file_in = use_stdin ? stdin : FOPEN(file_name, T("rb"));
|
||||
if (!file_in)
|
||||
{
|
||||
FPRINTF(stderr, T("Error: Failed to open input file \"%") T(PRISTR) T("\" for reading!\n\n"), file_name);
|
||||
free(buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
if (!fgets(buffer, (int)max_len, file_in))
|
||||
{
|
||||
buffer[0U] = '\0';
|
||||
goto finish;
|
||||
}
|
||||
size_t length = strlen(buffer);
|
||||
while ((length > 0U) && ((buffer[length - 1U] == '\r') || (buffer[length - 1U] == '\n')))
|
||||
{
|
||||
buffer[--length] = '\0';
|
||||
}
|
||||
}
|
||||
while (!buffer[0U]);
|
||||
|
||||
finish:
|
||||
|
||||
if ((!use_stdin) && file_in)
|
||||
{
|
||||
fclose(file_in);
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
// ==========================================================================
|
||||
// Passphrase generator
|
||||
// ==========================================================================
|
||||
|
||||
int weak_passphrase(const char *str)
|
||||
{
|
||||
unsigned int flags = 0U;
|
||||
while ((*str) && (flags != 0xF))
|
||||
{
|
||||
const int c = *str++;
|
||||
if (isalpha(c))
|
||||
{
|
||||
flags |= isupper(c) ? 0x1 : 0x2;
|
||||
}
|
||||
else
|
||||
{
|
||||
flags |= isdigit(c) ? 0x4 : 0x8;
|
||||
}
|
||||
}
|
||||
return (flags != 0xF);
|
||||
}
|
||||
|
||||
int generate_passphrase(const size_t length)
|
||||
{
|
||||
int result = EXIT_FAILURE;
|
||||
const size_t passwd_len = BOUND(SLUNKCRYPT_PWDLEN_MIN, length, SLUNKCRYPT_PWDLEN_MAX);
|
||||
|
||||
char *const buffer = (char*) malloc((passwd_len + 1U) * sizeof(char));
|
||||
if (!buffer)
|
||||
{
|
||||
FPUTS(T("Error: Failed to allocate memory buffer!\n\n"), stderr);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
for (size_t i = 0U; i < passwd_len; ++i)
|
||||
{
|
||||
uint64_t value;
|
||||
if (slunkcrypt_generate_nonce(&value) != SLUNKCRYPT_SUCCESS)
|
||||
{
|
||||
FPUTS(T("Error: Failed to generate next random number!\n\n"), stderr);
|
||||
goto clean_up;
|
||||
}
|
||||
buffer[i] = PASSWD_SYMBOLS[value % ARRAY_SIZE(PASSWD_SYMBOLS)];
|
||||
}
|
||||
buffer[passwd_len] = '\0';
|
||||
}
|
||||
while ((!isalnum((int)buffer[0U])) || (!isalnum((int)buffer[passwd_len - 1U])) || weak_passphrase(buffer));
|
||||
|
||||
FPRINTF(stdout, T("%") T(PRIstr) T("\n\n"), buffer);
|
||||
fflush(stdout);
|
||||
result = EXIT_SUCCESS;
|
||||
|
||||
clean_up:
|
||||
|
||||
if (buffer)
|
||||
{
|
||||
slunkcrypt_bzero(buffer, passwd_len * sizeof(char));
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
16
frontend/src/pwgen.h
Normal file
16
frontend/src/pwgen.h
Normal file
@ -0,0 +1,16 @@
|
||||
/******************************************************************************/
|
||||
/* SlunkCrypt, by LoRd_MuldeR <MuldeR2@GMX.de> */
|
||||
/* This work has been released under the CC0 1.0 Universal license! */
|
||||
/******************************************************************************/
|
||||
|
||||
#ifndef INC_SLUNKAPP_PWGEN_H
|
||||
#define INC_SLUNKAPP_PWGEN_H
|
||||
|
||||
#include "platform.h"
|
||||
#include <stdint.h>
|
||||
|
||||
char *read_passphrase(const CHR *const file_name);
|
||||
int weak_passphrase(const char *str);
|
||||
int generate_passphrase(const size_t length);
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user