summaryrefslogtreecommitdiff
path: root/sql-common/client.c
diff options
context:
space:
mode:
Diffstat (limited to 'sql-common/client.c')
-rw-r--r--sql-common/client.c314
1 files changed, 241 insertions, 73 deletions
diff --git a/sql-common/client.c b/sql-common/client.c
index 6b5f04f2bff..21f41e4da0b 100644
--- a/sql-common/client.c
+++ b/sql-common/client.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2003 MySQL AB
+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -24,7 +24,6 @@
mysql_real_connect()
- Support for reading local file with LOAD DATA LOCAL
- SHARED memory handling
- - Protection against sigpipe
- Prepared statements
- Things that only works for the server
@@ -70,9 +69,9 @@ my_bool net_flush(NET *net);
#include "mysqld_error.h"
#include "errmsg.h"
#include <violite.h>
-#if defined(THREAD) && !defined(__WIN__)
+#if !defined(__WIN__)
#include <my_pthread.h> /* because of signal() */
-#endif /* defined(THREAD) && !defined(__WIN__) */
+#endif /* !defined(__WIN__) */
#include <sys/stat.h>
#include <signal.h>
@@ -287,7 +286,7 @@ static int wait_for_data(my_socket fd, uint timeout)
{
tv.tv_sec = (long) timeout;
tv.tv_usec = 0;
-#if defined(HPUX10) && defined(THREAD)
+#if defined(HPUX10)
if ((res = select(fd+1, NULL, (int*) &sfds, NULL, &tv)) > 0)
break;
#else
@@ -731,13 +730,9 @@ cli_safe_read(MYSQL *mysql)
{
NET *net= &mysql->net;
ulong len=0;
- init_sigpipe_variables
- /* Don't give sigpipe errors if the client doesn't want them */
- set_sigpipe(mysql);
if (net->vio != 0)
len=my_net_read(net);
- reset_sigpipe(mysql);
if (len == packet_error || len == 0)
{
@@ -817,13 +812,9 @@ cli_advanced_command(MYSQL *mysql, enum enum_server_command command,
{
NET *net= &mysql->net;
my_bool result= 1;
- init_sigpipe_variables
my_bool stmt_skip= stmt ? stmt->state != MYSQL_STMT_INIT_DONE : FALSE;
DBUG_ENTER("cli_advanced_command");
- /* Don't give sigpipe errors if the client doesn't want them */
- set_sigpipe(mysql);
-
if (mysql->net.vio == 0)
{ /* Do reconnect if possible */
if (mysql_reconnect(mysql) || stmt_skip)
@@ -872,7 +863,6 @@ cli_advanced_command(MYSQL *mysql, enum enum_server_command command,
result= ((mysql->packet_length=cli_safe_read(mysql)) == packet_error ?
1 : 0);
end:
- reset_sigpipe(mysql);
DBUG_PRINT("exit",("result: %d", result));
DBUG_RETURN(result);
}
@@ -1089,14 +1079,11 @@ void end_server(MYSQL *mysql)
DBUG_ENTER("end_server");
if (mysql->net.vio != 0)
{
- init_sigpipe_variables
DBUG_PRINT("info",("Net: %s", vio_description(mysql->net.vio)));
#ifdef MYSQL_SERVER
slave_io_thread_detach_vio();
#endif
- set_sigpipe(mysql);
vio_delete(mysql->net.vio);
- reset_sigpipe(mysql);
mysql->net.vio= 0; /* Marker */
mysql_prune_stmt_list(mysql);
}
@@ -1161,6 +1148,7 @@ enum option_id {
OPT_ssl_cipher, OPT_max_allowed_packet, OPT_protocol, OPT_shared_memory_base_name,
OPT_multi_results, OPT_multi_statements, OPT_multi_queries, OPT_secure_auth,
OPT_report_data_truncation, OPT_plugin_dir, OPT_default_auth,
+ OPT_keep_this_one_last
};
static TYPELIB option_types={array_elements(default_options)-1,
@@ -1192,7 +1180,7 @@ static int add_init_command(struct st_mysql_options *options, const char *cmd)
return 0;
}
-#define extension_set_string(OPTS, X, STR) \
+#define EXTENSION_SET_STRING(OPTS, X, STR) \
if ((OPTS)->extension) \
my_free((OPTS)->extension->X); \
else \
@@ -1210,6 +1198,9 @@ void mysql_read_default_options(struct st_mysql_options *options,
DBUG_ENTER("mysql_read_default_options");
DBUG_PRINT("enter",("file: %s group: %s",filename,group ? group :"NULL"));
+ compile_time_assert(OPT_keep_this_one_last ==
+ array_elements(default_options));
+
argc=1; argv=argv_buff; argv_buff[0]= (char*) "client";
groups[0]= (char*) "client"; groups[1]= (char*) group; groups[2]=0;
@@ -1219,7 +1210,7 @@ void mysql_read_default_options(struct st_mysql_options *options,
char **option=argv;
while (*++option)
{
- if (option[0] == args_separator) /* skip arguments separator */
+ if (my_getopt_is_args_separator(option[0])) /* skip arguments separator */
continue;
/* DBUG_PRINT("info",("option: %s",option[0])); */
if (option[0][0] == '-' && option[0][1] == '-')
@@ -1234,7 +1225,7 @@ void mysql_read_default_options(struct st_mysql_options *options,
/* Change all '_' in variable name to '-' */
for (end= *option ; *(end= strcend(end,'_')) ; )
*end= '-';
- switch (find_type(*option+2,&option_types,2)) {
+ switch (find_type(*option + 2, &option_types, FIND_TYPE_BASIC)) {
case OPT_port:
if (opt_arg)
options->port=atoi(opt_arg);
@@ -1250,7 +1241,7 @@ void mysql_read_default_options(struct st_mysql_options *options,
options->compress=1;
options->client_flag|= CLIENT_COMPRESS;
break;
- case OPT_password:
+ case OPT_password:
if (opt_arg)
{
my_free(options->password);
@@ -1296,7 +1287,7 @@ void mysql_read_default_options(struct st_mysql_options *options,
case OPT_return_found_rows:
options->client_flag|=CLIENT_FOUND_ROWS;
break;
-#ifdef HAVE_OPENSSL
+#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
case OPT_ssl_key:
my_free(options->ssl_key);
options->ssl_key = my_strdup(opt_arg, MYF(MY_WME));
@@ -1324,8 +1315,8 @@ void mysql_read_default_options(struct st_mysql_options *options,
case OPT_ssl_capath:
case OPT_ssl_cipher:
break;
-#endif /* HAVE_OPENSSL */
- case OPT_character_sets_dir:
+#endif /* HAVE_OPENSSL && !EMBEDDED_LIBRARY */
+ case OPT_character_sets_dir:
my_free(options->charset_dir);
options->charset_dir = my_strdup(opt_arg, MYF(MY_WME));
break;
@@ -1350,8 +1341,8 @@ void mysql_read_default_options(struct st_mysql_options *options,
options->max_allowed_packet= atoi(opt_arg);
break;
case OPT_protocol:
- if ((options->protocol= find_type(opt_arg,
- &sql_protocol_typelib,0)) <= 0)
+ if ((options->protocol= find_type(opt_arg, &sql_protocol_typelib,
+ FIND_TYPE_BASIC)) <= 0)
{
fprintf(stderr, "Unknown option to protocol: %s\n", opt_arg);
exit(1);
@@ -1378,10 +1369,22 @@ void mysql_read_default_options(struct st_mysql_options *options,
options->report_data_truncation= opt_arg ? test(atoi(opt_arg)) : 1;
break;
case OPT_plugin_dir:
- extension_set_string(options, plugin_dir, opt_arg);
+ {
+ char buff[FN_REFLEN], buff2[FN_REFLEN];
+ if (strlen(opt_arg) >= FN_REFLEN)
+ opt_arg[FN_REFLEN]= '\0';
+ if (my_realpath(buff, opt_arg, 0))
+ {
+ DBUG_PRINT("warning",("failed to normalize the plugin path: %s",
+ opt_arg));
+ break;
+ }
+ convert_dirname(buff, buff2, NULL);
+ EXTENSION_SET_STRING(options, plugin_dir, buff2);
+ }
break;
case OPT_default_auth:
- extension_set_string(options, default_auth, opt_arg);
+ EXTENSION_SET_STRING(options, default_auth, opt_arg);
break;
default:
DBUG_PRINT("warning",("unknown option: %s",option[0]));
@@ -1842,6 +1845,8 @@ mysql_get_ssl_cipher(MYSQL *mysql __attribute__((unused)))
ssl_verify_server_cert()
vio pointer to a SSL connected vio
server_hostname name of the server that we connected to
+ errptr if we fail, we'll return (a pointer to a string
+ describing) the reason here
RETURN VALUES
0 Success
@@ -1851,7 +1856,7 @@ mysql_get_ssl_cipher(MYSQL *mysql __attribute__((unused)))
#if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY)
-static int ssl_verify_server_cert(Vio *vio, const char* server_hostname)
+static int ssl_verify_server_cert(Vio *vio, const char* server_hostname, const char **errptr)
{
SSL *ssl;
X509 *server_cert;
@@ -1862,19 +1867,19 @@ static int ssl_verify_server_cert(Vio *vio, const char* server_hostname)
if (!(ssl= (SSL*)vio->ssl_arg))
{
- DBUG_PRINT("error", ("No SSL pointer found"));
+ *errptr= "No SSL pointer found";
DBUG_RETURN(1);
}
if (!server_hostname)
{
- DBUG_PRINT("error", ("No server hostname supplied"));
+ *errptr= "No server hostname supplied";
DBUG_RETURN(1);
}
if (!(server_cert= SSL_get_peer_certificate(ssl)))
{
- DBUG_PRINT("error", ("Could not get server certificate"));
+ *errptr= "Could not get server certificate";
DBUG_RETURN(1);
}
@@ -1903,7 +1908,7 @@ static int ssl_verify_server_cert(Vio *vio, const char* server_hostname)
DBUG_RETURN(0);
}
}
- DBUG_PRINT("error", ("SSL certificate validation failure"));
+ *errptr= "SSL certificate validation failure";
DBUG_RETURN(1);
}
@@ -2266,6 +2271,7 @@ typedef struct st_mysql_client_plugin_AUTHENTICATION auth_plugin_t;
static int client_mpvio_write_packet(struct st_plugin_vio*, const uchar*, int);
static int native_password_auth_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql);
static int old_password_auth_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql);
+static int clear_password_auth_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql);
static auth_plugin_t native_password_client_plugin=
{
@@ -2275,6 +2281,9 @@ static auth_plugin_t native_password_client_plugin=
"R.J.Silk, Sergei Golubchik",
"Native MySQL authentication",
{1, 0, 0},
+ "GPL",
+ NULL,
+ NULL,
NULL,
NULL,
native_password_auth_client
@@ -2288,15 +2297,42 @@ static auth_plugin_t old_password_client_plugin=
"R.J.Silk, Sergei Golubchik",
"Old MySQL-3.23 authentication",
{1, 0, 0},
+ "GPL",
+ NULL,
+ NULL,
NULL,
NULL,
old_password_auth_client
};
+static auth_plugin_t clear_password_client_plugin=
+{
+ MYSQL_CLIENT_AUTHENTICATION_PLUGIN,
+ MYSQL_CLIENT_AUTHENTICATION_PLUGIN_INTERFACE_VERSION,
+ "mysql_clear_password",
+ "Georgi Kodinov",
+ "Clear password authentication plugin",
+ {0,1,0},
+ "GPL",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ clear_password_auth_client
+};
+
+#ifdef AUTHENTICATION_WIN
+extern auth_plugin_t win_auth_client_plugin;
+#endif
+
struct st_mysql_client_plugin *mysql_client_builtins[]=
{
(struct st_mysql_client_plugin *)&native_password_client_plugin,
(struct st_mysql_client_plugin *)&old_password_client_plugin,
+ (struct st_mysql_client_plugin *)&clear_password_client_plugin,
+#ifdef AUTHENTICATION_WIN
+ (struct st_mysql_client_plugin *)&win_auth_client_plugin,
+#endif
0
};
@@ -2309,15 +2345,15 @@ typedef struct {
void (*info)(struct st_plugin_vio *vio, struct st_plugin_vio_info *info);
/* -= end of MYSQL_PLUGIN_VIO =- */
MYSQL *mysql;
- auth_plugin_t *plugin; /**< what plugin we're under */
+ auth_plugin_t *plugin; /**< what plugin we're under */
const char *db;
struct {
- uchar *pkt; /**< pointer into NET::buff */
+ uchar *pkt; /**< pointer into NET::buff */
uint pkt_len;
} cached_server_reply;
- uint packets_read, packets_written; /**< counters for send/received packets */
- my_bool mysql_change_user; /**< if it's mysql_change_user() */
- int last_read_packet_len; /**< the length of the last *read* packet */
+ int packets_read, packets_written; /**< counters for send/received packets */
+ int mysql_change_user; /**< if it's mysql_change_user() */
+ int last_read_packet_len; /**< the length of the last *read* packet */
} MCPVIO_EXT;
/**
@@ -2339,7 +2375,6 @@ typedef struct {
@retval 0 ok
@retval 1 error
*/
-
static int send_change_user_packet(MCPVIO_EXT *mpvio,
const uchar *data, int data_len)
{
@@ -2423,7 +2458,6 @@ error:
@retval 0 ok
@retval 1 error
*/
-
static int send_client_reply_packet(MCPVIO_EXT *mpvio,
const uchar *data, int data_len)
{
@@ -2481,7 +2515,9 @@ static int send_client_reply_packet(MCPVIO_EXT *mpvio,
/* Do the SSL layering. */
struct st_mysql_options *options= &mysql->options;
struct st_VioSSLFd *ssl_fd;
- char error_string[1024];
+ enum enum_ssl_init_error ssl_init_error;
+ const char *cert_error;
+ unsigned long ssl_error;
/*
Send mysql->client_flag, max_packet_size - unencrypted otherwise
@@ -2501,32 +2537,36 @@ static int send_client_reply_packet(MCPVIO_EXT *mpvio,
options->ssl_cert,
options->ssl_ca,
options->ssl_capath,
- options->ssl_cipher)))
+ options->ssl_cipher,
+ &ssl_init_error)))
{
- set_mysql_error(mysql, CR_SSL_CONNECTION_ERROR, unknown_sqlstate);
+ set_mysql_extended_error(mysql, CR_SSL_CONNECTION_ERROR, unknown_sqlstate,
+ ER(CR_SSL_CONNECTION_ERROR), sslGetErrString(ssl_init_error));
goto error;
}
- mysql->connector_fd= (void*)ssl_fd;
+ mysql->connector_fd= (unsigned char *) ssl_fd;
/* Connect to the server */
DBUG_PRINT("info", ("IO layer change in progress..."));
if (sslconnect(ssl_fd, net->vio,
- (long) (mysql->options.connect_timeout),
- error_string))
- {
- set_mysql_extended_error(mysql, CR_SSL_CONNECTION_ERROR,
- unknown_sqlstate, "SSL error: %s",
- error_string[0] ? error_string :
- ER(CR_SSL_CONNECTION_ERROR));
+ (long) (mysql->options.connect_timeout), &ssl_error))
+ {
+ char buf[512];
+ ERR_error_string_n(ssl_error, buf, 512);
+ buf[511]= 0;
+ set_mysql_extended_error(mysql, CR_SSL_CONNECTION_ERROR, unknown_sqlstate,
+ ER(CR_SSL_CONNECTION_ERROR),
+ buf);
goto error;
}
DBUG_PRINT("info", ("IO layer change done!"));
/* Verify server cert */
if ((mysql->client_flag & CLIENT_SSL_VERIFY_SERVER_CERT) &&
- ssl_verify_server_cert(net->vio, mysql->host))
+ ssl_verify_server_cert(net->vio, mysql->host, &cert_error))
{
- set_mysql_error(mysql, CR_SSL_CONNECTION_ERROR, unknown_sqlstate);
+ set_mysql_extended_error(mysql, CR_SSL_CONNECTION_ERROR, unknown_sqlstate,
+ ER(CR_SSL_CONNECTION_ERROR), cert_error);
goto error;
}
}
@@ -2599,7 +2639,6 @@ error:
This function is called by a client authentication plugin, when it wants
to read data from the server.
*/
-
static int client_mpvio_read_packet(struct st_plugin_vio *mpv, uchar **buf)
{
MCPVIO_EXT *mpvio= (MCPVIO_EXT*)mpv;
@@ -2662,7 +2701,6 @@ static int client_mpvio_read_packet(struct st_plugin_vio *mpv, uchar **buf)
It transparently wraps the data into a change user or authentication
handshake packet, if neccessary.
*/
-
static int client_mpvio_write_packet(struct st_plugin_vio *mpv,
const uchar *pkt, int pkt_len)
{
@@ -2698,7 +2736,6 @@ static int client_mpvio_write_packet(struct st_plugin_vio *mpv,
fills MYSQL_PLUGIN_VIO_INFO structure with the information about the
connection
*/
-
void mpvio_info(Vio *vio, MYSQL_PLUGIN_VIO_INFO *info)
{
bzero(info, sizeof(*info));
@@ -2729,7 +2766,9 @@ void mpvio_info(Vio *vio, MYSQL_PLUGIN_VIO_INFO *info)
return;
case VIO_TYPE_SHARED_MEMORY:
info->protocol= MYSQL_VIO_MEMORY;
+#ifdef HAVE_SMEM
info->handle= vio->handle_file_map; /* or what ? */
+#endif
return;
#endif
default: DBUG_ASSERT(0);
@@ -2761,7 +2800,6 @@ static void client_mpvio_info(MYSQL_PLUGIN_VIO *vio,
@retval 0 ok
@retval 1 error
*/
-
int run_plugin_auth(MYSQL *mysql, char *data, uint data_len,
const char *data_plugin, const char *db)
{
@@ -2771,6 +2809,7 @@ int run_plugin_auth(MYSQL *mysql, char *data, uint data_len,
ulong pkt_length;
int res;
+ DBUG_ENTER ("run_plugin_auth");
/* determine the default/initial plugin to use */
if (mysql->options.extension && mysql->options.extension->default_auth &&
mysql->server_capabilities & CLIENT_PLUGIN_AUTH)
@@ -2778,7 +2817,7 @@ int run_plugin_auth(MYSQL *mysql, char *data, uint data_len,
auth_plugin_name= mysql->options.extension->default_auth;
if (!(auth_plugin= (auth_plugin_t*) mysql_client_find_plugin(mysql,
auth_plugin_name, MYSQL_CLIENT_AUTHENTICATION_PLUGIN)))
- return 1; /* oops, not found */
+ DBUG_RETURN (1); /* oops, not found */
}
else
{
@@ -2787,6 +2826,8 @@ int run_plugin_auth(MYSQL *mysql, char *data, uint data_len,
auth_plugin_name= auth_plugin->name;
}
+ DBUG_PRINT ("info", ("using plugin %s", auth_plugin_name));
+
mysql->net.last_errno= 0; /* just in case */
if (data_plugin && strcmp(data_plugin, auth_plugin_name))
@@ -2808,6 +2849,11 @@ int run_plugin_auth(MYSQL *mysql, char *data, uint data_len,
mpvio.plugin= auth_plugin;
res= auth_plugin->authenticate_user((struct st_plugin_vio *)&mpvio, mysql);
+ DBUG_PRINT ("info", ("authenticate_user returned %s",
+ res == CR_OK ? "CR_OK" :
+ res == CR_ERROR ? "CR_ERROR" :
+ res == CR_OK_HANDSHAKE_COMPLETE ?
+ "CR_OK_HANDSHAKE_COMPLETE" : "error"));
compile_time_assert(CR_OK == -1);
compile_time_assert(CR_ERROR == 0);
@@ -2818,12 +2864,13 @@ int run_plugin_auth(MYSQL *mysql, char *data, uint data_len,
unless the error code is CR_ERROR and mysql->net.last_errno
is already set (the plugin has done it)
*/
+ DBUG_PRINT ("info", ("res=%d", res));
if (res > CR_ERROR)
set_mysql_error(mysql, res, unknown_sqlstate);
else
if (!mysql->net.last_errno)
set_mysql_error(mysql, CR_UNKNOWN_ERROR, unknown_sqlstate);
- return 1;
+ DBUG_RETURN (1);
}
/* read the OK packet (or use the cached value in mysql->net.read_pos */
@@ -2832,6 +2879,7 @@ int run_plugin_auth(MYSQL *mysql, char *data, uint data_len,
else /* res == CR_OK_HANDSHAKE_COMPLETE */
pkt_length= mpvio.last_read_packet_len;
+ DBUG_PRINT ("info", ("OK packet length=%lu", pkt_length));
if (pkt_length == packet_error)
{
if (mysql->net.last_errno == CR_SERVER_LOST)
@@ -2839,7 +2887,7 @@ int run_plugin_auth(MYSQL *mysql, char *data, uint data_len,
ER(CR_SERVER_LOST_EXTENDED),
"reading authorization packet",
errno);
- return 1;
+ DBUG_RETURN (1);
}
if (mysql->net.read_pos[0] == 254)
@@ -2848,6 +2896,7 @@ int run_plugin_auth(MYSQL *mysql, char *data, uint data_len,
if (pkt_length == 1)
{
/* old "use short scramble" packet */
+ DBUG_PRINT ("info", ("old use short scramble packet from server"));
auth_plugin_name= old_password_plugin_name;
mpvio.cached_server_reply.pkt= (uchar*)mysql->scramble;
mpvio.cached_server_reply.pkt_len= SCRAMBLE_LENGTH + 1;
@@ -2860,15 +2909,22 @@ int run_plugin_auth(MYSQL *mysql, char *data, uint data_len,
len= strlen(auth_plugin_name); /* safe as my_net_read always appends \0 */
mpvio.cached_server_reply.pkt_len= pkt_length - len - 2;
mpvio.cached_server_reply.pkt= mysql->net.read_pos + len + 2;
+ DBUG_PRINT ("info", ("change plugin packet from server for plugin %s",
+ auth_plugin_name));
}
if (!(auth_plugin= (auth_plugin_t *) mysql_client_find_plugin(mysql,
auth_plugin_name, MYSQL_CLIENT_AUTHENTICATION_PLUGIN)))
- return 1;
+ DBUG_RETURN (1);
mpvio.plugin= auth_plugin;
res= auth_plugin->authenticate_user((struct st_plugin_vio *)&mpvio, mysql);
+ DBUG_PRINT ("info", ("second authenticate_user returned %s",
+ res == CR_OK ? "CR_OK" :
+ res == CR_ERROR ? "CR_ERROR" :
+ res == CR_OK_HANDSHAKE_COMPLETE ?
+ "CR_OK_HANDSHAKE_COMPLETE" : "error"));
if (res > CR_OK)
{
if (res > CR_ERROR)
@@ -2876,7 +2932,7 @@ int run_plugin_auth(MYSQL *mysql, char *data, uint data_len,
else
if (!mysql->net.last_errno)
set_mysql_error(mysql, CR_UNKNOWN_ERROR, unknown_sqlstate);
- return 1;
+ DBUG_RETURN (1);
}
if (res != CR_OK_HANDSHAKE_COMPLETE)
@@ -2889,7 +2945,7 @@ int run_plugin_auth(MYSQL *mysql, char *data, uint data_len,
ER(CR_SERVER_LOST_EXTENDED),
"reading final connect information",
errno);
- return 1;
+ DBUG_RETURN (1);
}
}
}
@@ -2897,7 +2953,7 @@ int run_plugin_auth(MYSQL *mysql, char *data, uint data_len,
net->read_pos[0] should always be 0 here if the server implements
the protocol correctly
*/
- return mysql->net.read_pos[0] != 0;
+ DBUG_RETURN (mysql->net.read_pos[0] != 0);
}
@@ -2907,8 +2963,8 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
uint port, const char *unix_socket,ulong client_flag)
{
char buff[NAME_LEN+USERNAME_LENGTH+100];
- int scramble_data_len, pkt_scramble_len;
- char *end, *host_info=0, *server_version_end, *pkt_end;
+ int scramble_data_len, pkt_scramble_len= 0;
+ char *end,*host_info= 0, *server_version_end, *pkt_end;
char *scramble_data;
const char *scramble_plugin;
ulong pkt_length;
@@ -2923,7 +2979,6 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
#ifdef HAVE_SYS_UN_H
struct sockaddr_un UNIXaddr;
#endif
- init_sigpipe_variables
DBUG_ENTER("mysql_real_connect");
LINT_INIT(pkt_scramble_len);
@@ -2939,8 +2994,6 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
DBUG_RETURN(0);
}
- /* Don't give sigpipe errors if the client doesn't want them */
- set_sigpipe(mysql);
mysql->methods= &client_methods;
net->vio = 0; /* If something goes wrong */
mysql->client_flag=0; /* For handshake */
@@ -3451,11 +3504,9 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
#endif
DBUG_PRINT("exit", ("Mysql handler: 0x%lx", (long) mysql));
- reset_sigpipe(mysql);
DBUG_RETURN(mysql);
error:
- reset_sigpipe(mysql);
DBUG_PRINT("error",("message: %u/%s (%s)",
net->last_errno,
net->sqlstate,
@@ -4076,10 +4127,10 @@ mysql_options(MYSQL *mysql,enum mysql_option option, const void *arg)
mysql->options.client_flag&= ~CLIENT_SSL_VERIFY_SERVER_CERT;
break;
case MYSQL_PLUGIN_DIR:
- extension_set_string(&mysql->options, plugin_dir, arg);
+ EXTENSION_SET_STRING(&mysql->options, plugin_dir, arg);
break;
case MYSQL_DEFAULT_AUTH:
- extension_set_string(&mysql->options, default_auth, arg);
+ EXTENSION_SET_STRING(&mysql->options, default_auth, arg);
break;
default:
DBUG_RETURN(1);
@@ -4188,6 +4239,123 @@ int STDCALL mysql_set_character_set(MYSQL *mysql, const char *cs_name)
return mysql->net.last_errno;
}
+/**
+ client authentication plugin that does native MySQL authentication
+ using a 20-byte (4.1+) scramble
+*/
+static int native_password_auth_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql)
+{
+ int pkt_len;
+ uchar *pkt;
+
+ DBUG_ENTER("native_password_auth_client");
+
+
+ if (((MCPVIO_EXT *)vio)->mysql_change_user)
+ {
+ /*
+ in mysql_change_user() the client sends the first packet.
+ we use the old scramble.
+ */
+ pkt= (uchar*)mysql->scramble;
+ pkt_len= SCRAMBLE_LENGTH + 1;
+ }
+ else
+ {
+ /* read the scramble */
+ if ((pkt_len= vio->read_packet(vio, &pkt)) < 0)
+ DBUG_RETURN(CR_ERROR);
+
+ if (pkt_len != SCRAMBLE_LENGTH + 1)
+ DBUG_RETURN(CR_SERVER_HANDSHAKE_ERR);
+
+ /* save it in MYSQL */
+ memcpy(mysql->scramble, pkt, SCRAMBLE_LENGTH);
+ mysql->scramble[SCRAMBLE_LENGTH] = 0;
+ }
+
+ if (mysql->passwd[0])
+ {
+ char scrambled[SCRAMBLE_LENGTH + 1];
+ DBUG_PRINT("info", ("sending scramble"));
+ scramble(scrambled, (char*)pkt, mysql->passwd);
+ if (vio->write_packet(vio, (uchar*)scrambled, SCRAMBLE_LENGTH))
+ DBUG_RETURN(CR_ERROR);
+ }
+ else
+ {
+ DBUG_PRINT("info", ("no password"));
+ if (vio->write_packet(vio, 0, 0)) /* no password */
+ DBUG_RETURN(CR_ERROR);
+ }
+
+ DBUG_RETURN(CR_OK);
+}
+
+/**
+ client authentication plugin that does old MySQL authentication
+ using an 8-byte (4.0-) scramble
+*/
+static int old_password_auth_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql)
+{
+ uchar *pkt;
+ int pkt_len;
+
+ DBUG_ENTER("old_password_auth_client");
+
+ if (((MCPVIO_EXT *)vio)->mysql_change_user)
+ {
+ /*
+ in mysql_change_user() the client sends the first packet.
+ we use the old scramble.
+ */
+ pkt= (uchar*)mysql->scramble;
+ pkt_len= SCRAMBLE_LENGTH_323 + 1;
+ }
+ else
+ {
+ /* read the scramble */
+ if ((pkt_len= vio->read_packet(vio, &pkt)) < 0)
+ DBUG_RETURN(CR_ERROR);
+
+ if (pkt_len != SCRAMBLE_LENGTH_323 + 1 &&
+ pkt_len != SCRAMBLE_LENGTH + 1)
+ DBUG_RETURN(CR_SERVER_HANDSHAKE_ERR);
+
+ /* save it in MYSQL */
+ memcpy(mysql->scramble, pkt, pkt_len);
+ mysql->scramble[pkt_len] = 0;
+ }
+
+ if (mysql->passwd[0])
+ {
+ char scrambled[SCRAMBLE_LENGTH_323 + 1];
+ scramble_323(scrambled, (char*)pkt, mysql->passwd);
+ if (vio->write_packet(vio, (uchar*)scrambled, SCRAMBLE_LENGTH_323 + 1))
+ DBUG_RETURN(CR_ERROR);
+ }
+ else
+ if (vio->write_packet(vio, 0, 0)) /* no password */
+ DBUG_RETURN(CR_ERROR);
+
+ DBUG_RETURN(CR_OK);
+}
+
+/**
+ The main function of the mysql_clear_password authentication plugin.
+*/
+
+static int clear_password_auth_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql)
+{
+ int res;
+
+ /* send password in clear text */
+ res= vio->write_packet(vio, (const unsigned char *) mysql->passwd,
+ strlen(mysql->passwd) + 1);
+
+ return res ? CR_ERROR : CR_OK;
+}
+
/**
client authentication plugin that does native MySQL authentication