aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--passgen.c120
1 files changed, 71 insertions, 49 deletions
diff --git a/passgen.c b/passgen.c
index c43ae8b..1215d3f 100644
--- a/passgen.c
+++ b/passgen.c
@@ -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;
}