diff --git a/puer.c b/puer.c index 4bb4f97..976c1d8 100644 --- a/puer.c +++ b/puer.c @@ -452,31 +452,34 @@ bool ccm_decrypt(unsigned char key[16], uint32_t messageindex, unsigned char mes return true; } -size_t passphrase_prompt(unsigned char *passphrase, size_t size, const char *prompt) { - // Read from controlling TTY, even if stdion has been redirected +ssize_t passphrase_prompt(unsigned char *passphrase, size_t size, const char *prompt) { + // Read from controlling TTY, even if stdio has been redirected int tty = open("/dev/tty", O_RDWR); if (tty == -1) { perror("Failed to open controlling tty"); - exit(1); + return -1; } if (write(tty, prompt, strlen(prompt)) == -1) { perror("Failed to write to terminal"); - exit(1); + close(tty); + return -1; } // Turn off echo struct termios saved; if (tcgetattr(tty, &saved) != 0) { - perror("tcgetattr"); - exit(1); + perror("Failed to get terminal attributes"); + close(tty); + return -1; } struct termios altered; altered = saved; altered.c_lflag &= ~ECHO; if (tcsetattr(tty, TCSANOW, &altered) != 0) { - perror("tcsetattr"); - exit(1); + perror("Failed to turn echoing off"); + close(tty); + return -1; } // Read until newline @@ -495,18 +498,21 @@ size_t passphrase_prompt(unsigned char *passphrase, size_t size, const char *pro } } tcsetattr(tty, TCSANOW, &saved); - exit(1); + close(tty); + return -1; } ssize_t bytes_read = read(tty, &passphrase[index], size - index); if (bytes_read == -1) { perror("Failed to read passphrase"); tcsetattr(tty, TCSANOW, &saved); - exit(1); + close(tty); + return -1; } else if (bytes_read == 0) { fprintf(stderr, "Unexpected EOF\n"); tcsetattr(tty, TCSANOW, &saved); - exit(1); + close(tty); + return -1; } index += bytes_read; @@ -520,9 +526,15 @@ size_t passphrase_prompt(unsigned char *passphrase, size_t size, const char *pro // terminal settings if (write(tty, "\n", 1) == -1) { perror("Failed to write to terminal"); - exit(1); + tcsetattr(tty, TCSANOW, &saved); + close(tty); + return -1; + } + if (tcsetattr(tty, TCSANOW, &saved) != 0) { + perror("Failed to restore terminal state"); + close(tty); + return -1; } - tcsetattr(tty, TCSANOW, &saved); close(tty); return index - 1; @@ -535,7 +547,11 @@ int main(void) { } unsigned char passphrase[128] = {0}; - size_t passphrase_len = passphrase_prompt(passphrase, sizeof(passphrase), "passphrase: "); + ssize_t passphrase_len = passphrase_prompt(passphrase, sizeof(passphrase), "passphrase: "); + if (passphrase_len == -1) { + explicit_bzero(passphrase, sizeof(passphrase)); + exit(1); + } unsigned char key[16]; kdf(key, salt, passphrase, passphrase_len);