From b3e15f838955217125476130766551731f1eaa4c Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Sat, 11 Feb 2012 03:25:49 +0100 Subject: [PATCH] A recent change in the server protocol code broke SSL connection for 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. --- sql/sql_connect.cc | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc index 7dd15ea731f84..13e3a82310347 100644 --- a/sql/sql_connect.cc +++ b/sql/sql_connect.cc @@ -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. @@ -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;