diff options
-rw-r--r-- | passgen.c | 120 |
1 files changed, 71 insertions, 49 deletions
@@ -39,8 +39,63 @@ break; +void init_rng(void) +{ + /* For now, this is only needed on rand() */ +#ifndef USE_GETENTROPY + /* + * TODO: seed better RNG + * this isn't very good, but it's enough(?) for now + * + * on linux we use the `getrandom` api which is supposedly + * what crypto uses to generate. potentially on win we + * can use the crypto thing (but it's more complicated + * to invoke). + * + * anything else we could use on posix systems? + */ + srand(time(NULL) + getpid() % 420 - 69); +#endif +} + +int get_rng(void) +{ +#ifdef USE_GETENTROPY + int r; + getentropy(&r, sizeof(r)); + return r; +#else + return rand(); +#endif +} + +char *build_grammar(int triplets, int specials, int numbers) +{ + if (triplets < 1) { + fprintf(stderr, "ERROR: Cannot have less than one triplet."); + return NULL; + } + + int grammar_size = triplets * 3 + specials + numbers; + char *build = malloc(grammar_size + 1); + if (build == NULL) { + perror("malloc"); + return NULL; + } + build[grammar_size] = 0; + + memcpy(build, "Cvc", 3); + for (int i = 1; i < triplets; ++i) + memcpy(build + (i * 3), "cvc", 3); + + memset(build + (triplets * 3), '!', specials); + memset(build + (triplets * 3) + specials, '#', numbers); + return build; +} + int main(int argc, char *argv[]) { + bool err = false; bool custom_grammar = false; char *grammar = DEFAULT_GRAMMAR; int grammar_size = sizeof(DEFAULT_GRAMMAR) - 1; @@ -54,53 +109,23 @@ int main(int argc, char *argv[]) * Take arguments as triplets, specials, numbers * atoi might be scuffed but so be it (it just goes = 0 if invalid input) */ - int triplets = atoi(argv[1]); - int specials = atoi(argv[2]); - int numbers = atoi(argv[3]); - - if (triplets < 1) { - fprintf(stderr, "ERROR: Cannot have less than one triplet."); - return 1; - } - - grammar_size = triplets * 3 + specials + numbers; - grammar = malloc(grammar_size + 1); + grammar = build_grammar(atoi(argv[1]), atoi(argv[2]), atoi(argv[3])); if (grammar == NULL) { - perror("malloc"); - return 1; + err = true; + goto cleanup; } - grammar[grammar_size] = 0; - - memcpy(grammar, "Cvc", 3); - for (int i = 1; i < triplets; ++i) - memcpy(grammar + (i * 3), "cvc", 3); - - memset(grammar + (triplets * 3), '!', specials); - memset(grammar + (triplets * 3) + specials, '#', numbers); custom_grammar = true; } char *password = malloc(grammar_size + 1); if (password == NULL) { perror("malloc"); - return 1; + err = true; + goto cleanup; } password[grammar_size] = 0; -#ifndef USE_GETENTROPY - /* - * TODO: seed better RNG - * this isn't very good, but it's enough(?) for now - * - * on linux we use the `getrandom` api which is supposedly - * what crypto uses to generate. potentially on win we - * can use the crypto thing (but it's more complicated - * to invoke). - * - * anything else we could use on posix systems? - */ - srand(time(NULL) + getpid() % 420 - 69); -#endif + init_rng(); for (int i = 0; i < grammar_size; ++i) { char c = grammar[i]; @@ -117,28 +142,25 @@ int main(int argc, char *argv[]) CLASSES default: fprintf(stderr, "ERROR: Invalid grammar character '%c'.\n", c); - if (custom_grammar) - free(grammar); - free(password); - return 1; + err = true; + goto cleanup; } do { -#ifdef USE_GETENTROPY - unsigned int r; - getentropy(&r, sizeof(r)); -#else - long r = rand(); -#endif - password[i] = class[r % class_size] - (caps ? 'a' - 'A' : 0); + password[i] = class[get_rng() % class_size] - (caps ? 'a' - 'A' : 0); } while (i != 0 && password[i] == password[i - 1]); } + printf("%s\n", password); + +cleanup: if (custom_grammar) free(grammar); + if (password) + free(password); - printf("%s\n", password); - free(password); + if (err) + return 1; return 0; } |