diff --git a/lrzip.c b/lrzip.c index 770dfcd..cdb590e 100644 --- a/lrzip.c +++ b/lrzip.c @@ -35,6 +35,7 @@ #include #endif #include +#include #include "md5.h" #include "rzip.h" @@ -843,8 +844,44 @@ void compress_file(rzip_control *control) const char *tmp, *tmpinfile; /* we're just using this as a proxy for control->infile. * Spares a compiler warning */ - int fd_in, fd_out; + int fd_in, fd_out, i = 0; char header[MAGIC_LEN]; + char *passphrase, *testphrase; + + if (ENCRYPT) { + struct termios termios_p; + + passphrase = calloc(PASS_LEN, 1); + testphrase = calloc(PASS_LEN, 1); + if (unlikely(!passphrase || !testphrase)) + fatal("Failed to calloc passphrase ram\n"); + mlock(passphrase, PASS_LEN); + mlock(testphrase, PASS_LEN); + + /* Disable stdin echo to screen */ + tcgetattr(fileno(stdin), &termios_p); +retry_pass: + print_output("Enter passphrase: "); + termios_p.c_lflag &= ~ECHO; + tcsetattr(fileno(stdin), 0, &termios_p); + if (unlikely(fgets(passphrase, PASS_LEN, stdin) == NULL)) + failure("Empty passphrase\n"); + print_output("\nRe-enter passphrase: "); + if (unlikely(fgets(testphrase, PASS_LEN, stdin) == NULL)) + failure("Empty passphrase\n"); + termios_p.c_lflag |= ECHO; + tcsetattr(fileno(stdin), 0, &termios_p); + print_output("\n"); + if (strcmp(passphrase, testphrase)) { + print_output("Passwords do not match. Try again.\n"); + goto retry_pass; + } + + /* Do stuff here with password */ + free(passphrase); + free(testphrase); + munlockall(); + } memset(header, 0, sizeof(header)); diff --git a/lrzip_private.h b/lrzip_private.h index f2f856e..abeb1a4 100644 --- a/lrzip_private.h +++ b/lrzip_private.h @@ -135,6 +135,8 @@ typedef struct md5_ctx md5_ctx; #define CTYPE_GZIP 7 #define CTYPE_ZPAQ 8 +#define PASS_LEN 512 + /* Needs to be less than 31 bits and page aligned on 32 bits */ #define two_gig ((1ull << 31) - 4096) diff --git a/main.c b/main.c index d79fc77..bf89455 100644 --- a/main.c +++ b/main.c @@ -36,6 +36,7 @@ # include #endif #include +#include #include "rzip.h" #include "lrzip.h" @@ -203,9 +204,15 @@ static void usage(void) } - static void sighandler(int sig __UNUSED__) { + struct termios termios_p; + + /* Make sure we haven't died after disabling stdin echo */ + tcgetattr(fileno(stdin), &termios_p); + termios_p.c_lflag |= ECHO; + tcsetattr(fileno(stdin), 0, &termios_p); + unlink_files(); exit(0); } @@ -768,6 +775,9 @@ int main(int argc, char *argv[]) gettimeofday(&start_time, NULL); + if (unlikely(STDIN && ENCRYPT)) + failure("Unable to work from STDIN while reading password\n"); + if (DECOMPRESS || TEST_ONLY) decompress_file(&control); else if (INFO) diff --git a/util.c b/util.c index 6f207c4..12c3ad3 100644 --- a/util.c +++ b/util.c @@ -38,6 +38,7 @@ #ifdef HAVE_UNISTD_H # include #endif +#include #ifdef _SC_PAGE_SIZE # define PAGE_SIZE (sysconf(_SC_PAGE_SIZE)) @@ -86,6 +87,13 @@ void unlink_files(void) static void fatal_exit(void) { + struct termios termios_p; + + /* Make sure we haven't died after disabling stdin echo */ + tcgetattr(fileno(stdin), &termios_p); + termios_p.c_lflag |= ECHO; + tcsetattr(fileno(stdin), 0, &termios_p); + unlink_files(); fprintf(outputfile, "Fatal error - exiting\n"); fflush(outputfile);