From b5d276c1047350a13551a98f470fa2d78f4a84f8 Mon Sep 17 00:00:00 2001 From: Moritz Röhrich Date: Sat, 5 Dec 2020 14:12:16 +0100 Subject: new toy: Add pwgen Add new toy `pwgen`. A usefule password generation utility. --- toys/pending/pwgen.c | 130 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 toys/pending/pwgen.c (limited to 'toys/pending') diff --git a/toys/pending/pwgen.c b/toys/pending/pwgen.c new file mode 100644 index 00000000..c63ebee7 --- /dev/null +++ b/toys/pending/pwgen.c @@ -0,0 +1,130 @@ +/* pwgen.c - A password generator. + * + * Copyright 2020 Moritz Röhrich + +USE_PWGEN(NEWTOY(pwgen, ">2?r(remove):c(capitalize)n(numerals)y(symbols)s(secure)B(ambiguous)h(help)C1vA(no-capitalize)0(no-numerals)[-cA][-n0]", TOYFLAG_USR|TOYFLAG_BIN)) + +config PWGEN + bool "pwgen" + default n + help + usage: pwgen [ OPTIONS ] [ length ] [ number ] + + A password generator. + + Options supported by pwgen: + -c --capitalize Permit capital letters. + -A --no-capitalize Don't include capital letters. + -n --numerals Permit numbers. + -0 --no-numerals Don't include numbers. + -y --symbols Permit special characters ($#%...). + -r --remove= Don't include the given characters. + -s --secure Generate more random passwords. + -B --ambiguous Avoid ambiguous characters (e.g. 0, O). + -h --help Print this help message. + -C Print the output in columns. + -1 Print the output one line each. + -v Don't include vowels. +*/ + +#define FOR_pwgen +#include "toys.h" + +GLOBALS( + char *r; +) + +// Generate one random printable/typeable ascii character. +char get_rand_chr() { + return (char) (33 + (rand() % 93)); +} + +// Uses get_rand_chr to generate a character that conforms the requirements set +// by the argument flags. +char get_valid_chr(const char *illegal) { + char c = get_rand_chr(); + + while (strchr(illegal, c) != NULL) + c = get_rand_chr(); + + return c; +} + +char * get_illegal_chars() { + char* illegal = malloc(94 * sizeof(char)); + memset(illegal, 0, 94 * sizeof(char)); + if (toys.optflags & FLAG(A)) + strcat(illegal, "ABCDEFGHIJKLMNOPQRSTUVWXYZ"); + if (toys.optflags & FLAG(0)) + strcat(illegal, "1234567890"); + if (toys.optflags & FLAG(B)) + strcat(illegal, "0O1lI'`.,"); + if (toys.optflags & FLAG(v)) + strcat(illegal, "ieaouIEAOU"); + if (!(toys.optflags & FLAG(y))) + strcat(illegal, "!@#$%^&*()-_=+`~{}[];:'\",.<>/?\\|"); + if (TT.r){ + strcat(illegal, TT.r); + } + return illegal; +} + +// Generate a new password of length l. +char * get_pw(const unsigned long l, const char *illegal) { + char *pw = malloc((l+1) * sizeof(char)); + memset(pw, 0, (l+1) * sizeof(char)); // zero out memory for new password. + unsigned long i; + for (i = 0; i < l; i++){ + pw[i] = get_valid_chr(illegal); + } + + return pw; +} + +void pwgen_main(void) +{ + // seed the (pseudo) RNG. + time_t t; + srand((unsigned) time(&t)); + + int length = 8; + int count = 160; + int num_columns = 8; + if (toys.optc > 0) { + length = atoi(toys.optargs[0]); + num_columns = 80 / (length+1); + if (toys.optc > 1) { + count = atoi(toys.optargs[1]); + } else if (toys.optflags & FLAG(1)) { + count = 1; + } else { + count = 20 * num_columns; + } + } + + char *illegal = get_illegal_chars(); + char **passwords = malloc(count * sizeof(char*)); + int c; + for (c = 0; c < count; c++) + passwords[c] = get_pw(length, illegal); + + if (toys.optflags & FLAG(1)){ + for (c = 0; c < count; c++) + xprintf("%s\n", passwords[c]); + } else { + int col; + c = 0; + while(c < count){ + for (col = 0; c < count && col < num_columns; col++){ + xprintf("%s ", passwords[c]); + c += 1; + } + xprintf("\n"); + } + } + + for (c = 0; c < count; c++) + free(passwords[c]); + free(passwords); + free(illegal); +} -- cgit v1.2.3