1 926e1c04 2022-12-30 aa_src #include <ctype.h>
2 33d6c58e 2024-11-17 aa #include <err.h>
3 7ab29a2b 2022-09-30 src #include <errno.h>
4 aab4ecb3 2022-07-14 src #include <limits.h>
5 aab4ecb3 2022-07-14 src #include <math.h>
6 aab4ecb3 2022-07-14 src #include <stdarg.h>
7 aab4ecb3 2022-07-14 src #include <stdio.h>
8 7ab29a2b 2022-09-30 src #include <stdlib.h>
9 7ab29a2b 2022-09-30 src #include <string.h>
10 e9952e59 2022-08-21 src #include <strings.h>
11 aab4ecb3 2022-07-14 src #include <unistd.h>
13 33d6c58e 2024-11-17 aa #define MAXWORDS 32768
14 33d6c58e 2024-11-17 aa #define NNUM ('9'-'0' + 1)
15 33d6c58e 2024-11-17 aa #define NALPHA ('z'-'a' + 1)
17 aab4ecb3 2022-07-14 src #ifndef PREFIX
18 33d6c58e 2024-11-17 aa # define PREFIX "/usr/local"
21 caf30c15 2024-11-17 aa int aflag = 0;
26 d8c0fc7b 2024-11-17 aa fprintf(stderr,
27 d8c0fc7b 2024-11-17 aa "usage: gpass [-a] [-d dict] [-e bits] [-l length] [-n count]\n");
28 aab4ecb3 2022-07-14 src exit(EXIT_FAILURE);
32 33d6c58e 2024-11-17 aa getplen(int n, int ent) {
36 33d6c58e 2024-11-17 aa temp = log2(n);
37 33d6c58e 2024-11-17 aa plen = ent / temp + !!(ent % temp);
38 33d6c58e 2024-11-17 aa return (plen > 0) ? plen : 1;
42 33d6c58e 2024-11-17 aa genalpha(int plen, int max)
48 926e1c04 2022-12-30 aa_src for (left = plen; left; left--) {
49 33d6c58e 2024-11-17 aa n = arc4random_uniform(max);
51 caf30c15 2024-11-17 aa putchar('0' + n);
52 caf30c15 2024-11-17 aa else if (n < NNUM + NALPHA)
53 caf30c15 2024-11-17 aa putchar('A' + (n - NNUM));
55 caf30c15 2024-11-17 aa putchar('a' + (n - NNUM - NALPHA));
57 caf30c15 2024-11-17 aa putchar('\n');
61 d8c0fc7b 2024-11-17 aa gpass_alpha(int npass, int plen, int ent)
63 d8c0fc7b 2024-11-17 aa int n = NNUM + NALPHA*2;
65 caf30c15 2024-11-17 aa #ifdef __OpenBSD__
66 caf30c15 2024-11-17 aa if (pledge("stdio rpath", NULL) == -1) /* revoke unveil */
67 caf30c15 2024-11-17 aa err(1, "pledge");
69 d8c0fc7b 2024-11-17 aa if (plen == 0)
70 d8c0fc7b 2024-11-17 aa plen = getplen(n, ent);
71 caf30c15 2024-11-17 aa for (int i = 0; i < npass; i++)
72 33d6c58e 2024-11-17 aa genalpha(plen, n);
76 33d6c58e 2024-11-17 aa genwords(int plen, int max, const long *offs, FILE *fp)
79 33d6c58e 2024-11-17 aa unsigned int n, left;
81 33d6c58e 2024-11-17 aa for (left = plen; left > 0; left--) {
82 33d6c58e 2024-11-17 aa n = arc4random_uniform(max);
83 33d6c58e 2024-11-17 aa if (fseek(fp, offs[n], SEEK_SET) == -1)
84 926e1c04 2022-12-30 aa_src err(1, "fseek");
85 33d6c58e 2024-11-17 aa while ((c = getc(fp)) != EOF && isgraph(c))
87 926e1c04 2022-12-30 aa_src if (left > 1)
88 926e1c04 2022-12-30 aa_src putchar(' ');
90 aab4ecb3 2022-07-14 src putchar('\n');
94 d8c0fc7b 2024-11-17 aa gpass_words(int npass, int plen, int ent, char *f)
97 33d6c58e 2024-11-17 aa long offs[MAXWORDS];
98 d8c0fc7b 2024-11-17 aa int c, isword = 0, nwords;
100 caf30c15 2024-11-17 aa #ifdef __OpenBSD__
101 caf30c15 2024-11-17 aa if (unveil(f, "r") == -1)
102 caf30c15 2024-11-17 aa err(1, "unveil %s", f);
103 caf30c15 2024-11-17 aa if (pledge("stdio rpath", NULL) == -1) /* revoke unveil */
104 caf30c15 2024-11-17 aa err(1, "pledge");
106 33d6c58e 2024-11-17 aa if (!(fp = fopen(f, "r")))
107 caf30c15 2024-11-17 aa err(1, "could not open %s", f);
108 33d6c58e 2024-11-17 aa while ((c = getc(fp)) != EOF && nwords < MAXWORDS)
109 33d6c58e 2024-11-17 aa if (!isgraph(c))
111 33d6c58e 2024-11-17 aa else if (!isword) {
113 33d6c58e 2024-11-17 aa offs[nwords++] = ftell(fp) - 1;
115 caf30c15 2024-11-17 aa if (nwords < 2)
116 caf30c15 2024-11-17 aa errx(1, "%s has less that 2 words", f);
117 d8c0fc7b 2024-11-17 aa if (plen == 0)
118 d8c0fc7b 2024-11-17 aa plen = getplen(nwords, ent);
119 caf30c15 2024-11-17 aa for (int i = 0; i < npass; i++)
120 33d6c58e 2024-11-17 aa genwords(plen, nwords, offs, fp);
125 aab4ecb3 2022-07-14 src main(int argc, char *argv[])
127 d8c0fc7b 2024-11-17 aa int c, ent = 70, npass = 1, plen = 0;
128 33d6c58e 2024-11-17 aa char *dicname = NULL;
129 33d6c58e 2024-11-17 aa const char *errstr = NULL;
131 699d07dd 2022-09-30 src #ifdef __OpenBSD__
132 bb118a6c 2022-10-19 src if (pledge("stdio unveil rpath", NULL) == -1) /* first call */
133 699d07dd 2022-09-30 src err(1, "pledge");
135 d8c0fc7b 2024-11-17 aa while ((c = getopt(argc, argv, "ad:e:l:n:")) != -1) {
136 aab4ecb3 2022-07-14 src switch (c) {
141 699d07dd 2022-09-30 src dicname = optarg;
144 d8c0fc7b 2024-11-17 aa ent = strtonum(optarg, 0, INT_MAX, &errstr);
145 33d6c58e 2024-11-17 aa if (errstr != NULL)
146 33d6c58e 2024-11-17 aa errx(1, "entropy is %s: %s", errstr, optarg);
149 d8c0fc7b 2024-11-17 aa plen = strtonum(optarg, 0, INT_MAX, &errstr);
150 d8c0fc7b 2024-11-17 aa if (errstr != NULL)
151 d8c0fc7b 2024-11-17 aa errx(1, "length is %s: %s", errstr, optarg);
154 d8c0fc7b 2024-11-17 aa npass = strtonum(optarg, 0, INT_MAX, &errstr);
155 33d6c58e 2024-11-17 aa if (errstr != NULL)
156 33d6c58e 2024-11-17 aa errx(1, "npass is %s: %s", errstr, optarg);
163 d8c0fc7b 2024-11-17 aa if (npass == 0 || (plen == 0 && ent == 0))
167 d8c0fc7b 2024-11-17 aa gpass_alpha(npass, plen, ent);
169 caf30c15 2024-11-17 aa if (!dicname && !(dicname = getenv("GPASS_DIC")))
170 caf30c15 2024-11-17 aa dicname = PREFIX "/share/gpass/eff.long";
171 d8c0fc7b 2024-11-17 aa gpass_words(npass, plen, ent, dicname);