1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00

BUG#11879051: FIRST REPLY LENGTH LIMIT (255) CAN BE VIOLATED

BEFORE: First packet sent by client-side plugin (generated by Windows
function InitializeSecurityContext()) could be longer than 255 bytes 
violating the limitation imposed by authentication protocol.

AFTER: Handshake protocol is  changed so that if first client's reply is 
longer than 254 bytes then  it is be sent in 2 parts. However, for replies
shorter than 255 bytes nothing changes.

ADDITIONAL CHANGES: 
- The generic packet processing loop  (Handshake::packet_processing_loop) 
has been refactored. Communication with the peer has been abstracted
into virtual methods read/write_packet() which are implemented in client 
and server and transparently do the required splitting and gluing of packets.
- Make it possible to optionally use dbug library in the plugin.
- Add code for testing splitting of long first client reply.
This commit is contained in:
Rafal Somla
2011-04-28 21:39:42 +02:00
parent 6d7aceeead
commit a6acc73bb1
5 changed files with 284 additions and 141 deletions

View File

@ -90,17 +90,19 @@ Handshake::~Handshake()
@note In case of error, appropriate error message is logged.
*/
int Handshake::packet_processing_loop(Connection &con)
int Handshake::packet_processing_loop()
{
unsigned round= 1;
m_round= 0;
do {
++m_round;
// Read packet send by the peer
DBUG_PRINT("info", ("Waiting for packet"));
Blob packet= con.read();
if (con.error() || packet.is_null())
Blob packet= read_packet();
if (error())
{
ERROR_LOG(ERROR, ("Error reading packet in round %d", round));
ERROR_LOG(ERROR, ("Error reading packet in round %d", m_round));
return 1;
}
DBUG_PRINT("info", ("Got packet of length %d", packet.len()));
@ -113,7 +115,7 @@ int Handshake::packet_processing_loop(Connection &con)
if (error())
{
ERROR_LOG(ERROR, ("Error processing packet in round %d", round));
ERROR_LOG(ERROR, ("Error processing packet in round %d", m_round));
return 1;
}
@ -124,14 +126,13 @@ int Handshake::packet_processing_loop(Connection &con)
if (!new_data.is_null())
{
++round;
DBUG_PRINT("info", ("Round %d started", round));
DBUG_PRINT("info", ("Round %d started", m_round));
DBUG_PRINT("info", ("Sending packet of length %d", new_data.len()));
int ret= con.write(new_data);
int ret= write_packet(new_data);
if (ret)
{
ERROR_LOG(ERROR, ("Error writing packet in round %d", round));
ERROR_LOG(ERROR, ("Error writing packet in round %d", m_round));
return 1;
}
DBUG_PRINT("info", ("Data sent"));
@ -139,7 +140,7 @@ int Handshake::packet_processing_loop(Connection &con)
else if (!is_complete())
{
ERROR_LOG(ERROR, ("No data to send in round %d"
" but handshake is not complete", round));
" but handshake is not complete", m_round));
return 1;
}
@ -148,16 +149,16 @@ int Handshake::packet_processing_loop(Connection &con)
too many rounds.
*/
if (round > MAX_HANDSHAKE_ROUNDS)
if (m_round > MAX_HANDSHAKE_ROUNDS)
{
ERROR_LOG(ERROR, ("Authentication handshake could not be completed"
" after %d rounds", round));
" after %d rounds", m_round));
return 1;
}
} while(!is_complete());
ERROR_LOG(INFO, ("Handshake completed after %d rounds", round));
ERROR_LOG(INFO, ("Handshake completed after %d rounds", m_round));
return 0;
}