1/* pwgen.c - A password generator. 2 * 3 * Copyright 2020 Moritz R�hrich <moritz@ildefons.de> 4 5USE_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 7config PWGEN 8 bool "pwgen" 9 default y 10 help 11 usage: pwgen [-cAn0yrsBhC1v] [LENGTH] [COUNT] 12 13 Generate human-readable random passwords. When output is to tty produces 14 a screenfull to defeat shoulder surfing (pick one and clear the screen). 15 16 -c --capitalize Permit capital letters. 17 -A --no-capitalize Don't include capital letters. 18 -n --numerals Permit numbers. 19 -0 --no-numerals Don't include numbers. 20 -y --symbols Permit special characters ($#%...). 21 -r <chars> --remove=<chars> Don't include the given characters. 22 -s --secure Generate more random passwords. 23 -B --ambiguous Avoid ambiguous characters (e.g. 0, O). 24 -h --help Print this help message. 25 -C Print the output in columns. 26 -1 Print the output one line each. 27 -v Don't include vowels. 28*/ 29 30#define FOR_pwgen 31#include "toys.h" 32 33GLOBALS( 34 char *r; 35) 36 37void pwgen_main(void) 38{ 39 int length = 8, count, ii, jj, c, rand = 0, x = 0; 40 unsigned xx = 80, yy = 24; 41 char randbuf[16]; 42 43 if (isatty(1)) terminal_size(&xx, &yy); 44 else toys.optflags |= FLAG_1; 45 46 if (toys.optc && (length = atolx(*toys.optargs))>sizeof(toybuf)) 47 error_exit("bad length"); 48 if (toys.optc>1) count = atolx(toys.optargs[1]); 49 else count = FLAG(1) ? 1 : (xx/(length+1))*(yy-1); 50 51 for (jj = 0; jj<count; jj++) { 52 for (ii = 0; ii<length;) { 53 // Don't fetch more random than necessary, give each byte 2 tries to fit 54 if (!rand) xgetrandom(randbuf, rand = sizeof(randbuf), 0); 55 c = 33+randbuf[--rand]%93; // remainder 69 makes >102 less likely 56 if (FLAG(s)) randbuf[rand] = 0; 57 58 if (c>='A' && c<='Z') { 59 if (FLAG(A)) continue; 60 // take out half the capital letters to be more human readable 61 else c |= (0x80&randbuf[rand])>>2; 62 } 63 if (FLAG(0) && c>='0' && c<='9') continue; 64 if (FLAG(B) && strchr("0O1lI'`.,", c)) continue; 65 if (FLAG(v) && strchr("aeiou", tolower(c))) continue; 66 if (!FLAG(y) || (0x80&randbuf[rand])) 67 if (c<'0' || (c>'9' && c<'A') || (c>'Z' && c<'a') || c>'z') continue; 68 if (TT.r && strchr(TT.r, c)) continue; 69 70 toybuf[ii++] = c; 71 } 72 if (FLAG(1) || (x += length+1)+length>=xx) x = 0; 73 xprintf("%.*s%c", length, toybuf, x ? ' ' : '\n'); 74 } 75 if (x) xputc('\n'); 76} 77