SlunkCrypt/etc/worstpwd/gen_worstpwd.c

172 lines
4.8 KiB
C

/******************************************************************************/
/* SlunkCrypt, by LoRd_MuldeR <MuldeR2@GMX.de> */
/* This work has been released under the CC0 1.0 Universal license! */
/******************************************************************************/
#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS 1
#endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#ifdef _MSC_VER
#define strdup(X) _strdup((X))
#define strcasecmp(X,Y) _stricmp((X),(Y))
#define __inline__ __inline
#endif
#ifdef __MINGW64_VERSION_MAJOR
int _dowildcard = -1;
#endif
#define MIN_LENGTH 8U
#define MAX_LENGTH 128U
#define TABLE_SIZE 1000000U
static char *g_table[TABLE_SIZE];
static __inline__ int string_compare(void const *lhs, void const *rhs)
{
return strcasecmp(*((const char* const*)lhs), *((const char* const*)rhs));
}
static __inline__ int is_ascii(const char *str)
{
unsigned char chr;
while ((chr = *str++)) {
if ((chr < 0x20) || (chr >= 0x7F)) {
return 0;
}
}
return 1;
}
static __inline__ int append_char(char *const buffer, const size_t size, size_t *const offset, const char chr)
{
if (*offset < size) {
buffer[(*offset)++] = chr;
return 1;
}
return 0;
}
static __inline__ int escape_char(char *const chr)
{
switch (*chr) {
case '\\': return 1;
case '"' : return 1;
case '\a': *chr = 'a'; return 2;
case '\b': *chr = 'b'; return 2;
case '\n': *chr = 'n'; return 2;
case '\r': *chr = 'r'; return 2;
case '\t': *chr = 't'; return 2;
case '\v': *chr = 'v'; return 2;
default:
if ((*chr < 0x20) || (*chr == 0x7F)) {
return -1;
}
return 0;
}
}
static __inline__ int escape_str(char *const dst, const size_t capacity, const char *src)
{
size_t offset = 0U;
char chr;
static const char ESC = '\\', NUL = '\0';
while ((chr = *src++)) {
switch (escape_char(&chr)) {
case 1:
case 2:
if (!append_char(dst, capacity, &offset, ESC)) {
return -1;
}
case 0:
if (!append_char(dst, capacity, &offset, chr)) {
return -1;
}
break;
default:
return 0; /* error! */
}
}
if (!append_char(dst, capacity, &offset, NUL)) {
return -1;
}
return 1;
}
int main(int argc, char* argv[])
{
char *line, buffer[1024U], escaped[256U];
FILE* file = NULL;
size_t i, j, len, count = 0U;
if (argc < 2) {
fputs("Error: Input file not specified!\n", stderr);
return 1;
}
for (i = 1; i < argc; ++i) {
if (!(file = fopen(argv[i], "r"))) {
fputs("Error: Failed to open input file!\n", stderr);
return 1;
}
while ((line = fgets(buffer, sizeof(buffer), file))) {
if ((len = strlen(line)) > 0U) {
while ((len > 0U) && ((line[len - 1U] == '\r') || (line[len - 1U] == '\n'))) {
line[--len] = '\0';
}
while ((len > 0U) && ((line[0U] == '\x20') || (line[0U] == '\t'))) {
++line; --len;
}
while ((len > 0U) && ((line[len - 1U] == '\x20') || (line[len - 1U] == '\t'))) {
line[--len] = '\0';
}
if ((len >= MIN_LENGTH) && (len <= MAX_LENGTH) && is_ascii(line)) {
for (j = 0U; j < count; ++j) {
if (!strcasecmp(line, g_table[j])) {
goto skip_line;
}
}
if (count >= TABLE_SIZE) {
fputs("Error: Too many lines!\n", stderr);
abort();
}
if (escape_str(escaped, sizeof(escaped), line) > 0) {
if (!(g_table[count++] = strdup(escaped))) {
fputs("Error: Memory allocation has failed!\n", stderr);
abort();
}
}
else {
fprintf(stderr, "Failed to encode line: \"%s\"\n", line);
}
}
skip_line:;
}
}
fclose(file);
}
qsort(g_table, count, sizeof(const char*), string_compare);
printf("#define WORST_PASSWD_SIZE %zuU\n\n", count);
puts("static const char *const WORST_PASSWD[WORST_PASSWD_SIZE] =\n{");
for (i = 0U; i < count; ++i) {
if (i > 0U) {
printf(",\n");
}
printf("\t \"%s\"", g_table[i]);
}
puts("\n};");
for (i = 0U; i < count; ++i) {
free(g_table[i]);
}
}