]> andersk Git - openssh.git/blob - readpass.c
Initial revision
[openssh.git] / readpass.c
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"
17 RCSID("$Id$");
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. */
26 static void (*old_handler)(int sig) = NULL;
27
28 /* Interrupt signal handler for read_passphrase. */
29
30 void intr_handler(int sig)
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           /* No controlling terminal and no DISPLAY.  Nowhere to read. */
61           fprintf(stderr, "You have no controlling tty and no DISPLAY.  Cannot read passphrase.\n");
62           exit(1);
63         }
64     }
65
66   /* Display the prompt (on stderr because stdout might be redirected). */
67   fflush(stdout);
68   fprintf(stderr, "%s", prompt);
69   fflush(stderr);
70
71   /* Get terminal modes. */
72   tcgetattr(fileno(f), &tio);
73   saved_tio = tio;
74   /* Save signal handler and set the new handler. */
75   old_handler = signal(SIGINT, intr_handler);
76
77   /* Set new terminal modes disabling all echo. */
78   tio.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
79   tcsetattr(fileno(f), TCSANOW, &tio);
80
81   /* Read the passphrase from the terminal. */
82   if (fgets(buf, sizeof(buf), f) == NULL)
83     {
84       /* Got EOF.  Just exit. */
85       /* Restore terminal modes. */
86       tcsetattr(fileno(f), TCSANOW, &saved_tio);
87       /* Restore the signal handler. */
88       signal(SIGINT, old_handler);
89       /* Print a newline (the prompt probably didn\'t have one). */
90       fprintf(stderr, "\n");
91       /* Close the file. */
92       if (f != stdin)
93         fclose(f);
94       exit(1);
95     }
96   /* Restore terminal modes. */
97   tcsetattr(fileno(f), TCSANOW, &saved_tio);
98   /* Restore the signal handler. */
99   (void)signal(SIGINT, old_handler);
100   /* Remove newline from the passphrase. */
101   if (strchr(buf, '\n'))
102     *strchr(buf, '\n') = 0;
103   /* Allocate a copy of the passphrase. */
104   cp = xstrdup(buf);
105   /* Clear the buffer so we don\'t leave copies of the passphrase laying
106      around. */
107   memset(buf, 0, sizeof(buf));
108   /* Print a newline since the prompt probably didn\'t have one. */
109   fprintf(stderr, "\n");
110   /* Close the file. */
111   if (f != stdin)
112     fclose(f);
113   return cp;
114 }
This page took 0.044463 seconds and 5 git commands to generate.