diff --git a/io.c b/io.c index a19553f..3af8607 100644 --- a/io.c +++ b/io.c @@ -43,6 +43,7 @@ #include #include #include +#include #include "tcplay.h" @@ -336,14 +337,25 @@ write_to_disk(const char *dev, off_t offset, size_t blksz, void *mem, return 0; } + +static struct termios termios_old; +static int tty_fd; + +static void sigint_termios(int sa) +{ + tcsetattr(tty_fd, TCSAFLUSH, &termios_old); + exit(sa); +} + int read_passphrase(const char *prompt, char *pass, size_t passlen, time_t timeout) { - struct termios termios_old, termios_new; + struct termios termios_new; struct timeval to; fd_set fds; ssize_t n; int fd, r = 0, cfd = 0, nready; + struct sigaction act, old_act; if ((fd = open("/dev/tty", O_RDONLY)) == -1) { fd = STDIN_FILENO; @@ -358,6 +370,14 @@ read_passphrase(const char *prompt, char *pass, size_t passlen, time_t timeout) tcgetattr(fd, &termios_old); memcpy(&termios_new, &termios_old, sizeof(termios_new)); termios_new.c_lflag &= ~ECHO; + + act.sa_handler = sigint_termios; + act.sa_flags = SA_RESETHAND; + sigemptyset(&act.sa_mask); + + tty_fd = fd; + sigaction(SIGINT, &act, &old_act); + tcsetattr(fd, TCSAFLUSH, &termios_new); if (timeout > 0) { @@ -387,5 +407,7 @@ read_passphrase(const char *prompt, char *pass, size_t passlen, time_t timeout) tcsetattr(fd, TCSAFLUSH, &termios_old); putchar('\n'); + sigaction(SIGINT, &old_act, NULL); + return r; } diff --git a/main.c b/main.c index 4c085ae..3523650 100644 --- a/main.c +++ b/main.c @@ -56,7 +56,7 @@ void usage(void) { fprintf(stderr, - "usage: tcplay -c -d device [-g] [-a pbkdb_hash] [-b cipher]\n" + "usage: tcplay -c -d device [-g] [-z] [-a pbkdb_hash] [-b cipher]\n" " [-f keyfile_hidden] [-k keyfile] [-x pbkdf_hash] [-y cipher]\n" " tcplay -i -d device [-e] [-f keyfile_hidden] [-k keyfile]\n" " [-s system_devcie]\n" @@ -96,6 +96,8 @@ usage(void) "\t Specifies which cipher to use when creating a new hidden volume.\n" "\t By default, the same as for the outer volume will be used.\n" "\t To see valid options, specify '-y help'.\n" + " -z, --insecure-erase\n" + "\t Skips the erase of the disk. Possible security hazard.\n" "\n" "Valid options for --info and --map are:\n" " -e, --protect-hidden\n" @@ -133,6 +135,7 @@ static struct option longopts[] = { { "device", required_argument, NULL, 'd' }, { "system-encryption", required_argument, NULL, 's' }, { "version", no_argument, NULL, 'v' }, + { "insecure-erase", no_argument, NULL, 'z' }, { "help", no_argument, NULL, 'h' }, { NULL, 0, NULL, 0 }, }; @@ -147,7 +150,7 @@ main(int argc, char *argv[]) int n_hkeyfiles; int ch, error; int sflag = 0, info_vol = 0, map_vol = 0, protect_hidden = 0, - create_vol = 0, contain_hidden = 0; + create_vol = 0, contain_hidden = 0, use_secure_erase = 1; struct pbkdf_prf_algo *prf = NULL; struct tc_cipher_chain *cipher_chain = NULL; struct pbkdf_prf_algo *h_prf = NULL; @@ -165,7 +168,7 @@ main(int argc, char *argv[]) nkeyfiles = 0; n_hkeyfiles = 0; - while ((ch = getopt_long(argc, argv, "a:b:cd:ef:ghik:m:s:vx:y:", + while ((ch = getopt_long(argc, argv, "a:b:cd:ef:ghik:m:s:vx:y:z", longopts, NULL)) != -1) { switch(ch) { case 'a': @@ -245,6 +248,10 @@ main(int argc, char *argv[]) /* NOT REACHED */ } break; + + case 'z': + use_secure_erase = 0; + break; case 'h': case '?': default: @@ -274,7 +281,8 @@ main(int argc, char *argv[]) error = create_volume(dev, contain_hidden, keyfiles, nkeyfiles, h_keyfiles, n_hkeyfiles, prf, cipher_chain, h_prf, h_cipher_chain, NULL, NULL, - 0, 1 /* interactive */); + 0, 1 /* interactive */, + use_secure_erase); if (error) { tc_log(1, "could not create new volume on %s\n", dev); } diff --git a/tcplay.c b/tcplay.c index 637b5da..f517971 100644 --- a/tcplay.c +++ b/tcplay.c @@ -381,7 +381,8 @@ create_volume(const char *dev, int hidden, const char *keyfiles[], int nkeyfiles const char *h_keyfiles[], int n_hkeyfiles, struct pbkdf_prf_algo *prf_algo, struct tc_cipher_chain *cipher_chain, struct pbkdf_prf_algo *h_prf_algo, struct tc_cipher_chain *h_cipher_chain, char *passphrase, - char *h_passphrase, size_t size_hidden_bytes_in, int interactive) + char *h_passphrase, size_t size_hidden_bytes_in, int interactive, + int use_secure_erase) { char *pass, *pass_again; char *h_pass = NULL; @@ -584,13 +585,14 @@ create_volume(const char *dev, int hidden, const char *keyfiles[], int nkeyfiles } } - tc_log(0, "Securely erasing the volume...\nThis process may take " - "some time depending on the size of the volume\n"); - /* erase volume */ - if ((error = secure_erase(dev, blocks * blksz, blksz)) != 0) { - tc_log(1, "could not securely erase device %s\n", dev); - goto out; + if (use_secure_erase) { + tc_log(0, "Securely erasing the volume...\nThis process may take " + "some time depending on the size of the volume\n"); + if ((error = secure_erase(dev, blocks * blksz, blksz)) != 0) { + tc_log(1, "could not securely erase device %s\n", dev); + goto out; + } } tc_log(0, "Creating volume headers...\nDepending on your system, this " @@ -1091,7 +1093,7 @@ dm_setup(const char *mapname, struct tcplay_info *info) if ((dm_task_run(dmt)) == 0) { dm_udev_wait(cookie); - tc_log(1, "dm_task_task_run failed\n"); + tc_log(1, "dm_task_run failed\n"); ret = -1; goto out; } diff --git a/tcplay.h b/tcplay.h index ce7cb2d..b1f322d 100644 --- a/tcplay.h +++ b/tcplay.h @@ -195,7 +195,7 @@ int create_volume(const char *dev, int hidden, const char *keyfiles[], struct pbkdf_prf_algo *prf_algo, struct tc_cipher_chain *cipher_chain, struct pbkdf_prf_algo *h_prf_algo, struct tc_cipher_chain *h_cipher_chain, char *passphrase, char *h_passphrase, size_t hidden_bytes_in, - int interactive); + int interactive, int secure_erase); int info_volume(const char *device, int sflag, const char *sys_dev, int protect_hidden, const char *keyfiles[], int nkeyfiles, const char *h_keyfiles[], int n_hkeyfiles,