From 3eb0ae9b58683cc59468e3f5b2e28163a722e11b Mon Sep 17 00:00:00 2001 From: Samuel Fadel Date: Sun, 9 Apr 2023 10:41:31 +0200 Subject: Proper argument parsing. Also started charset restriction implementation. * lpass.c: Argument parsing & stub charset restriction. --- lpass.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 87 insertions(+), 16 deletions(-) diff --git a/lpass.c b/lpass.c index 2193359..44f88a2 100644 --- a/lpass.c +++ b/lpass.c @@ -1,13 +1,16 @@ -#include -#include - #include #include +#include #include +#include +#include +#include + #define MAX_BUF 1024 #define ENTROPY_ITERATIONS 100000 #define ENTROPY_KEY_LENGTH 32 +#define DEFAULT_LENGTH 16 #define CHAR_SUBSET_LOWER "abcdefghijklmnopqrstuvwxyz" #define CHAR_SUBSET_UPPER "ABCDEFGHIJKLMNOPQRSTUVWXYZ" @@ -19,6 +22,13 @@ const char *CHAR_SET = (CHAR_SUBSET_LOWER CHAR_SUBSET_DIGITS CHAR_SUBSET_SYMBOLS); +enum CharSet { + CHAR_SET_LOWER = 1 << 0, + CHAR_SET_UPPER = 1 << 1, + CHAR_SET_DIGITS = 1 << 2, + CHAR_SET_SYMBOLS = 1 << 3, +}; + static BIGNUM * calc_entropy(const char *site, const char *login, @@ -30,7 +40,7 @@ calc_entropy(const char *site, memset(salt, 0, sizeof(salt)); int saltlen = snprintf(salt, MAX_BUF, "%s%s%lx", site, login, counter); if (saltlen > MAX_BUF) { - return 0; + return NULL; } unsigned char key[ENTROPY_KEY_LENGTH]; @@ -42,7 +52,7 @@ calc_entropy(const char *site, ENTROPY_KEY_LENGTH, key); if (status == 0) { - return 0; + return NULL; } /* NULL as last arg to allocate a new BIGNUM */ @@ -132,26 +142,87 @@ render_pass(BIGNUM *entropy, char *out, int length) insert_str_pseudo_randomly(out, entropy, str_to_add); } +static void +err(const char *msg) +{ + fprintf(stderr, "lpass: %s\n", msg); + exit(EXIT_FAILURE); +} + +static void +usage() +{ + fputs("usage: lpass SITE LOGIN [OPTIONS]\n", stderr); + fputs("\nlpass is a C implementation of LessPass, a stateless password manager.\n", stderr); + fputs("\nPositional arguments:\n", stderr); + fputs(" SITE The domain name or URL used in password generation.\n", stderr); + fputs(" LOGIN The username/login used in that domain or URL.\n", stderr); + fputs("\nOptions:\n", stderr); + fputs(" -L LENGTH, --length LENGTH\n", stderr); + fputs(" password length (default: 16)\n", stderr); + fputs(" --no-symbols no symbols in password\n", stderr); + fputs("\nThe environment variable LESSPASS_MASTER_PASSWORD must be set with the master\n", stderr); + fputs("password for producing the desired password.\n", stderr); +} + int main(int argc, char *argv[]) { - if (argc != 5) { - return 1; + const char *master_pass = getenv("LESSPASS_MASTER_PASSWORD"); + if (master_pass == NULL) { + err("environment variable LESSPASS_MASTER_PASSWORD is not set"); } - const char *master_pass = argv[1]; - int passlen = strlen(master_pass); - const char *site = argv[2]; - const char *login = argv[3]; - int length = 0; - if (sscanf(argv[4], "%d", &length) == 0) { - return 1; + int c; + int length = DEFAULT_LENGTH; + uint8_t charsets = 0; + for (;;) { + int option_index = 0; + static struct option long_options[] = { + {"length", required_argument, 0, 'L'}, + {"no-symbols", no_argument, 0, 0 }, + {0, 0, 0, 0 } + }; + + c = getopt_long(argc, argv, "L:", long_options, &option_index); + if (c == -1) { + break; + } + + switch (c) { + case 0: + if (option_index == 1) { + /* TODO: no-symbols */ + } + break; + case 'L': + if (!optarg || sscanf(optarg, "%d", &length) == 0 || length < 1) { + usage(); + exit(EXIT_FAILURE); + } + break; + default: + usage(); + exit(EXIT_FAILURE); + } + } + + /* + * We are still looking for 2 positional arguments, abort if they + * are not there. + */ + if (optind > argc - 2) { + usage(); + exit(EXIT_FAILURE); } + const char *site = argv[optind++]; + const char *login = argv[optind++]; + int passlen = strlen(master_pass); uint64_t counter = 1; BIGNUM *entropy = calc_entropy(site, login, counter, master_pass, passlen); if (entropy == NULL) { - return 1; + err("Failed to calculate entropy"); } char generated_pass[length + 1]; @@ -159,5 +230,5 @@ main(int argc, char *argv[]) render_pass(entropy, generated_pass, length); printf("%s\n", generated_pass); BN_free(entropy); - return 0; + return EXIT_SUCCESS; } -- cgit v1.2.3