diff --git a/.gitignore b/.gitignore index a774788..24bfb13 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /build +debian/*.ex diff --git a/src/libexim-encrypt-dlfunc-decrypt-sealedbox.c b/src/libexim-encrypt-dlfunc-decrypt-sealedbox.c new file mode 100644 index 0000000..6dd0117 --- /dev/null +++ b/src/libexim-encrypt-dlfunc-decrypt-sealedbox.c @@ -0,0 +1,119 @@ +#include +#include +#include +#include +#include +#include + +/* +#define PASSWORD_MAXLEN 1024 +#define CIPHERSTRING_MAX (1024*64) + +void print_usage(char * progname) { + printf("Usage: %s [OPTIONS]\n\n", progname); + printf("Secret and public key:\n"); + printf(" -s, --secret-key FILE read secret key from file FILE\n"); + printf(" -p, --public-key FILE read public key from file FILE\n"); + printf("\n"); + printf("Select input:\n"); + printf(" -c, --input STRING decrypt contents of STRING\n"); + printf(" -f, --infile FILE decrypt contents of the first line of file FILE\n"); + printf("\n"); +} + +typedef enum { + PASSWORD = 1, + SECRETKEY = 2 +} decryption_mode; + +typedef enum { + ARGUMENT = 1, + FROMFILE = 2 +} input_source; + +int main(int argc, char *argv[]) { + int opt= 0; + char password[PASSWORD_MAXLEN]; + char secret_key[PATH_MAX]; + char cipherstring[CIPHERSTRING_MAX]; + char infile[PATH_MAX]; + bool pass_from_env = false; + + decryption_mode mode = 0; + input_source input = 0; + + if (sodium_init() < 0) { + fputs("Unable to initialize libsodium", stderr); + exit(128); + } + + // define arguments + static struct option long_options[] = { + {"password", required_argument, NULL, 'p'}, + {"pass-from-env", no_argument, NULL, 'e'}, + {"secret-key", required_argument, NULL, 'k'}, + {"public-key", required_argument, NULL, 'k'}, + {"cipherstring", required_argument, NULL, 's'}, + {"infile", required_argument, NULL, 'f'} + }; + + // parse arguments + int long_index = 0; + while ((opt = getopt_long(argc, argv,"p:ek:s:f:", + long_options, &long_index )) != -1) { + switch (opt) { + case 'p': + strncpy(password, optarg, sizeof(password)-1); + mode |= PASSWORD; + break; + case 'e': + pass_from_env = true; + mode |= PASSENV; + break; + case 'k': + strncpy(secret_key, optarg, sizeof(secret_key)-1); + mode |= SECRETKEY; + break; + case 's': + strncpy(cipherstring, optarg, sizeof(cipherstring)-1); + input |= ARGUMENT; + break; + case 'f': + strncpy(infile, optarg, sizeof(infile)-1); + input |= FROMFILE; + break; + default: + print_usage(argv[0]); + exit(EXIT_FAILURE); + } + } + + // retrieve password/key + switch (mode) { + case PASSWORD: + if (pass_from_env == true) { + + } else { + + } + break; + case SECRETKEY: + break; + default: + printf("ERROR: Please specify a password OR a key file.\n\n"); + print_usage(argv[0]); + exit(EXIT_FAILURE); + } + switch (input) { + case ARGUMENT: + case FROMFILE: + break; + default: + printf("ERROR: Please specify a ciphertext.\n\n"); + print_usage(argv[0]); + exit(EXIT_FAILURE); + } +} +*/ + +int main(void) { return 0; } \ No newline at end of file diff --git a/src/libexim-encrypt-dlfunc-decrypt-secretbox.c b/src/libexim-encrypt-dlfunc-decrypt-secretbox.c new file mode 100644 index 0000000..d9d2a75 --- /dev/null +++ b/src/libexim-encrypt-dlfunc-decrypt-secretbox.c @@ -0,0 +1,149 @@ +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#include + +#define ENVVAR_PASSWORD_NAME "LIBEXIM_PASSWORD" + +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("Select input:\n"); + printf(" -c, --input STRING decrypt contents of STRING\n"); + printf(" -f, --infile FILE decrypt contents of the first line of file FILE\n"); + printf("\n"); +} + +typedef enum { + NONE = 0, + PASSARG = 1, + PASSENV = 2, + INSTRING = 4, + INFILE = 8 +} seen_args; + +int main(int argc, char *argv[]) { + char* prog_basename = basename(argv[0]); + int opt; + char *cipherstring; + size_t pwlen; + char *b64password; + char *password_env; + int fd; + char *endptr; + + seen_args mode = NONE; + seen_args input = NONE; + + if (sodium_init() < 0) { + fputs("Unable to initialize libsodium", stderr); + exit(128); + } + + // define arguments + 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} + }; + + // parse arguments + int long_index = 0; + while ((opt = getopt_long(argc, argv,shortargs, + long_options, &long_index )) != -1) { + switch (opt) { + case 'p': + pwlen = strlen(optarg); + 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); + } + pwlen = strlen(password_env); + b64password = malloc(pwlen+1); + strncpy(b64password, password_env, pwlen); + mode |= PASSENV; + break; + case 'f': + // open file + fd = open(optarg, O_RDONLY, (mode_t)0600); + if (fd == -1) { + perror("Error opening file"); + exit(EXIT_FAILURE); + } + // get length + struct stat fileInfo = {0}; + if (fstat(fd, &fileInfo) == -1) { + perror("Error getting the file size"); + exit(EXIT_FAILURE); + } + if (fileInfo.st_size == 0) { + fprintf(stderr, "Error: File is empty, nothing to do\n"); + exit(EXIT_FAILURE); + } + // mmap file + char *map = mmap(0, fileInfo.st_size, PROT_READ, MAP_SHARED, fd, 0); + if (map == MAP_FAILED) + { + close(fd); + perror("Error mmapping the file"); + exit(EXIT_FAILURE); + } + // find first line + endptr = strchrnul(map, 0x0a); + + size_t cipherstring_len = endptr - map; + cipherstring = malloc(cipherstring_len+1); + strncpy(cipherstring, map, cipherstring_len); + + // munmap and close file + if (munmap(map, fileInfo.st_size) == -1) + { + close(fd); + perror("Error un-mmapping the file"); + exit(EXIT_FAILURE); + } + close(fd); + + input |= INFILE; + break; + } + } + + // 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 (optind < argc) { + size_t cipherstring_len = strlen(argv[optind])+1; + cipherstring = malloc(cipherstring_len+1); + strncpy(cipherstring, argv[optind], cipherstring_len); + input |= INSTRING; + } + + if (input == NONE) { + fprintf(stderr, "[ERROR] Please specify a ciphertext source.\n\n"); + print_usage(prog_basename); + exit(EXIT_FAILURE); + } + printf("»%s«\n", cipherstring); +} \ No newline at end of file diff --git a/src/meson.build b/src/meson.build index 8da17bf..22e5ac3 100644 --- a/src/meson.build +++ b/src/meson.build @@ -4,11 +4,18 @@ executable('libexim-encrypt-dlfunc-genkeys', 'libexim-encrypt-dlfunc-genkeys.c', dependencies : [ sodium_deps ], install: true) +executable('libexim-encrypt-dlfunc-decrypt-sealedbox', 'libexim-encrypt-dlfunc-decrypt-sealedbox.c', + dependencies : [ sodium_deps ], + install: true) + +executable('libexim-encrypt-dlfunc-decrypt-secretbox', 'libexim-encrypt-dlfunc-decrypt-secretbox.c', + dependencies : [ sodium_deps ], + install: true) + shared_library('exim-encrypt-dlfunc', 'libexim-encrypt-dlfunc.c', dependencies : [ sodium_deps ], install: true) - simple_exim_test = find_program('simple_exim_test.sh') test('simple test', simple_exim_test)