Skip to content

Commit 5be28f0

Browse files
harinvadodarialtangvald
authored andcommitted
Bug#27306178: ERROR IN SERVER HANDSHAKE WHILE CONNECTING
WITH AUTH_SOCK PLUGIN USER Description: On client side, if server's default plugin is different than that of client, client discards packet containing scramble information. This means that if server has default plugin caching_sha2_password and client has default plugin mysql_native_password, and if client is trying to connect to server using a user with plugin C (in this case auth_socket), following will happen: 1. Client will discard scramble data 2. Client will call native_password's client side authentication plugin 3. In client_mpvio_read_packet, client will send user details to server and wait for scramble 4. Server, having received user details, goes on to process client reply and finds that there are 3 plugins involved. It then triggers a RESTART of authentication on server side without sending anything to client. As a part of restart, server uses user's actual plugin (auth_socket) and calls authenticate API for the same. 5. auth_socket plugin, having received user details and connection info, performs verification and sends OK/ERROR. 6. On client side, since client expects random data of length 20 from server, native plugin's authentication API will report error upon receing OK/ERROR. 7. run_plugin_auth() won't find expected reply (because OK/ERROR was already read) and exit with error. Solution: In run_plugin_auth(), there is a check for auth-switch packet. Fix is to extend it to cover OK packet too. (cherry picked from commit b5840b451966469f4b527ba062147897750258cf)
1 parent eee24f2 commit 5be28f0

File tree

5 files changed

+294
-22
lines changed

5 files changed

