Make passphrase_prompt() return -1 on failure so that caller can clean up

This commit is contained in:
Juhani Krekelä 2021-04-09 20:52:04 +03:00
parent 0cb02aaf14
commit f445783a44
1 changed files with 30 additions and 14 deletions

44
puer.c
View File

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