commit 08805fb06c71d0025a1f0fcf3443540cf52152ae Spenser Truex <truex@equwal.com> 2025-09-02 13:59:28 -0700 Bugfix v2: pass ver and help
Makefile | 1 + pass.c | 550 ++++++++++++++++++++++++++++++--------------------------------- 2 files changed, 264 insertions(+), 287 deletions(-)
diff --git a/Makefile b/Makefile index 0dff475..93e4882 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,4 @@ +# also bump the version in pass.c when bumping VERSION = 0.1 include config.mk diff --git a/pass.c b/pass.c index bcad67f..2e7dc3a 100644 --- a/pass.c +++ b/pass.c @@ -1,15 +1,15 @@ -/* See LICENSE file for copyright and license details. */ +/* See LICENSE file for copyright and license details. */ #include <errno.h> #include <fcntl.h> -#include <gpgme.h> #include <getopt.h> -#include <limits.h> +#include <gpgme.h> #include <libgen.h> +#include <limits.h> #include <locale.h> #include <pwd.h> #include <stdio.h> -#include <string.h> #include <stdlib.h> +#include <string.h> #include <sys/stat.h> #include <unistd.h> @@ -19,327 +19,303 @@ #define MAX_BUFSIZ 512 static char file[PATH_MAX]; const char *home; +const char *version = "0.1"; // also change makefile -void -initgpgme(void) -{ - const char *reqlibver = "1.6.0"; - const char *reqgpgver = "2.1.0"; +void initgpgme(void) { + const char *reqlibver = "1.6.0"; + const char *reqgpgver = "2.1.0"; - setlocale(LC_ALL, "en_US.UTF-8"); - gpgme_set_locale(NULL, LC_ALL, "en_US.UTF-8"); - gpgme_set_global_flag("require-gnupg", reqgpgver); - gpgme_check_version(reqlibver); + setlocale(LC_ALL, "en_US.UTF-8"); + gpgme_set_locale(NULL, LC_ALL, "en_US.UTF-8"); + gpgme_set_global_flag("require-gnupg", reqgpgver); + gpgme_check_version(reqlibver); } -void -gethomedir(void) -{ - if (!(home = getenv("HOME"))) - fatalx("$HOME not set, cannot determine password-store location"); +void gethomedir(void) { + if (!(home = getenv("HOME"))) + fatalx("$HOME not set, cannot determine password-store location"); } +void delete(char *item) { + char *l; + int r; -void -delete(char *item) -{ - char *l; - int r; - - gethomedir(); - snprintf(file, sizeof(file), "%s/.password-store/%s.gpg", home, item); - printf("Are you sure you would like to delete %s? [y/N] ", item); - if ((r = getchar()) == 'N' || r == 'n') - exit(0); - else if ((r == 'y' || r == 'Y') && !remove(file)) { - printf("removed '%s'\n", file); - if ((l = strrchr(file, '/'))) - *l = '\0'; - rmdir(file); - } + gethomedir(); + snprintf(file, sizeof(file), "%s/.password-store/%s.gpg", home, item); + printf("Are you sure you would like to delete %s? [y/N] ", item); + if ((r = getchar()) == 'N' || r == 'n') + exit(0); + else if ((r == 'y' || r == 'Y') && !remove(file)) { + printf("removed '%s'\n", file); + if ((l = strrchr(file, '/'))) + *l = '\0'; + rmdir(file); + } } -void -usage(void) -{ - fprintf(stderr, - "usage:\tpass init gpg-id\n" - "\tpass insert pass-name\n" - "\tpass pass-name\n" - "\tpass rm pass-name\n" - ); - exit(1); +void usage(void) { + fprintf(stderr, "usage:\tpass init gpg-id\n" + "\tpass insert pass-name\n" + "\tpass pass-name\n" + "\tpass rm pass-name\n"); + exit(1); } -void -decrypt(char *buf) -{ - gpgme_data_t in, out; - gpgme_error_t gpgerr; - gpgme_ctx_t ctx; - gpgme_protocol_t proto; - int a, ret; +void decrypt(char *buf) { + gpgme_data_t in, out; + gpgme_error_t gpgerr; + gpgme_ctx_t ctx; + gpgme_protocol_t proto; + int a, ret; - initgpgme(); - proto = GPGME_PROTOCOL_OpenPGP; + initgpgme(); + proto = GPGME_PROTOCOL_OpenPGP; - gpgerr = gpgme_new(&ctx); - if (gpgme_err_code(gpgerr) != GPG_ERR_NO_ERROR) - fatalgpg(gpgerr, "Error: gpgme_new: %s"); - gpgerr = gpgme_set_protocol(ctx, proto); - if (gpgme_err_code(gpgerr) == GPG_ERR_INV_VALUE) - fatalgpg(gpgerr, "Error: gpgme_set_protocol"); - gpgerr = gpgme_data_new_from_file(&in, file, 1); - if (gpgme_err_code(gpgerr) != GPG_ERR_NO_ERROR) - fatalgpg(gpgerr, "Error: gpgme_data_new_from_file"); - gpgerr = gpgme_data_new(&out); - if (gpgme_err_code(gpgerr) != GPG_ERR_NO_ERROR) - fatalgpg(gpgerr, "Error: gpgme_data_new"); - gpgerr = gpgme_op_decrypt(ctx, in, out); - if (gpgme_err_code(gpgerr) != GPG_ERR_NO_ERROR) - fatalgpg(gpgerr, "Error: gpgme_op_decrypt"); - ret = gpgme_data_seek(out, 0, SEEK_SET); - if (ret) - fatalx("gpgme_data_seek"); - if ((a = gpgme_data_read(out, buf, 100)) > 0) - buf[a] = '\0'; - gpgme_data_release(in); - gpgme_data_release(out); - gpgme_release(ctx); + gpgerr = gpgme_new(&ctx); + if (gpgme_err_code(gpgerr) != GPG_ERR_NO_ERROR) + fatalgpg(gpgerr, "Error: gpgme_new: %s"); + gpgerr = gpgme_set_protocol(ctx, proto); + if (gpgme_err_code(gpgerr) == GPG_ERR_INV_VALUE) + fatalgpg(gpgerr, "Error: gpgme_set_protocol"); + gpgerr = gpgme_data_new_from_file(&in, file, 1); + if (gpgme_err_code(gpgerr) != GPG_ERR_NO_ERROR) + fatalgpg(gpgerr, "Error: gpgme_data_new_from_file"); + gpgerr = gpgme_data_new(&out); + if (gpgme_err_code(gpgerr) != GPG_ERR_NO_ERROR) + fatalgpg(gpgerr, "Error: gpgme_data_new"); + gpgerr = gpgme_op_decrypt(ctx, in, out); + if (gpgme_err_code(gpgerr) != GPG_ERR_NO_ERROR) + fatalgpg(gpgerr, "Error: gpgme_op_decrypt"); + ret = gpgme_data_seek(out, 0, SEEK_SET); + if (ret) + fatalx("gpgme_data_seek"); + if ((a = gpgme_data_read(out, buf, 100)) > 0) + buf[a] = '\0'; + gpgme_data_release(in); + gpgme_data_release(out); + gpgme_release(ctx); } +void printpass(char *item) { + char buf[MAX_BUFSIZ]; + int fin; -void -printpass(char *item) -{ - char buf[MAX_BUFSIZ]; - int fin; - - gethomedir(); - snprintf(file, sizeof(file), "%s/.password-store/%s.gpg", home, item); - /* Check if file exists */ - fin = open(file, O_RDONLY); - if (fin == -1) - fatal("%s is not in password store.", file); - decrypt(buf); - printf("%s\n", buf); - close(fin); + gethomedir(); + snprintf(file, sizeof(file), "%s/.password-store/%s.gpg", home, item); + /* Check if file exists */ + fin = open(file, O_RDONLY); + if (fin == -1) + fatal("%s is not in password store.", file); + decrypt(buf); + printf("%s\n", buf); + close(fin); } -void -getuserid(char *u, int usize) -{ - char file[PATH_MAX]; - FILE *fp; - int i; +void printversion(void) { printf("%s\n", version); } + +void getuserid(char *u, int usize) { + char file[PATH_MAX]; + FILE *fp; + int i; - snprintf(file, sizeof(file), "%s/.password-store/.gpg-id", home); - fp = fopen(file, "r"); - if (!fp) - fatal("fopen: %s", file); - while ((i = fgetc(fp)) != EOF && usize--) - *u++ = i; - *u = '\0'; + snprintf(file, sizeof(file), "%s/.password-store/.gpg-id", home); + fp = fopen(file, "r"); + if (!fp) + fatal("fopen: %s", file); + while ((i = fgetc(fp)) != EOF && usize--) + *u++ = i; + *u = '\0'; } -void -mkdirp(const char *tp) -{ - char *i, t[PATH_MAX]; - int r; - mode_t mode = S_IRWXU; +void mkdirp(const char *tp) { + char *i, t[PATH_MAX]; + int r; + mode_t mode = S_IRWXU; - memcpy(t, file, strlen(file) + 1); - while ((i = strchr(tp, '/'))) { - *i = '\0'; - snprintf(file, sizeof(file), "%s/%s", t, tp); - printf("mkdir %s\n", file); - if ((r = mkdir(file, mode)) == -1) { - if (errno != EEXIST) - fatal("mkdir"); - } - tp = i + 1; - } + memcpy(t, file, strlen(file) + 1); + while ((i = strchr(tp, '/'))) { + *i = '\0'; + snprintf(file, sizeof(file), "%s/%s", t, tp); + printf("mkdir %s\n", file); + if ((r = mkdir(file, mode)) == -1) { + if (errno != EEXIST) + fatal("mkdir"); + } + tp = i + 1; + } } -void -encrypt() -{ - gpgme_data_t in, out; - gpgme_error_t gpgerr; - gpgme_ctx_t ctx; - gpgme_key_t key; - gpgme_key_t keys[2]; - gpgme_protocol_t proto; - char uid[MAX_BUFSIZ], t[PATH_MAX]; - FILE *fin, *fout; +void encrypt() { + gpgme_data_t in, out; + gpgme_error_t gpgerr; + gpgme_ctx_t ctx; + gpgme_key_t key; + gpgme_key_t keys[2]; + gpgme_protocol_t proto; + char uid[MAX_BUFSIZ], t[PATH_MAX]; + FILE *fin, *fout; - proto = GPGME_PROTOCOL_OpenPGP; - key = NULL; + proto = GPGME_PROTOCOL_OpenPGP; + key = NULL; - initgpgme(); - getuserid(uid, MAX_BUFSIZ); - gpgerr = gpgme_new(&ctx); - if (gpgme_err_code(gpgerr) != GPG_ERR_NO_ERROR) - fatalgpg(gpgerr, "gpme_new"); - gpgerr = gpgme_set_protocol(ctx, proto); - if (gpgme_err_code(gpgerr) == GPG_ERR_INV_VALUE) - fatalgpg(gpgerr, "gpgme_set_protocol"); - gpgme_set_armor(ctx, 1); - if (gpgme_op_keylist_start(ctx, uid, 0) != GPG_ERR_INV_VALUE) - while (!(gpgerr = gpgme_op_keylist_next(ctx, &key))) { - if (key->can_encrypt) - break; - } - if (gpgme_err_code(gpgerr) == GPG_ERR_EOF) - fatalgpg(gpgerr, "can not find key"); - keys[0] = key; - keys[1] = NULL; - fin = fopen(file, "r"); - memcpy(t, file, strlen(file) + 1); - snprintf(file, sizeof(file), "%s.gpg", t); - fout = fopen(file, "w"); - gpgerr = gpgme_data_new_from_stream(&in, fin); - if (gpgme_err_code(gpgerr) != GPG_ERR_NO_ERROR) - fatalgpg(gpgerr, "gpgme_data_new_from_stream"); - gpgerr = gpgme_data_new_from_stream(&out, fout); - gpgme_data_set_encoding(out, GPGME_DATA_ENCODING_ARMOR); - if (gpgme_err_code(gpgerr) != GPG_ERR_NO_ERROR) - fatalgpg(gpgerr, "gpgme_data_new_from_stream"); - gpgerr = gpgme_op_encrypt(ctx, keys, GPGME_ENCRYPT_ALWAYS_TRUST, in, out); - if (gpgme_err_code(gpgerr) != GPG_ERR_NO_ERROR) - fatalgpg(gpgerr, "gpgme_op_encrypt"); - if (remove(t)) - fprintf(stderr, "remove failed\n"); - gpgme_key_release(key); - gpgme_data_release(in); - gpgme_data_release(out); - gpgme_release(ctx); + initgpgme(); + getuserid(uid, MAX_BUFSIZ); + gpgerr = gpgme_new(&ctx); + if (gpgme_err_code(gpgerr) != GPG_ERR_NO_ERROR) + fatalgpg(gpgerr, "gpme_new"); + gpgerr = gpgme_set_protocol(ctx, proto); + if (gpgme_err_code(gpgerr) == GPG_ERR_INV_VALUE) + fatalgpg(gpgerr, "gpgme_set_protocol"); + gpgme_set_armor(ctx, 1); + if (gpgme_op_keylist_start(ctx, uid, 0) != GPG_ERR_INV_VALUE) + while (!(gpgerr = gpgme_op_keylist_next(ctx, &key))) { + if (key->can_encrypt) + break; + } + if (gpgme_err_code(gpgerr) == GPG_ERR_EOF) + fatalgpg(gpgerr, "can not find key"); + keys[0] = key; + keys[1] = NULL; + fin = fopen(file, "r"); + memcpy(t, file, strlen(file) + 1); + snprintf(file, sizeof(file), "%s.gpg", t); + fout = fopen(file, "w"); + gpgerr = gpgme_data_new_from_stream(&in, fin); + if (gpgme_err_code(gpgerr) != GPG_ERR_NO_ERROR) + fatalgpg(gpgerr, "gpgme_data_new_from_stream"); + gpgerr = gpgme_data_new_from_stream(&out, fout); + gpgme_data_set_encoding(out, GPGME_DATA_ENCODING_ARMOR); + if (gpgme_err_code(gpgerr) != GPG_ERR_NO_ERROR) + fatalgpg(gpgerr, "gpgme_data_new_from_stream"); + gpgerr = gpgme_op_encrypt(ctx, keys, GPGME_ENCRYPT_ALWAYS_TRUST, in, out); + if (gpgme_err_code(gpgerr) != GPG_ERR_NO_ERROR) + fatalgpg(gpgerr, "gpgme_op_encrypt"); + if (remove(t)) + fprintf(stderr, "remove failed\n"); + gpgme_key_release(key); + gpgme_data_release(in); + gpgme_data_release(out); + gpgme_release(ctx); } -void -insert(char *item) -{ - char *filename, t[PATH_MAX]; - FILE *fp; - char pass[MAX_BUFSIZ]; - int c, fd; +void insert(char *item) { + char *filename, t[PATH_MAX]; + FILE *fp; + char pass[MAX_BUFSIZ]; + int c, fd; - c = 'y'; - fd = fileno(stdin); + c = 'y'; + fd = fileno(stdin); - gethomedir(); - snprintf(file, sizeof(file), "%s/.password-store", home); - filename = basename(item); - mkdirp(item); - memcpy(t, file, strlen(file) + 1); - snprintf(file, sizeof(file), "%s/%s", t, filename); - snprintf(t, sizeof(t), "%s.gpg", file); - if ((fp = fopen(t, "r"))) { - if (isatty(fd)) { - printf("An entry already exists for %s. Overwrite it? [y/N] ", filename); - if ((c = getchar()) == 'N' || c == 'n') { - fclose(fp); - logdbgx("Don't overwrite"); - exit(1); - } - } else - /* Assuming user knows what he/she is doing */ - printf("Overwriting %s\n", filename); - } - if (c != 'Y' && c != 'y') - exit(1); - if (!(fp = fopen(file, "w+b"))) - fatal("fopen: %s", file); - if (isatty(fd)) { - readpassphrase("Enter password: ", pass, MAX_BUFSIZ, RPP_ECHO_OFF); - memcpy(t, pass, strlen(pass) + 1); - readpassphrase("Retype password: ", pass, MAX_BUFSIZ, RPP_ECHO_OFF); - if (!strcmp(pass, t)) - { - int i = 0; - while(t[i] != '\0') { - if (fputc(t[i], fp) == EOF) - fatal("fputc: %s", file); - i++; - } - } else - fatalx("Passwords don't match."); - } else { - int c; - while ((c = getchar()) != EOF && c != '\n') - fputc(c, fp); - } - fclose(fp); - encrypt(); + gethomedir(); + snprintf(file, sizeof(file), "%s/.password-store", home); + filename = basename(item); + mkdirp(item); + memcpy(t, file, strlen(file) + 1); + snprintf(file, sizeof(file), "%s/%s", t, filename); + snprintf(t, sizeof(t), "%s.gpg", file); + if ((fp = fopen(t, "r"))) { + if (isatty(fd)) { + printf("An entry already exists for %s. Overwrite it? [y/N] ", filename); + if ((c = getchar()) == 'N' || c == 'n') { + fclose(fp); + logdbgx("Don't overwrite"); + exit(1); + } + } else + /* Assuming user knows what he/she is doing */ + printf("Overwriting %s\n", filename); + } + if (c != 'Y' && c != 'y') + exit(1); + if (!(fp = fopen(file, "w+b"))) + fatal("fopen: %s", file); + if (isatty(fd)) { + readpassphrase("Enter password: ", pass, MAX_BUFSIZ, RPP_ECHO_OFF); + memcpy(t, pass, strlen(pass) + 1); + readpassphrase("Retype password: ", pass, MAX_BUFSIZ, RPP_ECHO_OFF); + if (!strcmp(pass, t)) { + int i = 0; + while (t[i] != '\0') { + if (fputc(t[i], fp) == EOF) + fatal("fputc: %s", file); + i++; + } + } else + fatalx("Passwords don't match."); + } else { + int c; + while ((c = getchar()) != EOF && c != '\n') + fputc(c, fp); + } + fclose(fp); + encrypt(); } -int -isinit(void) -{ - int fp; - struct stat sb; +int isinit(void) { + int fp; + struct stat sb; - gethomedir(); - snprintf(file, sizeof(file), "%s/.password-store", home); - if ((fp = open(file, O_RDONLY)) != -1 && - (!fstat(fp, &sb)) && - (S_ISDIR(sb.st_mode))) { - close(fp); - return 1; - } - return 0; + gethomedir(); + snprintf(file, sizeof(file), "%s/.password-store", home); + if ((fp = open(file, O_RDONLY)) != -1 && (!fstat(fp, &sb)) && (S_ISDIR(sb.st_mode))) { + close(fp); + return 1; + } + return 0; } -void -initpass(char *pgpid) -{ - FILE *gpg; - mode_t mode = S_IRWXU; +void initpass(char *pgpid) { + FILE *gpg; + mode_t mode = S_IRWXU; - if (!pgpid) { - usage(); - } - if (!isinit()) - { - if (mkdir(file, mode)) - fatal("mkdir"); - snprintf(file, sizeof(file), "%s/.password-store/.gpg-id", home); - if (!(gpg = fopen(file, "a"))) - fatal("fopen"); - if (fputs(pgpid, gpg) == EOF) - fatal("fputs"); - printf("Password store initialized for %s\n", pgpid); - fclose(gpg); - } else - printf("Password store initialized for %s\n", pgpid); + if (!pgpid) { + usage(); + } + if (!isinit()) { + if (mkdir(file, mode)) + fatal("mkdir"); + snprintf(file, sizeof(file), "%s/.password-store/.gpg-id", home); + if (!(gpg = fopen(file, "a"))) + fatal("fopen"); + if (fputs(pgpid, gpg) == EOF) + fatal("fputs"); + printf("Password store initialized for %s\n", pgpid); + fclose(gpg); + } else + printf("Password store initialized for %s\n", pgpid); } -int -main(int argc, char** argv) -{ - char **s; - int i; +int main(int argc, char **argv) { + char **s; + int i; - debug = 0; + debug = 0; - for (s = argv, i = 0; i < argc; i++) { - if (!strcmp("-d", *s++)) - debug = 1; - } - if (argc > 1) - { - argv++; - loginit("pass"); - if (!strcmp("init", *argv)) - initpass(*(argv + 1)); - else if (!strcmp("insert", *argv)) - insert(*(argv + 1)); - else if (!strcmp("rm", *argv)) - delete(*(argv + 1)); - else - printpass(*argv); - } else - usage(); - return 0; + for (s = argv, i = 0; i < argc - 1; i++) { + if (!strcmp("-d", *s++)) { + debug = 1; + argv++; + } + } + if (argc > 1) { + argv++; + loginit("pass"); + if (!strcmp("init", *argv)) + initpass(*(argv + 1)); + else if (!strcmp("insert", *argv)) + insert(*(argv + 1)); + else if (!strcmp("rm", *argv)) + delete(*(argv + 1)); + else if (!strcmp("show", *argv)) + printpass(*(argv + 1)); + else if (!strcmp("help", *argv)) + usage(); + else if (!strcmp("ver", *argv)) + printversion(); + else + printpass(*argv); + } else + usage(); + return 0; }