Always read password from environment.

Factored base64-decoding into its own function.
This commit is contained in:
Heiko Reese
2021-09-11 00:24:44 +02:00
parent 0b01283cd9
commit 41e7c43ab8
2 changed files with 62 additions and 48 deletions

View File

@ -2,15 +2,17 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <fcntl.h> #include <fcntl.h>
#include <unistd.h> #include <unistd.h>
#include <string.h>
#include <sodium.h>
#include "common.h" #include "common.h"
char * read_first_line(const char * filename) { char *read_first_line(const char *filename) {
int fd; int fd;
char *endptr; char *endptr;
char *cipherstring; char *cipherstring;
// open file // open file
fd = open(filename, O_RDONLY, (mode_t)0600); fd = open(filename, O_RDONLY, (mode_t) 0600);
if (fd == -1) { if (fd == -1) {
perror("Error opening file"); perror("Error opening file");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
@ -41,8 +43,7 @@ char * read_first_line(const char * filename) {
strncpy(cipherstring, map, cipherstring_len); strncpy(cipherstring, map, cipherstring_len);
// munmap and close file // munmap and close file
if (munmap(map, fileInfo.st_size) == -1) if (munmap(map, fileInfo.st_size) == -1) {
{
close(fd); close(fd);
perror("Error un-mmapping the file"); perror("Error un-mmapping the file");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
@ -50,4 +51,24 @@ char * read_first_line(const char * filename) {
close(fd); close(fd);
return cipherstring; 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;
} }

View File

@ -12,7 +12,8 @@ void print_usage(char * progname) {
printf("Usage: %s [OPTIONS]\n\n", progname); printf("Usage: %s [OPTIONS]\n\n", progname);
printf("Password:\n"); printf("Password:\n");
printf(" -p, --password PASSWORD decrypt using 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("\n");
printf("Select input:\n"); printf("Select input:\n");
printf(" -c, --input STRING decrypt contents of STRING\n"); printf(" -c, --input STRING decrypt contents of STRING\n");
@ -45,36 +46,34 @@ int main(int argc, char *argv[]) {
} }
// define arguments // define arguments
const char * shortargs = "p:ef:"; const char *shortargs = "p:ef:";
static struct option long_options[] = { static struct option long_options[] = {
{"password", required_argument, NULL, 'p'}, {"password", required_argument, NULL, 'p'},
{"pass-from-env", no_argument, NULL, 'e'}, {"pass-from-env", no_argument, NULL, 'e'},
{"infile", required_argument, NULL, 'f'}, {"infile", required_argument, NULL, 'f'},
{0,0,0,0} {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 // parse arguments
int long_index = 0; int long_index = 0;
while ((opt = getopt_long(argc, argv,shortargs, while ((opt = getopt_long(argc, argv, shortargs,
long_options, &long_index )) != -1) { long_options, &long_index)) != -1) {
switch (opt) { switch (opt) {
case 'p': case 'p':
pwlen = strlen(optarg); pwlen = strlen(optarg);
b64password = malloc(pwlen+1); b64password = malloc(pwlen + 1);
strncpy(b64password, optarg, pwlen); strncpy(b64password, optarg, pwlen);
mode |= PASSARG; mode |= PASSARG;
break; 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': case 'f':
cipherstring = read_first_line(optarg); cipherstring = read_first_line(optarg);
input |= INFILE; 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 // read first non-option argument as ciphertext if present
if (optind < argc) { if (optind < argc) {
size_t cipherstring_len = strlen(argv[optind])+1; size_t cipherstring_len = strlen(argv[optind]) + 1;
cipherstring = malloc(cipherstring_len+1); cipherstring = malloc(cipherstring_len + 1);
strncpy(cipherstring, argv[optind], cipherstring_len); strncpy(cipherstring, argv[optind], cipherstring_len);
input |= INSTRING; 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 // check if a password was provided
size_t password_len = strlen(b64password) / 4 * 3; if (mode == NONE) {
unsigned char * password = malloc(password_len); fprintf(stderr, "[ERROR] Please specify a password.\n\n");
int b64err = sodium_base642bin(password, password_len, print_usage(prog_basename);
(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");
exit(EXIT_FAILURE); 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);
} }