summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/hostname.cc9
-rw-r--r--sql/sql_connect.cc68
2 files changed, 69 insertions, 8 deletions
diff --git a/sql/hostname.cc b/sql/hostname.cc
index 9796755e9fb..38316a8ee19 100644
--- a/sql/hostname.cc
+++ b/sql/hostname.cc
@@ -214,6 +214,15 @@ char * ip_to_hostname(struct in_addr *in, uint *errors)
}
my_gethostbyname_r_free();
#else
+
+ DBUG_EXECUTE_IF("addr_fake_ipv4",
+ {
+ const char* fake_host= "santa.claus.ipv4.example.com";
+ name=my_strdup(fake_host, MYF(0));
+ add_hostname(in,name);
+ DBUG_RETURN(name);
+ };);
+
VOID(pthread_mutex_lock(&LOCK_hostname));
if (!(hp=gethostbyaddr((char*) in,sizeof(*in), AF_INET)))
{
diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc
index 21e2701d06c..e7aa48c94f5 100644
--- a/sql/sql_connect.cc
+++ b/sql/sql_connect.cc
@@ -336,6 +336,7 @@ check_user(THD *thd, enum enum_server_command command,
USER_RESOURCES ur;
int res= acl_getroot(thd, &ur, passwd, passwd_len);
+ DBUG_EXECUTE_IF("password_format_mismatch",{res= -1;};);
#ifndef EMBEDDED_LIBRARY
if (res == -1)
{
@@ -346,6 +347,12 @@ check_user(THD *thd, enum enum_server_command command,
in old format.
*/
NET *net= &thd->net;
+ DBUG_EXECUTE_IF("password_format_mismatch",
+ {
+ inc_host_errors(&thd->remote.sin_addr);
+ my_error(ER_HANDSHAKE_ERROR, MYF(0));
+ DBUG_RETURN(1);
+ };);
if (opt_secure_auth_local)
{
my_error(ER_SERVER_IS_IN_SECURE_AUTH_MODE, MYF(0),
@@ -816,6 +823,8 @@ static int check_connection(THD *thd)
size_t passwd_len;
char *user;
size_t user_len;
+ uint charset_code= 0;
+ size_t bytes_remaining_in_packet= 0;
DBUG_PRINT("info",
("New connection received on %s", vio_description(net->vio)));
@@ -832,6 +841,19 @@ static int check_connection(THD *thd)
my_error(ER_BAD_HOST_ERROR, MYF(0));
return 1;
}
+ /* BEGIN : DEBUG */
+ DBUG_EXECUTE_IF("addr_fake_ipv4",
+ {
+ struct sockaddr *sa= (sockaddr *) &net->vio->remote;
+ sa->sa_family= AF_INET;
+ struct in_addr *ip4= &((struct sockaddr_in *)sa)->sin_addr;
+ /* See RFC 5737, 192.0.2.0/23 is reserved */
+ const char* fake= "192.0.2.4";
+ ip4->s_addr= inet_addr(fake);
+ strcpy(ip, fake);
+ };);
+ /* END : DEBUG */
+
if (!(thd->main_security_ctx.ip= my_strdup(ip,MYF(MY_WME))))
return 1; /* The error is set by my_strdup(). */
thd->main_security_ctx.host_or_ip= thd->main_security_ctx.ip;
@@ -927,32 +949,31 @@ static int check_connection(THD *thd)
(uchar*) buff, (size_t) (end-buff)) ||
(pkt_len= my_net_read(net)) == packet_error)
{
- inc_host_errors(&thd->remote.sin_addr);
- my_error(ER_HANDSHAKE_ERROR, MYF(0));
- return 1;
+ goto error;
}
}
#ifdef _CUSTOMCONFIG_
#include "_cust_sql_parse.h"
#endif
- if (connect_errors)
- reset_host_errors(&thd->remote.sin_addr);
if (thd->packet.alloc(thd->variables.net_buffer_length))
return 1; /* The error is set by alloc(). */
- uint charset_code= 0;
end= (char *)net->read_pos;
/*
In order to safely scan a head for '\0' string terminators
we must keep track of how many bytes remain in the allocated
buffer or we might read past the end of the buffer.
*/
- size_t bytes_remaining_in_packet= pkt_len;
+ bytes_remaining_in_packet= pkt_len;
/*
Peek ahead on the client capability packet and determine which version of
the protocol should be used.
*/
+ DBUG_EXECUTE_IF("host_error_packet_length",
+ {
+ bytes_remaining_in_packet= 0;
+ };);
if (bytes_remaining_in_packet < 2)
goto error;
@@ -1011,6 +1032,10 @@ static int check_connection(THD *thd)
skip_to_ssl:
+ DBUG_EXECUTE_IF("host_error_charset",
+ {
+ goto error;
+ };);
DBUG_PRINT("info", ("client_character_set: %u", charset_code));
if (thd_init_client_charset(thd, charset_code))
goto error;
@@ -1079,6 +1104,10 @@ skip_to_ssl:
bytes_remaining_in_packet -= AUTH_PACKET_HEADER_SIZE_PROTO_40;
}
+ DBUG_EXECUTE_IF("host_error_SSL_layering",
+ {
+ packet_has_required_size= 0;
+ };);
if (!packet_has_required_size)
goto error;
}
@@ -1104,6 +1133,11 @@ skip_to_ssl:
get_string= get_40_protocol_string;
user= get_string(&end, &bytes_remaining_in_packet, &user_len);
+ DBUG_EXECUTE_IF("host_error_user",
+ {
+ user= NULL;
+ };);
+
if (user == NULL)
goto error;
@@ -1131,6 +1165,11 @@ skip_to_ssl:
passwd= get_string(&end, &bytes_remaining_in_packet, &passwd_len);
}
+ DBUG_EXECUTE_IF("host_error_password",
+ {
+ passwd= NULL;
+ };);
+
if (passwd == NULL)
goto error;
@@ -1191,7 +1230,20 @@ skip_to_ssl:
if (!(thd->main_security_ctx.user= my_strdup(user, MYF(MY_WME))))
return 1; /* The error is set by my_strdup(). */
- return check_user(thd, COM_CONNECT, passwd, passwd_len, db, TRUE);
+
+ if (!check_user(thd, COM_CONNECT, passwd, passwd_len, db, TRUE))
+ {
+ /*
+ Call to reset_host_errors() should be made only when all sanity checks
+ are done and connection is going to be a successful.
+ */
+ reset_host_errors(&thd->remote.sin_addr);
+ return 0;
+ }
+ else
+ {
+ return 1;
+ }
error:
inc_host_errors(&thd->remote.sin_addr);