Refactored passphrase generator into a separate file.
This commit is contained in:
parent
46dc28f3ca
commit
b7e32f5f0a
@ -45,6 +45,7 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="src\blake2.c" />
|
<ClCompile Include="src\blake2.c" />
|
||||||
<ClCompile Include="src\crypt.c" />
|
<ClCompile Include="src\crypt.c" />
|
||||||
|
<ClCompile Include="src\pwgen.c" />
|
||||||
<ClCompile Include="src\selftest.c" />
|
<ClCompile Include="src\selftest.c" />
|
||||||
<ClCompile Include="src\test_data.c" />
|
<ClCompile Include="src\test_data.c" />
|
||||||
<ClCompile Include="src\main.c" />
|
<ClCompile Include="src\main.c" />
|
||||||
@ -54,6 +55,7 @@
|
|||||||
<ClInclude Include="src\blake2.h" />
|
<ClInclude Include="src\blake2.h" />
|
||||||
<ClInclude Include="src\crypt.h" />
|
<ClInclude Include="src\crypt.h" />
|
||||||
<ClInclude Include="src\platform.h" />
|
<ClInclude Include="src\platform.h" />
|
||||||
|
<ClInclude Include="src\pwgen.h" />
|
||||||
<ClInclude Include="src\selftest.h" />
|
<ClInclude Include="src\selftest.h" />
|
||||||
<ClInclude Include="src\test_data.h" />
|
<ClInclude Include="src\test_data.h" />
|
||||||
<ClInclude Include="src\utils.h" />
|
<ClInclude Include="src\utils.h" />
|
||||||
|
@ -33,6 +33,9 @@
|
|||||||
<ClCompile Include="src\selftest.c">
|
<ClCompile Include="src\selftest.c">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="src\pwgen.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="src\utils.h">
|
<ClInclude Include="src\utils.h">
|
||||||
@ -53,6 +56,9 @@
|
|||||||
<ClInclude Include="src\selftest.h">
|
<ClInclude Include="src\selftest.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="src\pwgen.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Manifest Include="res\compatibility.manifest">
|
<Manifest Include="res\compatibility.manifest">
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include <slunkcrypt.h>
|
#include <slunkcrypt.h>
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "crypt.h"
|
#include "crypt.h"
|
||||||
|
#include "pwgen.h"
|
||||||
#include "selftest.h"
|
#include "selftest.h"
|
||||||
|
|
||||||
/* CRT */
|
/* CRT */
|
||||||
@ -33,7 +34,8 @@
|
|||||||
#define MODE_PASS 4
|
#define MODE_PASS 4
|
||||||
#define MODE_TEST 5
|
#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_PASSWORD = T("SLUNK_PASSPHRASE");
|
||||||
static const CHR* const ENV_KEEPFILE = T("SLUNK_KEEP_INCOMPLETE");
|
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_PASS = T("pass:");
|
||||||
static const CHR* const PREFIX_FILE = T("file:");
|
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
|
// Auxiliary functions
|
||||||
// ==========================================================================
|
// ==========================================================================
|
||||||
|
|
||||||
|
#define PW_FROM_ENV (!(argc > 4))
|
||||||
|
|
||||||
static int parse_slunk_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"))))
|
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;
|
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)
|
static int keep_incomplete_files(void)
|
||||||
{
|
{
|
||||||
const CHR *const keep_files = GETENV(ENV_KEEPFILE);
|
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))
|
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);
|
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