Skip to content

Commit

Permalink
A recent change in the server protocol code broke SSL connection for …
Browse files Browse the repository at this point in the history
…some client libraries.

Protocol documentation (http://forge.mysql.com/wiki/MySQL_Internals_ClientServer_Protocol)
says that initial packet sent by client if client wants SSL, consists of client capability flags only
(4 bytes or 2 bytes edependent on protocol versionl). 
Some clients happen to send more in the initial SSL packet (C client, Python connector), while others (Java, .NET) follow the docs and send only client capability flags.

A change that broke Java client was a newly introduced check that frst client packet
has 32 or more bytes. This is generally wrong, if client capability flags contains CLIENT_SSL.

Also, fixed the code such that read max client packet size and charset in the first packet prior to SSL handshake.  With SSL, clients do not have to send this info, they can only send client flags.

This is now fixed such that max packet size and charset are not read prior to SSL handshake, in case of SSL they are read from the "complete" client authentication packet after SSL initialization.
  • Loading branch information
vaintroub committed Feb 11, 2012
1 parent 125e22e commit b3e15f8
Showing 1 changed file with 21 additions and 14 deletions.
35 changes: 21 additions & 14 deletions sql/sql_connect.cc
Original file line number Diff line number Diff line change
Expand Up @@ -810,25 +810,12 @@ static int check_connection(THD *thd)
thd->client_capabilities= uint2korr(net->read_pos);
if (thd->client_capabilities & CLIENT_PROTOCOL_41)
{
if (pkt_len < 32)
if (pkt_len < 4)
goto error;

thd->client_capabilities|= ((ulong) uint2korr(net->read_pos+2)) << 16;
thd->max_client_packet_length= uint4korr(net->read_pos+4);
DBUG_PRINT("info", ("client_character_set: %d", (uint) net->read_pos[8]));
if (thd_init_client_charset(thd, (uint) net->read_pos[8]))
return 1;
thd->update_charset();
end= (char*) net->read_pos+32;
}
else
{
if (pkt_len < 5)
goto error;

thd->max_client_packet_length= uint3korr(net->read_pos+2);
end= (char*) net->read_pos+5;
}
/*
Disable those bits which are not supported by the server.
This is a precautionary measure, if the client lies. See Bug#27944.
Expand Down Expand Up @@ -861,6 +848,26 @@ static int check_connection(THD *thd)
}
}
#endif /* HAVE_OPENSSL */
if (thd->client_capabilities & CLIENT_PROTOCOL_41)
{
if (pkt_len < 32)
goto error;

thd->max_client_packet_length= uint4korr(net->read_pos+4);
DBUG_PRINT("info", ("client_character_set: %d", (uint) net->read_pos[8]));
if (thd_init_client_charset(thd, (uint) net->read_pos[8]))
return 1;
thd->update_charset();
end= (char*) net->read_pos+32;
}
else
{
if (pkt_len < 5)
goto error;

thd->max_client_packet_length= uint3korr(net->read_pos+2);
end= (char*) net->read_pos+5;
}

if (end >= (char*) net->read_pos+ pkt_len +2)
goto error;
Expand Down

0 comments on commit b3e15f8

Please sign in to comment.