diff options
Diffstat (limited to 'src/main.c')
-rw-r--r-- | src/main.c | 138 |
1 files changed, 84 insertions, 54 deletions
@@ -1,25 +1,27 @@ -// upwgen generates random internationalized passwords -// Copyright (C) 2019 Aaron Ball <nullspoon@oper.io> -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see <http://www.gnu.org/licenses/>. +/** + * upwgen generates random internationalized passwords + * Copyright (C) 2019 Aaron Ball <nullspoon@oper.io> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ #include <stdlib.h> #include <stdio.h> #include <string.h> #include <time.h> #include <locale.h> -#include "i18n_cat.h" +#include "i18n_set.h" // Shamelessly ripped off from the GCC docs on stringizing // This (xstr) converts a macro to a string literal @@ -35,15 +37,16 @@ void usage() { "and symbols).\n\n" "Usage:\n upwgen [options] [length]\n\n" "Options:\n" - " -c,--capitalize Include at least one capital letter in output\n" - " -l,--lower Include at least one lower case letter in output\n" - " -n,--numerals Include at least one numeral in output\n" - " -y,--symbols Include at least one symbol in output\n" - " -i,--i18n Include at least one international letter in output\n" - " -1 Include chars from the most used scripts in the world\n" - " -2 Include chars from the second most used scripts in the world\n" - " -3 Include chars from the third most used scripts in the world\n" - " -4 Include chars from the forth most used scripts in the world\n" + " -0,--no-numerals Include at least one numeral in output\n" + " -A,--no-capitalize Include at least one numeral in output\n" + " -c,--capitalize Include at least one capital letter in output\n" + " -n,--numerals Include at least one numeral in output\n" + " -y,--symbols Include at least one symbol in output\n" + " -i,--i18n Include at least one international letter in output\n" + " -1 Include chars from the most used scripts in the world\n" + " -2 Include chars from the second most used scripts in the world\n" + " -3 Include chars from the third most used scripts in the world\n" + " -4 Include chars from the forth most used scripts in the world\n" "\n" " -h,--help Print this help text\n" " -d,--debug Enable debug mode (prints entire character pool)\n" @@ -54,51 +57,71 @@ void usage() { int main(int argc, char* argv[]) { struct timespec ts; // Timespec for seeding rng - unsigned int count; // Number of chars to choose from int debug; // Debug mode switch int len; // Password length int i; // Arg index unsigned long seed; // Seed for the RNG (current seconds * nanoseconds) - unsigned int chars[4096]; // Uint array to hold international chars + + struct i18n_set* set = NULL; // Linked list of i18n_set structs + struct i18n_set* cursor = NULL; // Cursor to track current position with in + // the linked list // Initialize debug = 0; - count = 0; len = 32; i = 1; - chars[0] = '\0'; - setlocale(LC_ALL, "en_US.UTF-8"); + setlocale(LC_ALL, ""); + + // Start with the defaults + set = i18n_set_new(I18N_TYPE_ASCII_UPPER); + i18n_set_add(set, I18N_TYPE_ASCII_LOWER); + i18n_set_add(set, I18N_TYPE_ASCII_NUMERALS); + while(i < argc) { - if(strcmp(argv[i], "-c") == 0 || strcmp(argv[i], "--capitals") == 0) { - count += i18n_cat_ascii_upper(chars); + if(strcmp(argv[i], "-0") == 0 || strcmp(argv[i], "--no-numerals") == 0) { + set = i18n_set_rm_type(set, I18N_TYPE_ASCII_NUMERALS); + + } else if(strcmp(argv[i], "-A") == 0 || strcmp(argv[i], "--no-capitalize") == 0) { + set = i18n_set_rm_type(set, I18N_TYPE_ASCII_UPPER); - } else if(strcmp(argv[i], "-l") == 0 || strcmp(argv[i], "--lower") == 0) { - count += i18n_cat_ascii_lower(chars); + } else if(strcmp(argv[i], "-c") == 0 || strcmp(argv[i], "--capitalize") == 0) { + if(!i18n_set_exists(set, I18N_TYPE_ASCII_UPPER)) + i18n_set_add(set, I18N_TYPE_ASCII_UPPER); } else if(strcmp(argv[i], "-n") == 0 || strcmp(argv[i], "--numerals") == 0) { - count += i18n_cat_ascii_numerals(chars); + if(!i18n_set_exists(set, I18N_TYPE_ASCII_NUMERALS)) + i18n_set_add(set, I18N_TYPE_ASCII_NUMERALS); } else if(strcmp(argv[i], "-y") == 0 || strcmp(argv[i], "--symbols") == 0) { - count += i18n_cat_ascii_symbols(chars); + if(!i18n_set_exists(set, I18N_TYPE_ASCII_SYMBOLS)) + i18n_set_add(set, I18N_TYPE_ASCII_SYMBOLS); } else if(strcmp(argv[i], "-i") == 0 || strcmp(argv[i], "--i18n") == 0) { - count += i18n_cat_one(chars); - count += i18n_cat_two(chars); - count += i18n_cat_three(chars); - count += i18n_cat_four(chars); + if(!i18n_set_exists(set, I18N_TYPE_ONE)) + i18n_set_add(set, I18N_TYPE_ONE); + if(!i18n_set_exists(set, I18N_TYPE_TWO)) + i18n_set_add(set, I18N_TYPE_TWO); + if(!i18n_set_exists(set, I18N_TYPE_THREE)) + i18n_set_add(set, I18N_TYPE_THREE); + if(!i18n_set_exists(set, I18N_TYPE_FOUR)) + i18n_set_add(set, I18N_TYPE_FOUR); } else if(strcmp(argv[i], "-1") == 0) { - count += i18n_cat_one(chars); + if(!i18n_set_exists(set, I18N_TYPE_ONE)) + i18n_set_add(set, I18N_TYPE_ONE); } else if(strcmp(argv[i], "-2") == 0) { - count += i18n_cat_two(chars); + if(!i18n_set_exists(set, I18N_TYPE_TWO)) + i18n_set_add(set, I18N_TYPE_TWO); } else if(strcmp(argv[i], "-3") == 0) { - count += i18n_cat_three(chars); + if(!i18n_set_exists(set, I18N_TYPE_THREE)) + i18n_set_add(set, I18N_TYPE_THREE); } else if(strcmp(argv[i], "-4") == 0) { - count += i18n_cat_four(chars); + if(!i18n_set_exists(set, I18N_TYPE_FOUR)) + i18n_set_add(set, I18N_TYPE_FOUR); } else if(strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "--help") == 0) { usage(); @@ -125,25 +148,32 @@ int main(int argc, char* argv[]) { i++; } - // If no charset was specified, use standard ascii 33 - 126 chars, which - // includes english lower case, upper case, numbers, and some symbols. - if(chars[0] == '\0') - count += i18n_cat_ascii(chars); - if(debug) - i18n_dump_arr(chars); + i18n_set_dump(set); // Get the random data seed clock_gettime(CLOCK_REALTIME, &ts); seed = ts.tv_sec + ts.tv_nsec; srand((unsigned)seed); - while(len > 0) { - int r = rand() % count; - printf("%lc", chars[r]); - len--; + cursor = set; + while((len--) > 0) { + // Randomly select the number of character sets to advance through + int i = rand() % 10; + while((i--) > 0) { + // Loop + if(!cursor->next) + cursor = set; + else + cursor = cursor->next; + } + + // Randomly select an integer within the set size + int rc = rand() % cursor->count; // Random char within set + printf("%lc", cursor->chars[rc]); } printf("\n"); + i18n_set_free(set); return 0; } |