Commit 9f072780 authored by Harin Vadodaria's avatar Harin Vadodaria

Bug#11753779: MAX_CONNECT_ERRORS WORKS ONLY WHEN 1ST

              INC_HOST_ERRORS() IS CALLED.

Issue       : Sequence of calling inc_host_errors()
              and reset_host_errors() required some
              changes in order to maintain correct
              connection error count.

Solution    : Call to reset_host_errors() is shifted
              to a location after which no calls to
              inc_host_errors() are made.
parent 4bfeb52d
...@@ -214,6 +214,15 @@ char * ip_to_hostname(struct in_addr *in, uint *errors) ...@@ -214,6 +214,15 @@ char * ip_to_hostname(struct in_addr *in, uint *errors)
} }
my_gethostbyname_r_free(); my_gethostbyname_r_free();
#else #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)); VOID(pthread_mutex_lock(&LOCK_hostname));
if (!(hp=gethostbyaddr((char*) in,sizeof(*in), AF_INET))) if (!(hp=gethostbyaddr((char*) in,sizeof(*in), AF_INET)))
{ {
......
...@@ -336,6 +336,7 @@ check_user(THD *thd, enum enum_server_command command, ...@@ -336,6 +336,7 @@ check_user(THD *thd, enum enum_server_command command,
USER_RESOURCES ur; USER_RESOURCES ur;
int res= acl_getroot(thd, &ur, passwd, passwd_len); int res= acl_getroot(thd, &ur, passwd, passwd_len);
DBUG_EXECUTE_IF("password_format_mismatch",{res= -1;};);
#ifndef EMBEDDED_LIBRARY #ifndef EMBEDDED_LIBRARY
if (res == -1) if (res == -1)
{ {
...@@ -346,6 +347,12 @@ check_user(THD *thd, enum enum_server_command command, ...@@ -346,6 +347,12 @@ check_user(THD *thd, enum enum_server_command command,
in old format. in old format.
*/ */
NET *net= &thd->net; 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) if (opt_secure_auth_local)
{ {
my_error(ER_SERVER_IS_IN_SECURE_AUTH_MODE, MYF(0), my_error(ER_SERVER_IS_IN_SECURE_AUTH_MODE, MYF(0),
...@@ -816,6 +823,8 @@ static int check_connection(THD *thd) ...@@ -816,6 +823,8 @@ static int check_connection(THD *thd)
size_t passwd_len; size_t passwd_len;
char *user; char *user;
size_t user_len; size_t user_len;
uint charset_code= 0;
size_t bytes_remaining_in_packet= 0;
DBUG_PRINT("info", DBUG_PRINT("info",
("New connection received on %s", vio_description(net->vio))); ("New connection received on %s", vio_description(net->vio)));
...@@ -832,6 +841,19 @@ static int check_connection(THD *thd) ...@@ -832,6 +841,19 @@ static int check_connection(THD *thd)
my_error(ER_BAD_HOST_ERROR, MYF(0)); my_error(ER_BAD_HOST_ERROR, MYF(0));
return 1; 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)))) if (!(thd->main_security_ctx.ip= my_strdup(ip,MYF(MY_WME))))
return 1; /* The error is set by my_strdup(). */ return 1; /* The error is set by my_strdup(). */
thd->main_security_ctx.host_or_ip= thd->main_security_ctx.ip; thd->main_security_ctx.host_or_ip= thd->main_security_ctx.ip;
...@@ -927,32 +949,31 @@ static int check_connection(THD *thd) ...@@ -927,32 +949,31 @@ static int check_connection(THD *thd)
(uchar*) buff, (size_t) (end-buff)) || (uchar*) buff, (size_t) (end-buff)) ||
(pkt_len= my_net_read(net)) == packet_error) (pkt_len= my_net_read(net)) == packet_error)
{ {
inc_host_errors(&thd->remote.sin_addr); goto error;
my_error(ER_HANDSHAKE_ERROR, MYF(0));
return 1;
} }
} }
#ifdef _CUSTOMCONFIG_ #ifdef _CUSTOMCONFIG_
#include "_cust_sql_parse.h" #include "_cust_sql_parse.h"
#endif #endif
if (connect_errors)
reset_host_errors(&thd->remote.sin_addr);
if (thd->packet.alloc(thd->variables.net_buffer_length)) if (thd->packet.alloc(thd->variables.net_buffer_length))
return 1; /* The error is set by alloc(). */ return 1; /* The error is set by alloc(). */
uint charset_code= 0;
end= (char *)net->read_pos; end= (char *)net->read_pos;
/* /*
In order to safely scan a head for '\0' string terminators In order to safely scan a head for '\0' string terminators
we must keep track of how many bytes remain in the allocated we must keep track of how many bytes remain in the allocated
buffer or we might read past the end of the buffer. 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 Peek ahead on the client capability packet and determine which version of
the protocol should be used. the protocol should be used.
*/ */
DBUG_EXECUTE_IF("host_error_packet_length",
{
bytes_remaining_in_packet= 0;
};);
if (bytes_remaining_in_packet < 2) if (bytes_remaining_in_packet < 2)
goto error; goto error;
...@@ -1011,6 +1032,10 @@ static int check_connection(THD *thd) ...@@ -1011,6 +1032,10 @@ static int check_connection(THD *thd)
skip_to_ssl: skip_to_ssl:
DBUG_EXECUTE_IF("host_error_charset",
{
goto error;
};);
DBUG_PRINT("info", ("client_character_set: %u", charset_code)); DBUG_PRINT("info", ("client_character_set: %u", charset_code));
if (thd_init_client_charset(thd, charset_code)) if (thd_init_client_charset(thd, charset_code))
goto error; goto error;
...@@ -1079,6 +1104,10 @@ skip_to_ssl: ...@@ -1079,6 +1104,10 @@ skip_to_ssl:
bytes_remaining_in_packet -= AUTH_PACKET_HEADER_SIZE_PROTO_40; 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) if (!packet_has_required_size)
goto error; goto error;
} }
...@@ -1104,6 +1133,11 @@ skip_to_ssl: ...@@ -1104,6 +1133,11 @@ skip_to_ssl:
get_string= get_40_protocol_string; get_string= get_40_protocol_string;
user= get_string(&end, &bytes_remaining_in_packet, &user_len); user= get_string(&end, &bytes_remaining_in_packet, &user_len);
DBUG_EXECUTE_IF("host_error_user",
{
user= NULL;
};);
if (user == NULL) if (user == NULL)
goto error; goto error;
...@@ -1131,6 +1165,11 @@ skip_to_ssl: ...@@ -1131,6 +1165,11 @@ skip_to_ssl:
passwd= get_string(&end, &bytes_remaining_in_packet, &passwd_len); passwd= get_string(&end, &bytes_remaining_in_packet, &passwd_len);
} }
DBUG_EXECUTE_IF("host_error_password",
{
passwd= NULL;
};);
if (passwd == NULL) if (passwd == NULL)
goto error; goto error;
...@@ -1191,7 +1230,20 @@ skip_to_ssl: ...@@ -1191,7 +1230,20 @@ skip_to_ssl:
if (!(thd->main_security_ctx.user= my_strdup(user, MYF(MY_WME)))) if (!(thd->main_security_ctx.user= my_strdup(user, MYF(MY_WME))))
return 1; /* The error is set by my_strdup(). */ 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: error:
inc_host_errors(&thd->remote.sin_addr); inc_host_errors(&thd->remote.sin_addr);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment