diff options
author | Samuel Fadel <samuel@nihil.ws> | 2023-04-09 10:41:31 +0200 |
---|---|---|
committer | Samuel Fadel <samuel@nihil.ws> | 2023-04-09 10:41:31 +0200 |
commit | 3eb0ae9b58683cc59468e3f5b2e28163a722e11b (patch) | |
tree | 4cf1b1daafc7c11a803cb8bdf999a6c12a5530de /lpass.c | |
parent | d314d0cf4b92e1dd9c1f761498b06160dcf5e104 (diff) |
Proper argument parsing.
Also started charset restriction implementation.
* lpass.c: Argument parsing & stub charset restriction.
Diffstat (limited to 'lpass.c')
-rw-r--r-- | lpass.c | 103 |
1 files changed, 87 insertions, 16 deletions
@@ -1,13 +1,16 @@ -#include <openssl/bn.h> -#include <openssl/evp.h> - #include <stdint.h> #include <stdio.h> +#include <stdlib.h> #include <string.h> +#include <getopt.h> +#include <openssl/bn.h> +#include <openssl/evp.h> + #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; } |