+294
-22
lines changed
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
#
2+
# Input(s) :
3+
# $server_default_authentication_plugin
4+
#
5+
6+
--echo # Restart the server with $server_default_authentication_plugin as default authnetication plugin
7+
let $restart_file= $MYSQLTEST_VARDIR/tmp/mysqld.1.expect;
8+
--exec echo "wait" > $restart_file
9+
--shutdown_server
10+
--source include/wait_until_disconnected.inc
11+
--exec echo "restart:--default-authentication-plugin=$server_default_authentication_plugin" > $restart_file
12+
--enable_reconnect
13+
--source include/wait_until_connected_again.inc
14+
--disable_reconnect
15+
16+
17+
--echo # Create users
18+
CREATE USER qa_test_1_user IDENTIFIED WITH qa_auth_interface AS 'qa_test_1_dest';
19+
CREATE USER qa_test_1_dest IDENTIFIED BY 'dest_passwd';
20+
GRANT ALL PRIVILEGES ON test_user_db.* TO qa_test_1_dest identified by 'dest_passwd';
21+
GRANT PROXY ON qa_test_1_dest TO qa_test_1_user;
22+
23+
CREATE USER native@localhost IDENTIFIED WITH 'mysql_native_password' BY 'abcd';
24+
CREATE USER sha256@localhost IDENTIFIED WITH 'sha256_password' BY 'abcd';
25+
26+
--echo # Connection tests
27+
28+
--exec $MYSQL $PLUGIN_AUTH_OPT --protocol=TCP --host=127.0.0.1 -P$MASTER_MYPORT -uqa_test_1_user -pqa_test_1_dest --ssl-mode=DISABLED --server-public-key-path=$MYSQL_TEST_DIR/std_data/rsa_public_key.pem -e "SELECT CURRENT_USER()" 2>&1
29+
--exec $MYSQL $PLUGIN_AUTH_OPT --default-auth=mysql_native_password --protocol=TCP --host=127.0.0.1 -P$MASTER_MYPORT -uqa_test_1_user -pqa_test_1_dest --ssl-mode=DISABLED --server-public-key-path=$MYSQL_TEST_DIR/std_data/rsa_public_key.pem -e "SELECT CURRENT_USER()" 2>&1
30+
--exec $MYSQL $PLUGIN_AUTH_OPT --default-auth=sha256_password --protocol=TCP --host=127.0.0.1 -P$MASTER_MYPORT -uqa_test_1_user -pqa_test_1_dest --ssl-mode=DISABLED --server-public-key-path=$MYSQL_TEST_DIR/std_data/rsa_public_key.pem -e "SELECT CURRENT_USER()" 2>&1
31+
FLUSH PRIVILEGES;
32+
33+
--exec $MYSQL $PLUGIN_AUTH_OPT --protocol=TCP --host=127.0.0.1 -P$MASTER_MYPORT -uqa_test_1_user -pqa_test_1_dest --ssl-mode=DISABLED --server-public-key-path=$MYSQL_TEST_DIR/std_data/rsa_public_key.pem -e "SELECT CURRENT_USER()" 2>&1
34+
FLUSH PRIVILEGES;
35+
--exec $MYSQL $PLUGIN_AUTH_OPT --default-auth=mysql_native_password --protocol=TCP --host=127.0.0.1 -P$MASTER_MYPORT -uqa_test_1_user -pqa_test_1_dest --ssl-mode=DISABLED --server-public-key-path=$MYSQL_TEST_DIR/std_data/rsa_public_key.pem -e "SELECT CURRENT_USER()" 2>&1
36+
FLUSH PRIVILEGES;
37+
--exec $MYSQL $PLUGIN_AUTH_OPT --default-auth=sha256_password --protocol=TCP --host=127.0.0.1 -P$MASTER_MYPORT -uqa_test_1_user -pqa_test_1_dest --ssl-mode=DISABLED --server-public-key-path=$MYSQL_TEST_DIR/std_data/rsa_public_key.pem -e "SELECT CURRENT_USER()" 2>&1
38+
FLUSH PRIVILEGES;
39+
40+
41+
--exec $MYSQL $PLUGIN_AUTH_OPT --protocol=TCP --host=127.0.0.1 -P$MASTER_MYPORT -unative -pabcd --ssl-mode=DISABLED --server-public-key-path=$MYSQL_TEST_DIR/std_data/rsa_public_key.pem -e "SELECT CURRENT_USER()" 2>&1
42+
--exec $MYSQL $PLUGIN_AUTH_OPT --default-auth=mysql_native_password --protocol=TCP --host=127.0.0.1 -P$MASTER_MYPORT -unative -pabcd --ssl-mode=DISABLED --server-public-key-path=$MYSQL_TEST_DIR/std_data/rsa_public_key.pem -e "SELECT CURRENT_USER()" 2>&1
43+
--exec $MYSQL $PLUGIN_AUTH_OPT --default-auth=sha256_password --protocol=TCP --host=127.0.0.1 -P$MASTER_MYPORT -unative -pabcd --ssl-mode=DISABLED --server-public-key-path=$MYSQL_TEST_DIR/std_data/rsa_public_key.pem -e "SELECT CURRENT_USER()" 2>&1
44+
FLUSH PRIVILEGES;
45+
46+
47+
--exec $MYSQL $PLUGIN_AUTH_OPT --protocol=TCP --host=127.0.0.1 -P$MASTER_MYPORT -usha256 -pabcd --ssl-mode=DISABLED --server-public-key-path=$MYSQL_TEST_DIR/std_data/rsa_public_key.pem -e "SELECT CURRENT_USER()" 2>&1
48+
--exec $MYSQL $PLUGIN_AUTH_OPT --default-auth=mysql_native_password --protocol=TCP --host=127.0.0.1 -P$MASTER_MYPORT -usha256 -pabcd --ssl-mode=DISABLED --server-public-key-path=$MYSQL_TEST_DIR/std_data/rsa_public_key.pem -e "SELECT CURRENT_USER()" 2>&1
49+
--exec $MYSQL $PLUGIN_AUTH_OPT --default-auth=sha256_password --protocol=TCP --host=127.0.0.1 -P$MASTER_MYPORT -usha256 -pabcd --ssl-mode=DISABLED --server-public-key-path=$MYSQL_TEST_DIR/std_data/rsa_public_key.pem -e "SELECT CURRENT_USER()" 2>&1
50+
FLUSH PRIVILEGES;
51+
52+
--echo # Change user tests
53+
54+
--connect(qa_test_1_conn, localhost, qa_test_1_user, qa_test_1_dest,,,,SSL)
55+
--change_user native, abcd
56+
SELECT CURRENT_USER();
57+
--change_user sha256, abcd
58+
SELECT CURRENT_USER();
59+
--change_user
60+
SELECT CURRENT_USER();
61+
62+
--connect(native_conn, localhost, native, abcd,,,,SSL)
63+
--change_user qa_test_1_user, qa_test_1_dest
64+
SELECT CURRENT_USER();
65+
--change_user sha256, abcd
66+
SELECT CURRENT_USER();
67+
--change_user
68+
SELECT CURRENT_USER();
69+
70+
--connect(sha256_conn, localhost, sha256, abcd,,,,SSL)
71+
--change_user qa_test_1_user, qa_test_1_dest
72+
SELECT CURRENT_USER();
73+
--change_user native, abcd
74+
SELECT CURRENT_USER();
75+
--change_user
76+
SELECT CURRENT_USER();
77+
78+
--connection default
79+
--disconnect qa_test_1_conn
80+
--disconnect native_conn
81+
--disconnect sha256_conn
82+
83+
--echo # Drop users
84+
DROP USER qa_test_1_user;
85+
DROP USER qa_test_1_dest;
86+
DROP USER native@localhost;
87+
DROP USER sha256@localhost;
88+
89+
--source include/force_restart.inc
Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
# Check with mysql_native_password as --default-authentication-plugin
2+
# Restart the server with mysql_native_password as default authnetication plugin
3+
# Create users
4+
CREATE USER qa_test_1_user IDENTIFIED WITH qa_auth_interface AS 'qa_test_1_dest';
5+
CREATE USER qa_test_1_dest IDENTIFIED BY 'dest_passwd';
6+
GRANT ALL PRIVILEGES ON test_user_db.* TO qa_test_1_dest identified by 'dest_passwd';
7+
Warnings:
8+
Warning 1287 Using GRANT statement to modify existing user's properties other than privileges is deprecated and will be removed in future release. Use ALTER USER statement for this operation.
9+
GRANT PROXY ON qa_test_1_dest TO qa_test_1_user;
10+
CREATE USER native@localhost IDENTIFIED WITH 'mysql_native_password' BY 'abcd';
11+
CREATE USER sha256@localhost IDENTIFIED WITH 'sha256_password' BY 'abcd';
12+
# Connection tests
13+
mysql: [Warning] Using a password on the command line interface can be insecure.
14+
CURRENT_USER()
15+
qa_test_1_user@%
16+
mysql: [Warning] Using a password on the command line interface can be insecure.
17+
CURRENT_USER()
18+
qa_test_1_user@%
19+
mysql: [Warning] Using a password on the command line interface can be insecure.
20+
CURRENT_USER()
21+
qa_test_1_user@%
22+
FLUSH PRIVILEGES;
23+
mysql: [Warning] Using a password on the command line interface can be insecure.
24+
CURRENT_USER()
25+
qa_test_1_user@%
26+
FLUSH PRIVILEGES;
27+
mysql: [Warning] Using a password on the command line interface can be insecure.
28+
CURRENT_USER()
29+
qa_test_1_user@%
30+
FLUSH PRIVILEGES;
31+
mysql: [Warning] Using a password on the command line interface can be insecure.
32+
CURRENT_USER()
33+
qa_test_1_user@%
34+
FLUSH PRIVILEGES;
35+
mysql: [Warning] Using a password on the command line interface can be insecure.
36+
CURRENT_USER()
37+
native@localhost
38+
mysql: [Warning] Using a password on the command line interface can be insecure.
39+
CURRENT_USER()
40+
native@localhost
41+
mysql: [Warning] Using a password on the command line interface can be insecure.
42+
CURRENT_USER()
43+
native@localhost
44+
FLUSH PRIVILEGES;
45+
mysql: [Warning] Using a password on the command line interface can be insecure.
46+
CURRENT_USER()
47+
sha256@localhost
48+
mysql: [Warning] Using a password on the command line interface can be insecure.
49+
CURRENT_USER()
50+
sha256@localhost
51+
mysql: [Warning] Using a password on the command line interface can be insecure.
52+
CURRENT_USER()
53+
sha256@localhost
54+
FLUSH PRIVILEGES;
55+
# Change user tests
56+
SELECT CURRENT_USER();
57+
CURRENT_USER()
58+
native@localhost
59+
SELECT CURRENT_USER();
60+
CURRENT_USER()
61+
sha256@localhost
62+
SELECT CURRENT_USER();
63+
CURRENT_USER()
64+
sha256@localhost
65+
SELECT CURRENT_USER();
66+
CURRENT_USER()
67+
qa_test_1_user@%
68+
SELECT CURRENT_USER();
69+
CURRENT_USER()
70+
sha256@localhost
71+
SELECT CURRENT_USER();
72+
CURRENT_USER()
73+
sha256@localhost
74+
SELECT CURRENT_USER();
75+
CURRENT_USER()
76+
qa_test_1_user@%
77+
SELECT CURRENT_USER();
78+
CURRENT_USER()
79+
native@localhost
80+
SELECT CURRENT_USER();
81+
CURRENT_USER()
82+
native@localhost
83+
# Drop users
84+
DROP USER qa_test_1_user;
85+
DROP USER qa_test_1_dest;
86+
DROP USER native@localhost;
87+
DROP USER sha256@localhost;
88+
# Check with sha256_password as --default-authentication-plugin
89+
# Restart the server with sha256_password as default authnetication plugin
90+
# Create users
91+
CREATE USER qa_test_1_user IDENTIFIED WITH qa_auth_interface AS 'qa_test_1_dest';
92+
CREATE USER qa_test_1_dest IDENTIFIED BY 'dest_passwd';
93+
GRANT ALL PRIVILEGES ON test_user_db.* TO qa_test_1_dest identified by 'dest_passwd';
94+
Warnings:
95+
Warning 1287 Using GRANT statement to modify existing user's properties other than privileges is deprecated and will be removed in future release. Use ALTER USER statement for this operation.
96+
GRANT PROXY ON qa_test_1_dest TO qa_test_1_user;
97+
CREATE USER native@localhost IDENTIFIED WITH 'mysql_native_password' BY 'abcd';
98+
CREATE USER sha256@localhost IDENTIFIED WITH 'sha256_password' BY 'abcd';
99+
# Connection tests
100+
mysql: [Warning] Using a password on the command line interface can be insecure.
101+
CURRENT_USER()
102+
qa_test_1_user@%
103+
mysql: [Warning] Using a password on the command line interface can be insecure.
104+
CURRENT_USER()
105+
qa_test_1_user@%
106+
mysql: [Warning] Using a password on the command line interface can be insecure.
107+
CURRENT_USER()
108+
qa_test_1_user@%
109+
FLUSH PRIVILEGES;
110+
mysql: [Warning] Using a password on the command line interface can be insecure.
111+
CURRENT_USER()
112+
qa_test_1_user@%
113+
FLUSH PRIVILEGES;
114+
mysql: [Warning] Using a password on the command line interface can be insecure.
115+
CURRENT_USER()
116+
qa_test_1_user@%
117+
FLUSH PRIVILEGES;
118+
mysql: [Warning] Using a password on the command line interface can be insecure.
119+
CURRENT_USER()
120+
qa_test_1_user@%
121+
FLUSH PRIVILEGES;
122+
mysql: [Warning] Using a password on the command line interface can be insecure.
123+
CURRENT_USER()
124+
native@localhost
125+
mysql: [Warning] Using a password on the command line interface can be insecure.
126+
CURRENT_USER()
127+
native@localhost
128+
mysql: [Warning] Using a password on the command line interface can be insecure.
129+
CURRENT_USER()
130+
native@localhost
131+
FLUSH PRIVILEGES;
132+
mysql: [Warning] Using a password on the command line interface can be insecure.
133+
CURRENT_USER()
134+
sha256@localhost
135+
mysql: [Warning] Using a password on the command line interface can be insecure.
136+
CURRENT_USER()
137+
sha256@localhost
138+
mysql: [Warning] Using a password on the command line interface can be insecure.
139+
CURRENT_USER()
140+
sha256@localhost
141+
FLUSH PRIVILEGES;
142+
# Change user tests
143+
SELECT CURRENT_USER();
144+
CURRENT_USER()
145+
native@localhost
146+
SELECT CURRENT_USER();
147+
CURRENT_USER()
148+
sha256@localhost
149+
SELECT CURRENT_USER();
150+
CURRENT_USER()
151+
sha256@localhost
152+
SELECT CURRENT_USER();
153+
CURRENT_USER()
154+
qa_test_1_user@%
155+
SELECT CURRENT_USER();
156+
CURRENT_USER()
157+
sha256@localhost
158+
SELECT CURRENT_USER();
159+
CURRENT_USER()
160+
sha256@localhost
161+
SELECT CURRENT_USER();
162+
CURRENT_USER()
163+
qa_test_1_user@%
164+
SELECT CURRENT_USER();
165+
CURRENT_USER()
166+
native@localhost
167+
SELECT CURRENT_USER();
168+
CURRENT_USER()
169+
native@localhost
170+
# Drop users
171+
DROP USER qa_test_1_user;
172+
DROP USER qa_test_1_dest;
173+
DROP USER native@localhost;
174+
DROP USER sha256@localhost;
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
$PLUGIN_AUTH_INTERFACE_OPT
2+
$PLUGIN_AUTH_INTERFACE_LOAD
3+
--loose-sha256_password_private_key_path=$MYSQL_TEST_DIR/std_data/rsa_private_key.pem
4+
--loose-sha256_password_public_key_path=$MYSQL_TEST_DIR/std_data/rsa_public_key.pem
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
--source include/have_plugin_interface.inc
2+
--source include/not_embedded.inc
3+
--source include/have_ssl.inc
4+
--source include/have_sha256_rsa_auth.inc
5+
6+
--echo # Check with mysql_native_password as --default-authentication-plugin
7+
let $server_default_authentication_plugin=mysql_native_password;
8+
--source ../include/multiple_plugins.inc
9+
10+
--echo # Check with sha256_password as --default-authentication-plugin
11+
let $server_default_authentication_plugin=sha256_password;
12+
--source ../include/multiple_plugins.inc

