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