Skip to content


Subversion checkout URL

You can clone with
Download ZIP


3 Changes: use variable in make, change tty handling, and remove undefined behavior wrt memcpy #8

wants to merge 5 commits into from

2 participants

  • Notes on the tty handling changes: I didn't understand why you where doing open("/dev/tty", O_RDONLY), so the changes may be wrong.
    The goal was to allow me to pipe a password into tcplay via standard in. isatty is used to determine whether to prompt the user or simply read from input. I suppose this could cause issues if the user (for some reason) lacks a tty. Let me know what you think.

  • In the makefile, I use variables in the test and clean target instead of hardcoded programs.

  • tcplay memcpy's to the same buffer when doing cipher chaning (in = out, in the cipher chaining loop). This eventually gets to a function which memcpy's in to out. memcpy is not technically allowed to do this (pointers must point to independed memory regions), so I check for that case and remove it.
    Thoughts: It would probably be cleaner to remove the memcpy between buffers entirely by somehow hoisting it out of this function. I honestly didn't look to hard at this option yet.


Sorry - I haven't had time to review this yet. I'll hopefully have time this weekend.



The reason I am accessing /dev/tty instead of just relying on stdin is pretty much to avoid hijacking of stdin - someone putting a wrapper around tcplay that logs passphrases.

To pass in passphrases non-interactively the best thing to do would be to use the API, although I see how that is not convenient at all for a shell script or so.

If you separate out the changes to the tty business, I'll merge the rest straight ahead.



Wouldn't hijacking the controlling terminal also be possible in any case where hijacking stdin is possible?


After having another look at all of this, I've decided it's not really worth trying to handle weird cases when the advantages outweigh the disadvantages like they do in this case.

I've committed your code with some minor changes. Thanks, and sorry for the delay!

@bwalex bwalex closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
Showing with 28 additions and 23 deletions.
  1. +28 −23 io.c
51 io.c
@@ -354,31 +354,34 @@ read_passphrase(const char *prompt, char *pass, size_t passlen, time_t timeout)
struct timeval to;
fd_set fds;
ssize_t n;
- int fd, r = 0, cfd = 0, nready;
+ int fd = STDIN_FILENO, r = 0, nready;
struct sigaction act, old_act;
+ int is_tty = isatty(fd);
- if ((fd = open("/dev/tty", O_RDONLY)) == -1) {
- cfd = 1;
- }
- printf("%s", prompt);
- fflush(stdout);
+ if (is_tty == 0)
+ errno = 0;
memset(pass, 0, passlen);
- tcgetattr(fd, &termios_old);
- memcpy(&termios_new, &termios_old, sizeof(termios_new));
- termios_new.c_lflag &= ~ECHO;
+ /* If input is being provided by something which is not a terminal, don't
+ * change the settings. */
+ if (is_tty) {
+ printf("%s", prompt);
+ fflush(stdout);
- act.sa_handler = sigint_termios;
- act.sa_flags = SA_RESETHAND;
- sigemptyset(&act.sa_mask);
+ tcgetattr(fd, &termios_old);
+ memcpy(&termios_new, &termios_old, sizeof(termios_new));
+ termios_new.c_lflag &= ~ECHO;
- tty_fd = fd;
- sigaction(SIGINT, &act, &old_act);
+ act.sa_handler = sigint_termios;
+ act.sa_flags = SA_RESETHAND;
+ sigemptyset(&act.sa_mask);
- tcsetattr(fd, TCSAFLUSH, &termios_new);
+ tty_fd = fd;
+ sigaction(SIGINT, &act, &old_act);
+ tcsetattr(fd, TCSAFLUSH, &termios_new);
+ }
if (timeout > 0) {
memset(&to, 0, sizeof(to));
@@ -388,26 +391,28 @@ read_passphrase(const char *prompt, char *pass, size_t passlen, time_t timeout)
FD_SET(fd, &fds);
nready = select(fd + 1, &fds, NULL, NULL, &to);
if (nready <= 0) {
+ tc_log(1, "Timeout waiting for password.\n");
r = EINTR;
goto out;
n = read(fd, pass, passlen-1);
if (n > 0) {
pass[n-1] = '\0'; /* Strip trailing \n */
} else {
+ tc_log(1, "IO error %d, %d, %s\n", n, errno, strerror(errno));
r = EIO;
- if (cfd)
- close(fd);
+ if (is_tty) {
+ tcsetattr(fd, TCSAFLUSH, &termios_old);
+ putchar('\n');
- tcsetattr(fd, TCSAFLUSH, &termios_old);
- putchar('\n');
- sigaction(SIGINT, &old_act, NULL);
+ sigaction(SIGINT, &old_act, NULL);
+ }
return r;
Something went wrong with that request. Please try again.