apm

Minimalistic command line password manager and a rewrite of pass in C
git clone https://codeberg.org/night0721/apm
Log | Files | Refs | README | LICENSE

commit 57ffcff2f1d8b00e08053f11bd2a8bccc85bbd25
parent 1910c7aa99299e7ff46dd2320c5e9fe0f6beb187
Author: night0721 <[email protected]>
Date:   Mon,  8 Apr 2024 11:41:57 +0000

use arg.h to parse options

Diffstat:
MMakefile | 3+--
Aarg.h | 65+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Margon.c | 117++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------
3 files changed, 137 insertions(+), 48 deletions(-)

diff --git a/Makefile b/Makefile @@ -11,13 +11,12 @@ CFLAGS = -O3 -march=native -mtune=native -pipe -s -std=c99 -pedantic -Wall -D_DE SRC = argon.c -argon: +argon: argon.c ${CC} ${SRC} -o $@ ${CFLAGS} clean: rm -rf argon - dist: version argon mkdir -p argon-${VERSION} cp -R LICENSE README.md argon.1 argon argon-${VERSION} diff --git a/arg.h b/arg.h @@ -0,0 +1,65 @@ +/* + * Copy me if you can. + * by 20h + */ + +#ifndef ARG_H__ +#define ARG_H__ + +extern char *argv0; + +/* use main(int argc, char *argv[]) */ +#define ARGBEGIN for (argv0 = *argv, argv++, argc--;\ + argv[0] && argv[0][0] == '-'\ + && argv[0][1];\ + argc--, argv++) {\ + char argc_;\ + char **argv_;\ + int brk_;\ + if (argv[0][1] == '-' && argv[0][2] == '\0') {\ + argv++;\ + argc--;\ + break;\ + }\ + for (brk_ = 0, argv[0]++, argv_ = argv;\ + argv[0][0] && !brk_;\ + argv[0]++) {\ + if (argv_ != argv)\ + break;\ + argc_ = argv[0][0];\ + switch (argc_) + +/* Handles obsolete -NUM syntax */ +#define ARGNUM case '0':\ + case '1':\ + case '2':\ + case '3':\ + case '4':\ + case '5':\ + case '6':\ + case '7':\ + case '8':\ + case '9' + +#define ARGEND }\ + } + +#define ARGC() argc_ + +#define ARGNUMF() (brk_ = 1, estrtonum(argv[0], 0, INT_MAX)) + +#define EARGF(x) ((argv[0][1] == '\0' && argv[1] == NULL)?\ + ((x), abort(), (char *)0) :\ + (brk_ = 1, (argv[0][1] != '\0')?\ + (&argv[0][1]) :\ + (argc--, argv++, argv[0]))) + +#define ARGF() ((argv[0][1] == '\0' && argv[1] == NULL)?\ + (char *)0 :\ + (brk_ = 1, (argv[0][1] != '\0')?\ + (&argv[0][1]) :\ + (argc--, argv++, argv[0]))) + +#define LNGARG() &argv[0][0] + +#endif diff --git a/argon.c b/argon.c @@ -9,10 +9,14 @@ #include <sys/resource.h> #include <sodium.h> +#include "arg.h" + #define KEY_SIZE crypto_secretbox_KEYBYTES #define NONCE_SIZE crypto_secretbox_NONCEBYTES #define SALT_SIZE crypto_pwhash_SALTBYTES +char *argv0; + void die(char *str); void *memalloc(size_t size) @@ -27,16 +31,19 @@ void *memalloc(size_t size) char *get_master_key(); -void usage(char **args) +void usage() { - printf("Usage: %s [-vheRIQLG] [-v] [-h] [-e <password>] [-R <password>] [-I <password>] [-Q <password>] [-L] [-G <password> <length>]\n", args[0]); + printf("Usage: %s [-vhL] [[-e | -R | -I | -Q] <password>] [-G <password> <length>]\n", argv0); + exit(EXIT_SUCCESS); } -int compare(const void *a, const void *b) { +int compare(const void *a, const void *b) +{ return strcmp(*(const char **)a, *(const char **)b); } -void tree(const char *basepath, int depth) { +void tree(const char *basepath, int depth) +{ char path[PATH_MAX]; struct dirent *dp; DIR *dir = opendir(basepath); @@ -140,7 +147,6 @@ char *get_password() /* remove newline character */ password[strcspn(password, "\n")] = '\0'; return password; - } void encrypt_password(const char *name, char *password) @@ -297,7 +303,7 @@ char *get_master_key() return m_key; } -void generate_password(int length, char *name) +void generate_password(char*name, int length) { srand(time(NULL)); const char *characters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890123456789~`!@#$%^&*()-_+=[]{}|/,.<>;:'"; @@ -307,7 +313,7 @@ void generate_password(int length, char *name) random_string[i] = characters[rand() % (characters_len - 1)]; } random_string[length] = '\0'; - printf("The geneated password for %s is: %s\n", name, random_string); + printf("The generated password for %s is: %s\n", name, random_string); encrypt_password(name, random_string); free(random_string); } @@ -318,7 +324,7 @@ void die(char *str) exit(EXIT_FAILURE); } -int main(int argc, char **argv) +int main(int argc, char *argv[]) { if (sodium_init() == -1) { die("Error initializing sodium"); @@ -327,45 +333,64 @@ int main(int argc, char **argv) /* disable core dump for security */ setrlimit(RLIMIT_CORE, &(struct rlimit) {0, 0}); - if (argc == 1) { - usage(argv); - return 0; - } - if (strncmp(argv[1], "-v", 2) == 0 && argc == 2) { - printf("argon 1.0.0\n"); - } else if (strncmp(argv[1], "-h", 2) == 0 && argc == 2) { - usage(argv); - } else if (strncmp(argv[1], "-e", 2) == 0 && argc == 3) { - decrypt_password(argv[2], 1); - } else if (strncmp(argv[1], "-R", 2) == 0 && argc == 3) { - char *pass_file = get_passfile(argv[2]); - if (remove(pass_file)) { - perror("argon"); - } else { - printf("Removed %s\n", basename(pass_file)); - } - free(pass_file); - } else if (strncmp(argv[1], "-I", 2) == 0 && argc == 3) { - char *pw = get_password(); - encrypt_password(argv[2], pw); - free(pw); - } else if (strncmp(argv[1], "-Q", 2) == 0 && argc == 3) { - decrypt_password(argv[2], 0); - } else if (strncmp(argv[1], "-L", 2) == 0 && argc == 2) { - char *argon = get_argon(); - tree(argon, 0); - free(argon); - } else if (strncmp(argv[1], "-G", 2) == 0) { - if (argc < 4) { - die("Missing length or name to generate password"); + ARGBEGIN { + case 'h': + usage(); + break; + case 'v': + printf("argon 1.0.0\n"); + exit(EXIT_SUCCESS); + break; + case 'e': + decrypt_password(EARGF(usage()), 1); + exit(EXIT_SUCCESS); + break; + case 'R':; + char *pass_file = get_passfile(EARGF(usage())); + if (remove(pass_file)) { + perror("argon"); + } else { + printf("Removed %s\n", basename(pass_file)); + } + free(pass_file); + exit(EXIT_SUCCESS); + break; + case 'I':; + char *pw = get_password(); + encrypt_password(EARGF(usage()), pw); + free(pw); + exit(EXIT_SUCCESS); + break; + case 'Q': + decrypt_password(EARGF(usage()), 0); + exit(EXIT_SUCCESS); + break; + case 'L':; + char *argon = get_argon(); + tree(argon, 0); + free(argon); + exit(EXIT_SUCCESS); + break; + case 'G':; + if (argc > 0) + --argc, ++argv; + goto run; + default: + usage(); + } ARGEND; + + run: + switch (argc) { + case 0: + usage(); + break; + case 1: + decrypt_password(argv[0], 0); + break; + case 2: + generate_password(argv[0], atoi(argv[1])); + break; } - int length = atoi(argv[3]); - generate_password(length, argv[2]); - } else if (argc == 2) { - decrypt_password(argv[1], 0); - } else { - usage(argv); - } return 0;