diff --git a/CHANGES b/CHANGES index bb4be8740..134787afa 100644 --- a/CHANGES +++ b/CHANGES @@ -3,6 +3,8 @@ Version 9.0.0 + - WL#16376, Set 'caching_sha2_password' as default fallback authentication plugin. + - WL#16342, Update MySQL error codes mapping. - WL#16353, Refresh the list of acceptable TLS ciphers. diff --git a/src/main/core-api/java/com/mysql/cj/conf/PropertyDefinitions.java b/src/main/core-api/java/com/mysql/cj/conf/PropertyDefinitions.java index 94a710300..1e2d06ea7 100644 --- a/src/main/core-api/java/com/mysql/cj/conf/PropertyDefinitions.java +++ b/src/main/core-api/java/com/mysql/cj/conf/PropertyDefinitions.java @@ -196,7 +196,7 @@ public enum DatabaseTerm { new StringPropertyDefinition(PropertyKey.disabledAuthenticationPlugins, DEFAULT_VALUE_NULL_STRING, RUNTIME_MODIFIABLE, Messages.getString("ConnectionProperties.disabledAuthenticationPlugins"), "5.1.19", CATEGORY_AUTH, Integer.MIN_VALUE + 7), - new StringPropertyDefinition(PropertyKey.defaultAuthenticationPlugin, "mysql_native_password", RUNTIME_MODIFIABLE, + new StringPropertyDefinition(PropertyKey.defaultAuthenticationPlugin, "caching_sha2_password", RUNTIME_MODIFIABLE, Messages.getString("ConnectionProperties.defaultAuthenticationPlugin"), "5.1.19", CATEGORY_AUTH, Integer.MIN_VALUE + 8), new StringPropertyDefinition(PropertyKey.ldapServerHostname, DEFAULT_VALUE_NULL_STRING, RUNTIME_MODIFIABLE, diff --git a/src/main/protocol-impl/java/com/mysql/cj/protocol/a/NativeAuthenticationProvider.java b/src/main/protocol-impl/java/com/mysql/cj/protocol/a/NativeAuthenticationProvider.java index 7efb0d5ab..7783bfa9e 100644 --- a/src/main/protocol-impl/java/com/mysql/cj/protocol/a/NativeAuthenticationProvider.java +++ b/src/main/protocol-impl/java/com/mysql/cj/protocol/a/NativeAuthenticationProvider.java @@ -77,7 +77,7 @@ public class NativeAuthenticationProvider implements AuthenticationProvider> authenticationPlugins = null; /** @@ -213,10 +213,9 @@ public void connect(String user, String pass, String db) { * Starts by filling the map with instances of the built-in authentication plugins. Then creates instances of plugins listed in the "authenticationPlugins" * connection property and adds them to the map too. * - * The key for the map entry is got by {@link AuthenticationPlugin#getProtocolPluginName()} thus it is possible to replace built-in plugins with custom - * implementations. To do it, the custom plugin should return one of the values "mysql_native_password", "mysql_clear_password", "sha256_password", - * "caching_sha2_password", "mysql_old_password", "authentication_ldap_sasl_client" or "authentication_kerberos_client" from its own getProtocolPluginName() - * method. + * The plugins map uses the plugin names as keys, which are obtained from {@link AuthenticationPlugin#getProtocolPluginName()} thus it is possible to + * replace built-in plugins with custom implementations as long as the implementations use the same MySQL authentication plugin client-side name, such as, + * "caching_sha2_password" and "mysql_native_password". */ @SuppressWarnings("unchecked") private void loadAuthenticationPlugins() { @@ -308,7 +307,7 @@ private void loadAuthenticationPlugins() { * if it was Auth Method Switch Request Packet then handshake will be interrupted with exception. * * @param pluginName - * mysql protocol plugin names, for example "mysql_native_password" and "mysql_old_password" for built-in plugins + * mysql protocol plugin names, for example "caching_sha2_password" and "mysql_native_password" for built-in plugins * @return null if plugin is not found or authentication plugin instance initialized with current connection properties */ @SuppressWarnings("unchecked") diff --git a/src/test/java/testsuite/regression/CharsetRegressionTest.java b/src/test/java/testsuite/regression/CharsetRegressionTest.java index 165dcf606..95354cdcc 100644 --- a/src/test/java/testsuite/regression/CharsetRegressionTest.java +++ b/src/test/java/testsuite/regression/CharsetRegressionTest.java @@ -692,37 +692,21 @@ public T preProcess(Supplier str, Query intercepte public void testBug72630() throws Exception { // bug is related to authentication plugins, available only in 5.5.7+ if (versionMeetsMinimum(5, 5, 7)) { - try { - createUser("'Bug72630User'@'%'", "IDENTIFIED WITH mysql_native_password"); - this.stmt.execute("GRANT ALL ON *.* TO 'Bug72630User'@'%'"); - this.stmt.executeUpdate( - ((MysqlConnection) this.conn).getSession().versionMeetsMinimum(5, 7, 6) ? "ALTER USER 'Bug72630User'@'%' IDENTIFIED BY 'pwd'" - : "set password for 'Bug72630User'@'%' = PASSWORD('pwd')"); - - final Properties props = new Properties(); - props.setProperty(PropertyKey.USER.getKeyName(), "Bug72630User"); - props.setProperty(PropertyKey.PASSWORD.getKeyName(), "pwd"); - props.setProperty(PropertyKey.characterEncoding.getKeyName(), "NonexistentEncoding"); - - assertThrows(SQLException.class, "Unsupported character encoding 'NonexistentEncoding'", () -> { - try { - getConnectionWithProps(props); - return null; - } catch (Exception ex) { - ex.printStackTrace(); - throw ex; - } - }); - - props.remove(PropertyKey.characterEncoding.getKeyName()); - props.setProperty(PropertyKey.passwordCharacterEncoding.getKeyName(), "NonexistentEncoding"); - assertThrows(SQLException.class, "Unsupported character encoding 'NonexistentEncoding'", () -> { - getConnectionWithProps(props); - return null; - }); - } catch (SQLException e) { - e.printStackTrace(); - } + createUser("'Bug72630User'@'%'", ""); + this.stmt.execute("GRANT ALL ON *.* TO 'Bug72630User'@'%'"); + this.stmt + .executeUpdate(((MysqlConnection) this.conn).getSession().versionMeetsMinimum(5, 7, 6) ? "ALTER USER 'Bug72630User'@'%' IDENTIFIED BY 'pwd'" + : "SET PASSWORD FOR 'Bug72630User'@'%' = PASSWORD('pwd')"); + + final Properties props = new Properties(); + props.setProperty(PropertyKey.USER.getKeyName(), "Bug72630User"); + props.setProperty(PropertyKey.PASSWORD.getKeyName(), "pwd"); + props.setProperty(PropertyKey.characterEncoding.getKeyName(), "NonexistentEncoding"); + assertThrows(SQLException.class, "Unsupported character encoding 'NonexistentEncoding'", () -> getConnectionWithProps(props)); + + props.remove(PropertyKey.characterEncoding.getKeyName()); + props.setProperty(PropertyKey.passwordCharacterEncoding.getKeyName(), "NonexistentEncoding"); + assertThrows(SQLException.class, "Unsupported character encoding 'NonexistentEncoding'", () -> getConnectionWithProps(props)); } } diff --git a/src/test/java/testsuite/regression/ConnectionRegressionTest.java b/src/test/java/testsuite/regression/ConnectionRegressionTest.java index 3b6bec321..99958fd0a 100644 --- a/src/test/java/testsuite/regression/ConnectionRegressionTest.java +++ b/src/test/java/testsuite/regression/ConnectionRegressionTest.java @@ -3164,15 +3164,15 @@ public void testDisabledPlugins() throws Exception { props.setProperty(PropertyKey.allowPublicKeyRetrieval.getKeyName(), "true"); // Disable the built-in default authentication plugin, by name. - props.setProperty(PropertyKey.disabledAuthenticationPlugins.getKeyName(), "mysql_native_password"); - assertThrows(SQLException.class, "Can't disable the default authentication plugin\\. Either remove \"mysql_native_password\" from the disabled " + props.setProperty(PropertyKey.disabledAuthenticationPlugins.getKeyName(), "caching_sha2_password"); + assertThrows(SQLException.class, "Can't disable the default authentication plugin\\. Either remove \"caching_sha2_password\" from the disabled " + "authentication plugins list, or choose a different default authentication plugin\\.", () -> getConnectionWithProps(props)); // Disable the built-in default authentication plugin, by class. - props.setProperty(PropertyKey.disabledAuthenticationPlugins.getKeyName(), MysqlNativePasswordPlugin.class.getName()); + props.setProperty(PropertyKey.disabledAuthenticationPlugins.getKeyName(), CachingSha2PasswordPlugin.class.getName()); assertThrows(SQLException.class, "Can't disable the default authentication plugin\\. Either remove " - + "\"com\\.mysql\\.cj\\.protocol\\.a\\.authentication\\.MysqlNativePasswordPlugin\" from the disabled authentication plugins list, " + + "\"com\\.mysql\\.cj\\.protocol\\.a\\.authentication\\.CachingSha2PasswordPlugin\" from the disabled authentication plugins list, " + "or choose a different default authentication plugin\\.", () -> getConnectionWithProps(props));