aboutsummaryrefslogtreecommitdiffstats
path: root/src/encpipe.c
diff options
context:
space:
mode:
authorGravatar Frank Denis <github@pureftpd.org>2017-12-31 14:20:35 +0100
committerGravatar Frank Denis <github@pureftpd.org>2017-12-31 14:36:01 +0100
commit360365cdaf843ea5f56af75b64bec8d39f34bf37 (patch)
tree51f132f4a1c8342bc7a663bae28b76d4efc58a6e /src/encpipe.c
parentaaca11ca8615e72aa0f281422df2614bb2f3e945 (diff)
downloadtweetpipe-360365cdaf843ea5f56af75b64bec8d39f34bf37.tar.gz
Add -P (read password from file) and -G (generate a password)
Diffstat (limited to 'src/encpipe.c')
-rw-r--r--src/encpipe.c159
1 files changed, 106 insertions, 53 deletions
diff --git a/src/encpipe.c b/src/encpipe.c
index 88cbd24..d280919 100644
--- a/src/encpipe.c
+++ b/src/encpipe.c
@@ -1,63 +1,25 @@
#include "encpipe_p.h"
static struct option getopt_long_options[] = {
- { "help", 0, NULL, 'h' }, { "decrypt", 0, NULL, 'd' }, { "encrypt", 0, NULL, 'e' },
- { "in", 1, NULL, 'i' }, { "out", 1, NULL, 'o' }, { "p", 1, NULL, 'p' },
- { NULL, 0, NULL, 0 }
+ { "help", 0, NULL, 'h' }, { "decrypt", 0, NULL, 'd' }, { "encrypt", 0, NULL, 'e' },
+ { "in", 1, NULL, 'i' }, { "out", 1, NULL, 'o' }, { "pass", 1, NULL, 'p' },
+ { "passfile", 1, NULL, 'P' }, { "passgen", 0, NULL, 'G' }, { NULL, 0, NULL, 0 }
};
-static const char *getopt_options = "hdei:o:p:";
+static const char *getopt_options = "hdeGi:o:p:P:";
static void
usage(void)
{
puts(
"Usage:\n\n"
- "Encrypt: encpipe -e -p <password> [-i <inputfile>] [-o <outputfile>]\n"
- "Decrypt: encpipe -d -p <password> [-i <inputfile>] [-o <outputfile>]");
+ "Encrypt: encpipe -e -p <password> [-i <inputfile>] [-o <outputfile>]\n"
+ " encpipe -e -P <password file> [-i <inputfile>] [-o <outputfile>]\n\n"
+ "Decrypt: encpipe -d -p <password> [-i <inputfile>] [-o <outputfile>]\n"
+ " encpipe -d -P <password file> [-i <inputfile>] [-o <outputfile>]\n\n"
+ "Passgen: encpipe -G\n");
exit(0);
}
-static void
-options_parse(Context *ctx, int argc, char *argv[])
-{
- int opt_flag;
- int option_index = 0;
-
- ctx->encrypt = -1;
- ctx->in = NULL;
- ctx->out = NULL;
- ctx->password = NULL;
- optind = 0;
-#ifdef _OPTRESET
- optreset = 1;
-#endif
- while ((opt_flag = getopt_long(argc, argv, getopt_options, getopt_long_options,
- &option_index)) != -1) {
- switch (opt_flag) {
- case 'd':
- ctx->encrypt = 0;
- break;
- case 'e':
- ctx->encrypt = 1;
- break;
- case 'i':
- ctx->in = optarg;
- break;
- case 'o':
- ctx->out = optarg;
- break;
- case 'p':
- ctx->password = optarg;
- break;
- default:
- usage();
- }
- }
- if (ctx->password == NULL || ctx->encrypt == -1) {
- usage();
- }
-}
-
static int
file_open(const char *file, int create)
{
@@ -74,17 +36,20 @@ file_open(const char *file, int create)
}
static void
-derive_key(Context *ctx)
+derive_key(Context *ctx, char *password, size_t password_len)
{
static uint8_t master_key[hydro_pwhash_MASTERKEYBYTES] = { 0 };
- size_t password_len = strlen(ctx->password);
- if (hydro_pwhash_deterministic(ctx->key, sizeof ctx->key, ctx->password, password_len,
- HYDRO_CONTEXT, master_key, PWHASH_OPSLIMIT, PWHASH_MEMLIMIT,
+ if (ctx->has_key) {
+ die(0, "A single key is enough");
+ }
+ if (hydro_pwhash_deterministic(ctx->key, sizeof ctx->key, password, password_len, HYDRO_CONTEXT,
+ master_key, PWHASH_OPSLIMIT, PWHASH_MEMLIMIT,
PWHASH_THREADS) != 0) {
die(0, "Password hashing failed");
}
- hydro_memzero(ctx->password, password_len);
+ hydro_memzero(password, password_len);
+ ctx->has_key = 1;
}
static int
@@ -170,6 +135,95 @@ stream_decrypt(Context *ctx)
return 0;
}
+static int
+read_password_file(Context *ctx, const char *file)
+{
+ char password_[512], *password = password_;
+ ssize_t password_len;
+ int fd;
+
+ fd = file_open(file, 0);
+ if ((password_len = safe_read(fd, password, sizeof password_)) < 0) {
+ die(1, "Unable to read the password");
+ }
+ while (password_len > 0 &&
+ (password[password_len - 1] == ' ' || password[password_len - 1] == '\r' ||
+ password[password_len - 1] == '\n')) {
+ password[--password_len] = 0;
+ }
+ while (password_len > 0 && (*password == ' ' || *password == '\r' || *password == '\n')) {
+ password++;
+ password_len--;
+ }
+ if (password_len <= 0) {
+ die(0, "Empty password");
+ }
+ close(fd);
+ derive_key(ctx, password, password_len);
+
+ return 0;
+}
+
+static void
+passgen(void)
+{
+ unsigned char password[32];
+ char hex[32 * 2 + 1];
+
+ randombytes_buf(password, sizeof password);
+ hydro_bin2hex(hex, sizeof hex, password, sizeof password);
+ puts(hex);
+ hydro_memzero(password, sizeof password);
+ hydro_memzero(hex, sizeof hex);
+ exit(0);
+}
+
+static void
+options_parse(Context *ctx, int argc, char *argv[])
+{
+ int opt_flag;
+ int option_index = 0;
+
+ ctx->encrypt = -1;
+ ctx->in = NULL;
+ ctx->out = NULL;
+ optind = 0;
+#ifdef _OPTRESET
+ optreset = 1;
+#endif
+ while ((opt_flag = getopt_long(argc, argv, getopt_options, getopt_long_options,
+ &option_index)) != -1) {
+ switch (opt_flag) {
+ case 'd':
+ ctx->encrypt = 0;
+ break;
+ case 'e':
+ ctx->encrypt = 1;
+ break;
+ case 'G':
+ passgen();
+ break;
+ case 'i':
+ ctx->in = optarg;
+ break;
+ case 'o':
+ ctx->out = optarg;
+ break;
+ case 'p':
+ derive_key(ctx, optarg, strlen(optarg));
+ break;
+ case 'P':
+ read_password_file(ctx, optarg);
+ break;
+ default:
+ usage();
+ }
+ }
+ if (ctx->has_key == 0 || ctx->encrypt == -1) {
+ usage();
+ }
+}
+
int
main(int argc, char *argv[])
{
@@ -180,7 +234,6 @@ main(int argc, char *argv[])
}
memset(&ctx, 0, sizeof ctx);
options_parse(&ctx, argc, argv);
- derive_key(&ctx);
ctx.sizeof_buf = DEFAULT_BUFFER_SIZE;
if (ctx.sizeof_buf < MIN_BUFFER_SIZE) {
ctx.sizeof_buf = MIN_BUFFER_SIZE;