Blame


1 926e1c04 2022-12-30 aa_src #include <ctype.h>
2 7ab29a2b 2022-09-30 src #include <errno.h>
3 aab4ecb3 2022-07-14 src #include <limits.h>
4 aab4ecb3 2022-07-14 src #include <math.h>
5 aab4ecb3 2022-07-14 src #include <stdarg.h>
6 aab4ecb3 2022-07-14 src #include <stdio.h>
7 7ab29a2b 2022-09-30 src #include <stdlib.h>
8 7ab29a2b 2022-09-30 src #include <string.h>
9 e9952e59 2022-08-21 src #include <strings.h>
10 aab4ecb3 2022-07-14 src #include <unistd.h>
11 aab4ecb3 2022-07-14 src
12 926e1c04 2022-12-30 aa_src #define MAXWORDS 32768
13 aab4ecb3 2022-07-14 src #ifndef PREFIX
14 11cbec53 2022-09-29 src # define PREFIX "/usr/local"
15 aab4ecb3 2022-07-14 src #endif
16 aab4ecb3 2022-07-14 src
17 699d07dd 2022-09-30 src FILE *dicfp;
18 926e1c04 2022-12-30 aa_src uint32_t nwords = 0;
19 926e1c04 2022-12-30 aa_src int offs[MAXWORDS];
20 699d07dd 2022-09-30 src int plen = 70;
21 aab4ecb3 2022-07-14 src
22 7ab29a2b 2022-09-30 src void
23 7ab29a2b 2022-09-30 src errx(int eval, const char *fmt, ...)
24 7ab29a2b 2022-09-30 src {
25 7ab29a2b 2022-09-30 src fputs("gpass: ", stderr);
26 7ab29a2b 2022-09-30 src if (fmt != NULL) {
27 7ab29a2b 2022-09-30 src va_list argp;
28 7ab29a2b 2022-09-30 src va_start(argp, fmt);
29 7ab29a2b 2022-09-30 src vfprintf(stderr, fmt, argp);
30 7ab29a2b 2022-09-30 src va_end(argp);
31 7ab29a2b 2022-09-30 src }
32 7ab29a2b 2022-09-30 src fputc('\n', stderr);
33 7ab29a2b 2022-09-30 src exit(eval);
34 7ab29a2b 2022-09-30 src }
35 7ab29a2b 2022-09-30 src
36 7ab29a2b 2022-09-30 src void
37 7ab29a2b 2022-09-30 src err(int eval, const char *fmt, ...)
38 7ab29a2b 2022-09-30 src {
39 7ab29a2b 2022-09-30 src char *e = strerror(errno);
40 7ab29a2b 2022-09-30 src fputs("gpass: ", stderr);
41 7ab29a2b 2022-09-30 src if (fmt != NULL) {
42 7ab29a2b 2022-09-30 src va_list argp;
43 7ab29a2b 2022-09-30 src va_start(argp, fmt);
44 7ab29a2b 2022-09-30 src vfprintf(stderr, fmt, argp);
45 7ab29a2b 2022-09-30 src va_end(argp);
46 7ab29a2b 2022-09-30 src }
47 7ab29a2b 2022-09-30 src fputs(": ", stderr);
48 7ab29a2b 2022-09-30 src fputs(e, stderr);
49 7ab29a2b 2022-09-30 src fputc('\n', stderr);
50 7ab29a2b 2022-09-30 src exit(eval);
51 7ab29a2b 2022-09-30 src }
52 7ab29a2b 2022-09-30 src
53 aab4ecb3 2022-07-14 src int
54 aab4ecb3 2022-07-14 src usage(void)
55 aab4ecb3 2022-07-14 src {
56 7ab29a2b 2022-09-30 src fprintf(stderr, "usage: gpass [-d dict] [-e bits] [-n count]\n");
57 aab4ecb3 2022-07-14 src exit(EXIT_FAILURE);
58 aab4ecb3 2022-07-14 src }
59 aab4ecb3 2022-07-14 src
60 aab4ecb3 2022-07-14 src void
61 aab4ecb3 2022-07-14 src gen(void)
62 aab4ecb3 2022-07-14 src {
63 926e1c04 2022-12-30 aa_src int c;
64 926e1c04 2022-12-30 aa_src int left;
65 926e1c04 2022-12-30 aa_src uint32_t n;
66 699d07dd 2022-09-30 src
67 926e1c04 2022-12-30 aa_src for (left = plen; left; left--) {
68 77987d57 2023-04-05 aa_src n = arc4random_uniform(nwords) + 1;
69 926e1c04 2022-12-30 aa_src if (fseek(dicfp, offs[n], SEEK_SET) == -1)
70 926e1c04 2022-12-30 aa_src err(1, "fseek");
71 926e1c04 2022-12-30 aa_src while ((c = getc(dicfp)) != EOF && !isspace(c))
72 699d07dd 2022-09-30 src putchar(c);
73 926e1c04 2022-12-30 aa_src if (left > 1)
74 926e1c04 2022-12-30 aa_src putchar(' ');
75 aab4ecb3 2022-07-14 src }
76 aab4ecb3 2022-07-14 src putchar('\n');
77 aab4ecb3 2022-07-14 src }
78 aab4ecb3 2022-07-14 src
79 aab4ecb3 2022-07-14 src int
80 aab4ecb3 2022-07-14 src main(int argc, char *argv[])
81 aab4ecb3 2022-07-14 src {
82 926e1c04 2022-12-30 aa_src int c, isword, npass, temp;
83 926e1c04 2022-12-30 aa_src char *dicname;
84 699d07dd 2022-09-30 src
85 926e1c04 2022-12-30 aa_src isword = 0;
86 926e1c04 2022-12-30 aa_src npass = 1;
87 926e1c04 2022-12-30 aa_src dicname = NULL;
88 926e1c04 2022-12-30 aa_src
89 699d07dd 2022-09-30 src #ifdef __OpenBSD__
90 bb118a6c 2022-10-19 src if (pledge("stdio unveil rpath", NULL) == -1) /* first call */
91 699d07dd 2022-09-30 src err(1, "pledge");
92 699d07dd 2022-09-30 src #endif
93 aab4ecb3 2022-07-14 src while ((c = getopt(argc, argv, "d:e:n:")) != -1) {
94 aab4ecb3 2022-07-14 src switch (c) {
95 aab4ecb3 2022-07-14 src case 'd':
96 699d07dd 2022-09-30 src dicname = optarg;
97 aab4ecb3 2022-07-14 src break;
98 aab4ecb3 2022-07-14 src case 'e':
99 bb118a6c 2022-10-19 src if ((plen = atoi(optarg)) < 1)
100 bb118a6c 2022-10-19 src errx(1, "less than 1 bit of entropy requested");
101 aab4ecb3 2022-07-14 src break;
102 aab4ecb3 2022-07-14 src case 'n':
103 bb118a6c 2022-10-19 src if ((npass = atoi(optarg)) < 1)
104 bb118a6c 2022-10-19 src errx(1, "less than 1 passphrase requested");
105 aab4ecb3 2022-07-14 src break;
106 aab4ecb3 2022-07-14 src default:
107 aab4ecb3 2022-07-14 src usage();
108 aab4ecb3 2022-07-14 src }
109 aab4ecb3 2022-07-14 src }
110 ffe25f1f 2022-08-21 src
111 699d07dd 2022-09-30 src if (!dicname && !(dicname = getenv("GPASS_DIC")))
112 699d07dd 2022-09-30 src dicname = PREFIX "/share/gpass/eff.long";
113 699d07dd 2022-09-30 src #ifdef __OpenBSD__
114 699d07dd 2022-09-30 src if (unveil(dicname, "r") == -1)
115 699d07dd 2022-09-30 src err(1, "unveil %s", dicname);
116 bb118a6c 2022-10-19 src if (pledge("stdio rpath", NULL) == -1) /* revoke unveil */
117 c4607c91 2022-09-30 src err(1, "pledge");
118 699d07dd 2022-09-30 src #endif
119 926e1c04 2022-12-30 aa_src
120 699d07dd 2022-09-30 src if (!(dicfp = fopen(dicname, "r")))
121 699d07dd 2022-09-30 src err(1, "could not open %s", dicname);
122 926e1c04 2022-12-30 aa_src offs[0] = ftell(dicfp);
123 926e1c04 2022-12-30 aa_src while ((c = getc(dicfp)) != EOF && nwords < MAXWORDS)
124 926e1c04 2022-12-30 aa_src if (isspace(c)) {
125 926e1c04 2022-12-30 aa_src nwords += isword ? 1 : 0;
126 926e1c04 2022-12-30 aa_src isword = 0;
127 926e1c04 2022-12-30 aa_src offs[nwords] = ftell(dicfp);
128 926e1c04 2022-12-30 aa_src } else
129 926e1c04 2022-12-30 aa_src isword = 1;
130 926e1c04 2022-12-30 aa_src if (nwords < 2)
131 926e1c04 2022-12-30 aa_src errx(1, "%s has less that 2 words", dicname);
132 926e1c04 2022-12-30 aa_src
133 926e1c04 2022-12-30 aa_src temp = log2(nwords);
134 926e1c04 2022-12-30 aa_src plen = plen / temp + !!(plen % temp);
135 8babeffb 2022-08-21 src plen += !plen;
136 ffe25f1f 2022-08-21 src
137 aab4ecb3 2022-07-14 src for (int i = 0; i < npass; i++)
138 aab4ecb3 2022-07-14 src gen();
139 699d07dd 2022-09-30 src fclose(dicfp);
140 56fdb92d 2022-08-21 src
141 56fdb92d 2022-08-21 src return 0;
142 aab4ecb3 2022-07-14 src }