Description:
At line 602-611 in function send_server_handshake_packet(sql_authentication.cc):
/* write scramble tail */
end= (char*) memcpy(end, data + AUTH_PLUGIN_DATA_PART_1_LENGTH,
data_len - AUTH_PLUGIN_DATA_PART_1_LENGTH);
end+= data_len - AUTH_PLUGIN_DATA_PART_1_LENGTH;
end= strmake(end, plugin_name(mpvio->plugin)->str,
plugin_name(mpvio->plugin)->length);
int res= protocol->write((uchar*) buff, (size_t) (end - buff + 1)) ||
protocol->flush_net();
DBUG_RETURN (res);
The server sends the name of server-side auth plugin name to the client.
The client user the server-side auth plugin name to do these things:(run_plugin_auth in client.c)
if (data_plugin && strcmp(data_plugin, auth_plugin_name))
{
/* data was prepared for a different plugin, don't show it to this one */
data= 0;
data_len= 0;
}
...
mpvio.cached_server_reply.pkt= (uchar*)data;
mpvio.cached_server_reply.pkt_len= data_len;
...
res= auth_plugin->authenticate_user((struct st_plugin_vio *)&mpvio, mysql);
Imagine that the auth_server and auth_client can be set as default auth plugin.
If in the server side, the .cnf file of an instance contains:
default_authentication_plugin=auth_server
And in the client side, user the command to login:
mysql --default_auth=auth_client -utest_user -pabc
Then the do_auth_once() will only run once and the auth will fail as
mpvio.cached_server_reply.pkt_len= data_len=0.
So sending the client-side auth plugin name to the client in function
send_server_handshake_packet(sql_authentication.cc) may be a better choice.
How to repeat:
In 5.7.15 and 5.7.16, the value of default_authentication_plugin can only be equal to
mysql_native_password and sha256_password. Because the client-side name and the
server-side name of these plugins are equal, I can't repeat the description above.
Suggested fix:
change
end= strmake(end, plugin_name(mpvio->plugin)->str,
plugin_name(mpvio->plugin)->length);
to
const char *client_auth_plugin=
((st_mysql_auth *) (plugin_decl(mpvio->plugin)->info))->client_auth_plugin;
end= strmake(end, client_auth_plugin,
strlen(client_auth_plugin));