Drizzled Public API Documentation

get_password.cc
1 /* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3  *
4  * Copyright (C) 2008 Sun Microsystems, Inc.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; version 2 of the License.
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 /*
21 ** Ask for a password from tty
22 ** This is an own file to avoid conflicts with curses
23 */
24 
25 #include <config.h>
26 #include <client/get_password.h>
27 
28 #include <string>
29 
30 #include <string.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <ctype.h>
34 #include <unistd.h>
35 
36 #include <sys/ioctl.h>
37 #ifdef HAVE_TERMIOS_H /* For tty-password */
38 # include <termios.h>
39 # define TERMIO struct termios
40 #else
41 # ifdef HAVE_TERMIO_H /* For tty-password */
42 # include <termio.h>
43 # define TERMIO struct termio
44 # else
45 # include <sgtty.h>
46 # define TERMIO struct sgttyb
47 # endif
48 #endif
49 
50 using namespace std;
51 
52 bool tty_password= false;
53 const std::string PASSWORD_SENTINEL("\0\0\0\0\0", 5);
54 
55 /*
56  Can't use fgets, because readline will get confused
57  length is max number of chars in to, not counting \0
58  to will not include the eol characters.
59 */
60 
61 static void get_password(char *to, uint32_t length,int fd, bool echo)
62 {
63  char *pos=to,*end=to+length;
64 
65  for (;;)
66  {
67  char tmp;
68  if (read(fd,&tmp,1) != 1)
69  break;
70  if (tmp == '\b' || (int) tmp == 127)
71  {
72  if (pos != to)
73  {
74  if (echo)
75  {
76  fputs("\b \b",stderr);
77  fflush(stderr);
78  }
79  pos--;
80  continue;
81  }
82  }
83  if (tmp == '\n' || tmp == '\r' || tmp == 3)
84  break;
85  if (iscntrl(tmp) || pos == end)
86  continue;
87  *(pos++) = tmp;
88  }
89  while (pos != to && isspace(pos[-1]) == ' ')
90  pos--; /* Allow dummy space at end */
91  *pos=0;
92  return;
93 }
94 
95 
96 char *client_get_tty_password(const char *opt_message)
97 {
98  TERMIO org,tmp;
99  char buff[80];
100 
101  if (isatty(fileno(stderr)))
102  {
103  fputs(opt_message ? opt_message : "Enter password: ",stderr);
104  fflush(stderr);
105  }
106 # if defined(HAVE_TERMIOS_H)
107  tcgetattr(fileno(stdin), &org);
108  tmp = org;
109  tmp.c_lflag &= ~(ECHO | ISIG | ICANON);
110  tmp.c_cc[VMIN] = 1;
111  tmp.c_cc[VTIME] = 0;
112  tcsetattr(fileno(stdin), TCSADRAIN, &tmp);
113  get_password(buff, sizeof(buff)-1, fileno(stdin), isatty(fileno(stderr)));
114  tcsetattr(fileno(stdin), TCSADRAIN, &org);
115 # elif defined(HAVE_TERMIO_H)
116  ioctl(fileno(stdin), (int) TCGETA, &org);
117  tmp=org;
118  tmp.c_lflag &= ~(ECHO | ISIG | ICANON);
119  tmp.c_cc[VMIN] = 1;
120  tmp.c_cc[VTIME]= 0;
121  ioctl(fileno(stdin),(int) TCSETA, &tmp);
122  get_password(buff,sizeof(buff)-1,fileno(stdin),isatty(fileno(stderr)));
123  ioctl(fileno(stdin),(int) TCSETA, &org);
124 # else
125  gtty(fileno(stdin), &org);
126  tmp=org;
127  tmp.sg_flags &= ~ECHO;
128  tmp.sg_flags |= RAW;
129  stty(fileno(stdin), &tmp);
130  get_password(buff,sizeof(buff)-1,fileno(stdin),isatty(fileno(stderr)));
131  stty(fileno(stdin), &org);
132 # endif
133  if (isatty(fileno(stderr)))
134  fputc('\n',stderr);
135 
136  return strdup(buff);
137 }
138 
139 pair<string, string> parse_password_arg(string s)
140 {
141  if (s.find("--password") == 0)
142  {
143  if (s == "--password")
144  {
145  tty_password= true;
146  //check if no argument is passed.
147  return make_pair("password", PASSWORD_SENTINEL);
148  }
149 
150  if (s.substr(10,3) == "=\"\"" || s.substr(10,3) == "=''")
151  {
152  // Check if --password="" or --password=''
153  return make_pair("password", PASSWORD_SENTINEL);
154  }
155 
156  if(s.substr(10) == "=" && s.length() == 11)
157  {
158  // check if --password= and return a default value
159  return make_pair("password", PASSWORD_SENTINEL);
160  }
161  }
162 
163  else if (s.find("-P") == 0)
164  {
165  if (s == "-P")
166  {
167  tty_password= true;
168  //check if no argument is passed.
169  return make_pair("password", PASSWORD_SENTINEL);
170  }
171 
172  if (s.substr(2,2) == "\"\"" || s.substr(2,2) == "''")
173  {
174  // Check if -P"" or -P''
175  return make_pair("password", PASSWORD_SENTINEL);
176  }
177  }
178  return make_pair(string(""), string(""));
179 }
180