Files
mariadb-connector-c/libmariadb/get_password.c
Georg Richter cd16280a3f - mysql_load_plugin_v supports now the environment variable MARIADB_PLUGIN_DIR
to load plugins from a different destination than PLUGINDIR.

- added dialog plugin for authentication (e.g. PAM). If an application provides
  it's own dialog function, the name must be mariadb_auth_dialog (or for libmysql
  compatibility mysql_authentication_dialog_ask).
  Windows-Todo: 
  1. provide a simple GUI dialog on windows, in case opening the console failed.
  2. convert data from console code page to character set of current connection
2014-12-11 09:47:49 +01:00

251 lines
6.0 KiB
C

/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA */
/*
** Ask for a password from tty
** This is an own file to avoid conflicts with curses
*/
#include <my_global.h>
#include <my_sys.h>
#include "mysql.h"
#include <m_string.h>
#include <m_ctype.h>
#include <dbug.h>
#if defined(HAVE_BROKEN_GETPASS) && !defined(HAVE_GETPASSPHRASE)
#undef HAVE_GETPASS
#endif
#ifdef HAVE_GETPASS
#ifdef HAVE_PWD_H
#include <pwd.h>
#endif /* HAVE_PWD_H */
#else /* ! HAVE_GETPASS */
#if !defined( _WIN32) && !defined(OS2)
#include <sys/ioctl.h>
#ifdef HAVE_TERMIOS_H /* For tty-password */
#include <termios.h>
#define TERMIO struct termios
#else
#ifdef HAVE_TERMIO_H /* For tty-password */
#include <termio.h>
#define TERMIO struct termio
#else
#include <sgtty.h>
#define TERMIO struct sgttyb
#endif
#endif
#ifdef alpha_linux_port
#include <asm/ioctls.h> /* QQ; Fix this in configure */
#include <asm/termiobits.h>
#endif
#else
#include <conio.h>
#endif /* _WIN32 */
#endif /* HAVE_GETPASS */
#ifdef HAVE_GETPASSPHRASE /* For Solaris */
#define getpass(A) getpassphrase(A)
#endif
#if defined( _WIN32) || defined(OS2)
/* {{{ statuc char* get_password */
/*
reads password from tty/console
SYNOPSIS
get_password()
buffer input buffer
length length of input buffer
DESCRIPTION
reads a password from console (Windows) or tty without echoing
it's characters. Input buffer must be allocated by calling function.
RETURNS
buffer pointer to input buffer
*/
char* get_tty_password(char *prompt, char *buffer, int length)
{
#ifdef _WIN32
DWORD SaveState;
HANDLE Hdl;
int Offset= 0;
DWORD CharsProcessed= 0;
char inChar;
ZeroMemory(buffer, length);
if (!(Hdl= CreateFile("CONIN$",
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING, 0, NULL)))
{
/* todo: provide a graphical dialog */
return buffer;
}
/* Save ConsoleMode and set ENABLE_PROCESSED_INPUT:
CTRL+C is processed by the system and is not placed in the input buffer */
GetConsoleMode(Hdl, &SaveState);
SetConsoleMode(Hdl, ENABLE_PROCESSED_INPUT);
do
{
if (!ReadConsole(Hdl, &inChar, 1, &CharsProcessed, NULL) ||
!CharsProcessed)
break;
switch(inChar) {
case '\b': /* backslash */
if (Offset)
{
/* cursor is always at the end */
Offset--;
buffer[Offset]= 0;
_cputs("\b \b");
}
break;
case '\n':
case '\r':
break;
default:
buffer[Offset]= inChar;
if (Offset < length - 2)
Offset++;
_cputs("*");
break;
}
} while (CharsProcessed && inChar != '\n' && inChar != '\r');
SetConsoleMode(Hdl, SaveState);
CloseHandle(Hdl);
return buffer;
#else
#endif
}
/* }}} */
#else
#ifndef HAVE_GETPASS
/*
** Can't use fgets, because readline will get confused
** length is max number of chars in to, not counting \0
* to will not include the eol characters.
*/
static void get_password(char *to,uint length,int fd,bool echo)
{
char *pos=to,*end=to+length;
for (;;)
{
char tmp;
if (my_read(fd,&tmp,1,MYF(0)) != 1)
break;
if (tmp == '\b' || (int) tmp == 127)
{
if (pos != to)
{
if (echo)
{
fputs("\b \b",stdout);
fflush(stdout);
}
pos--;
continue;
}
}
if (tmp == '\n' || tmp == '\r' || tmp == 3)
break;
if (iscntrl(tmp) || pos == end)
continue;
if (echo)
{
fputc('*',stdout);
fflush(stdout);
}
*(pos++) = tmp;
}
while (pos != to && isspace(pos[-1]) == ' ')
pos--; /* Allow dummy space at end */
*pos=0;
return;
}
#endif /* ! HAVE_GETPASS */
char *get_tty_password(char *opt_message, char *buff, int bufflen)
{
#ifdef HAVE_GETPASS
char *passbuff;
#else /* ! HAVE_GETPASS */
TERMIO org,tmp;
#endif /* HAVE_GETPASS */
DBUG_ENTER("get_tty_password");
#ifdef HAVE_GETPASS
passbuff = getpass(opt_message ? opt_message : "Enter password: ");
/* copy the password to buff and clear original (static) buffer */
strnmov(buff, passbuff, bufflen - 1);
#ifdef _PASSWORD_LEN
memset(passbuff, 0, _PASSWORD_LEN);
#endif
#else
if (isatty(fileno(stdout)))
{
fputs(opt_message ? opt_message : "Enter password: ",stdout);
fflush(stdout);
}
#if defined(HAVE_TERMIOS_H)
tcgetattr(fileno(stdin), &org);
tmp = org;
tmp.c_lflag &= ~(ECHO | ISIG | ICANON);
tmp.c_cc[VMIN] = 1;
tmp.c_cc[VTIME] = 0;
tcsetattr(fileno(stdin), TCSADRAIN, &tmp);
get_password(buff, bufflen-1, fileno(stdin), isatty(fileno(stdout)));
tcsetattr(fileno(stdin), TCSADRAIN, &org);
#elif defined(HAVE_TERMIO_H)
ioctl(fileno(stdin), (int) TCGETA, &org);
tmp=org;
tmp.c_lflag &= ~(ECHO | ISIG | ICANON);
tmp.c_cc[VMIN] = 1;
tmp.c_cc[VTIME]= 0;
ioctl(fileno(stdin),(int) TCSETA, &tmp);
get_password(buff,bufflen-1,fileno(stdin),isatty(fileno(stdout)));
ioctl(fileno(stdin),(int) TCSETA, &org);
#else
gtty(fileno(stdin), &org);
tmp=org;
tmp.sg_flags &= ~ECHO;
tmp.sg_flags |= RAW;
stty(fileno(stdin), &tmp);
get_password(buff,bufflen-1,fileno(stdin),isatty(fileno(stdout)));
stty(fileno(stdin), &org);
#endif
if (isatty(fileno(stdout)))
fputc('\n',stdout);
#endif /* HAVE_GETPASS */
DBUG_RETURN(buff);
}
#endif /*_WIN32*/