diff --git a/CHANGES b/CHANGES index 5bfb71954..d3440bdbd 100644 --- a/CHANGES +++ b/CHANGES @@ -3,6 +3,8 @@ Version 9.0.0 + - Fix for Bug#114687 (Bug#36529541), Tests fail after mysql_native_password has been made optional in server. + - WL#16319, Remove deprecated insensitive terminology based methods. - WL#16324, Update static MySQL keywords list. diff --git a/src/test/java/testsuite/BaseTestCase.java b/src/test/java/testsuite/BaseTestCase.java index 86535ddb0..f02b55adf 100644 --- a/src/test/java/testsuite/BaseTestCase.java +++ b/src/test/java/testsuite/BaseTestCase.java @@ -1288,6 +1288,16 @@ protected boolean supportsTLSv1_2(ServerVersion version) throws Exception { || version.meetsMinimum(new ServerVersion(5, 6, 0)) && Util.isEnterpriseEdition(version.toString()); } + protected boolean supportsMysqlNativePassword(Statement st) throws Exception { + return isPluginActive(st, "mysql_native_password"); + } + + protected boolean isPluginActive(Statement st, String plugin) throws SQLException { + ResultSet rsCheck = st.executeQuery( + "SELECT EXISTS(SELECT * FROM information_schema.plugins WHERE plugin_name = '" + plugin + "' AND plugin_status = 'ACTIVE') AS is_active"); + return rsCheck.next() && rsCheck.getBoolean(1); + } + protected String getHighestCommonTlsVersion() throws Exception { // Find out which TLS protocol versions are supported by this JVM. SSLContext sslContext = SSLContext.getInstance("TLS"); diff --git a/src/test/java/testsuite/regression/ConnectionRegressionTest.java b/src/test/java/testsuite/regression/ConnectionRegressionTest.java index 6809c1844..d34afe146 100644 --- a/src/test/java/testsuite/regression/ConnectionRegressionTest.java +++ b/src/test/java/testsuite/regression/ConnectionRegressionTest.java @@ -1789,7 +1789,7 @@ public void testBug37570() throws Exception { String user = "bug37570"; Statement st = con.createStatement(); - createUser(st, "'" + user + "'@'%'", "identified WITH mysql_native_password"); + createUser(st, "'" + user + "'@'%'", ""); st.executeUpdate("grant all on *.* to '" + user + "'@'%'"); st.executeUpdate(versionMeetsMinimum(5, 7, 6) ? "ALTER USER '" + user + "'@'%' IDENTIFIED BY '" + unicodePassword + "'" : "SET PASSWORD FOR '" + user + "'@'%' = PASSWORD('" + unicodePassword + "')"); @@ -1797,8 +1797,7 @@ public void testBug37570() throws Exception { try { ((JdbcConnection) con).changeUser(user, unicodePassword); - } catch (SQLException sqle) { - sqle.printStackTrace(); + } catch (SQLException e) { fail("Connection with non-latin1 password failed"); } } @@ -3214,14 +3213,7 @@ public void testAuthTestPlugin() throws Exception { boolean installPluginInRuntime = false; try { // Install plugin if required. - this.rs = this.stmt.executeQuery( - "SELECT (PLUGIN_LIBRARY LIKE 'auth_test_plugin%') as `TRUE` FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME='test_plugin_server'"); - if (this.rs.next()) { - installPluginInRuntime = !this.rs.getBoolean(1); - } else { - installPluginInRuntime = true; - } - + installPluginInRuntime = !isPluginActive(this.stmt, "test_plugin_server"); if (installPluginInRuntime) { try { String ext = isServerRunningOnWindows() ? ".dll" : ".so"; @@ -3278,13 +3270,7 @@ public void testTwoQuestionsPlugin() throws Exception { boolean installPluginInRuntime = false; try { // Install plugin if required. - this.rs = this.stmt.executeQuery("SELECT PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME='two_questions'"); - if (this.rs.next()) { - assumeTrue(this.rs.getString(1).equals("ACTIVE"), "The 'two_questions' plugin is preinstalled but not active."); - } else { - installPluginInRuntime = true; - } - + installPluginInRuntime = !isPluginActive(this.stmt, "two_questions"); if (installPluginInRuntime) { try { String ext = isServerRunningOnWindows() ? ".dll" : ".so"; @@ -3337,13 +3323,7 @@ public void testThreeAttemptsPlugin() throws Exception { boolean installPluginInRuntime = false; try { // Install plugin if required. - this.rs = this.stmt.executeQuery("SELECT PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME='three_attempts'"); - if (this.rs.next()) { - assumeTrue(this.rs.getString(1).equals("ACTIVE"), "The 'three_attempts' plugin is preinstalled but not active."); - } else { - installPluginInRuntime = true; - } - + installPluginInRuntime = !isPluginActive(this.stmt, "three_attempts"); if (installPluginInRuntime) { try { String ext = isServerRunningOnWindows() ? ".dll" : ".so"; @@ -3651,14 +3631,7 @@ public void testAuthCleartextPlugin() throws Exception { boolean installPluginInRuntime = false; try { // Install plugin if required. - this.rs = this.stmt.executeQuery("SELECT (PLUGIN_LIBRARY LIKE 'auth_test_plugin%') as `TRUE` FROM INFORMATION_SCHEMA.PLUGINS " - + "WHERE PLUGIN_NAME='cleartext_plugin_server'"); - if (this.rs.next()) { - installPluginInRuntime = !this.rs.getBoolean(1); - } else { - installPluginInRuntime = true; - } - + installPluginInRuntime = !isPluginActive(this.stmt, "cleartext_plugin_server"); if (installPluginInRuntime) { try { String ext = isServerRunningOnWindows() ? ".dll" : ".so"; @@ -3723,7 +3696,7 @@ public void testSha256PasswordPlugin() throws Exception { assumeTrue(versionMeetsMinimum(5, 6, 5), "MySQL 5.6.5+ is required to run this test."); assumeTrue((((MysqlConnection) this.conn).getSession().getServerSession().getCapabilities().getCapabilityFlags() & NativeServerSession.CLIENT_SSL) != 0, "This test requires server with SSL support."); - assumeTrue(pluginIsActive(this.stmt, "sha256_password"), "sha256_password plugin required to run this test"); + assumeTrue(isPluginActive(this.stmt, "sha256_password"), "sha256_password plugin required to run this test"); assumeTrue(supportsTestCertificates(this.stmt), "This test requires the server configured with SSL certificates from ConnectorJ/src/test/config/ssl-test-certs"); @@ -3963,15 +3936,6 @@ private void assertCurrentUser(String url, Properties props, String expectedUser connection.close(); } - private boolean pluginIsActive(Statement st, String plugin) throws SQLException { - ResultSet rset = st.executeQuery("SELECT (PLUGIN_STATUS='ACTIVE') AS `TRUE` FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME='" + plugin + "'"); - boolean pluginIsActive = false; - if (rset.next()) { - pluginIsActive = rset.getBoolean(1); - } - return pluginIsActive; - } - private boolean allowsRsa(Statement st) throws SQLException { boolean allowsRSA = false; ResultSet rset = st.executeQuery("SHOW STATUS LIKE 'Rsa_public_key'"); @@ -5208,7 +5172,7 @@ private boolean isResultSetClosedForTestBug69746(ResultSet resultSet) { public void testLongAuthResponsePayload() throws Exception { NativeSession testSess; assumeTrue((testSess = (NativeSession) ((MysqlConnection) this.conn).getSession()).versionMeetsMinimum(5, 6, 6), "Requires MySQL 5.6.6+."); - assumeTrue(pluginIsActive(this.stmt, "sha256_password"), "sha256_password required to run this test"); + assumeTrue(isPluginActive(this.stmt, "sha256_password"), "sha256_password required to run this test"); assumeTrue(supportsTestCertificates(this.stmt), "This test requires the server configured with SSL certificates from ConnectorJ/src/test/config/ssl-test-certs"); assumeTrue(supportsTestSha256PasswordKeys(this.stmt), @@ -5771,33 +5735,37 @@ private void testBug62577TestUrl(String url) throws Exception { @Test public void testBug18869381() throws Exception { assumeTrue(((MysqlConnection) this.conn).getSession().versionMeetsMinimum(5, 6, 6), "Requires MySQL 5.6.6+."); - assumeTrue(pluginIsActive(this.stmt, "sha256_password"), "sha256_password plugin required to run this test"); + assumeTrue(isPluginActive(this.stmt, "sha256_password"), "sha256_password plugin required to run this test"); assumeTrue(supportsTestCertificates(this.stmt), "This test requires the server configured with SSL certificates from ConnectorJ/src/test/config/ssl-test-certs"); + boolean supportsMysqlNative = supportsMysqlNativePassword(this.stmt); + try { if (!((MysqlConnection) this.conn).getSession().versionMeetsMinimum(8, 0, 5)) { this.stmt.executeUpdate("SET @current_old_passwords = @@global.old_passwords"); } - createUser(this.stmt, "'bug18869381user1'@'%'", "identified WITH sha256_password"); - this.stmt.executeUpdate("grant all on *.* to 'bug18869381user1'@'%'"); - createUser(this.stmt, "'bug18869381user2'@'%'", "identified WITH sha256_password"); - this.stmt.executeUpdate("grant all on *.* to 'bug18869381user2'@'%'"); - createUser(this.stmt, "'bug18869381user3'@'%'", "identified WITH mysql_native_password"); - this.stmt.executeUpdate("grant all on *.* to 'bug18869381user3'@'%'"); - this.stmt.executeUpdate( - ((MysqlConnection) this.conn).getSession().versionMeetsMinimum(5, 7, 6) ? "ALTER USER 'bug18869381user3'@'%' IDENTIFIED BY 'pwd3'" - : "set password for 'bug18869381user3'@'%' = PASSWORD('pwd3')"); + createUser(this.stmt, "'bug18869381user1'@'%'", "IDENTIFIED WITH sha256_password"); + this.stmt.executeUpdate("GRANT ALL ON *.* TO 'bug18869381user1'@'%'"); + createUser(this.stmt, "'bug18869381user2'@'%'", "IDENTIFIED WITH sha256_password"); + this.stmt.executeUpdate("GRANT ALL ON *.* TO 'bug18869381user2'@'%'"); + if (supportsMysqlNative) { + createUser(this.stmt, "'bug18869381user3'@'%'", "IDENTIFIED WITH mysql_native_password"); + this.stmt.executeUpdate("GRANT ALL ON *.* TO 'bug18869381user3'@'%'"); + this.stmt.executeUpdate( + ((MysqlConnection) this.conn).getSession().versionMeetsMinimum(5, 7, 6) ? "ALTER USER 'bug18869381user3'@'%' IDENTIFIED BY 'pwd3'" + : "SET PASSWORD FOR 'bug18869381user3'@'%' = PASSWORD('pwd3')"); + } if (!((MysqlConnection) this.conn).getSession().versionMeetsMinimum(8, 0, 5)) { - this.stmt.executeUpdate("SET GLOBAL old_passwords= 2"); - this.stmt.executeUpdate("SET SESSION old_passwords= 2"); + this.stmt.executeUpdate("SET GLOBAL old_passwords = 2"); + this.stmt.executeUpdate("SET SESSION old_passwords = 2"); } this.stmt.executeUpdate(((MysqlConnection) this.conn).getSession().versionMeetsMinimum(5, 7, 6) ? "ALTER USER 'bug18869381user1'@'%' IDENTIFIED BY 'LongLongLongLongLongLongLongLongLongLongLongLongPwd1'" - : "set password for 'bug18869381user1'@'%' = PASSWORD('LongLongLongLongLongLongLongLongLongLongLongLongPwd1')"); + : "SET PASSWORD FOR 'bug18869381user1'@'%' = PASSWORD('LongLongLongLongLongLongLongLongLongLongLongLongPwd1')"); this.stmt.executeUpdate( ((MysqlConnection) this.conn).getSession().versionMeetsMinimum(5, 7, 6) ? "ALTER USER 'bug18869381user2'@'%' IDENTIFIED BY 'pwd2'" - : "set password for 'bug18869381user2'@'%' = PASSWORD('pwd2')"); + : "SET PASSWORD FOR 'bug18869381user2'@'%' = PASSWORD('pwd2')"); this.stmt.executeUpdate("flush privileges"); Properties props = new Properties(); @@ -5805,21 +5773,21 @@ public void testBug18869381() throws Exception { props.setProperty(PropertyKey.defaultAuthenticationPlugin.getKeyName(), MysqlNativePasswordPlugin.class.getName()); props.setProperty(PropertyKey.useCompression.getKeyName(), "false"); - testBug18869381WithProperties(dbUrl, props); + testBug18869381WithProperties(dbUrl, props, supportsMysqlNative); props.setProperty(PropertyKey.useCompression.getKeyName(), "true"); - testBug18869381WithProperties(dbUrl, props); + testBug18869381WithProperties(dbUrl, props, supportsMysqlNative); props.setProperty(PropertyKey.defaultAuthenticationPlugin.getKeyName(), Sha256PasswordPlugin.class.getName()); props.setProperty(PropertyKey.useCompression.getKeyName(), "false"); - testBug18869381WithProperties(dbUrl, props); + testBug18869381WithProperties(dbUrl, props, supportsMysqlNative); props.setProperty(PropertyKey.useCompression.getKeyName(), "true"); - testBug18869381WithProperties(dbUrl, props); + testBug18869381WithProperties(dbUrl, props, supportsMysqlNative); props.setProperty(PropertyKey.serverRSAPublicKeyFile.getKeyName(), "src/test/config/ssl-test-certs/mykey.pub"); props.setProperty(PropertyKey.useCompression.getKeyName(), "false"); - testBug18869381WithProperties(dbUrl, props); + testBug18869381WithProperties(dbUrl, props, supportsMysqlNative); props.setProperty(PropertyKey.useCompression.getKeyName(), "true"); - testBug18869381WithProperties(dbUrl, props); + testBug18869381WithProperties(dbUrl, props, supportsMysqlNative); String trustStorePath = "src/test/config/ssl-test-certs/ca-truststore"; System.setProperty("javax.net.ssl.keyStore", trustStorePath); @@ -5828,9 +5796,9 @@ public void testBug18869381() throws Exception { System.setProperty("javax.net.ssl.trustStorePassword", "password"); props.setProperty(PropertyKey.sslMode.getKeyName(), SslMode.REQUIRED.name()); props.setProperty(PropertyKey.useCompression.getKeyName(), "false"); - testBug18869381WithProperties(dbUrl, props); + testBug18869381WithProperties(dbUrl, props, supportsMysqlNative); props.setProperty(PropertyKey.useCompression.getKeyName(), "true"); - testBug18869381WithProperties(dbUrl, props); + testBug18869381WithProperties(dbUrl, props, supportsMysqlNative); } finally { if (!((MysqlConnection) this.conn).getSession().versionMeetsMinimum(8, 0, 5)) { @@ -5840,7 +5808,7 @@ public void testBug18869381() throws Exception { } @Test - private void testBug18869381WithProperties(String url, Properties props) throws Exception { + private void testBug18869381WithProperties(String url, Properties props, boolean supportsMysqlNative) throws Exception { Connection testConn = null; Statement testSt = null; ResultSet testRs = null; @@ -5850,7 +5818,7 @@ private void testBug18869381WithProperties(String url, Properties props) throws ((JdbcConnection) testConn).changeUser("bug18869381user1", "LongLongLongLongLongLongLongLongLongLongLongLongPwd1"); testSt = testConn.createStatement(); - testRs = testSt.executeQuery("select USER(),CURRENT_USER()"); + testRs = testSt.executeQuery("SELECT USER(),CURRENT_USER()"); testRs.next(); assertEquals("bug18869381user1", testRs.getString(1).split("@")[0]); assertEquals("bug18869381user1", testRs.getString(2).split("@")[0]); @@ -5858,18 +5826,20 @@ private void testBug18869381WithProperties(String url, Properties props) throws ((JdbcConnection) testConn).changeUser("bug18869381user2", "pwd2"); testSt = testConn.createStatement(); - testRs = testSt.executeQuery("select USER(),CURRENT_USER()"); + testRs = testSt.executeQuery("SELECT USER(),CURRENT_USER()"); testRs.next(); assertEquals("bug18869381user2", testRs.getString(1).split("@")[0]); assertEquals("bug18869381user2", testRs.getString(2).split("@")[0]); testSt.close(); - ((JdbcConnection) testConn).changeUser("bug18869381user3", "pwd3"); - testSt = testConn.createStatement(); - testRs = testSt.executeQuery("select USER(),CURRENT_USER()"); - testRs.next(); - assertEquals("bug18869381user3", testRs.getString(1).split("@")[0]); - assertEquals("bug18869381user3", testRs.getString(2).split("@")[0]); + if (supportsMysqlNative) { + ((JdbcConnection) testConn).changeUser("bug18869381user3", "pwd3"); + testSt = testConn.createStatement(); + testRs = testSt.executeQuery("SELECT USER(),CURRENT_USER()"); + testRs.next(); + assertEquals("bug18869381user3", testRs.getString(1).split("@")[0]); + assertEquals("bug18869381user3", testRs.getString(2).split("@")[0]); + } } finally { if (testConn != null) { @@ -6324,11 +6294,11 @@ public void testBug19354014() throws Exception { assumeTrue(versionMeetsMinimum(5, 5, 7), "MySQL 5.7.7+ is required to run this test."); Connection con = null; - createUser("'bug19354014user'@'%'", "identified WITH mysql_native_password"); - this.stmt.executeUpdate("grant all on *.* to 'bug19354014user'@'%'"); + createUser("'bug19354014user'@'%'", ""); + this.stmt.executeUpdate("GRANT ALL ON *.* to 'bug19354014user'@'%'"); this.stmt.executeUpdate(versionMeetsMinimum(5, 7, 6) ? "ALTER USER 'bug19354014user'@'%' IDENTIFIED BY 'pwd'" - : "set password for 'bug19354014user'@'%' = PASSWORD('pwd')"); - this.stmt.executeUpdate("flush privileges"); + : "SET PASSWORD FOR 'bug19354014user'@'%' = PASSWORD('pwd')"); + this.stmt.executeUpdate("FLUSH PRIVILEGES"); try { Properties props = new Properties(); @@ -6339,7 +6309,7 @@ public void testBug19354014() throws Exception { con = getConnectionWithProps(props); ((JdbcConnection) con).changeUser("bug19354014user", "pwd"); } finally { - this.stmt.executeUpdate("flush privileges"); + this.stmt.executeUpdate("FLUSH PRIVILEGES"); if (con != null) { con.close(); @@ -6772,9 +6742,7 @@ public void testBug20825727() throws Exception { String[] plugins; // install cleartext plugin if required - this.rs = testStmt.executeQuery( - "SELECT (PLUGIN_LIBRARY LIKE 'auth_test_plugin%') FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME='cleartext_plugin_server'"); - if (!this.rs.next() || !this.rs.getBoolean(1)) { + if (!isPluginActive(this.stmt, "cleartext_plugin_server")) { String ext = System.getProperty(PropertyDefinitions.SYSP_os_name).toUpperCase().indexOf("WINDOWS") > -1 ? ".dll" : ".so"; try { @@ -6790,9 +6758,12 @@ public void testBug20825727() throws Exception { clearTextPluginInstalled = true; } - if (testConn.getSession().versionMeetsMinimum(5, 7, 5)) { - // mysql_old_password plugin not supported - plugins = new String[] { "cleartext_plugin_server,-1", "mysql_native_password,0", "sha256_password,2" }; + if (testConn.getSession().versionMeetsMinimum(5, 7, 5)) { // mysql_old_password plugin not supported + if (supportsMysqlNativePassword(this.stmt)) { + plugins = new String[] { "cleartext_plugin_server,-1", "mysql_native_password,0", "sha256_password,2" }; + } else { + plugins = new String[] { "cleartext_plugin_server,-1", "sha256_password,2" }; + } } else if (testConn.getSession().versionMeetsMinimum(5, 6, 6)) { plugins = new String[] { "cleartext_plugin_server,-1", "mysql_native_password,0", "mysql_old_password,1", "sha256_password,2" }; @@ -7047,7 +7018,7 @@ public Void call() throws Exception { @Test public void testBug75670() throws Exception { assumeTrue(((MysqlConnection) this.conn).getSession().versionMeetsMinimum(5, 6, 6), "Requires MySQL 5.6.6+."); - assumeTrue(pluginIsActive(this.stmt, "sha256_password"), "sha256_password plugin required to run this test"); + assumeTrue(isPluginActive(this.stmt, "sha256_password"), "sha256_password plugin required to run this test"); assumeTrue(supportsTestCertificates(this.stmt), "This test requires the server configured with SSL certificates from ConnectorJ/src/test/config/ssl-test-certs"); assumeTrue(supportsTestSha256PasswordKeys(this.stmt), @@ -9418,7 +9389,7 @@ public void testCachingSha2PasswordPlugin() throws Exception { "This test requires server with SSL support."); assumeTrue(supportsTestCertificates(this.stmt), "This test requires the server configured with SSL certificates from ConnectorJ/src/test/config/ssl-test-certs"); - assumeTrue(pluginIsActive(this.stmt, "caching_sha2_password"), "caching_sha2_password plugin required to run this test"); + assumeTrue(isPluginActive(this.stmt, "caching_sha2_password"), "caching_sha2_password plugin required to run this test"); String trustStorePath = "src/test/config/ssl-test-certs/ca-truststore"; System.setProperty("javax.net.ssl.keyStore", trustStorePath); @@ -10480,7 +10451,7 @@ public void testBug25642226() throws Exception { assumeTrue((((MysqlConnection) this.conn).getSession().getServerSession().getCapabilities().getCapabilityFlags() & NativeServerSession.CLIENT_SSL) != 0, "This test requires server with SSL support."); assumeTrue(((MysqlConnection) this.conn).getSession().versionMeetsMinimum(5, 6, 5), "Requires MySQL 5.6.5+ server."); - assumeTrue(pluginIsActive(this.stmt, "sha256_password"), "sha256_password required to run this test"); + assumeTrue(isPluginActive(this.stmt, "sha256_password"), "sha256_password required to run this test"); assumeTrue(supportsTestCertificates(this.stmt), "This test requires the server configured with SSL certificates from ConnectorJ/src/test/config/ssl-test-certs"); @@ -10528,7 +10499,7 @@ public void testBug25642226() throws Exception { // create user with required password and caching_sha2_password auth if (sess.versionMeetsMinimum(8, 0, 3)) { - assertTrue(pluginIsActive(s1, "caching_sha2_password"), "caching_sha2_password required to run this test"); + assertTrue(isPluginActive(s1, "caching_sha2_password"), "caching_sha2_password required to run this test"); // create user with required password and sha256_password auth createUser(s1, "'Bug25642226u2'@'%'", "identified WITH caching_sha2_password"); s1.executeUpdate("grant all on *.* to 'Bug25642226u2'@'%'"); @@ -11209,7 +11180,7 @@ public void testDefaultUserWithoutPasswordAuthentication() throws Exception { String[] authenticationPlugins = new String[] { "caching_sha2_password", "sha256_password", "mysql_native_password" }; List authenticationPluginsTested = new ArrayList<>(); for (String authPlugin : authenticationPlugins) { - if (pluginIsActive(this.stmt, authPlugin)) { + if (isPluginActive(this.stmt, authPlugin)) { assertThrows(SQLException.class, String.format("Access denied for user '%s'@.*", systemUsername), () -> getConnectionWithProps(String.format("jdbc:mysql://%s:%s", getHostFromTestsuiteUrl(), getPortFromTestsuiteUrl()), "sslMode=DISABLED,allowPublicKeyRetrieval=true,defaultAuthenticationPlugin=" + authPlugin)); @@ -11250,10 +11221,10 @@ public void testDefaultUserWithPasswordAuthentication() throws Exception { String[] authenticationPlugins = new String[] { "caching_sha2_password", "sha256_password", "mysql_native_password" }; List authenticationPluginsTested = new ArrayList<>(); for (String authPlugin : authenticationPlugins) { - if (pluginIsActive(this.stmt, authPlugin)) { + if (isPluginActive(this.stmt, authPlugin)) { assertThrows(SQLException.class, String.format("Access denied for user '%s'@.*", systemUsername), () -> getConnectionWithProps(String.format("jdbc:mysql://%s:%s", getHostFromTestsuiteUrl(), getPortFromTestsuiteUrl()), - "defaultAuthenticationPlugin=" + authPlugin)); + "defaultAuthenticationPlugin=" + authPlugin + ",sslMode=DISABLED,allowPublicKeyRetreival=true")); createUser(systemUsername, "IDENTIFIED WITH " + authPlugin + " BY 'testpwd'"); this.stmt.execute("GRANT ALL ON *.* TO " + systemUsername); diff --git a/src/test/java/testsuite/regression/SyntaxRegressionTest.java b/src/test/java/testsuite/regression/SyntaxRegressionTest.java index a378cfd3e..74c2e0528 100644 --- a/src/test/java/testsuite/regression/SyntaxRegressionTest.java +++ b/src/test/java/testsuite/regression/SyntaxRegressionTest.java @@ -1978,12 +1978,7 @@ public void testUserAccountPwdExpiration() throws Exception { public void testInnodbTablespaceEncryption() throws Exception { assumeTrue(versionMeetsMinimum(5, 7, 11), "MySQL 5.7.11+ is required to run this test."); - boolean keyringPluginIsActive = false; - this.rs = this.stmt.executeQuery("SELECT (PLUGIN_STATUS='ACTIVE') AS `TRUE` FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME LIKE 'keyring_file'"); - if (this.rs.next()) { - keyringPluginIsActive = this.rs.getBoolean(1); - } - + boolean keyringPluginIsActive = isPluginActive(this.stmt, "keyring_file"); if (keyringPluginIsActive) { createTable("testInnodbTablespaceEncryption", "(id INT, txt VARCHAR(100)) ENCRYPTION='y'"); diff --git a/src/test/java/testsuite/simple/AuthenticationTest.java b/src/test/java/testsuite/simple/AuthenticationTest.java index 05acd32ea..f2981cde0 100644 --- a/src/test/java/testsuite/simple/AuthenticationTest.java +++ b/src/test/java/testsuite/simple/AuthenticationTest.java @@ -549,9 +549,7 @@ public void testWl14650() throws Exception { boolean installPluginInRuntime = false; try { // Install plugin if required. - this.rs = this.stmt.executeQuery("SELECT (PLUGIN_LIBRARY LIKE 'auth_test_plugin%') AS installed FROM INFORMATION_SCHEMA.PLUGINS " - + "WHERE PLUGIN_NAME='cleartext_plugin_server'"); - installPluginInRuntime = !this.rs.next() || !this.rs.getBoolean(1); + installPluginInRuntime = !isPluginActive(this.stmt, "cleartext_plugin_server"); if (installPluginInRuntime) { try { diff --git a/src/test/java/testsuite/x/devapi/DevApiBaseTestCase.java b/src/test/java/testsuite/x/devapi/DevApiBaseTestCase.java index 155a0b7fe..4b71a1745 100644 --- a/src/test/java/testsuite/x/devapi/DevApiBaseTestCase.java +++ b/src/test/java/testsuite/x/devapi/DevApiBaseTestCase.java @@ -211,6 +211,12 @@ int getPreparedStatementExecutionsCount(Session sess, int prepStmtId) { return -1; } + protected boolean isPluginActive(Session sess, String plugin) { + SqlResult res = sess.sql("SELECT EXISTS(SELECT * FROM information_schema.plugins WHERE plugin_name = ? AND plugin_status = 'ACTIVE') AS is_active") + .bind(plugin).execute(); + return res.fetchOne().getBoolean(0); + } + protected boolean supportsTestCertificates(Session sess) { SqlResult res = sess.sql("SELECT @@mysqlx_ssl_ca, @@ssl_ca").execute(); if (res.hasNext()) { diff --git a/src/test/java/testsuite/x/devapi/Ipv6SupportTest.java b/src/test/java/testsuite/x/devapi/Ipv6SupportTest.java index ac4d423b2..d74f3dc07 100644 --- a/src/test/java/testsuite/x/devapi/Ipv6SupportTest.java +++ b/src/test/java/testsuite/x/devapi/Ipv6SupportTest.java @@ -53,7 +53,7 @@ public void setupIpv6SupportTest() { } this.session.sql("DROP USER IF EXISTS '" + this.testUser + "'@'%'").execute(); - this.session.sql("CREATE USER '" + this.testUser + "'@'%' IDENTIFIED WITH mysql_native_password BY '" + this.testUser + "'").execute(); + this.session.sql("CREATE USER '" + this.testUser + "'@'%' IDENTIFIED BY '" + this.testUser + "'").execute(); this.session.sql("GRANT ALL ON *.* TO '" + this.testUser + "'@'%'").execute(); } } diff --git a/src/test/java/testsuite/x/devapi/SecureSessionTest.java b/src/test/java/testsuite/x/devapi/SecureSessionTest.java index 542ecdf74..f354b0785 100644 --- a/src/test/java/testsuite/x/devapi/SecureSessionTest.java +++ b/src/test/java/testsuite/x/devapi/SecureSessionTest.java @@ -178,7 +178,7 @@ public void teardownSecureSessionTest() { public void testNonSecureSession() { try { Session testSession = this.fact.getSession(this.baseUrl); - testSession.sql("CREATE USER IF NOT EXISTS 'testPlainAuth'@'%' IDENTIFIED WITH mysql_native_password BY 'pwd'").execute(); + testSession.sql("CREATE USER IF NOT EXISTS 'testPlainAuth'@'%' IDENTIFIED BY 'pwd'").execute(); testSession.sql("GRANT SELECT ON *.* TO 'testPlainAuth'@'%'").execute(); testSession.close(); @@ -187,6 +187,11 @@ public void testNonSecureSession() { userAndSslFreeBaseUrl = userAndSslFreeBaseUrl.replaceAll(PropertyKey.USER.getKeyName() + "=", PropertyKey.USER.getKeyName() + "VOID="); userAndSslFreeBaseUrl = userAndSslFreeBaseUrl.replaceAll(PropertyKey.PASSWORD.getKeyName() + "=", PropertyKey.PASSWORD.getKeyName() + "VOID="); + // Connect securely once so that the user credentials get cached in case of using caching_sha2_password by default. + testSession = this.fact.getSession(userAndSslFreeBaseUrl + makeParam(PropertyKey.xdevapiSslMode, XdevapiSslMode.REQUIRED) + + makeParam(PropertyKey.USER, "testPlainAuth") + makeParam(PropertyKey.PASSWORD, "pwd")); + + // Connect via non-secure session. testSession = this.fact.getSession(userAndSslFreeBaseUrl + makeParam(PropertyKey.xdevapiSslMode, XdevapiSslMode.DISABLED) + makeParam(PropertyKey.USER, "testPlainAuth") + makeParam(PropertyKey.PASSWORD, "pwd")); assertNonSecureSession(testSession); @@ -379,9 +384,13 @@ public void testSecureSessionVerifyServerCertificateIdentityFailure() { */ @Test public void testAuthMechanisms() throws Throwable { + boolean supportsMysqlNative = isPluginActive(this.session, "mysql_native_password"); + try { - this.session.sql("CREATE USER IF NOT EXISTS 'testAuthMechNative'@'%' IDENTIFIED WITH mysql_native_password BY 'mysqlnative'").execute(); - this.session.sql("GRANT SELECT ON *.* TO 'testAuthMechNative'@'%'").execute(); + if (supportsMysqlNative) { + this.session.sql("CREATE USER IF NOT EXISTS 'testAuthMechNative'@'%' IDENTIFIED WITH mysql_native_password BY 'mysqlnative'").execute(); + this.session.sql("GRANT SELECT ON *.* TO 'testAuthMechNative'@'%'").execute(); + } this.session.sql("CREATE USER IF NOT EXISTS 'testAuthMechSha256'@'%' IDENTIFIED WITH sha256_password BY 'sha256'").execute(); this.session.sql("GRANT SELECT ON *.* TO 'testAuthMechSha256'@'%'").execute(); if (mysqlVersionMeetsMinimum(ServerVersion.parseVersion("8.0.3"))) { @@ -419,15 +428,17 @@ public void testAuthMechanisms() throws Throwable { // With default auth mechanism for secure connections (PLAIN). - // *** User: mysqlnative; Auth: default. - props.setProperty(PropertyKey.USER.getKeyName(), "testAuthMechNative"); - props.setProperty(PropertyKey.PASSWORD.getKeyName(), "mysqlnative"); + if (supportsMysqlNative) { + // *** User: mysqlnative; Auth: default. + props.setProperty(PropertyKey.USER.getKeyName(), "testAuthMechNative"); + props.setProperty(PropertyKey.PASSWORD.getKeyName(), "mysqlnative"); - testSession = this.fact.getSession(props); - assertSecureSession(testSession); - assertEquals(AuthMech.PLAIN, getAuthMech.apply(testSession)); // Connection is secure, passwords are safe & account gets cached. - assertUser("testAuthMechNative", testSession); - testSession.close(); + testSession = this.fact.getSession(props); + assertSecureSession(testSession); + assertEquals(AuthMech.PLAIN, getAuthMech.apply(testSession)); // Connection is secure, passwords are safe & account gets cached. + assertUser("testAuthMechNative", testSession); + testSession.close(); + } if (mysqlVersionMeetsMinimum(ServerVersion.parseVersion("8.0.3"))) { // *** User: testAuthMechSha256; Auth: default. @@ -455,35 +466,37 @@ public void testAuthMechanisms() throws Throwable { // Forcing an auth mechanism. - // *** User: testAuthMechNative; Auth: PLAIN. - props.setProperty(PropertyKey.USER.getKeyName(), "testAuthMechNative"); - props.setProperty(PropertyKey.PASSWORD.getKeyName(), "mysqlnative"); - props.setProperty(PropertyKey.xdevapiAuth.getKeyName(), "PLAIN"); - - testSession = this.fact.getSession(props); - assertSecureSession(testSession); - assertEquals(AuthMech.PLAIN, getAuthMech.apply(testSession)); // Connection is secure, passwords are safe. - assertUser("testAuthMechNative", testSession); - testSession.close(); - - // *** User: testAuthMechNative; Auth: MYSQL41. - props.setProperty(PropertyKey.xdevapiAuth.getKeyName(), "MYSQL41"); + if (supportsMysqlNative) { + // *** User: testAuthMechNative; Auth: PLAIN. + props.setProperty(PropertyKey.USER.getKeyName(), "testAuthMechNative"); + props.setProperty(PropertyKey.PASSWORD.getKeyName(), "mysqlnative"); + props.setProperty(PropertyKey.xdevapiAuth.getKeyName(), "PLAIN"); - testSession = this.fact.getSession(props); - assertSecureSession(testSession); - assertEquals(AuthMech.MYSQL41, getAuthMech.apply(testSession)); // Matching auth mechanism. - assertUser("testAuthMechNative", testSession); - testSession.close(); + testSession = this.fact.getSession(props); + assertSecureSession(testSession); + assertEquals(AuthMech.PLAIN, getAuthMech.apply(testSession)); // Connection is secure, passwords are safe. + assertUser("testAuthMechNative", testSession); + testSession.close(); - if (mysqlVersionMeetsMinimum(ServerVersion.parseVersion("8.0.4"))) { // SHA256_MEMORY support added in MySQL 8.0.4. - // *** User: testAuthMechNative; Auth: SHA256_MEMORY. - props.setProperty(PropertyKey.xdevapiAuth.getKeyName(), "SHA256_MEMORY"); + // *** User: testAuthMechNative; Auth: MYSQL41. + props.setProperty(PropertyKey.xdevapiAuth.getKeyName(), "MYSQL41"); testSession = this.fact.getSession(props); assertSecureSession(testSession); - assertEquals(AuthMech.SHA256_MEMORY, getAuthMech.apply(testSession)); // Account is cached by now. + assertEquals(AuthMech.MYSQL41, getAuthMech.apply(testSession)); // Matching auth mechanism. assertUser("testAuthMechNative", testSession); testSession.close(); + + if (mysqlVersionMeetsMinimum(ServerVersion.parseVersion("8.0.4"))) { // SHA256_MEMORY support added in MySQL 8.0.4. + // *** User: testAuthMechNative; Auth: SHA256_MEMORY. + props.setProperty(PropertyKey.xdevapiAuth.getKeyName(), "SHA256_MEMORY"); + + testSession = this.fact.getSession(props); + assertSecureSession(testSession); + assertEquals(AuthMech.SHA256_MEMORY, getAuthMech.apply(testSession)); // Account is cached by now. + assertUser("testAuthMechNative", testSession); + testSession.close(); + } } if (mysqlVersionMeetsMinimum(ServerVersion.parseVersion("8.0.3"))) { @@ -566,15 +579,17 @@ public void testAuthMechanisms() throws Throwable { // With default auth mechanism for non-secure connections (MYSQL41|SHA2_MEMORY). - // *** User: testAuthMechNative; Auth: default. - props.setProperty(PropertyKey.USER.getKeyName(), "testAuthMechNative"); - props.setProperty(PropertyKey.PASSWORD.getKeyName(), "mysqlnative"); + if (supportsMysqlNative) { + // *** User: testAuthMechNative; Auth: default. + props.setProperty(PropertyKey.USER.getKeyName(), "testAuthMechNative"); + props.setProperty(PropertyKey.PASSWORD.getKeyName(), "mysqlnative"); - testSession = this.fact.getSession(props); - assertNonSecureSession(testSession); - assertEquals(AuthMech.MYSQL41, getAuthMech.apply(testSession)); // Matching auth mechanism. - assertUser("testAuthMechNative", testSession); - testSession.close(); + testSession = this.fact.getSession(props); + assertNonSecureSession(testSession); + assertEquals(AuthMech.MYSQL41, getAuthMech.apply(testSession)); // Matching auth mechanism. + assertUser("testAuthMechNative", testSession); + testSession.close(); + } if (mysqlVersionMeetsMinimum(ServerVersion.parseVersion("8.0.4"))) { // SHA256_PASSWORD requires secure connections in MySQL 8.0.3 and below. // *** User: testAuthMechSha256; Auth: default. @@ -602,31 +617,33 @@ public void testAuthMechanisms() throws Throwable { // Forcing an auth mechanism. - // *** User: testAuthMechNative; Auth: PLAIN. - props.setProperty(PropertyKey.USER.getKeyName(), "testAuthMechNative"); - props.setProperty(PropertyKey.PASSWORD.getKeyName(), "mysqlnative"); - props.setProperty(PropertyKey.xdevapiAuth.getKeyName(), "PLAIN"); - - assertThrows(XProtocolError.class, "PLAIN authentication is not allowed via unencrypted connection\\.", () -> this.fact.getSession(props)); - - // *** User: testAuthMechNative; Auth: MYSQL41. - props.setProperty(PropertyKey.xdevapiAuth.getKeyName(), "MYSQL41"); + if (supportsMysqlNative) { + // *** User: testAuthMechNative; Auth: PLAIN. + props.setProperty(PropertyKey.USER.getKeyName(), "testAuthMechNative"); + props.setProperty(PropertyKey.PASSWORD.getKeyName(), "mysqlnative"); + props.setProperty(PropertyKey.xdevapiAuth.getKeyName(), "PLAIN"); - testSession = this.fact.getSession(props); - assertNonSecureSession(testSession); - assertEquals(AuthMech.MYSQL41, getAuthMech.apply(testSession)); // Matching auth mechanism. - assertUser("testAuthMechNative", testSession); - testSession.close(); + assertThrows(XProtocolError.class, "PLAIN authentication is not allowed via unencrypted connection\\.", () -> this.fact.getSession(props)); - if (mysqlVersionMeetsMinimum(ServerVersion.parseVersion("8.0.4"))) { // SHA256_MEMORY support added in MySQL 8.0.4. - // *** User: testAuthMechNative; Auth: SHA256_MEMORY. - props.setProperty(PropertyKey.xdevapiAuth.getKeyName(), "SHA256_MEMORY"); + // *** User: testAuthMechNative; Auth: MYSQL41. + props.setProperty(PropertyKey.xdevapiAuth.getKeyName(), "MYSQL41"); testSession = this.fact.getSession(props); assertNonSecureSession(testSession); - assertEquals(AuthMech.SHA256_MEMORY, getAuthMech.apply(testSession)); // Account is cached by now. + assertEquals(AuthMech.MYSQL41, getAuthMech.apply(testSession)); // Matching auth mechanism. assertUser("testAuthMechNative", testSession); testSession.close(); + + if (mysqlVersionMeetsMinimum(ServerVersion.parseVersion("8.0.4"))) { // SHA256_MEMORY support added in MySQL 8.0.4. + // *** User: testAuthMechNative; Auth: SHA256_MEMORY. + props.setProperty(PropertyKey.xdevapiAuth.getKeyName(), "SHA256_MEMORY"); + + testSession = this.fact.getSession(props); + assertNonSecureSession(testSession); + assertEquals(AuthMech.SHA256_MEMORY, getAuthMech.apply(testSession)); // Account is cached by now. + assertUser("testAuthMechNative", testSession); + testSession.close(); + } } if (mysqlVersionMeetsMinimum(ServerVersion.parseVersion("8.0.3"))) { @@ -694,7 +711,9 @@ public void testAuthMechanisms() throws Throwable { props.remove(PropertyKey.xdevapiAuth.getKeyName()); } finally { - this.session.sql("DROP USER IF EXISTS testAuthMechNative").execute(); + if (supportsMysqlNative) { + this.session.sql("DROP USER IF EXISTS testAuthMechNative").execute(); + } this.session.sql("DROP USER IF EXISTS testAuthMechSha256").execute(); this.session.sql("DROP USER IF EXISTS testAuthMechCachingSha2").execute(); } @@ -822,8 +841,7 @@ public void testBug25494338() throws Exception { Properties props = new Properties(this.sslFreeTestProperties); testSession = this.fact.getSession(props); - testSession.sql("CREATE USER 'bug25494338user'@'%' IDENTIFIED WITH mysql_native_password BY 'pwd' REQUIRE CIPHER '" + expectedCipher2 + "'") - .execute(); + testSession.sql("CREATE USER 'bug25494338user'@'%' IDENTIFIED BY 'pwd' REQUIRE CIPHER '" + expectedCipher2 + "'").execute(); testSession.sql("GRANT SELECT ON *.* TO 'bug25494338user'@'%'").execute(); props.setProperty(PropertyKey.xdevapiSslMode.getKeyName(), PropertyDefinitions.XdevapiSslMode.VERIFY_CA.toString()); @@ -920,6 +938,7 @@ public void testBug26227653() { public void testBug27629553() { assumeTrue(supportsTestCertificates(this.session), "This test requires the server configured with SSL certificates from ConnectorJ/src/test/config/ssl-test-certs"); + assumeTrue(isPluginActive(this.session, "mysql_native_password"), "This test requires support for 'mysql_native_password'"); Session testSession = this.fact.getSession(this.baseUrl); testSession.sql("CREATE USER IF NOT EXISTS 'testBug27629553'@'%' IDENTIFIED WITH mysql_native_password").execute(); diff --git a/src/test/java/testsuite/x/devapi/SessionTest.java b/src/test/java/testsuite/x/devapi/SessionTest.java index cceec0f7b..800677b5f 100644 --- a/src/test/java/testsuite/x/devapi/SessionTest.java +++ b/src/test/java/testsuite/x/devapi/SessionTest.java @@ -138,6 +138,8 @@ private String getRandomTestSchemaName() { @Test public void urlWithDefaultSchema() { + assumeTrue(isPluginActive(this.session, "mysql_native_password"), "This test requires support for 'mysql_native_password'"); + try { // Create user with mysql_native_password authentication plugin as it can be used with any of the authentication mechanisms. this.session.sql("CREATE USER IF NOT EXISTS 'testUserN'@'%' IDENTIFIED WITH mysql_native_password BY 'testUserN'").execute(); @@ -190,6 +192,8 @@ public void urlWithDefaultSchema() { @Test public void urlWithoutDefaultSchema() { + assumeTrue(isPluginActive(this.session, "mysql_native_password"), "This test requires support for 'mysql_native_password'"); + try { // Create user with mysql_native_password authentication plugin as it can be used with any of the authentication mechanisms. this.session.sql("CREATE USER IF NOT EXISTS 'testUserN'@'%' IDENTIFIED WITH mysql_native_password BY 'testUserN'").execute(); @@ -240,6 +244,8 @@ public void urlWithoutDefaultSchema() { @Test public void invalidDefaultSchema() { + assumeTrue(isPluginActive(this.session, "mysql_native_password"), "This test requires support for 'mysql_native_password'"); + try { // Create user with mysql_native_password authentication plugin as it can be used with any of the authentication mechanisms. this.session.sql("CREATE USER IF NOT EXISTS 'testUserN'@'%' IDENTIFIED WITH mysql_native_password BY 'testUserN'").execute(); @@ -353,7 +359,7 @@ public void errorOnPacketTooBig() { @Test public void testBug21690043() { try { - this.session.sql("CREATE USER 'bug21690043user1'@'%' IDENTIFIED WITH mysql_native_password").execute(); + this.session.sql("CREATE USER 'bug21690043user1'@'%'").execute(); this.session.sql("GRANT SELECT ON *.* TO 'bug21690043user1'@'%'").execute(); Properties props = new Properties(); diff --git a/src/test/java/testsuite/x/internal/InternalXBaseTestCase.java b/src/test/java/testsuite/x/internal/InternalXBaseTestCase.java index 22874d88b..f167720cb 100644 --- a/src/test/java/testsuite/x/internal/InternalXBaseTestCase.java +++ b/src/test/java/testsuite/x/internal/InternalXBaseTestCase.java @@ -270,4 +270,11 @@ protected static void assertSessionStatusNotEquals(Session sess, String statusVa assertNotEquals(unexpected, actual); } + protected boolean isPluginActive(String plugin) { + Session session = new SessionFactory().getSession(this.baseUrl); + SqlResult res = session.sql("SELECT EXISTS(SELECT * FROM information_schema.plugins WHERE plugin_name = ? AND plugin_status = 'ACTIVE') AS is_active") + .bind(plugin).execute(); + return res.fetchOne().getBoolean(0); + } + } diff --git a/src/test/java/testsuite/x/internal/XProtocolAuthTest.java b/src/test/java/testsuite/x/internal/XProtocolAuthTest.java index 001333333..b87abde49 100644 --- a/src/test/java/testsuite/x/internal/XProtocolAuthTest.java +++ b/src/test/java/testsuite/x/internal/XProtocolAuthTest.java @@ -86,6 +86,7 @@ public void testBasicSaslPlainAuth() throws Exception { @Test public void testBasicSaslMysql41Auth() throws Exception { assumeTrue(this.isSetForXTests, PropertyDefinitions.SYSP_testsuite_url_mysqlx + " must be set to run this test."); + assumeTrue(isPluginActive("mysql_native_password"), "This test requires support for 'mysql_native_password'"); try { Session testSession = this.fact.getSession(this.baseUrl); @@ -127,6 +128,7 @@ public void testBasicSaslPlainAuthFailure() throws Exception { @Test public void testEmptyDatabaseMYSQL41() { assumeTrue(this.isSetForXTests, PropertyDefinitions.SYSP_testsuite_url_mysqlx + " must be set to run this test."); + assumeTrue(isPluginActive("mysql_native_password"), "This test requires support for 'mysql_native_password'"); try { Session testSession = this.fact.getSession(this.baseUrl);