[BACK]Return to readpass.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / ssh

Annotation of src/usr.bin/ssh/readpass.c, Revision 1.3

1.1       deraadt     1: /*
                      2:
                      3: readpass.c
                      4:
                      5: Author: Tatu Ylonen <ylo@cs.hut.fi>
                      6:
                      7: Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
                      8:                    All rights reserved
                      9:
                     10: Created: Mon Jul 10 22:08:59 1995 ylo
                     11:
                     12: Functions for reading passphrases and passwords.
                     13:
                     14: */
                     15:
                     16: #include "includes.h"
1.3     ! deraadt    17: RCSID("$Id: readpass.c,v 1.2 1999/09/30 05:03:05 deraadt Exp $");
1.1       deraadt    18:
                     19: #include "xmalloc.h"
                     20: #include "ssh.h"
                     21:
                     22: /* Saved old terminal mode for read_passphrase. */
                     23: static struct termios saved_tio;
                     24:
                     25: /* Old interrupt signal handler for read_passphrase. */
1.3     ! deraadt    26: static void (*old_handler)(int sig) = NULL;
1.1       deraadt    27:
                     28: /* Interrupt signal handler for read_passphrase. */
                     29:
1.3     ! deraadt    30: void intr_handler(int sig)
1.1       deraadt    31: {
                     32:   /* Restore terminal modes. */
                     33:   tcsetattr(fileno(stdin), TCSANOW, &saved_tio);
                     34:   /* Restore the old signal handler. */
                     35:   signal(sig, old_handler);
                     36:   /* Resend the signal, with the old handler. */
                     37:   kill(getpid(), sig);
                     38: }
                     39:
                     40: /* Reads a passphrase from /dev/tty with echo turned off.  Returns the
                     41:    passphrase (allocated with xmalloc).  Exits if EOF is encountered.
                     42:    The passphrase if read from stdin if from_stdin is true (as is the
                     43:    case with ssh-keygen).  */
                     44:
                     45: char *read_passphrase(const char *prompt, int from_stdin)
                     46: {
                     47:   char buf[1024], *cp;
                     48:   struct termios tio;
                     49:   FILE *f;
                     50:
                     51:   if (from_stdin)
                     52:     f = stdin;
                     53:   else
                     54:     {
                     55:       /* Read the passphrase from /dev/tty to make it possible to ask it even
                     56:         when stdin has been redirected. */
                     57:       f = fopen("/dev/tty", "r");
                     58:       if (!f)
                     59:        {
                     60:          if (getenv("DISPLAY"))
                     61:            {
                     62:              char command[512];
                     63:              fprintf(stderr,
                     64:                      "Executing ssh-askpass to query the password...\n");
                     65:              fflush(stdout);
                     66:              fflush(stderr);
                     67:              sprintf(command, "ssh-askpass '%.400s'", prompt);
                     68:              f = popen(command, "r");
                     69:              if (!fgets(buf, sizeof(buf), f))
                     70:                {
                     71:                  pclose(f);
                     72:                  fprintf(stderr, "No passphrase supplied.  Exiting.\n");
                     73:                  exit(1);
                     74:                }
                     75:              pclose(f);
                     76:              if (strchr(buf, '\n'))
                     77:                *strchr(buf, '\n') = 0;
                     78:              return xstrdup(buf);
                     79:            }
                     80:
                     81:          /* No controlling terminal and no DISPLAY.  Nowhere to read. */
                     82:          fprintf(stderr, "You have no controlling tty and no DISPLAY.  Cannot read passphrase.\n");
                     83:          exit(1);
                     84:        }
                     85:     }
                     86:
                     87:   /* Display the prompt (on stderr because stdout might be redirected). */
                     88:   fflush(stdout);
                     89:   fprintf(stderr, "%s", prompt);
                     90:   fflush(stderr);
                     91:
                     92:   /* Get terminal modes. */
                     93:   tcgetattr(fileno(f), &tio);
                     94:   saved_tio = tio;
                     95:   /* Save signal handler and set the new handler. */
                     96:   old_handler = signal(SIGINT, intr_handler);
                     97:
                     98:   /* Set new terminal modes disabling all echo. */
                     99:   tio.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
                    100:   tcsetattr(fileno(f), TCSANOW, &tio);
                    101:
                    102:   /* Read the passphrase from the terminal. */
                    103:   if (fgets(buf, sizeof(buf), f) == NULL)
                    104:     {
                    105:       /* Got EOF.  Just exit. */
                    106:       /* Restore terminal modes. */
                    107:       tcsetattr(fileno(f), TCSANOW, &saved_tio);
                    108:       /* Restore the signal handler. */
                    109:       signal(SIGINT, old_handler);
                    110:       /* Print a newline (the prompt probably didn\'t have one). */
                    111:       fprintf(stderr, "\n");
                    112:       /* Close the file. */
                    113:       if (f != stdin)
                    114:        fclose(f);
                    115:       exit(1);
                    116:     }
                    117:   /* Restore terminal modes. */
                    118:   tcsetattr(fileno(f), TCSANOW, &saved_tio);
                    119:   /* Restore the signal handler. */
                    120:   (void)signal(SIGINT, old_handler);
                    121:   /* Remove newline from the passphrase. */
                    122:   if (strchr(buf, '\n'))
                    123:     *strchr(buf, '\n') = 0;
                    124:   /* Allocate a copy of the passphrase. */
                    125:   cp = xstrdup(buf);
                    126:   /* Clear the buffer so we don\'t leave copies of the passphrase laying
                    127:      around. */
                    128:   memset(buf, 0, sizeof(buf));
                    129:   /* Print a newline since the prompt probably didn\'t have one. */
                    130:   fprintf(stderr, "\n");
                    131:   /* Close the file. */
                    132:   if (f != stdin)
                    133:     fclose(f);
                    134:   return cp;
                    135: }