You've already forked mariadb-connector-c
mirror of
https://github.com/mariadb-corporation/mariadb-connector-c.git
synced 2025-08-07 02:42:49 +03:00
- 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
This commit is contained in:
@@ -76,7 +76,7 @@ SET(BIN_INSTALL_DIR_DEFAULT "bin")
|
|||||||
SET(LIB_INSTALL_DIR_DEFAULT "lib")
|
SET(LIB_INSTALL_DIR_DEFAULT "lib")
|
||||||
SET(INCLUDE_INSTALL_DIR_DEFAULT "include")
|
SET(INCLUDE_INSTALL_DIR_DEFAULT "include")
|
||||||
SET(DOCS_INSTALL_DIR_DEFAULT "docs")
|
SET(DOCS_INSTALL_DIR_DEFAULT "docs")
|
||||||
SET(LIB_INSTALL_PLUGIN_DIR_DEFAULT "lib/plugins")
|
SET(PLUGIN_INSTALL_DIR_DEFAULT "lib/plugin")
|
||||||
|
|
||||||
#
|
#
|
||||||
# RPM layout
|
# RPM layout
|
||||||
@@ -85,15 +85,15 @@ SET(SUFFIX_INSTALL_DIR_RPM "mariadb")
|
|||||||
SET(BIN_INSTALL_DIR_RPM "bin")
|
SET(BIN_INSTALL_DIR_RPM "bin")
|
||||||
IF(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64")
|
IF(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64")
|
||||||
SET(LIB_INSTALL_DIR_RPM "lib64")
|
SET(LIB_INSTALL_DIR_RPM "lib64")
|
||||||
SET(LIB_INSTALL_PLUGINDIR_RPM "lib64/plugins")
|
SET(PLUGIN_INSTALL_DIRDIR_RPM "lib64/plugin")
|
||||||
ELSE()
|
ELSE()
|
||||||
SET(LIB_INSTALL_DIR_RPM "lib")
|
SET(LIB_INSTALL_DIR_RPM "lib")
|
||||||
SET(LIB_INSTALL_PLUGINDIR_RPM "lib/plugins")
|
SET(PLUGIN_INSTALL_DIRDIR_RPM "lib/plugin")
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
SET(INCLUDE_INSTALL_DIR_RPM "include")
|
SET(INCLUDE_INSTALL_DIR_RPM "include")
|
||||||
SET(DOCS_INSTALL_DIR_RPM "docs")
|
SET(DOCS_INSTALL_DIR_RPM "docs")
|
||||||
SET(LIB_INSTALL_PLUGIN_DIR_RPM "lib/plugins")
|
SET(PLUGIN_INSTALL_DIR_RPM "lib/plugin")
|
||||||
|
|
||||||
#
|
#
|
||||||
# Overwrite defaults
|
# Overwrite defaults
|
||||||
@@ -102,6 +102,10 @@ IF(LIB_INSTALL_DIR)
|
|||||||
SET(LIB_INSTALL_DIR_${INSTALL_LAYOUT} ${LIB_INSTALL_DIR})
|
SET(LIB_INSTALL_DIR_${INSTALL_LAYOUT} ${LIB_INSTALL_DIR})
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
|
IF(PLUGIN_INSTALL_DIR)
|
||||||
|
SET(PLUGIN_INSTALL_DIR_${INSTALL_LAYOUT} ${PLUGIN_INSTALL_DIR})
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
IF(INCLUDE_INSTALL_DIR)
|
IF(INCLUDE_INSTALL_DIR)
|
||||||
SET(INCLUDE_INSTALL_DIR_${INSTALL_LAYOUT} ${INCLUDE_INSTALL_DIR})
|
SET(INCLUDE_INSTALL_DIR_${INSTALL_LAYOUT} ${INCLUDE_INSTALL_DIR})
|
||||||
ENDIF()
|
ENDIF()
|
||||||
@@ -118,7 +122,7 @@ IF(NOT SUFFIX_INSTALL_DIR)
|
|||||||
SET(SUFFIX_INSTALL_DIR_${INSTALL_LAYOUT} "mariadb")
|
SET(SUFFIX_INSTALL_DIR_${INSTALL_LAYOUT} "mariadb")
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
FOREACH(dir "BIN" "LIB" "INCLUDE" "DOCS" "PREFIX" "SUFFIX")
|
FOREACH(dir "BIN" "LIB" "INCLUDE" "DOCS" "PREFIX" "SUFFIX" "PLUGIN")
|
||||||
SET(${dir}_INSTALL_DIR ${${dir}_INSTALL_DIR_${INSTALL_LAYOUT}})
|
SET(${dir}_INSTALL_DIR ${${dir}_INSTALL_DIR_${INSTALL_LAYOUT}})
|
||||||
MARK_AS_ADVANCED(${dir}_INSTALL_DIR)
|
MARK_AS_ADVANCED(${dir}_INSTALL_DIR)
|
||||||
ENDFOREACH()
|
ENDFOREACH()
|
||||||
|
@@ -274,5 +274,5 @@
|
|||||||
#cmakedefine HAVE_THREADS 1
|
#cmakedefine HAVE_THREADS 1
|
||||||
#cmakedefine SHAREDIR "@SHAREDIR@"
|
#cmakedefine SHAREDIR "@SHAREDIR@"
|
||||||
#cmakedefine DEFAULT_CHARSET_HOME "@DEFAULT_CHARSET_HOME@"
|
#cmakedefine DEFAULT_CHARSET_HOME "@DEFAULT_CHARSET_HOME@"
|
||||||
#cmakedefine PLUGINDIR "@PLUGINDIR@"
|
#cmakedefine PLUGINDIR "@PREFIX_INSTALL_DIR@/@PLUGIN_INSTALL_DIR@"
|
||||||
|
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
/* Copyright (C) 2010 - 2012 Sergei Golubchik and Monty Program Ab
|
/* Copyright (C) 2010 - 2012 Sergei Golubchik and Monty Program Ab
|
||||||
|
2014 MariaDB Corporation AB
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
This library is free software; you can redistribute it and/or
|
||||||
modify it under the terms of the GNU Library General Public
|
modify it under the terms of the GNU Library General Public
|
||||||
|
@@ -175,6 +175,7 @@ enum enum_server_command
|
|||||||
CLIENT_PROGRESS |\
|
CLIENT_PROGRESS |\
|
||||||
CLIENT_SSL_VERIFY_SERVER_CERT |\
|
CLIENT_SSL_VERIFY_SERVER_CERT |\
|
||||||
CLIENT_REMEMBER_OPTIONS |\
|
CLIENT_REMEMBER_OPTIONS |\
|
||||||
|
CLIENT_PLUGIN_AUTH |\
|
||||||
CLIENT_CONNECT_ATTRS)
|
CLIENT_CONNECT_ATTRS)
|
||||||
|
|
||||||
#define CLIENT_CAPABILITIES (CLIENT_LONG_PASSWORD |\
|
#define CLIENT_CAPABILITIES (CLIENT_LONG_PASSWORD |\
|
||||||
@@ -384,7 +385,6 @@ char *scramble_323(char *to,const char *message,const char *password);
|
|||||||
void my_scramble_41(const unsigned char *buffer, const char *scramble, const char *password);
|
void my_scramble_41(const unsigned char *buffer, const char *scramble, const char *password);
|
||||||
my_bool check_scramble(const char *, const char *message,
|
my_bool check_scramble(const char *, const char *message,
|
||||||
unsigned long *salt,my_bool old_ver);
|
unsigned long *salt,my_bool old_ver);
|
||||||
char *get_tty_password(char *opt_message);
|
|
||||||
void hash_password(unsigned long *result, const char *password, size_t len);
|
void hash_password(unsigned long *result, const char *password, size_t len);
|
||||||
|
|
||||||
/* Some other useful functions */
|
/* Some other useful functions */
|
||||||
|
@@ -346,6 +346,7 @@ mysql_load_plugin_v(MYSQL *mysql, const char *name, int type,
|
|||||||
char dlpath[FN_REFLEN+1];
|
char dlpath[FN_REFLEN+1];
|
||||||
void *sym, *dlhandle;
|
void *sym, *dlhandle;
|
||||||
struct st_mysql_client_plugin *plugin;
|
struct st_mysql_client_plugin *plugin;
|
||||||
|
char *env_plugin_dir= getenv("MARIADB_PLUGIN_DIR");
|
||||||
|
|
||||||
if (is_not_initialized(mysql, name))
|
if (is_not_initialized(mysql, name))
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -362,7 +363,8 @@ mysql_load_plugin_v(MYSQL *mysql, const char *name, int type,
|
|||||||
/* Compile dll path */
|
/* Compile dll path */
|
||||||
strxnmov(dlpath, sizeof(dlpath) - 1,
|
strxnmov(dlpath, sizeof(dlpath) - 1,
|
||||||
mysql->options.extension && mysql->options.extension->plugin_dir ?
|
mysql->options.extension && mysql->options.extension->plugin_dir ?
|
||||||
mysql->options.extension->plugin_dir : PLUGINDIR, "/",
|
mysql->options.extension->plugin_dir : (env_plugin_dir) ? env_plugin_dir :
|
||||||
|
PLUGINDIR, "/",
|
||||||
name, SO_EXT, NullS);
|
name, SO_EXT, NullS);
|
||||||
|
|
||||||
/* Open new dll handle */
|
/* Open new dll handle */
|
||||||
|
@@ -63,42 +63,82 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined( _WIN32) || defined(OS2)
|
#if defined( _WIN32) || defined(OS2)
|
||||||
/* were just going to fake it here and get input from the keyboard */
|
/* {{{ statuc char* get_password */
|
||||||
|
/*
|
||||||
|
reads password from tty/console
|
||||||
|
|
||||||
char *get_tty_password(char *opt_message)
|
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)
|
||||||
{
|
{
|
||||||
char to[80];
|
#ifdef _WIN32
|
||||||
char *pos=to,*end=to+sizeof(to)-1;
|
DWORD SaveState;
|
||||||
int i=0;
|
HANDLE Hdl;
|
||||||
DBUG_ENTER("get_tty_password");
|
int Offset= 0;
|
||||||
fprintf(stdout,opt_message ? opt_message : "Enter password: ");
|
DWORD CharsProcessed= 0;
|
||||||
for (;;)
|
char inChar;
|
||||||
|
|
||||||
|
ZeroMemory(buffer, length);
|
||||||
|
|
||||||
|
if (!(Hdl= CreateFile("CONIN$",
|
||||||
|
GENERIC_READ | GENERIC_WRITE,
|
||||||
|
FILE_SHARE_READ,
|
||||||
|
NULL,
|
||||||
|
OPEN_EXISTING, 0, NULL)))
|
||||||
{
|
{
|
||||||
char tmp;
|
/* todo: provide a graphical dialog */
|
||||||
tmp=_getch();
|
return buffer;
|
||||||
if (tmp == '\b' || (int) tmp == 127)
|
|
||||||
{
|
|
||||||
if (pos != to)
|
|
||||||
{
|
|
||||||
_cputs("\b \b");
|
|
||||||
pos--;
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
}
|
/* Save ConsoleMode and set ENABLE_PROCESSED_INPUT:
|
||||||
if (tmp == '\n' || tmp == '\r' || tmp == 3)
|
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;
|
break;
|
||||||
if (iscntrl(tmp) || pos == end)
|
|
||||||
continue;
|
|
||||||
_cputs("*");
|
|
||||||
*(pos++) = tmp;
|
|
||||||
}
|
|
||||||
while (pos != to && isspace(pos[-1]) == ' ')
|
|
||||||
pos--; /* Allow dummy space at end */
|
|
||||||
*pos=0;
|
|
||||||
_cputs("\n");
|
|
||||||
DBUG_RETURN(my_strdup(to,MYF(MY_FAE)));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
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
|
#else
|
||||||
|
|
||||||
|
|
||||||
@@ -150,14 +190,13 @@ static void get_password(char *to,uint length,int fd,bool echo)
|
|||||||
#endif /* ! HAVE_GETPASS */
|
#endif /* ! HAVE_GETPASS */
|
||||||
|
|
||||||
|
|
||||||
char *get_tty_password(char *opt_message)
|
char *get_tty_password(char *opt_message, char *buff, int bufflen)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_GETPASS
|
#ifdef HAVE_GETPASS
|
||||||
char *passbuff;
|
char *passbuff;
|
||||||
#else /* ! HAVE_GETPASS */
|
#else /* ! HAVE_GETPASS */
|
||||||
TERMIO org,tmp;
|
TERMIO org,tmp;
|
||||||
#endif /* HAVE_GETPASS */
|
#endif /* HAVE_GETPASS */
|
||||||
char buff[80];
|
|
||||||
|
|
||||||
DBUG_ENTER("get_tty_password");
|
DBUG_ENTER("get_tty_password");
|
||||||
|
|
||||||
@@ -165,7 +204,7 @@ char *get_tty_password(char *opt_message)
|
|||||||
passbuff = getpass(opt_message ? opt_message : "Enter password: ");
|
passbuff = getpass(opt_message ? opt_message : "Enter password: ");
|
||||||
|
|
||||||
/* copy the password to buff and clear original (static) buffer */
|
/* copy the password to buff and clear original (static) buffer */
|
||||||
strnmov(buff, passbuff, sizeof(buff) - 1);
|
strnmov(buff, passbuff, bufflen - 1);
|
||||||
#ifdef _PASSWORD_LEN
|
#ifdef _PASSWORD_LEN
|
||||||
memset(passbuff, 0, _PASSWORD_LEN);
|
memset(passbuff, 0, _PASSWORD_LEN);
|
||||||
#endif
|
#endif
|
||||||
@@ -182,7 +221,7 @@ char *get_tty_password(char *opt_message)
|
|||||||
tmp.c_cc[VMIN] = 1;
|
tmp.c_cc[VMIN] = 1;
|
||||||
tmp.c_cc[VTIME] = 0;
|
tmp.c_cc[VTIME] = 0;
|
||||||
tcsetattr(fileno(stdin), TCSADRAIN, &tmp);
|
tcsetattr(fileno(stdin), TCSADRAIN, &tmp);
|
||||||
get_password(buff, sizeof(buff)-1, fileno(stdin), isatty(fileno(stdout)));
|
get_password(buff, bufflen-1, fileno(stdin), isatty(fileno(stdout)));
|
||||||
tcsetattr(fileno(stdin), TCSADRAIN, &org);
|
tcsetattr(fileno(stdin), TCSADRAIN, &org);
|
||||||
#elif defined(HAVE_TERMIO_H)
|
#elif defined(HAVE_TERMIO_H)
|
||||||
ioctl(fileno(stdin), (int) TCGETA, &org);
|
ioctl(fileno(stdin), (int) TCGETA, &org);
|
||||||
@@ -191,7 +230,7 @@ char *get_tty_password(char *opt_message)
|
|||||||
tmp.c_cc[VMIN] = 1;
|
tmp.c_cc[VMIN] = 1;
|
||||||
tmp.c_cc[VTIME]= 0;
|
tmp.c_cc[VTIME]= 0;
|
||||||
ioctl(fileno(stdin),(int) TCSETA, &tmp);
|
ioctl(fileno(stdin),(int) TCSETA, &tmp);
|
||||||
get_password(buff,sizeof(buff)-1,fileno(stdin),isatty(fileno(stdout)));
|
get_password(buff,bufflen-1,fileno(stdin),isatty(fileno(stdout)));
|
||||||
ioctl(fileno(stdin),(int) TCSETA, &org);
|
ioctl(fileno(stdin),(int) TCSETA, &org);
|
||||||
#else
|
#else
|
||||||
gtty(fileno(stdin), &org);
|
gtty(fileno(stdin), &org);
|
||||||
@@ -199,13 +238,13 @@ char *get_tty_password(char *opt_message)
|
|||||||
tmp.sg_flags &= ~ECHO;
|
tmp.sg_flags &= ~ECHO;
|
||||||
tmp.sg_flags |= RAW;
|
tmp.sg_flags |= RAW;
|
||||||
stty(fileno(stdin), &tmp);
|
stty(fileno(stdin), &tmp);
|
||||||
get_password(buff,sizeof(buff)-1,fileno(stdin),isatty(fileno(stdout)));
|
get_password(buff,bufflen-1,fileno(stdin),isatty(fileno(stdout)));
|
||||||
stty(fileno(stdin), &org);
|
stty(fileno(stdin), &org);
|
||||||
#endif
|
#endif
|
||||||
if (isatty(fileno(stdout)))
|
if (isatty(fileno(stdout)))
|
||||||
fputc('\n',stdout);
|
fputc('\n',stdout);
|
||||||
#endif /* HAVE_GETPASS */
|
#endif /* HAVE_GETPASS */
|
||||||
|
|
||||||
DBUG_RETURN(my_strdup(buff,MYF(MY_FAE)));
|
DBUG_RETURN(buff);
|
||||||
}
|
}
|
||||||
#endif /*_WIN32*/
|
#endif /*_WIN32*/
|
||||||
|
@@ -8,6 +8,7 @@
|
|||||||
"@extra_dynamic_LDFLAGS@"
|
"@extra_dynamic_LDFLAGS@"
|
||||||
#define CFLAGS INCLUDE " @CMAKE_C_FLAGS@"
|
#define CFLAGS INCLUDE " @CMAKE_C_FLAGS@"
|
||||||
#define VERSION "@MYSQL_CLIENT_VERSION@"
|
#define VERSION "@MYSQL_CLIENT_VERSION@"
|
||||||
|
#define PLUGIN_DIR "@PREFIX_INSTALL_DIR@/@PLUGIN_INSTALL_DIR@"
|
||||||
#define SOCKET "@MYSQL_UNIX_ADDR@"
|
#define SOCKET "@MYSQL_UNIX_ADDR@"
|
||||||
#define PORT "@MYSQL_PORT@"
|
#define PORT "@MYSQL_PORT@"
|
||||||
|
|
||||||
@@ -21,6 +22,7 @@ static struct option long_options[]=
|
|||||||
{"version", no_argument, 0, 'f'},
|
{"version", no_argument, 0, 'f'},
|
||||||
{"socket", no_argument, 0, 'g'},
|
{"socket", no_argument, 0, 'g'},
|
||||||
{"port", no_argument, 0, 'h'},
|
{"port", no_argument, 0, 'h'},
|
||||||
|
{"plugindir", no_argument, 0, 'p'},
|
||||||
{NULL, 0, 0, 0}
|
{NULL, 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -33,7 +35,8 @@ static char *values[]=
|
|||||||
LIBS,
|
LIBS,
|
||||||
VERSION,
|
VERSION,
|
||||||
SOCKET,
|
SOCKET,
|
||||||
PORT
|
PORT,
|
||||||
|
PLUGIN_DIR
|
||||||
};
|
};
|
||||||
|
|
||||||
void usage(void)
|
void usage(void)
|
||||||
@@ -90,6 +93,9 @@ int main(int argc, char **argv)
|
|||||||
case 'h':
|
case 'h':
|
||||||
puts(PORT);
|
puts(PORT);
|
||||||
break;
|
break;
|
||||||
|
case 'p':
|
||||||
|
puts(PLUGINDIR);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
13
plugins/auth/CMakeLists.txt
Normal file
13
plugins/auth/CMakeLists.txt
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
# Dialog plugin
|
||||||
|
SET(DIALOG_SOURCES dialog.c ${CMAKE_SOURCE_DIR}/libmariadb/get_password.c)
|
||||||
|
IF(WIN32)
|
||||||
|
SET(DIALOG_SOURCES ${DIALOG_SOURCES} ${CMAKE_SOURCE_DIR}/plugins/plugin.def)
|
||||||
|
ENDIF()
|
||||||
|
ADD_LIBRARY(dialog SHARED ${DIALOG_SOURCES})
|
||||||
|
SET_TARGET_PROPERTIES(dialog PROPERTIES PREFIX "")
|
||||||
|
|
||||||
|
INSTALL(TARGETS
|
||||||
|
dialog
|
||||||
|
RUNTIME DESTINATION "${PLUGIN_INSTALL_DIR}"
|
||||||
|
LIBRARY DESTINATION "${PLUGIN_INSTALL_DIR}"
|
||||||
|
ARCHIVE DESTINATION "${PLUGIN_INSTALL_DIR}")
|
218
plugins/auth/dialog.c
Normal file
218
plugins/auth/dialog.c
Normal file
@@ -0,0 +1,218 @@
|
|||||||
|
/************************************************************************************
|
||||||
|
Copyright (C) 2014 MariaDB Corporation 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 see <http://www.gnu.org/licenses>
|
||||||
|
or write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin St., Fifth Floor, Boston, MA 02110, USA
|
||||||
|
|
||||||
|
Part of this code includes code from the PHP project which
|
||||||
|
is freely available from http://www.php.net
|
||||||
|
*************************************************************************************/
|
||||||
|
#ifndef _WIN32
|
||||||
|
#define _GNU_SOURCE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <my_global.h>
|
||||||
|
#include <mysql.h>
|
||||||
|
#include <mysql/client_plugin.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <memory.h>
|
||||||
|
|
||||||
|
#ifndef WIN32
|
||||||
|
#include <dlfcn.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* function prototypes */
|
||||||
|
extern char *get_tty_password(char *opt_message, char *buff, int bufflen);
|
||||||
|
static int auth_dialog_open(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql);
|
||||||
|
static int auth_dialog_init(char *unused1,
|
||||||
|
size_t unused2,
|
||||||
|
int unused3,
|
||||||
|
va_list);
|
||||||
|
|
||||||
|
mysql_authentication_dialog_ask_t auth_dialog_func;
|
||||||
|
|
||||||
|
mysql_declare_client_plugin(AUTHENTICATION)
|
||||||
|
"dialog",
|
||||||
|
"Sergei Golubchik, Georg Richter",
|
||||||
|
"Dialog Client Authentication Plugin",
|
||||||
|
{0,1,0},
|
||||||
|
auth_dialog_init,
|
||||||
|
NULL,
|
||||||
|
auth_dialog_open
|
||||||
|
mysql_end_client_plugin;
|
||||||
|
|
||||||
|
|
||||||
|
/* {{{ static char *auth_dialog_native_prompt */
|
||||||
|
/*
|
||||||
|
Native dialog prompt via stdin
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
auth_dialog_native_prompt
|
||||||
|
mysql connection handle
|
||||||
|
type input type
|
||||||
|
prompt prompt
|
||||||
|
buffer Input buffer
|
||||||
|
buffer_len Input buffer length
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
|
||||||
|
RETURNS
|
||||||
|
Input buffer
|
||||||
|
*/
|
||||||
|
static char *auth_dialog_native_prompt(MYSQL *mysql,
|
||||||
|
int type,
|
||||||
|
const char *prompt,
|
||||||
|
char *buffer,
|
||||||
|
int buffer_len)
|
||||||
|
{
|
||||||
|
/* display prompt */
|
||||||
|
fprintf(stdout, "%s", prompt);
|
||||||
|
|
||||||
|
memset(buffer, 0, buffer_len);
|
||||||
|
|
||||||
|
/* for type 2 (password) don't display input */
|
||||||
|
if (type != 2)
|
||||||
|
{
|
||||||
|
if (fgets(buffer, buffer_len - 1, stdin))
|
||||||
|
{
|
||||||
|
/* remove trailing line break */
|
||||||
|
size_t length= strlen(buffer);
|
||||||
|
if (length && buffer[length - 1] == '\n')
|
||||||
|
buffer[length - 1]= 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
get_tty_password("", buffer, buffer_len - 1);
|
||||||
|
}
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
/* }}} */
|
||||||
|
|
||||||
|
/* {{{ static int auth_dialog_open */
|
||||||
|
/*
|
||||||
|
opens dialog
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
vio Vio
|
||||||
|
mysql connection handle
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
reads prompt from server, waits for input and sends
|
||||||
|
input to server.
|
||||||
|
Note that first byte of prompt indicates if we have a
|
||||||
|
password which should not be echoed to stdout.
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
CR_ERROR if an error occurs
|
||||||
|
CR_OK
|
||||||
|
CR_OK_HANDSHAKE_COMPLETE
|
||||||
|
*/
|
||||||
|
static int auth_dialog_open(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql)
|
||||||
|
{
|
||||||
|
uchar *packet;
|
||||||
|
uchar type;
|
||||||
|
char dialog_buffer[1024];
|
||||||
|
char *response;
|
||||||
|
size_t packet_length;
|
||||||
|
my_bool first_loop= TRUE;
|
||||||
|
|
||||||
|
do {
|
||||||
|
if ((packet_length= vio->read_packet(vio, &packet)) < 0)
|
||||||
|
/* read error */
|
||||||
|
return CR_ERROR;
|
||||||
|
|
||||||
|
if (packet_length > 0)
|
||||||
|
{
|
||||||
|
type= *packet;
|
||||||
|
packet++;
|
||||||
|
|
||||||
|
/* check for protocol packet */
|
||||||
|
if (!type || type == 254)
|
||||||
|
return CR_OK_HANDSHAKE_COMPLETE;
|
||||||
|
|
||||||
|
/* shift one bit */
|
||||||
|
type= type >> 1;
|
||||||
|
|
||||||
|
if (type == 2 &&
|
||||||
|
first_loop &&
|
||||||
|
mysql->passwd && mysql->passwd[0])
|
||||||
|
response= mysql->passwd;
|
||||||
|
else
|
||||||
|
response= auth_dialog_func(mysql, type,
|
||||||
|
(const char *)packet,
|
||||||
|
dialog_buffer, 1024);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* in case mysql_change_user was called the client needs
|
||||||
|
to send packet first */
|
||||||
|
response= mysql->passwd;
|
||||||
|
}
|
||||||
|
if (!response ||
|
||||||
|
vio->write_packet(vio, response, strlen(response) + 1))
|
||||||
|
return CR_ERROR;
|
||||||
|
|
||||||
|
first_loop= FALSE;
|
||||||
|
|
||||||
|
} while(type != 2);
|
||||||
|
return CR_OK;
|
||||||
|
}
|
||||||
|
/* }}} */
|
||||||
|
|
||||||
|
/* {{{ static int auth_dialog_init */
|
||||||
|
/*
|
||||||
|
Initialization routine
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
auth_dialog_init
|
||||||
|
unused1
|
||||||
|
unused2
|
||||||
|
unused3
|
||||||
|
unused4
|
||||||
|
|
||||||
|
DESCRIPTION
|
||||||
|
Init function checks if the caller provides own dialog function.
|
||||||
|
The function name must be mariadb_auth_dialog or
|
||||||
|
mysql_authentication_dialog_ask. If the function cannot be found,
|
||||||
|
we will use owr own simple command line input.
|
||||||
|
|
||||||
|
RETURN
|
||||||
|
0 success
|
||||||
|
*/
|
||||||
|
static int auth_dialog_init(char *unused1 __attribute__((unused)),
|
||||||
|
size_t unused2 __attribute__((unused)),
|
||||||
|
int unused3 __attribute__((unused)),
|
||||||
|
va_list unused4 __attribute__((unused)))
|
||||||
|
{
|
||||||
|
void *func;
|
||||||
|
#ifdef WIN32
|
||||||
|
if (!(func= GetProcAddress(GetModuleHandle(NULL), "mariadb_auth_dialog")))
|
||||||
|
/* for MySQL users */
|
||||||
|
func= GetProcAddress(GetModuleHandle(NULL), "mysql_authentication_dialog_ask");
|
||||||
|
#else
|
||||||
|
if (!(func= dlsym(RTLD_DEFAULT, "mariadb_auth_dialog")))
|
||||||
|
/* for MySQL users */
|
||||||
|
func= dlsym(RTLD_DEFAULT, "mysql_authentication_dialog_ask");
|
||||||
|
#endif
|
||||||
|
if (func)
|
||||||
|
auth_dialog_func= (mysql_authentication_dialog_ask_t)func;
|
||||||
|
else
|
||||||
|
auth_dialog_func= auth_dialog_native_prompt;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* }}} */
|
2
plugins/plugin.def
Normal file
2
plugins/plugin.def
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
EXPORTS
|
||||||
|
_mysql_client_plugin_declaration_ DATA
|
@@ -38,8 +38,13 @@ IF (WITH_SIGNCODE)
|
|||||||
COMMAND signtool sign ${SIGN_OPTIONS} ${CLIENT_DBG_DIR}/libmariadb.lib)
|
COMMAND signtool sign ${SIGN_OPTIONS} ${CLIENT_DBG_DIR}/libmariadb.lib)
|
||||||
EXECUTE_PROCESS(
|
EXECUTE_PROCESS(
|
||||||
COMMAND signtool sign ${SIGN_OPTIONS} ${CLIENT_DBG_DIR}/mariadbclient.lib)
|
COMMAND signtool sign ${SIGN_OPTIONS} ${CLIENT_DBG_DIR}/mariadbclient.lib)
|
||||||
|
EXECUTE_PROCESS(
|
||||||
|
COMMAND signtool sign ${SIGN_OPTIONS} ${CMAKE_BINARY_DIR}/plugins/auth/${CMAKE_BUILD_TYPE}/dialog.dll)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
|
SET(MARIADB_PLUGINS "${MARIADB_PLUGINS} <File Id=\"dialog.dll\" Name=\"dialog.dll\" DiskId=\"1\" Source=\"${CMAKE_BINARY_DIR}/plugins/auth/${CMAKE_BUILD_TYPE}/dialog.dll\"/>\n")
|
||||||
|
|
||||||
|
|
||||||
FOREACH(src ${MARIADB_CLIENT_INCLUDES})
|
FOREACH(src ${MARIADB_CLIENT_INCLUDES})
|
||||||
STRING(REPLACE "-" "_" src_id ${src})
|
STRING(REPLACE "-" "_" src_id ${src})
|
||||||
SET(MARIADB_INCLUDE_FILES "${MARIADB_INCLUDE_FILES} <File Id=\"${src_id}\" Name=\"${src}\" DiskId=\"1\" Source=\"${CMAKE_SOURCE_DIR}/include/${src}\"/>\n")
|
SET(MARIADB_INCLUDE_FILES "${MARIADB_INCLUDE_FILES} <File Id=\"${src_id}\" Name=\"${src}\" DiskId=\"1\" Source=\"${CMAKE_SOURCE_DIR}/include/${src}\"/>\n")
|
||||||
|
@@ -33,6 +33,7 @@
|
|||||||
<Directory Id="INSTALLFOLDER" Name="@PRODUCT_NAME@" >
|
<Directory Id="INSTALLFOLDER" Name="@PRODUCT_NAME@" >
|
||||||
<Directory Id="instlib" Name="lib">
|
<Directory Id="instlib" Name="lib">
|
||||||
<Directory Id="instlib_debug" Name="debug"/>
|
<Directory Id="instlib_debug" Name="debug"/>
|
||||||
|
<Directory Id="instlib_plugin" Name="plugin"/>
|
||||||
</Directory>
|
</Directory>
|
||||||
<Directory Id="instinclude" Name="include" />
|
<Directory Id="instinclude" Name="include" />
|
||||||
</Directory>
|
</Directory>
|
||||||
@@ -58,6 +59,9 @@
|
|||||||
<File Id="dlibdllimp" Name="libmariadb.lib" DiskId="1" Source="@CLIENT_DBG_DIR@/libmariadb.lib" />
|
<File Id="dlibdllimp" Name="libmariadb.lib" DiskId="1" Source="@CLIENT_DBG_DIR@/libmariadb.lib" />
|
||||||
<File Id="dlibstatic" Name="mariadbclient.lib" DiskId="1" Source="@CLIENT_DBG_DIR@/mariadbclient.lib" />
|
<File Id="dlibstatic" Name="mariadbclient.lib" DiskId="1" Source="@CLIENT_DBG_DIR@/mariadbclient.lib" />
|
||||||
</Component>
|
</Component>
|
||||||
|
<Component Id="Plugins" Guid="" KeyPath="yes" DiskId="1" Directory="instlib_plugin" Win64="@IS_WIN64@">
|
||||||
|
@MARIADB_PLUGINS@
|
||||||
|
</Component>
|
||||||
<Component Id="Debug" Guid="FFAFCCCC-4E0C-4A87-840C-53B63C8A427A" KeyPath="yes" Directory="instlib" DiskId="1" Win64="@IS_WIN64@">
|
<Component Id="Debug" Guid="FFAFCCCC-4E0C-4A87-840C-53B63C8A427A" KeyPath="yes" Directory="instlib" DiskId="1" Win64="@IS_WIN64@">
|
||||||
<File Id="libdllpdb" Name="libmariadb.pdb" DiskId="1" Source="@CLIENT_LIB_DIR@/libmariadb.pdb" />
|
<File Id="libdllpdb" Name="libmariadb.pdb" DiskId="1" Source="@CLIENT_LIB_DIR@/libmariadb.pdb" />
|
||||||
<File Id="libstaticpdb" Name="mariadbclient.pdb" DiskId="1" Source="@CLIENT_LIB_DIR@/mariadbclient.pdb" />
|
<File Id="libstaticpdb" Name="mariadbclient.pdb" DiskId="1" Source="@CLIENT_LIB_DIR@/mariadbclient.pdb" />
|
||||||
|
Reference in New Issue
Block a user