From 41e7c43ab88cc38bc17efb2aaebe13838e0ec2bc Mon Sep 17 00:00:00 2001 From: Heiko Reese Date: Sat, 11 Sep 2021 00:24:44 +0200 Subject: [PATCH] Always read password from environment. Factored base64-decoding into its own function. --- src/common.c | 29 ++++++- ...libexim-encrypt-dlfunc-decrypt-secretbox.c | 81 +++++++++---------- 2 files changed, 62 insertions(+), 48 deletions(-) diff --git a/src/common.c b/src/common.c index 821590e..ae07d51 100644 --- a/src/common.c +++ b/src/common.c @@ -2,15 +2,17 @@ #include #include #include +#include +#include #include "common.h" -char * read_first_line(const char * filename) { +char *read_first_line(const char *filename) { int fd; char *endptr; char *cipherstring; // open file - fd = open(filename, O_RDONLY, (mode_t)0600); + fd = open(filename, O_RDONLY, (mode_t) 0600); if (fd == -1) { perror("Error opening file"); exit(EXIT_FAILURE); @@ -41,8 +43,7 @@ char * read_first_line(const char * filename) { strncpy(cipherstring, map, cipherstring_len); // munmap and close file - if (munmap(map, fileInfo.st_size) == -1) - { + if (munmap(map, fileInfo.st_size) == -1) { close(fd); perror("Error un-mmapping the file"); exit(EXIT_FAILURE); @@ -50,4 +51,24 @@ char * read_first_line(const char * filename) { close(fd); return cipherstring; +} + +typedef struct { + unsigned char *string; + size_t length; +} Password; + +Password base64_decode_string(const char *input) { + Password p; + size_t input_len = strlen(input); + size_t outmaxlen = input_len / 4 * 3; + p.string = malloc(outmaxlen); + int b64err = sodium_base642bin(p.string, outmaxlen, (const char *) input, input_len, + NULL, &p.length, NULL, sodium_base64_VARIANT_ORIGINAL); + if (b64err != 0) { + fprintf(stderr, "[ERROR] Unable to base64-decode the password\n"); + exit(EXIT_FAILURE); + } + + return p; } \ No newline at end of file diff --git a/src/libexim-encrypt-dlfunc-decrypt-secretbox.c b/src/libexim-encrypt-dlfunc-decrypt-secretbox.c index 1ab7779..f8d74b4 100644 --- a/src/libexim-encrypt-dlfunc-decrypt-secretbox.c +++ b/src/libexim-encrypt-dlfunc-decrypt-secretbox.c @@ -12,7 +12,8 @@ void print_usage(char * progname) { printf("Usage: %s [OPTIONS]\n\n", progname); printf("Password:\n"); printf(" -p, --password PASSWORD decrypt using PASSWORD\n"); - printf(" -e, --pass-from-env read password from environment variable LIBEXIM_PASSWORD\n"); + printf("\n"); + printf(" If the environment variable LIBEXIM_PASSWORD is set the password is read from it.\n"); printf("\n"); printf("Select input:\n"); printf(" -c, --input STRING decrypt contents of STRING\n"); @@ -45,36 +46,34 @@ int main(int argc, char *argv[]) { } // define arguments - const char * shortargs = "p:ef:"; + const char *shortargs = "p:ef:"; static struct option long_options[] = { - {"password", required_argument, NULL, 'p'}, - {"pass-from-env", no_argument, NULL, 'e'}, - {"infile", required_argument, NULL, 'f'}, - {0,0,0,0} + {"password", required_argument, NULL, 'p'}, + {"pass-from-env", no_argument, NULL, 'e'}, + {"infile", required_argument, NULL, 'f'}, + {0, 0, 0, 0} }; + // check environment for LIBEXIM_PASSWORD + password_env = getenv(ENVVAR_PASSWORD_NAME); + if (password_env != NULL && strlen(password_env) > 0) { + pwlen = strlen(password_env); + b64password = malloc(pwlen + 1); + strncpy(b64password, password_env, pwlen); + mode |= PASSENV; + } + // parse arguments int long_index = 0; - while ((opt = getopt_long(argc, argv,shortargs, - long_options, &long_index )) != -1) { + while ((opt = getopt_long(argc, argv, shortargs, + long_options, &long_index)) != -1) { switch (opt) { case 'p': pwlen = strlen(optarg); - b64password = malloc(pwlen+1); + b64password = malloc(pwlen + 1); strncpy(b64password, optarg, pwlen); mode |= PASSARG; break; - case 'e': - password_env = getenv(ENVVAR_PASSWORD_NAME); - if (password_env == NULL) { - fprintf(stderr, "[ERROR] Environment variable %s is undefined.\n\n", ENVVAR_PASSWORD_NAME); - exit(EXIT_FAILURE); - } - pwlen = strlen(password_env); - b64password = malloc(pwlen+1); - strncpy(b64password, password_env, pwlen); - mode |= PASSENV; - break; case 'f': cipherstring = read_first_line(optarg); input |= INFILE; @@ -82,37 +81,31 @@ int main(int argc, char *argv[]) { } } - // check if a password was provided - if (mode == NONE) { - fprintf(stderr, "[ERROR] Please specify a password.\n\n"); - print_usage(prog_basename); - exit(EXIT_FAILURE); - } - // read first non-option argument as ciphertext if present if (optind < argc) { - size_t cipherstring_len = strlen(argv[optind])+1; - cipherstring = malloc(cipherstring_len+1); + size_t cipherstring_len = strlen(argv[optind]) + 1; + cipherstring = malloc(cipherstring_len + 1); strncpy(cipherstring, argv[optind], cipherstring_len); input |= INSTRING; } - // fail if neither argument nor filename is present - if (input == NONE) { - fprintf(stderr, "[ERROR] Please specify a ciphertext source.\n\n"); - print_usage(prog_basename); - exit(EXIT_FAILURE); - } - // base64-decode password - size_t password_len = strlen(b64password) / 4 * 3; - unsigned char * password = malloc(password_len); - int b64err = sodium_base642bin(password, password_len, - (const char *) b64password, strlen(b64password), - NULL, &password_len, NULL, sodium_base64_VARIANT_ORIGINAL); - if (b64err != 0) { - fprintf(stderr, "[ERROR] Unable to base64-decode the password\n"); + // check if a password was provided + if (mode == NONE) { + fprintf(stderr, "[ERROR] Please specify a password.\n\n"); + print_usage(prog_basename); exit(EXIT_FAILURE); } - printf("»%s«\n", password); + // fail if neither argument nor filename is present + if (input == NONE) { + fprintf(stderr, "[ERROR] Please specify a ciphertext source.\n\n"); + print_usage(prog_basename); + exit(EXIT_FAILURE); + } + + // base64-decode password + Password p; + p = base64_decode_string(b64password); + + printf("»%s« [%zu]\n", p.string, p.length); } \ No newline at end of file