xref: /aosp_15_r20/external/toybox/toys/other/pwgen.c (revision cf5a6c84e2b8763fc1a7db14496fd4742913b199)
1*cf5a6c84SAndroid Build Coastguard Worker /* pwgen.c - A password generator.
2*cf5a6c84SAndroid Build Coastguard Worker  *
3*cf5a6c84SAndroid Build Coastguard Worker  * Copyright 2020 Moritz R�hrich <[email protected]>
4*cf5a6c84SAndroid Build Coastguard Worker 
5*cf5a6c84SAndroid Build Coastguard Worker USE_PWGEN(NEWTOY(pwgen, ">2r(remove):c(capitalize)n(numerals)y(symbols)s(secure)B(ambiguous)h(help)C1vA(no-capitalize)0(no-numerals)[-cA][-n0][-C1]", TOYFLAG_USR|TOYFLAG_BIN))
6*cf5a6c84SAndroid Build Coastguard Worker 
7*cf5a6c84SAndroid Build Coastguard Worker config PWGEN
8*cf5a6c84SAndroid Build Coastguard Worker   bool "pwgen"
9*cf5a6c84SAndroid Build Coastguard Worker   default y
10*cf5a6c84SAndroid Build Coastguard Worker   help
11*cf5a6c84SAndroid Build Coastguard Worker     usage: pwgen [-cAn0yrsBC1v] [-r CHARS] [LENGTH] [COUNT]
12*cf5a6c84SAndroid Build Coastguard Worker 
13*cf5a6c84SAndroid Build Coastguard Worker     Generate human-readable random passwords. Default output to tty fills screen
14*cf5a6c84SAndroid Build Coastguard Worker     with passwords to defeat shoulder surfing (pick one and clear the screen).
15*cf5a6c84SAndroid Build Coastguard Worker 
16*cf5a6c84SAndroid Build Coastguard Worker     -0	No numbers (--no-numerals)
17*cf5a6c84SAndroid Build Coastguard Worker     -1	Output one per line
18*cf5a6c84SAndroid Build Coastguard Worker     -A	No capital letters (--no-capitalize)
19*cf5a6c84SAndroid Build Coastguard Worker     -B	Avoid ambiguous characters like 0O and 1lI (--ambiguous)
20*cf5a6c84SAndroid Build Coastguard Worker     -C	Output in columns
21*cf5a6c84SAndroid Build Coastguard Worker     -c	Add capital letters (--capitalize)
22*cf5a6c84SAndroid Build Coastguard Worker     -n	Add numbers (--numerals)
23*cf5a6c84SAndroid Build Coastguard Worker     -r	Don't include the given CHARS (--remove)
24*cf5a6c84SAndroid Build Coastguard Worker     -v	No vowels.
25*cf5a6c84SAndroid Build Coastguard Worker     -y	Add punctuation (--symbols)
26*cf5a6c84SAndroid Build Coastguard Worker */
27*cf5a6c84SAndroid Build Coastguard Worker 
28*cf5a6c84SAndroid Build Coastguard Worker #define FOR_pwgen
29*cf5a6c84SAndroid Build Coastguard Worker #include "toys.h"
30*cf5a6c84SAndroid Build Coastguard Worker 
GLOBALS(char * r;)31*cf5a6c84SAndroid Build Coastguard Worker GLOBALS(
32*cf5a6c84SAndroid Build Coastguard Worker   char *r;
33*cf5a6c84SAndroid Build Coastguard Worker )
34*cf5a6c84SAndroid Build Coastguard Worker 
35*cf5a6c84SAndroid Build Coastguard Worker void pwgen_main(void)
36*cf5a6c84SAndroid Build Coastguard Worker {
37*cf5a6c84SAndroid Build Coastguard Worker   int length = 8, count, ii, jj, c, rand = 0, x = 0;
38*cf5a6c84SAndroid Build Coastguard Worker   unsigned xx = 80, yy = 24;
39*cf5a6c84SAndroid Build Coastguard Worker   char randbuf[16];
40*cf5a6c84SAndroid Build Coastguard Worker 
41*cf5a6c84SAndroid Build Coastguard Worker   if (isatty(1)) terminal_size(&xx, &yy);
42*cf5a6c84SAndroid Build Coastguard Worker   else toys.optflags |= FLAG_1;
43*cf5a6c84SAndroid Build Coastguard Worker 
44*cf5a6c84SAndroid Build Coastguard Worker   if (toys.optc && (length = atolx(*toys.optargs))>sizeof(toybuf))
45*cf5a6c84SAndroid Build Coastguard Worker     error_exit("bad length");
46*cf5a6c84SAndroid Build Coastguard Worker   if (toys.optc>1) count = atolx(toys.optargs[1]);
47*cf5a6c84SAndroid Build Coastguard Worker   else count = FLAG(1) ? 1 : (xx/(length+1))*(yy-1);
48*cf5a6c84SAndroid Build Coastguard Worker 
49*cf5a6c84SAndroid Build Coastguard Worker   for (jj = 0; jj<count; jj++) {
50*cf5a6c84SAndroid Build Coastguard Worker     for (ii = 0; ii<length;) {
51*cf5a6c84SAndroid Build Coastguard Worker       // Don't fetch more random than necessary, give each byte 2 tries to fit
52*cf5a6c84SAndroid Build Coastguard Worker       if (!rand) xgetrandom(randbuf, rand = sizeof(randbuf));
53*cf5a6c84SAndroid Build Coastguard Worker       c = 33+randbuf[--rand]%94; // remainder 67 makes >102 less likely
54*cf5a6c84SAndroid Build Coastguard Worker       randbuf[rand] = 0;
55*cf5a6c84SAndroid Build Coastguard Worker 
56*cf5a6c84SAndroid Build Coastguard Worker       if (c>='A' && c<='Z') {
57*cf5a6c84SAndroid Build Coastguard Worker         if (FLAG(A)) continue;
58*cf5a6c84SAndroid Build Coastguard Worker         // take out half the capital letters to be more human readable
59*cf5a6c84SAndroid Build Coastguard Worker         else c |= (0x80&randbuf[rand])>>2;
60*cf5a6c84SAndroid Build Coastguard Worker       }
61*cf5a6c84SAndroid Build Coastguard Worker       if (FLAG(0) && c>='0' && c<='9') continue;
62*cf5a6c84SAndroid Build Coastguard Worker       if (FLAG(B) && strchr("0O1lI8B5S2ZD'`.,", c)) continue;
63*cf5a6c84SAndroid Build Coastguard Worker       if (FLAG(v) && strchr("aeiou", tolower(c))) continue;
64*cf5a6c84SAndroid Build Coastguard Worker       if (!FLAG(y) || (0x80&randbuf[rand]))
65*cf5a6c84SAndroid Build Coastguard Worker         if (c<'0' || (c>'9' && c<'A') || (c>'Z' && c<'a') || c>'z') continue;
66*cf5a6c84SAndroid Build Coastguard Worker       if (TT.r && strchr(TT.r, c)) continue;
67*cf5a6c84SAndroid Build Coastguard Worker 
68*cf5a6c84SAndroid Build Coastguard Worker       toybuf[ii++] = c;
69*cf5a6c84SAndroid Build Coastguard Worker     }
70*cf5a6c84SAndroid Build Coastguard Worker     if (FLAG(1) || (x += length+1)+length>=xx) x = 0;
71*cf5a6c84SAndroid Build Coastguard Worker     xprintf("%.*s%c", length, toybuf, x ? ' ' : '\n');
72*cf5a6c84SAndroid Build Coastguard Worker   }
73*cf5a6c84SAndroid Build Coastguard Worker   if (x) xputc('\n');
74*cf5a6c84SAndroid Build Coastguard Worker }
75