#include #include #include #include #include #include #include #define DICTFILE "/usr/share/dict/american-english" #define VERSION "1.0" #define RLEN 1024 #define WMIN 6 #define WMAX 10 int humantoss = 0; int usage() { fprintf(stderr, "Generate a random diceware passphrase\n" "Usage: dice [-cfvh]\n" "Options: \n" "-t Asks interactively for tossed dices\n" "-c Number of words (default: 4)\n" "-f Dictionary file to use (default:\n" " /usr/share/dict/american-english)\n" "-v Print program version\n" "-h Print this help screen\n" ); return 1; } void _dump(unsigned char *d, size_t s) { size_t i; int c; for (i=0; i 6) goto RETRY; tosses[i] = onedice; } free(line); } else { rand = malloc(RLEN); if((RAND = fopen("/dev/urandom", "rb")) == NULL) { perror("Could not open /dev/urandom"); } fread(rand, RLEN, 1, RAND); fclose(RAND); for(i=0; i= 1 && onedice <= 6) { tosses[pos] = onedice; pos++; } if(pos == count) break; } free(rand); } return tosses; } int rand_lim(int limit) { /* return a random number in the range [0..limit) */ int divisor = RAND_MAX/limit; int retval; do { retval = rand() / divisor; } while (retval == limit); return retval; } void getwords(char *dictfile, int count) { char **words; int one, two, three, four, five, pos, i, next, jump; char *line = NULL; size_t len = 0; ssize_t linelen; FILE *DICT; unsigned char *tosses; int *tossed; one = 10000; two = 1000; three = 100; four = 10; five = 1; pos = 11111; words = malloc(66666 * sizeof(char *)); tossed = malloc(count); jump = rand_lim(32); if((DICT = fopen(dictfile, "rb")) == NULL) { perror("Could not open dictfile"); } LOOP: while ((linelen = getline(&line, &len, DICT)) != -1) { if(jump > 0) { jump--; continue; } else { jump = rand_lim(32); } if(linelen >= WMIN+1 && linelen <= WMAX+1) { line[linelen-1] = '\0'; /* remove newline */ for(i=0; i10 */ } /* while read */ if(pos < 66666) { fseek(DICT, 0L, SEEK_SET); goto LOOP; } fclose(DICT); free(line); for(i=0; i