commit 33d6c58e6acdb1ccf1ad84e52b2c896e9197b304 from: Alex Arx date: Sun Nov 17 07:55:28 2024 UTC complete refactor commit - caf30c150740e01b41af2fe0d5c32da701c089eb commit + 33d6c58e6acdb1ccf1ad84e52b2c896e9197b304 blob - 359be0d60a07a35d828fccddf3334f549fa16655 blob + aabcbf865fb6f370e8c90d078b0e262cb6f259e1 --- gpass.c +++ gpass.c @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -9,76 +10,42 @@ #include #include -#define MAXWORDS 32768 +#define MAXWORDS 32768 +#define NNUM ('9'-'0' + 1) +#define NALPHA ('z'-'a' + 1) + #ifndef PREFIX -# define PREFIX "/usr/local" +# 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, ...) -{ - fputs("gpass: ", stderr); - if (fmt != NULL) { - va_list argp; - va_start(argp, fmt); - vfprintf(stderr, fmt, argp); - va_end(argp); - } - fputc('\n', stderr); - exit(eval); -} - -void -err(int eval, const char *fmt, ...) -{ - char *e = strerror(errno); - fputs("gpass: ", stderr); - if (fmt != NULL) { - va_list argp; - va_start(argp, fmt); - vfprintf(stderr, fmt, argp); - va_end(argp); - } - fputs(": ", stderr); - fputs(e, stderr); - fputc('\n', stderr); - exit(eval); -} - -int +static int usage(void) { fprintf(stderr, "usage: gpass [-a] [-d dict] [-e bits] [-n count]\n"); exit(EXIT_FAILURE); } -void -setplen(void) { - int temp; +static int +getplen(int n, int ent) { + long temp; + int plen; - temp = log2(nwords); - plen = plen / temp + !!(plen % temp); - plen += !plen; + temp = log2(n); + plen = ent / temp + !!(ent % temp); + return (plen > 0) ? plen : 1; } -void -genalpha(void) +static void +genalpha(int plen, int max) { - int c; - int left; - uint32_t n; + int c; + int left; + uint32_t n; for (left = plen; left; left--) { - n = arc4random_uniform(NNUM + NALPHA*2); + n = arc4random_uniform(max); if (n < NNUM) putchar('0' + n); else if (n < NNUM + NALPHA) @@ -89,31 +56,31 @@ genalpha(void) putchar('\n'); } -void -gpass_alpha(int npass) +static void +gpass_alpha(int npass, int ent) { + int n = NNUM + NALPHA*2, plen; + #ifdef __OpenBSD__ if (pledge("stdio rpath", NULL) == -1) /* revoke unveil */ err(1, "pledge"); #endif - nwords = NNUM + NALPHA*2; - setplen(); + plen = getplen(n, ent); for (int i = 0; i < npass; i++) - genalpha(); + genalpha(plen, n); } -void -genwords(void) +static void +genwords(int plen, int max, const long *offs, FILE *fp) { - int c; - int left; - uint32_t n; + int c; + unsigned int n, left; - for (left = plen; left; left--) { - n = arc4random_uniform(nwords) + 1; - if (fseek(dicfp, offs[n], SEEK_SET) == -1) + for (left = plen; left > 0; left--) { + n = arc4random_uniform(max); + if (fseek(fp, offs[n], SEEK_SET) == -1) err(1, "fseek"); - while ((c = getc(dicfp)) != EOF && !isspace(c)) + while ((c = getc(fp)) != EOF && isgraph(c)) putchar(c); if (left > 1) putchar(' '); @@ -122,9 +89,11 @@ genwords(void) } void -gpass_words(int npass, char *f) +gpass_words(int npass, int ent, char *f) { - char c, isword; + FILE *fp; + long offs[MAXWORDS]; + int c, isword = 0, nwords, plen; #ifdef __OpenBSD__ if (unveil(f, "r") == -1) @@ -132,33 +101,30 @@ gpass_words(int npass, char *f) if (pledge("stdio rpath", NULL) == -1) /* revoke unveil */ err(1, "pledge"); #endif - if (!(dicfp = fopen(f, "r"))) + if (!(fp = 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; + while ((c = getc(fp)) != EOF && nwords < MAXWORDS) + if (!isgraph(c)) isword = 0; - offs[nwords] = ftell(dicfp); - } else + else if (!isword) { isword = 1; + offs[nwords++] = ftell(fp) - 1; + } if (nwords < 2) errx(1, "%s has less that 2 words", f); - setplen(); + plen = getplen(nwords, ent); for (int i = 0; i < npass; i++) - genwords(); - fclose(dicfp); + genwords(plen, nwords, offs, fp); + fclose(fp); } int main(int argc, char *argv[]) { - int c, npass; - char *dicname; + int c, ent = 70, npass = 1; + char *dicname = NULL; + const char *errstr = NULL; - npass = 1; - dicname = NULL; - #ifdef __OpenBSD__ if (pledge("stdio unveil rpath", NULL) == -1) /* first call */ err(1, "pledge"); @@ -172,12 +138,14 @@ main(int argc, char *argv[]) dicname = optarg; break; case 'e': - if ((plen = atoi(optarg)) < 1) - errx(1, "less than 1 bit of entropy requested"); + ent = strtonum(optarg, 1, INT_MAX, &errstr); + if (errstr != NULL) + errx(1, "entropy is %s: %s", errstr, optarg); break; case 'n': - if ((npass = atoi(optarg)) < 1) - errx(1, "less than 1 passphrase requested"); + npass = strtonum(optarg, 1, INT_MAX, &errstr); + if (errstr != NULL) + errx(1, "npass is %s: %s", errstr, optarg); break; default: usage(); @@ -185,11 +153,11 @@ main(int argc, char *argv[]) } if (aflag) - gpass_alpha(npass); + gpass_alpha(npass, ent); else { if (!dicname && !(dicname = getenv("GPASS_DIC"))) dicname = PREFIX "/share/gpass/eff.long"; - gpass_words(npass, dicname); + gpass_words(npass, ent, dicname); } return 0;