commit caf30c150740e01b41af2fe0d5c32da701c089eb from: Alex Arx date: Sun Nov 17 07:55:28 2024 UTC add the -a flag commit - 46c6b68fcc1011714b10ec0e4c497767510323db commit + caf30c150740e01b41af2fe0d5c32da701c089eb blob - 720e5d29369c312702fcf3b4ae7dafb6513e335a blob + 359be0d60a07a35d828fccddf3334f549fa16655 --- gpass.c +++ gpass.c @@ -14,10 +14,14 @@ # define PREFIX "/usr/local" #endif +#define NNUM ('9'-'0' + 1) +#define NALPHA ('z'-'a' + 1) + FILE *dicfp; uint32_t nwords = 0; int offs[MAXWORDS]; int plen = 70; +int aflag = 0; void errx(int eval, const char *fmt, ...) @@ -53,18 +57,59 @@ err(int eval, const char *fmt, ...) int usage(void) { - fprintf(stderr, "usage: gpass [-d dict] [-e bits] [-n count]\n"); + fprintf(stderr, "usage: gpass [-a] [-d dict] [-e bits] [-n count]\n"); exit(EXIT_FAILURE); } void -gen(void) +setplen(void) { + int temp; + + temp = log2(nwords); + plen = plen / temp + !!(plen % temp); + plen += !plen; +} + +void +genalpha(void) { int c; int left; uint32_t n; for (left = plen; left; left--) { + n = arc4random_uniform(NNUM + NALPHA*2); + if (n < NNUM) + putchar('0' + n); + else if (n < NNUM + NALPHA) + putchar('A' + (n - NNUM)); + else + putchar('a' + (n - NNUM - NALPHA)); + } + putchar('\n'); +} + +void +gpass_alpha(int npass) +{ +#ifdef __OpenBSD__ + if (pledge("stdio rpath", NULL) == -1) /* revoke unveil */ + err(1, "pledge"); +#endif + nwords = NNUM + NALPHA*2; + setplen(); + for (int i = 0; i < npass; i++) + genalpha(); +} + +void +genwords(void) +{ + int c; + int left; + uint32_t n; + + for (left = plen; left; left--) { n = arc4random_uniform(nwords) + 1; if (fseek(dicfp, offs[n], SEEK_SET) == -1) err(1, "fseek"); @@ -76,13 +121,41 @@ gen(void) putchar('\n'); } +void +gpass_words(int npass, char *f) +{ + char c, isword; + +#ifdef __OpenBSD__ + if (unveil(f, "r") == -1) + err(1, "unveil %s", f); + if (pledge("stdio rpath", NULL) == -1) /* revoke unveil */ + err(1, "pledge"); +#endif + if (!(dicfp = fopen(f, "r"))) + err(1, "could not open %s", f); + offs[0] = ftell(dicfp); + while ((c = getc(dicfp)) != EOF && nwords < MAXWORDS) + if (isspace(c)) { + nwords += isword ? 1 : 0; + isword = 0; + offs[nwords] = ftell(dicfp); + } else + isword = 1; + if (nwords < 2) + errx(1, "%s has less that 2 words", f); + setplen(); + for (int i = 0; i < npass; i++) + genwords(); + fclose(dicfp); +} + int main(int argc, char *argv[]) { - int c, isword, npass, temp; + int c, npass; char *dicname; - isword = 0; npass = 1; dicname = NULL; @@ -90,8 +163,11 @@ main(int argc, char *argv[]) if (pledge("stdio unveil rpath", NULL) == -1) /* first call */ err(1, "pledge"); #endif - while ((c = getopt(argc, argv, "d:e:n:")) != -1) { + while ((c = getopt(argc, argv, "ad:e:n:")) != -1) { switch (c) { + case 'a': + aflag = 1; + break; case 'd': dicname = optarg; break; @@ -108,35 +184,13 @@ main(int argc, char *argv[]) } } - if (!dicname && !(dicname = getenv("GPASS_DIC"))) - dicname = PREFIX "/share/gpass/eff.long"; -#ifdef __OpenBSD__ - if (unveil(dicname, "r") == -1) - err(1, "unveil %s", dicname); - if (pledge("stdio rpath", NULL) == -1) /* revoke unveil */ - err(1, "pledge"); -#endif + if (aflag) + gpass_alpha(npass); + else { + if (!dicname && !(dicname = getenv("GPASS_DIC"))) + dicname = PREFIX "/share/gpass/eff.long"; + gpass_words(npass, dicname); + } - if (!(dicfp = fopen(dicname, "r"))) - err(1, "could not open %s", dicname); - offs[0] = ftell(dicfp); - while ((c = getc(dicfp)) != EOF && nwords < MAXWORDS) - if (isspace(c)) { - nwords += isword ? 1 : 0; - isword = 0; - offs[nwords] = ftell(dicfp); - } else - isword = 1; - if (nwords < 2) - errx(1, "%s has less that 2 words", dicname); - - temp = log2(nwords); - plen = plen / temp + !!(plen % temp); - plen += !plen; - - for (int i = 0; i < npass; i++) - gen(); - fclose(dicfp); - return 0; } blob - 311505122b174272d1f3f39adcc93e0f0a046c0b blob + 367b9ca4da3f50c95145395fd730ddbda313541a --- gpass.m4 +++ gpass.m4 @@ -6,6 +6,7 @@ .Nd generate passphrases .Sh SYNOPSIS .Nm +.Op Fl a .Op Fl d Ar dict .Op Fl e Ar bits .Op Fl n Ar num @@ -16,6 +17,9 @@ outputs a secure passphrase by randomly choosing an ap from a dictionary file, containing whitespace-separated words. The options are as follows: .Bl -tag -width Ds +.It Fl a +Instead of generating a passphrases from the wordlist, generate strings of +random alphanumeric characters. .It Fl d Ar dict Use the dictionary .Ar dict .