sql-common/client.c

Lines changed: 15 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4016,9 +4016,15 @@ int run_plugin_auth(MYSQL *mysql, char *data, uint data_len,
40164016

40174017
/*
40184018
The connection may be closed. If so: do not try to read from the buffer.
4019+
If server sends OK packet without sending auth-switch first, client side
4020+
auth plugin may not be able to process it correctly.
4021+
However, if server sends OK, it means server side authentication plugin
4022+
already performed required checks. Further, server side plugin did not
4023+
really care about plugin used by client in this case.
40194024
*/
40204025
if (res > CR_OK &&
4021-
(!my_net_is_inited(&mysql->net) || mysql->net.read_pos[0] != 254))
4026+
(!my_net_is_inited(&mysql->net) ||
4027+
(mysql->net.read_pos[0] != 0 && mysql->net.read_pos[0] != 254)))
40224028
{
40234029
/*
40244030
the plugin returned an error. write it down in mysql,
@@ -6213,29 +6219,16 @@ static int native_password_auth_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql)
62136219

62146220
DBUG_ENTER("native_password_auth_client");
62156221

6222+
/* read the scramble */
6223+
if ((pkt_len= vio->read_packet(vio, &pkt)) < 0)
6224+
DBUG_RETURN(CR_ERROR);
62166225

6217-
if (((MCPVIO_EXT *)vio)->mysql_change_user)
6218-
{
6219-
/*
6220-
in mysql_change_user() the client sends the first packet.
6221-
we use the old scramble.
6222-
*/
6223-
pkt= (uchar*)mysql->scramble;
6224-
pkt_len= SCRAMBLE_LENGTH + 1;
6225-
}
6226-
else
6227-
{
6228-
/* read the scramble */
6229-
if ((pkt_len= vio->read_packet(vio, &pkt)) < 0)
6230-
DBUG_RETURN(CR_ERROR);
6226+
if (pkt_len != SCRAMBLE_LENGTH + 1)
6227+
DBUG_RETURN(CR_SERVER_HANDSHAKE_ERR);
62316228

6232-
if (pkt_len != SCRAMBLE_LENGTH + 1)
6233-
DBUG_RETURN(CR_SERVER_HANDSHAKE_ERR);
6234-
6235-
/* save it in MYSQL */
6236-
memcpy(mysql->scramble, pkt, SCRAMBLE_LENGTH);
6237-
mysql->scramble[SCRAMBLE_LENGTH] = 0;
6238-
}
6229+
/* save it in MYSQL */
6230+
memcpy(mysql->scramble, pkt, SCRAMBLE_LENGTH);
6231+
mysql->scramble[SCRAMBLE_LENGTH] = 0;
62396232

62406233
if (mysql->passwd[0])
62416234
{

0 commit comments

Comments
 (0)