Details
-
Bug
-
Status: Closed (View Workflow)
-
Major
-
Resolution: Fixed
-
1.5.4
-
None
-
5.5.31-MariaDB
jdk_1.8.0_77
Description
Description
MariaDB Connector/J does not check the packet length of a OldAuthSwitchRequest and assumes it is AuthSwitchRequest.
During authentication, if a OldAuthSwitchRequest is recieved and the server has PLUGIN_AUTH capability, the Connector/J assumes the request is a AuthSwitchRequest.
As per the protocol documentation: https://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::AuthSwitchRequest
Both AuthSwitchRequest and OldAuthSwitchRequest have the starting payload of [fe], however, OldAuthSwitchRequest is only one byte, and does not contain a plugin or auth data.
When the Connector/J recieves a OldAuthSwitchRequest it will assume it is a AuthSwitchRequest and throw an exception:
Exception in thread "main" java.sql.SQLNonTransientConnectionException: Client does not support authentication protocol requested by server. Consider upgrading MariaDB client. plugin was = |
at org.mariadb.jdbc.internal.util.ExceptionMapper.get(ExceptionMapper.java:125) |
at org.mariadb.jdbc.internal.util.ExceptionMapper.throwException(ExceptionMapper.java:71) |
at org.mariadb.jdbc.Driver.connect(Driver.java:109) |
at java.sql.DriverManager.getConnection(DriverManager.java:664) |
at java.sql.DriverManager.getConnection(DriverManager.java:247) |
at TestConnect.main(TestConnect.java:23) |
Caused by: org.mariadb.jdbc.internal.util.dao.QueryException: Client does not support authentication protocol requested by server. Consider upgrading MariaDB client. plugin was =
|
at org.mariadb.jdbc.internal.protocol.authentication.DefaultAuthenticationProvider.processAuthPlugin(DefaultAuthenticationProvider.java:94) |
at org.mariadb.jdbc.internal.protocol.authentication.AuthenticationProviderHolder$1.processAuthPlugin(AuthenticationProviderHolder.java:69) |
at org.mariadb.jdbc.internal.protocol.AbstractConnectProtocol.authentication(AbstractConnectProtocol.java:514) |
at org.mariadb.jdbc.internal.protocol.AbstractConnectProtocol.handleConnectionPhases(AbstractConnectProtocol.java:472) |
at org.mariadb.jdbc.internal.protocol.AbstractConnectProtocol.connect(AbstractConnectProtocol.java:374) |
at org.mariadb.jdbc.internal.protocol.AbstractConnectProtocol.connectWithoutProxy(AbstractConnectProtocol.java:763) |
at org.mariadb.jdbc.internal.util.Utils.retrieveProxy(Utils.java:469) |
at org.mariadb.jdbc.Driver.connect(Driver.java:104) |
... 3 more |
Reproduction
I was able to reproduce this by using MariaDB ( 5.5.31-MariaDB ) and setting a user with an OLD_PASSWORD format.
set password for 'testuser'@'testserver' = OLD_PASSWORD('testuser') |
Then connecting with a simple JDBC test program.
Workaround
Update the password on the server to the new format
Resolution
Add a check for the packet length into AbstractConnectProtocol.java and only treat it as a AuthSwitchRequest if it's length is greater than 1
From:
if ((serverCapabilities & MariaDbServerCapabilities.PLUGIN_AUTH) != 0) { |
To:
if ((serverCapabilities & MariaDbServerCapabilities.PLUGIN_AUTH) != 0 && buffer.remaining() > 1) { |