Commit 9f6ec599 authored by Davi Arnaut's avatar Davi Arnaut

Merge of mysql-5.1 into mysql-5.5.

parents f3e11429 9b68760f
...@@ -205,21 +205,16 @@ void scramble_323(char *to, const char *message, const char *password) ...@@ -205,21 +205,16 @@ void scramble_323(char *to, const char *message, const char *password)
} }
/* /**
Check scrambled message Check scrambled message. Used in pre 4.1 password handling.
Used in pre 4.1 password handling
SYNOPSIS
check_scramble_323()
scrambled scrambled message to check.
message original random message which was used for scrambling; must
be exactly SCRAMBLED_LENGTH_323 bytes long and
NULL-terminated.
hash_pass password which should be used for scrambling
All params are IN.
RETURN VALUE @param scrambled Scrambled message to check.
0 - password correct @param message Original random message which was used for scrambling.
!0 - password invalid @param hash_pass Password which should be used for scrambling.
@remark scrambled and message must be SCRAMBLED_LENGTH_323 bytes long.
@return FALSE if password is correct, TRUE otherwise.
*/ */
my_bool my_bool
...@@ -228,9 +223,16 @@ check_scramble_323(const unsigned char *scrambled, const char *message, ...@@ -228,9 +223,16 @@ check_scramble_323(const unsigned char *scrambled, const char *message,
{ {
struct rand_struct rand_st; struct rand_struct rand_st;
ulong hash_message[2]; ulong hash_message[2];
uchar buff[16],*to,extra; /* Big enough for check */ /* Big enough for checks. */
uchar buff[16], scrambled_buff[SCRAMBLE_LENGTH_323 + 1];
uchar *to, extra;
const uchar *pos; const uchar *pos;
/* Ensure that the scrambled message is null-terminated. */
memcpy(scrambled_buff, scrambled, SCRAMBLE_LENGTH_323);
scrambled_buff[SCRAMBLE_LENGTH_323]= '\0';
scrambled= scrambled_buff;
hash_password(hash_message, message, SCRAMBLE_LENGTH_323); hash_password(hash_message, message, SCRAMBLE_LENGTH_323);
randominit(&rand_st,hash_pass[0] ^ hash_message[0], randominit(&rand_st,hash_pass[0] ^ hash_message[0],
hash_pass[1] ^ hash_message[1]); hash_pass[1] ^ hash_message[1]);
......
...@@ -8400,14 +8400,21 @@ static bool parse_com_change_user_packet(MPVIO_EXT *mpvio, uint packet_length) ...@@ -8400,14 +8400,21 @@ static bool parse_com_change_user_packet(MPVIO_EXT *mpvio, uint packet_length)
} }
#ifndef EMBEDDED_LIBRARY #ifndef EMBEDDED_LIBRARY
/** Get a string according to the protocol of the underlying buffer. */
typedef char * (*get_proto_string_func_t) (char **, size_t *, size_t *);
/** /**
Get a null character terminated string from a user-supplied buffer. Get a string formatted according to the 4.1 version of the MySQL protocol.
@param buffer[in, out] Pointer to the buffer to be scanned. @param buffer[in, out] Pointer to the user-supplied buffer to be scanned.
@param max_bytes_available[in, out] Limit the bytes to scan. @param max_bytes_available[in, out] Limit the bytes to scan.
@param string_length[out] The number of characters scanned not including @param string_length[out] The number of characters scanned not including
the null character. the null character.
@remark Strings are always null character terminated in this version of the
protocol.
@remark The string_length does not include the terminating null character. @remark The string_length does not include the terminating null character.
However, after the call, the buffer is increased by string_length+1 However, after the call, the buffer is increased by string_length+1
bytes, beyond the null character if there still available bytes to bytes, beyond the null character if there still available bytes to
...@@ -8418,9 +8425,9 @@ static bool parse_com_change_user_packet(MPVIO_EXT *mpvio, uint packet_length) ...@@ -8418,9 +8425,9 @@ static bool parse_com_change_user_packet(MPVIO_EXT *mpvio, uint packet_length)
*/ */
static static
char *get_null_terminated_string(char **buffer, char *get_41_protocol_string(char **buffer,
size_t *max_bytes_available, size_t *max_bytes_available,
size_t *string_length) size_t *string_length)
{ {
char *str= (char *)memchr(*buffer, '\0', *max_bytes_available); char *str= (char *)memchr(*buffer, '\0', *max_bytes_available);
...@@ -8430,7 +8437,60 @@ char *get_null_terminated_string(char **buffer, ...@@ -8430,7 +8437,60 @@ char *get_null_terminated_string(char **buffer,
*string_length= (size_t)(str - *buffer); *string_length= (size_t)(str - *buffer);
*max_bytes_available-= *string_length + 1; *max_bytes_available-= *string_length + 1;
str= *buffer; str= *buffer;
*buffer += *string_length + 1; *buffer += *string_length + 1;
return str;
}
/**
Get a string formatted according to the 4.0 version of the MySQL protocol.
@param buffer[in, out] Pointer to the user-supplied buffer to be scanned.
@param max_bytes_available[in, out] Limit the bytes to scan.
@param string_length[out] The number of characters scanned not including
the null character.
@remark If there are not enough bytes left after the current position of
the buffer to satisfy the current string, the string is considered
to be empty and a pointer to empty_c_string is returned.
@remark A string at the end of the packet is not null terminated.
@return Pointer to beginning of the string scanned, or a pointer to a empty
string.
*/
static
char *get_40_protocol_string(char **buffer,
size_t *max_bytes_available,
size_t *string_length)
{
char *str;
size_t len;
/* No bytes to scan left, treat string as empty. */
if ((*max_bytes_available) == 0)
{
*string_length= 0;
return empty_c_string;
}
str= (char *) memchr(*buffer, '\0', *max_bytes_available);
/*
If the string was not null terminated by the client,
the remainder of the packet is the string. Otherwise,
advance the buffer past the end of the null terminated
string.
*/
if (str == NULL)
len= *string_length= *max_bytes_available;
else
len= (*string_length= (size_t)(str - *buffer)) + 1;
str= *buffer;
*buffer+= len;
*max_bytes_available-= len;
return str; return str;
} }
...@@ -8441,7 +8501,7 @@ char *get_null_terminated_string(char **buffer, ...@@ -8441,7 +8501,7 @@ char *get_null_terminated_string(char **buffer,
@param buffer[in, out] The buffer to scan; updates position after scan. @param buffer[in, out] The buffer to scan; updates position after scan.
@param max_bytes_available[in, out] Limit the number of bytes to scan @param max_bytes_available[in, out] Limit the number of bytes to scan
@param string_length[out] Number of characters scanned @param string_length[out] Number of characters scanned
@remark In case the length is zero, then the total size of the string is @remark In case the length is zero, then the total size of the string is
considered to be 1 byte; the size byte. considered to be 1 byte; the size byte.
...@@ -8557,7 +8617,20 @@ static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio, ...@@ -8557,7 +8617,20 @@ static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio,
if ((mpvio->client_capabilities & CLIENT_TRANSACTIONS) && if ((mpvio->client_capabilities & CLIENT_TRANSACTIONS) &&
opt_using_transactions) opt_using_transactions)
net->return_status= mpvio->server_status; net->return_status= mpvio->server_status;
/*
The 4.0 and 4.1 versions of the protocol differ on how strings
are terminated. In the 4.0 version, if a string is at the end
of the packet, the string is not null terminated. Do not assume
that the returned string is always null terminated.
*/
get_proto_string_func_t get_string;
if (mpvio->client_capabilities & CLIENT_PROTOCOL_41)
get_string= get_41_protocol_string;
else
get_string= get_40_protocol_string;
/* /*
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
...@@ -8566,8 +8639,7 @@ static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio, ...@@ -8566,8 +8639,7 @@ static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio,
size_t bytes_remaining_in_packet= pkt_len - (end - (char *)net->read_pos); size_t bytes_remaining_in_packet= pkt_len - (end - (char *)net->read_pos);
size_t user_len; size_t user_len;
char *user= get_null_terminated_string(&end, &bytes_remaining_in_packet, char *user= get_string(&end, &bytes_remaining_in_packet, &user_len);
&user_len);
if (user == NULL) if (user == NULL)
return packet_error; return packet_error;
...@@ -8592,8 +8664,7 @@ static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio, ...@@ -8592,8 +8664,7 @@ static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio,
/* /*
Old passwords are zero terminated strings. Old passwords are zero terminated strings.
*/ */
passwd= get_null_terminated_string(&end, &bytes_remaining_in_packet, passwd= get_string(&end, &bytes_remaining_in_packet, &passwd_len);
&passwd_len);
} }
if (passwd == NULL) if (passwd == NULL)
...@@ -8604,40 +8675,43 @@ static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio, ...@@ -8604,40 +8675,43 @@ static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio,
if (mpvio->client_capabilities & CLIENT_CONNECT_WITH_DB) if (mpvio->client_capabilities & CLIENT_CONNECT_WITH_DB)
{ {
db= get_null_terminated_string(&end, &bytes_remaining_in_packet, db= get_string(&end, &bytes_remaining_in_packet, &db_len);
&db_len);
if (db == NULL) if (db == NULL)
return packet_error; return packet_error;
} }
size_t client_plugin_len= 0; size_t client_plugin_len= 0;
char *client_plugin= get_null_terminated_string(&end, char *client_plugin= get_string(&end, &bytes_remaining_in_packet,
&bytes_remaining_in_packet, &client_plugin_len);
&client_plugin_len);
if (client_plugin == NULL) if (client_plugin == NULL)
client_plugin= &empty_c_string[0]; client_plugin= &empty_c_string[0];
char db_buff[NAME_LEN + 1]; // buffer to store db in utf8 char db_buff[NAME_LEN + 1]; // buffer to store db in utf8
char user_buff[USERNAME_LENGTH + 1]; // buffer to store user in utf8 char user_buff[USERNAME_LENGTH + 1]; // buffer to store user in utf8
uint dummy_errors; uint dummy_errors;
/* Since 4.1 all database names are stored in utf8 */
/*
Copy and convert the user and database names to the character set used
by the server. Since 4.1 all database names are stored in UTF-8. Also,
ensure that the names are properly null-terminated as this is relied
upon later.
*/
if (db) if (db)
{ {
db_len= copy_and_convert(db_buff, sizeof(db_buff) - 1, system_charset_info, db_len= copy_and_convert(db_buff, sizeof(db_buff) - 1, system_charset_info,
db, db_len, mpvio->charset_adapter->charset(), db, db_len, mpvio->charset_adapter->charset(),
&dummy_errors); &dummy_errors);
db_buff[db_len]= '\0';
db= db_buff; db= db_buff;
db_buff[db_len]= 0;
} }
user_len= copy_and_convert(user_buff, sizeof(user_buff) - 1, user_len= copy_and_convert(user_buff, sizeof(user_buff) - 1,
system_charset_info, user, user_len, system_charset_info, user, user_len,
mpvio->charset_adapter->charset(), mpvio->charset_adapter->charset(),
&dummy_errors); &dummy_errors);
user_buff[user_len]= '\0';
user= user_buff; user= user_buff;
user_buff[user_len]= 0;
/* If username starts and ends in "'", chop them off */ /* If username starts and ends in "'", chop them off */
if (user_len > 1 && user[0] == '\'' && user[user_len - 1] == '\'') if (user_len > 1 && user[0] == '\'' && user[user_len - 1] == '\'')
......
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