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

Diff for /src/usr.bin/ssh/readpass.c between version 1.7 and 1.8

version 1.7, 1999/11/24 19:53:50 version 1.8, 1999/12/08 19:32:55
Line 1 
Line 1 
 /*  /*
  *   * Copyright (c) 1988, 1993
  * readpass.c   *      The Regents of the University of California.  All rights reserved.
  *   *
  * Author: Tatu Ylonen <ylo@cs.hut.fi>   * Redistribution and use in source and binary forms, with or without
  *   * modification, are permitted provided that the following conditions
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland   * are met:
  *                    All rights reserved   * 1. Redistributions of source code must retain the above copyright
  *   *    notice, this list of conditions and the following disclaimer.
  * Created: Mon Jul 10 22:08:59 1995 ylo   * 2. Redistributions in binary form must reproduce the above copyright
  *   *    notice, this list of conditions and the following disclaimer in the
  * Functions for reading passphrases and passwords.   *    documentation and/or other materials provided with the distribution.
  *   * 3. All advertising materials mentioning features or use of this software
    *    must display the following acknowledgement:
    *      This product includes software developed by the University of
    *      California, Berkeley and its contributors.
    * 4. Neither the name of the University nor the names of its contributors
    *    may be used to endorse or promote products derived from this software
    *    without specific prior written permission.
    *
    * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
    * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
    * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
    * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
    * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
    * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
    * SUCH DAMAGE.
  */   */
   
 #include "includes.h"  #include "includes.h"
Line 19 
Line 37 
 #include "xmalloc.h"  #include "xmalloc.h"
 #include "ssh.h"  #include "ssh.h"
   
 /* Saved old terminal mode for read_passphrase. */  
 static struct termios saved_tio;  
   
 /* Old interrupt signal handler for read_passphrase. */  
 static void (*old_handler) (int sig) = NULL;  
   
 /* Interrupt signal handler for read_passphrase. */  
   
 void  
 intr_handler(int sig)  
 {  
         /* Restore terminal modes. */  
         tcsetattr(fileno(stdin), TCSANOW, &saved_tio);  
         /* Restore the old signal handler. */  
         signal(sig, old_handler);  
         /* Resend the signal, with the old handler. */  
         kill(getpid(), sig);  
 }  
   
 /*  /*
  * Reads a passphrase from /dev/tty with echo turned off.  Returns the   * Reads a passphrase from /dev/tty with echo turned off.  Returns the
  * passphrase (allocated with xmalloc).  Exits if EOF is encountered. The   * passphrase (allocated with xmalloc), being very careful to ensure that
  * passphrase if read from stdin if from_stdin is true (as is the case with   * no other userland buffer is storing the password.
  * ssh-keygen).  
  */   */
   
 char *  char *
 read_passphrase(const char *prompt, int from_stdin)  read_passphrase(const char *prompt, int from_stdin)
 {  {
         char buf[1024], *cp;          char buf[1024], *p, ch;
         struct termios tio;          struct termios tio, saved_tio;
         FILE *f;          sigset_t oset, nset;
           int input, output, echo = 0;
   
           if (from_stdin) {
                   input = STDIN_FILENO;
                   output = STDERR_FILENO;
           } else
                   input = output = open("/dev/tty", O_RDWR);
   
         if (from_stdin)          if (input == -1)
                 f = stdin;                  fatal("You have no controlling tty.  Cannot read passphrase.\n");
         else {  
                 /*          /* block signals, get terminal modes and turn off echo */
                  * Read the passphrase from /dev/tty to make it possible to          sigemptyset(&nset);
                  * ask it even when stdin has been redirected.          sigaddset(&nset, SIGINT);
                  */          sigaddset(&nset, SIGTSTP);
                 f = fopen("/dev/tty", "r");          (void) sigprocmask(SIG_BLOCK, &nset, &oset);
                 if (!f) {  
                         /* No controlling terminal and no DISPLAY.  Nowhere to read. */          if (tcgetattr(input, &tio) == 0 && (tio.c_lflag & ECHO)) {
                         fprintf(stderr, "You have no controlling tty and no DISPLAY.  Cannot read passphrase.\n");                  echo = 1;
                         exit(1);                  saved_tio = tio;
                 }                  tio.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
                   (void) tcsetattr(input, TCSANOW, &tio);
         }          }
   
         /* Display the prompt (on stderr because stdout might be redirected). */  
         fflush(stdout);          fflush(stdout);
         fprintf(stderr, "%s", prompt);  
         fflush(stderr);  
   
         /* Get terminal modes. */          (void)write(output, prompt, strlen(prompt));
         tcgetattr(fileno(f), &tio);          for (p = buf; read(input, &ch, 1) == 1 && ch != '\n';)
         saved_tio = tio;                  if (p < buf + sizeof(buf) - 1)
         /* Save signal handler and set the new handler. */                          *p++ = ch;
         old_handler = signal(SIGINT, intr_handler);          *p = '\0';
           (void)write(output, "\n", 1);
   
         /* Set new terminal modes disabling all echo. */          /* restore terminal modes and allow signals */
         tio.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);          if (echo)
         tcsetattr(fileno(f), TCSANOW, &tio);                  tcsetattr(input, TCSANOW, &saved_tio);
           (void) sigprocmask(SIG_SETMASK, &oset, NULL);
   
         /* Read the passphrase from the terminal. */          if (!from_stdin)
         if (fgets(buf, sizeof(buf), f) == NULL) {                  (void)close(input);
                 /* Got EOF.  Just exit. */          p = xstrdup(buf);
                 /* Restore terminal modes. */  
                 tcsetattr(fileno(f), TCSANOW, &saved_tio);  
                 /* Restore the signal handler. */  
                 signal(SIGINT, old_handler);  
                 /* Print a newline (the prompt probably didn\'t have one). */  
                 fprintf(stderr, "\n");  
                 /* Close the file. */  
                 if (f != stdin)  
                         fclose(f);  
                 exit(1);  
         }  
         /* Restore terminal modes. */  
         tcsetattr(fileno(f), TCSANOW, &saved_tio);  
         /* Restore the signal handler. */  
         (void) signal(SIGINT, old_handler);  
         /* Remove newline from the passphrase. */  
         if (strchr(buf, '\n'))  
                 *strchr(buf, '\n') = 0;  
         /* Allocate a copy of the passphrase. */  
         cp = xstrdup(buf);  
         /*  
          * Clear the buffer so we don\'t leave copies of the passphrase  
          * laying around.  
          */  
         memset(buf, 0, sizeof(buf));          memset(buf, 0, sizeof(buf));
         /* Print a newline since the prompt probably didn\'t have one. */          return (p);
         fprintf(stderr, "\n");  
         /* Close the file. */  
         if (f != stdin)  
                 fclose(f);  
         return cp;  
 }  }

Legend:
Removed from v.1.7  
changed lines
  Added in v.1.8