MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
get_password.c
1 /* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
2 
3  This program is free software; you can redistribute it and/or modify
4  it under the terms of the GNU General Public License as published by
5  the Free Software Foundation.
6 
7  There are special exceptions to the terms and conditions of the GPL as it
8  is applied to this software.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program; if not, write to the Free Software
17  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
18 
19 /*
20 ** Ask for a password from tty
21 ** This is an own file to avoid conflicts with curses
22 */
23 #include <my_global.h>
24 #include <my_sys.h>
25 #include "mysql.h"
26 #include <m_string.h>
27 #include <m_ctype.h>
28 
29 #if defined(HAVE_BROKEN_GETPASS) && !defined(HAVE_GETPASSPHRASE)
30 #undef HAVE_GETPASS
31 #endif
32 
33 #ifdef HAVE_GETPASS
34 #ifdef HAVE_PWD_H
35 #include <pwd.h>
36 #endif /* HAVE_PWD_H */
37 #else /* ! HAVE_GETPASS */
38 #if !defined(__WIN__)
39 #include <sys/ioctl.h>
40 #ifdef HAVE_TERMIOS_H /* For tty-password */
41 #include <termios.h>
42 #define TERMIO struct termios
43 #else
44 #ifdef HAVE_TERMIO_H /* For tty-password */
45 #include <termio.h>
46 #define TERMIO struct termio
47 #else
48 #include <sgtty.h>
49 #define TERMIO struct sgttyb
50 #endif
51 #endif
52 #ifdef alpha_linux_port
53 #include <asm/ioctls.h> /* QQ; Fix this in configure */
54 #include <asm/termiobits.h>
55 #endif
56 #else
57 #include <conio.h>
58 #endif /* __WIN__ */
59 #endif /* HAVE_GETPASS */
60 
61 #ifdef HAVE_GETPASSPHRASE /* For Solaris */
62 #define getpass(A) getpassphrase(A)
63 #endif
64 
65 #if defined(__WIN__)
66 /* were just going to fake it here and get input from the keyboard */
67 char *get_tty_password(const char *opt_message)
68 {
69  char to[80];
70  char *pos=to,*end=to+sizeof(to)-1;
71  int i=0;
72  DBUG_ENTER("get_tty_password");
73  _cputs(opt_message ? opt_message : "Enter password: ");
74  for (;;)
75  {
76  char tmp;
77  tmp=_getch();
78  if (tmp == '\b' || (int) tmp == 127)
79  {
80  if (pos != to)
81  {
82  _cputs("\b \b");
83  pos--;
84  continue;
85  }
86  }
87  if (tmp == '\n' || tmp == '\r' || tmp == 3)
88  break;
89  if (iscntrl(tmp) || pos == end)
90  continue;
91  _cputs("*");
92  *(pos++) = tmp;
93  }
94  while (pos != to && isspace(pos[-1]) == ' ')
95  pos--; /* Allow dummy space at end */
96  *pos=0;
97  _cputs("\n");
98  DBUG_RETURN(my_strdup(to,MYF(MY_FAE)));
99 }
100 
101 #else
102 
103 #ifndef HAVE_GETPASS
104 /*
105  Can't use fgets, because readline will get confused
106  length is max number of chars in to, not counting \0
107  to will not include the eol characters.
108 */
109 
110 static void get_password(char *to,uint length,int fd, my_bool echo)
111 {
112  char *pos=to,*end=to+length;
113 
114  for (;;)
115  {
116  char tmp;
117  if (my_read(fd,&tmp,1,MYF(0)) != 1)
118  break;
119  if (tmp == '\b' || (int) tmp == 127)
120  {
121  if (pos != to)
122  {
123  if (echo)
124  {
125  fputs("\b \b",stdout);
126  fflush(stdout);
127  }
128  pos--;
129  continue;
130  }
131  }
132  if (tmp == '\n' || tmp == '\r' || tmp == 3)
133  break;
134  if (iscntrl(tmp) || pos == end)
135  continue;
136  if (echo)
137  {
138  fputc('*',stdout);
139  fflush(stdout);
140  }
141  *(pos++) = tmp;
142  }
143  while (pos != to && isspace(pos[-1]) == ' ')
144  pos--; /* Allow dummy space at end */
145  *pos=0;
146  return;
147 }
148 #endif /* ! HAVE_GETPASS */
149 
150 
151 char *get_tty_password(const char *opt_message)
152 {
153 #ifdef HAVE_GETPASS
154  char *passbuff;
155 #else /* ! HAVE_GETPASS */
156  TERMIO org,tmp;
157 #endif /* HAVE_GETPASS */
158  char buff[80];
159 
160  DBUG_ENTER("get_tty_password");
161 
162 #ifdef HAVE_GETPASS
163  passbuff = getpass(opt_message ? opt_message : "Enter password: ");
164 
165  /* copy the password to buff and clear original (static) buffer */
166  strnmov(buff, passbuff, sizeof(buff) - 1);
167 #ifdef _PASSWORD_LEN
168  memset(passbuff, 0, _PASSWORD_LEN);
169 #endif
170 #else
171  if (isatty(fileno(stdout)))
172  {
173  fputs(opt_message ? opt_message : "Enter password: ",stdout);
174  fflush(stdout);
175  }
176 #if defined(HAVE_TERMIOS_H)
177  tcgetattr(fileno(stdin), &org);
178  tmp = org;
179  tmp.c_lflag &= ~(ECHO | ISIG | ICANON);
180  tmp.c_cc[VMIN] = 1;
181  tmp.c_cc[VTIME] = 0;
182  tcsetattr(fileno(stdin), TCSADRAIN, &tmp);
183  get_password(buff, sizeof(buff)-1, fileno(stdin), isatty(fileno(stdout)));
184  tcsetattr(fileno(stdin), TCSADRAIN, &org);
185 #elif defined(HAVE_TERMIO_H)
186  ioctl(fileno(stdin), (int) TCGETA, &org);
187  tmp=org;
188  tmp.c_lflag &= ~(ECHO | ISIG | ICANON);
189  tmp.c_cc[VMIN] = 1;
190  tmp.c_cc[VTIME]= 0;
191  ioctl(fileno(stdin),(int) TCSETA, &tmp);
192  get_password(buff,sizeof(buff)-1,fileno(stdin),isatty(fileno(stdout)));
193  ioctl(fileno(stdin),(int) TCSETA, &org);
194 #else
195  gtty(fileno(stdin), &org);
196  tmp=org;
197  tmp.sg_flags &= ~ECHO;
198  tmp.sg_flags |= RAW;
199  stty(fileno(stdin), &tmp);
200  get_password(buff,sizeof(buff)-1,fileno(stdin),isatty(fileno(stdout)));
201  stty(fileno(stdin), &org);
202 #endif
203  if (isatty(fileno(stdout)))
204  fputc('\n',stdout);
205 #endif /* HAVE_GETPASS */
206 
207  DBUG_RETURN(my_strdup(buff,MYF(MY_FAE)));
208 }
209 #endif /*__WIN__*/