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