commit 699d07dde281064877fe7ac92c64d7e191fefe8b from: Alexander Arkhipov date: Fri Sep 30 12:36:11 2022 UTC add some security features - When compiling on OpenBSD use pledge(2) and unveil(2). - Ensure there are no integer overflows etc. commit - 4aa3d68b13073db3384c9175ae6da53cd31c9906 commit + 699d07dde281064877fe7ac92c64d7e191fefe8b blob - 4f5de4e909738bf2c8483a2601b3ed44654f4f2c blob + e6b7c8cce70607c58a34b7ee80822da2ce4858e0 --- gpass.c +++ gpass.c @@ -1,4 +1,3 @@ -#include #include #include #include @@ -7,17 +6,19 @@ #include #include +#include + #include #define MAXWORDS 128 -#define RANDLINE (int)randombytes_uniform(nlines)+1 +#define RANDLINE randombytes_uniform(nlines)+1 #ifndef PREFIX # define PREFIX "/usr/local" #endif -char *dictname = NULL; -int plen = 70, nlines = 0, npass = 1; -FILE *dictfp; +FILE *dicfp; +int plen = 70; +uint32_t nlines = 0; int usage(void) @@ -29,38 +30,48 @@ usage(void) void gen(void) { - rewind(dictfp); char c; - for (int left = plen, cur = 1, sought = RANDLINE; left; - cur += (c == '\n')) { - c = getc(dictfp); - if (cur == sought) { - for (; c != '\n' && c != EOF; c = getc(dictfp)) - putchar(c); - if (--left) { - putchar(' '); - sought = RANDLINE; - if (sought <= cur) { - rewind(dictfp); - cur = 0; - } - } + int left = plen; + uint32_t cur = 1, sought = RANDLINE; + + rewind(dicfp); + + for (;;) { + while (getc(dicfp) != '\n') + ; + if (++cur != sought) + continue; + while ((c = getc(dicfp)) != '\n') + putchar(c); + if (!--left) + break; + putchar(' '); + if ((sought = RANDLINE) <= cur) { + rewind(dicfp); + cur = 0; } } + putchar('\n'); } int main(int argc, char *argv[]) { + int c, npass = 1; + char *dicname = NULL; + +#ifdef __OpenBSD__ + if (pledge("stdio unveil rpath", NULL) == -1) + err(1, "pledge"); +#endif if (sodium_init() < 0) err(1, "libsodium"); - int c; while ((c = getopt(argc, argv, "d:e:n:")) != -1) { switch (c) { case 'd': - dictname = optarg; + dicname = optarg; break; case 'e': plen = strtonum(optarg, 1, INT_MAX, NULL); @@ -80,21 +91,25 @@ main(int argc, char *argv[]) } } - if (!dictname && !(dictname = getenv("GPASS_DIC"))) - dictname = PREFIX "/share/gpass/eff.long"; - if (!(dictfp = fopen(dictname, "r"))) - err(1, "could not open the dictionary file %s", dictname); - for (char c = getc(dictfp); c != EOF; c = getc(dictfp)) + if (!dicname && !(dicname = getenv("GPASS_DIC"))) + dicname = PREFIX "/share/gpass/eff.long"; +#ifdef __OpenBSD__ + if (unveil(dicname, "r") == -1) + err(1, "unveil %s", dicname); +#endif + if (!(dicfp = fopen(dicname, "r"))) + err(1, "could not open %s", dicname); + while ((c = getc(dicfp)) != EOF && nlines < UINT32_MAX) nlines += (c == '\n'); if (nlines < 2) - errx(1, "the dictionary %s has less that 2 words", dictname); + errx(1, "%s has less that 2 lines", dicname); int log2nlines = log2(nlines); plen = plen / log2nlines + !!(plen % log2nlines); plen += !plen; for (int i = 0; i < npass; i++) gen(); - fclose(dictfp); + fclose(dicfp); return 0; }