Search in sources :

Example 6 with MysqlConnection

use of com.mysql.cj.MysqlConnection in project aws-mysql-jdbc by awslabs.

the class ConnectionRegressionTest method testBug18869381.

/**
 * Test fix for Bug#18869381 - CHANGEUSER() FOR SHA USER RESULTS IN NULLPOINTEREXCEPTION
 *
 * @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(supportsTestCertificates(this.stmt), "This test requires the server configured with SSL certificates from ConnectorJ/src/test/config/ssl-test-certs");
    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')");
        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(((MysqlConnection) this.conn).getSession().versionMeetsMinimum(5, 7, 6) ? "ALTER USER 'bug18869381user1'@'%' IDENTIFIED BY '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')");
        this.stmt.executeUpdate("flush privileges");
        Properties props = new Properties();
        props.setProperty(PropertyKey.allowPublicKeyRetrieval.getKeyName(), "true");
        props.setProperty(PropertyKey.defaultAuthenticationPlugin.getKeyName(), MysqlNativePasswordPlugin.class.getName());
        props.setProperty(PropertyKey.useCompression.getKeyName(), "false");
        testBug18869381WithProperties(dbUrl, props);
        props.setProperty(PropertyKey.useCompression.getKeyName(), "true");
        testBug18869381WithProperties(dbUrl, props);
        props.setProperty(PropertyKey.defaultAuthenticationPlugin.getKeyName(), Sha256PasswordPlugin.class.getName());
        props.setProperty(PropertyKey.useCompression.getKeyName(), "false");
        testBug18869381WithProperties(dbUrl, props);
        props.setProperty(PropertyKey.useCompression.getKeyName(), "true");
        testBug18869381WithProperties(dbUrl, props);
        props.setProperty(PropertyKey.serverRSAPublicKeyFile.getKeyName(), "src/test/config/ssl-test-certs/mykey.pub");
        props.setProperty(PropertyKey.useCompression.getKeyName(), "false");
        testBug18869381WithProperties(dbUrl, props);
        props.setProperty(PropertyKey.useCompression.getKeyName(), "true");
        testBug18869381WithProperties(dbUrl, props);
        String trustStorePath = "src/test/config/ssl-test-certs/ca-truststore";
        System.setProperty("javax.net.ssl.keyStore", trustStorePath);
        System.setProperty("javax.net.ssl.keyStorePassword", "password");
        System.setProperty("javax.net.ssl.trustStore", trustStorePath);
        System.setProperty("javax.net.ssl.trustStorePassword", "password");
        props.setProperty(PropertyKey.sslMode.getKeyName(), SslMode.REQUIRED.name());
        props.setProperty(PropertyKey.useCompression.getKeyName(), "false");
        testBug18869381WithProperties(dbUrl, props);
        props.setProperty(PropertyKey.useCompression.getKeyName(), "true");
        testBug18869381WithProperties(dbUrl, props);
    } finally {
        if (!((MysqlConnection) this.conn).getSession().versionMeetsMinimum(8, 0, 5)) {
            this.stmt.executeUpdate("SET GLOBAL old_passwords = @current_old_passwords");
        }
    }
}
Also used : MysqlConnection(com.mysql.cj.MysqlConnection) Sha256PasswordPlugin(com.mysql.cj.protocol.a.authentication.Sha256PasswordPlugin) Properties(java.util.Properties) MysqlNativePasswordPlugin(com.mysql.cj.protocol.a.authentication.MysqlNativePasswordPlugin) Test(org.junit.jupiter.api.Test)

Example 7 with MysqlConnection

use of com.mysql.cj.MysqlConnection in project aws-mysql-jdbc by awslabs.

the class ConnectionRegressionTest method testBug74711.

/**
 * Tests fix for Bug#74711 - FORGOTTEN WORKAROUND FOR BUG#36326.
 *
 * This test requires a server started with the options '--query_cache_type=1' and '--query_cache_size=N', (N > 0).
 *
 * @throws Exception
 */
@Test
public void testBug74711() throws Exception {
    assumeTrue(((MysqlConnection) this.conn).getSession().getServerSession().isQueryCacheEnabled(), "testBug77411() requires a server supporting a query cache.");
    this.rs = this.stmt.executeQuery("SELECT @@global.query_cache_type, @@global.query_cache_size");
    this.rs.next();
    assumeTrue("ON".equalsIgnoreCase(this.rs.getString(1)) && !"0".equals(this.rs.getString(2)), "testBug77411() requires a server started with the options '--query_cache_type=1' and '--query_cache_size=N', (N > 0).");
    boolean useLocTransSt = false;
    boolean useElideSetAC = false;
    do {
        final String testCase = String.format("Case: [LocTransSt: %s, ElideAC: %s ]", useLocTransSt ? "Y" : "N", useElideSetAC ? "Y" : "N");
        final Properties props = new Properties();
        props.setProperty(PropertyKey.useLocalTransactionState.getKeyName(), Boolean.toString(useLocTransSt));
        props.setProperty(PropertyKey.elideSetAutoCommits.getKeyName(), Boolean.toString(useElideSetAC));
        Connection testConn = getConnectionWithProps(props);
        assertEquals(useLocTransSt, ((JdbcConnection) testConn).getPropertySet().getBooleanProperty(PropertyKey.useLocalTransactionState).getValue().booleanValue(), testCase);
        assertEquals(useElideSetAC, ((JdbcConnection) testConn).getPropertySet().getBooleanProperty(PropertyKey.elideSetAutoCommits).getValue().booleanValue(), testCase);
        testConn.close();
    } while ((useLocTransSt = !useLocTransSt) || (useElideSetAC = !useElideSetAC));
}
Also used : ReplicationConnection(com.mysql.cj.jdbc.ha.ReplicationConnection) MysqlPooledConnection(com.mysql.cj.jdbc.MysqlPooledConnection) SuspendableXAConnection(com.mysql.cj.jdbc.SuspendableXAConnection) Connection(java.sql.Connection) XAConnection(javax.sql.XAConnection) PooledConnection(javax.sql.PooledConnection) MysqlXAConnection(com.mysql.cj.jdbc.MysqlXAConnection) JdbcConnection(com.mysql.cj.jdbc.JdbcConnection) MysqlConnection(com.mysql.cj.MysqlConnection) JdbcConnection(com.mysql.cj.jdbc.JdbcConnection) Properties(java.util.Properties) Test(org.junit.jupiter.api.Test)

Example 8 with MysqlConnection

use of com.mysql.cj.MysqlConnection in project aws-mysql-jdbc by awslabs.

the class ConnectionRegressionTest method testBug99767.

/**
 * Tests fix for Bug#99767 (31443178), Contribution: Check SubjectAlternativeName for TLS instead of commonName.
 *
 * This test requires a server X509 certificate that contains the following X509v3 extension:
 *
 * <pre>
 * X509v3 Subject Alternative Name:
 *     DNS:bug99767.mysql.san1.tst,
 *     DNS:*.mysql.san2.tst,
 *     DNS:bug*.mysql.san3.tst,
 *     DNS:*99767.mysql.san4.tst,
 *     DNS:bug99767.*.san5.tst,
 *     DNS:bug99767.*,
 *     DNS:*,
 *     IP Address:9.9.7.67,
 *     IP Address:99.7.6.7
 * </pre>
 *
 * @throws Exception
 */
@Test
public void testBug99767() throws Exception {
    assumeTrue((((MysqlConnection) this.conn).getSession().getServerSession().getCapabilities().getCapabilityFlags() & NativeServerSession.CLIENT_SSL) != 0, "This test requires server with SSL support.");
    assumeTrue(supportsTLSv1_2(((MysqlConnection) this.conn).getSession().getServerSession().getServerVersion()), "This test requires server with TLSv1.2+ support.");
    assumeTrue(supportsTestCertificates(this.stmt), "This test requires the server configured with SSL certificates from ConnectorJ/src/test/config/ssl-test-certs");
    try {
        final Properties props = getPropertiesFromTestsuiteUrl();
        props.setProperty(PropertyKey.socketFactory.getKeyName(), "testsuite.UnreliableSocketFactory");
        props.setProperty(PropertyKey.sslMode.getKeyName(), SslMode.VERIFY_IDENTITY.toString());
        props.setProperty(PropertyKey.trustCertificateKeyStoreUrl.getKeyName(), "file:src/test/config/ssl-test-certs/ca-truststore");
        props.setProperty(PropertyKey.trustCertificateKeyStoreType.getKeyName(), "JKS");
        props.setProperty(PropertyKey.trustCertificateKeyStorePassword.getKeyName(), "password");
        final String host = props.getProperty(PropertyKey.HOST.getKeyName());
        final String port = props.getProperty(PropertyKey.PORT.getKeyName());
        props.remove(PropertyKey.HOST.getKeyName());
        String[] okHosts = { "bug99767.mysql.san1.tst", "bug99767.mysql.san2.tst", "bug99767.mysql.san3.tst", "bug99767.mysql.san4.tst", "9.9.7.67", "99.7.6.7" };
        String[] notOkHosts = { "bug31443178.mysql.san1.tst", "bug99767.cj.mysql.san2.tst", "bug99767.cj.mysql.san3.tst", "cj.bug99767.mysql.san4.tst", "bug99767.mysql.san5.tst", "bug99767.cj.mysql.san5.tst", "bug99767.tst", "bug99767", "31.44.31.78" };
        UnreliableSocketFactory.flushAllStaticData();
        Arrays.stream(okHosts).forEach(h -> UnreliableSocketFactory.mapHost(h, host));
        Arrays.stream(notOkHosts).forEach(h -> UnreliableSocketFactory.mapHost(h, host));
        // OK hosts that match one of the DNS/IP SANs.
        for (String okHost : okHosts) {
            try (Connection testConn = getConnectionWithProps("jdbc:mysql:aws://" + okHost + ":" + port + "/", props)) {
                this.rs = testConn.createStatement().executeQuery("SELECT 1");
                assertTrue(this.rs.next());
                assertEquals(1, this.rs.getInt(1));
            }
        }
        // Not OK hosts that don't match any of the DNS/IP SANs.
        for (String notOkHost : notOkHosts) {
            Exception e = assertThrows(CommunicationsException.class, () -> getConnectionWithProps("jdbc:mysql://" + notOkHost + ":" + port + "/", props));
            assertNotNull(e.getCause());
            assertNotNull(e.getCause().getCause());
            String errMsg = e.getCause().getCause().getMessage();
            if (errMsg.startsWith("java.security.cert.CertificateException: ")) {
                errMsg = errMsg.substring("java.security.cert.CertificateException: ".length());
            }
            assertEquals("Server identity verification failed. None of the DNS or IP Subject Alternative Name " + "entries matched the server hostname/IP '" + notOkHost + "'.", errMsg);
        }
        // Not OK hosts are OK if not verifying identity, though.
        props.setProperty(PropertyKey.sslMode.getKeyName(), SslMode.VERIFY_CA.toString());
        for (String okHost : notOkHosts) {
            try (Connection testConn = getConnectionWithProps("jdbc:mysql:aws://" + okHost + ":" + port + "/", props)) {
                this.rs = testConn.createStatement().executeQuery("SELECT 1");
                assertTrue(this.rs.next());
                assertEquals(1, this.rs.getInt(1));
            }
        }
    } finally {
        UnreliableSocketFactory.flushAllStaticData();
    }
}
Also used : ReplicationConnection(com.mysql.cj.jdbc.ha.ReplicationConnection) MysqlPooledConnection(com.mysql.cj.jdbc.MysqlPooledConnection) SuspendableXAConnection(com.mysql.cj.jdbc.SuspendableXAConnection) Connection(java.sql.Connection) XAConnection(javax.sql.XAConnection) PooledConnection(javax.sql.PooledConnection) MysqlXAConnection(com.mysql.cj.jdbc.MysqlXAConnection) JdbcConnection(com.mysql.cj.jdbc.JdbcConnection) MysqlConnection(com.mysql.cj.MysqlConnection) MysqlConnection(com.mysql.cj.MysqlConnection) Properties(java.util.Properties) SQLFeatureNotSupportedException(java.sql.SQLFeatureNotSupportedException) SQLTransientException(java.sql.SQLTransientException) InvocationTargetException(java.lang.reflect.InvocationTargetException) XAException(javax.transaction.xa.XAException) SocketException(java.net.SocketException) SQLClientInfoException(java.sql.SQLClientInfoException) SQLException(java.sql.SQLException) SocketTimeoutException(java.net.SocketTimeoutException) IOException(java.io.IOException) PasswordExpiredException(com.mysql.cj.exceptions.PasswordExpiredException) ExecutionException(java.util.concurrent.ExecutionException) TimeoutException(java.util.concurrent.TimeoutException) SQLNonTransientConnectionException(java.sql.SQLNonTransientConnectionException) CommunicationsException(com.mysql.cj.jdbc.exceptions.CommunicationsException) CertificateException(java.security.cert.CertificateException) ClosedOnExpiredPasswordException(com.mysql.cj.exceptions.ClosedOnExpiredPasswordException) PropertyNotModifiableException(com.mysql.cj.exceptions.PropertyNotModifiableException) Test(org.junit.jupiter.api.Test)

Example 9 with MysqlConnection

use of com.mysql.cj.MysqlConnection in project aws-mysql-jdbc by awslabs.

the class ConnectionRegressionTest method testBug20685022.

/**
 * Tests fix for BUG#20685022 - SSL CONNECTION TO MYSQL 5.7.6 COMMUNITY SERVER FAILS
 *
 * @throws Exception
 */
@Test
public void testBug20685022() throws Exception {
    assumeTrue(isCommunityEdition(), "Commercial server version 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(supportsTLSv1_2(((MysqlConnection) this.conn).getSession().getServerSession().getServerVersion()), "This test requires server with TLSv1.2+ support.");
    assumeTrue(supportsTestCertificates(this.stmt), "This test requires the server configured with SSL certificates from ConnectorJ/src/test/config/ssl-test-certs");
    final Properties props = new Properties();
    /*
         * case 1: non verifying server certificate
         */
    props.clear();
    props.setProperty(PropertyKey.sslMode.getKeyName(), SslMode.REQUIRED.name());
    getConnectionWithProps(props);
    /*
         * case 2: verifying server certificate using key store provided by connection properties
         */
    props.clear();
    props.setProperty(PropertyKey.sslMode.getKeyName(), SslMode.VERIFY_CA.name());
    props.setProperty(PropertyKey.trustCertificateKeyStoreUrl.getKeyName(), "file:src/test/config/ssl-test-certs/ca-truststore");
    props.setProperty(PropertyKey.trustCertificateKeyStoreType.getKeyName(), "JKS");
    props.setProperty(PropertyKey.trustCertificateKeyStorePassword.getKeyName(), "password");
    getConnectionWithProps(props);
    /*
         * case 3: verifying server certificate using key store provided by system properties
         */
    props.clear();
    props.setProperty(PropertyKey.sslMode.getKeyName(), SslMode.VERIFY_CA.name());
    String trustStorePath = "src/test/config/ssl-test-certs/ca-truststore";
    System.setProperty("javax.net.ssl.keyStore", trustStorePath);
    System.setProperty("javax.net.ssl.keyStorePassword", "password");
    System.setProperty("javax.net.ssl.trustStore", trustStorePath);
    System.setProperty("javax.net.ssl.trustStorePassword", "password");
    getConnectionWithProps(props);
}
Also used : MysqlConnection(com.mysql.cj.MysqlConnection) Properties(java.util.Properties) Test(org.junit.jupiter.api.Test)

Example 10 with MysqlConnection

use of com.mysql.cj.MysqlConnection in project aws-mysql-jdbc by awslabs.

the class ConnectionRegressionTest method testSha256PasswordPlugin.

/**
 * Test for sha256_password authentication.
 *
 * @throws Exception
 */
@Test
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(supportsTestCertificates(this.stmt), "This test requires the server configured with SSL certificates from ConnectorJ/src/test/config/ssl-test-certs");
    String trustStorePath = "src/test/config/ssl-test-certs/ca-truststore";
    System.setProperty("javax.net.ssl.trustStore", trustStorePath);
    System.setProperty("javax.net.ssl.trustStorePassword", "password");
    try {
        // newer GPL servers, like 8.0.4+, are using OpenSSL and can use RSA encryption, while old ones compiled with yaSSL cannot
        boolean withRSA = allowsRsa(this.stmt);
        boolean withTestRsaKeys = supportsTestSha256PasswordKeys(this.stmt);
        // create user with long password and sha256_password auth
        if (!((MysqlConnection) this.conn).getSession().versionMeetsMinimum(8, 0, 5)) {
            this.stmt.executeUpdate("SET @current_old_passwords = @@global.old_passwords");
        }
        createUser(this.stmt, "'wl5602user'@'%'", "IDENTIFIED WITH sha256_password");
        this.stmt.executeUpdate("GRANT ALL ON *.* TO 'wl5602user'@'%'");
        createUser(this.stmt, "'wl5602nopassword'@'%'", "identified WITH sha256_password");
        this.stmt.executeUpdate("GRANT ALL ON *.* TO 'wl5602nopassword'@'%'");
        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(((MysqlConnection) this.conn).getSession().versionMeetsMinimum(5, 7, 6) ? "ALTER USER 'wl5602user'@'%' IDENTIFIED BY 'pwd'" : "SET PASSWORD FOR 'wl5602user'@'%' = PASSWORD('pwd')");
        this.stmt.executeUpdate("FLUSH PRIVILEGES");
        final Properties propsNoRetrieval = new Properties();
        propsNoRetrieval.setProperty(PropertyKey.USER.getKeyName(), "wl5602user");
        propsNoRetrieval.setProperty(PropertyKey.PASSWORD.getKeyName(), "pwd");
        final Properties propsNoRetrievalNoPassword = new Properties();
        propsNoRetrievalNoPassword.setProperty(PropertyKey.USER.getKeyName(), "wl5602nopassword");
        propsNoRetrievalNoPassword.setProperty(PropertyKey.PASSWORD.getKeyName(), "");
        final Properties propsAllowRetrieval = new Properties();
        propsAllowRetrieval.setProperty(PropertyKey.USER.getKeyName(), "wl5602user");
        propsAllowRetrieval.setProperty(PropertyKey.PASSWORD.getKeyName(), "pwd");
        propsAllowRetrieval.setProperty(PropertyKey.allowPublicKeyRetrieval.getKeyName(), "true");
        final Properties propsAllowRetrievalNoPassword = new Properties();
        propsAllowRetrievalNoPassword.setProperty(PropertyKey.USER.getKeyName(), "wl5602nopassword");
        propsAllowRetrievalNoPassword.setProperty(PropertyKey.PASSWORD.getKeyName(), "");
        propsAllowRetrievalNoPassword.setProperty(PropertyKey.allowPublicKeyRetrieval.getKeyName(), "true");
        // 1. with client-default MysqlNativePasswordPlugin
        propsNoRetrieval.setProperty(PropertyKey.defaultAuthenticationPlugin.getKeyName(), MysqlNativePasswordPlugin.class.getName());
        propsAllowRetrieval.setProperty(PropertyKey.defaultAuthenticationPlugin.getKeyName(), MysqlNativePasswordPlugin.class.getName());
        // 1.1. RSA
        propsNoRetrieval.setProperty(PropertyKey.sslMode.getKeyName(), SslMode.DISABLED.name());
        propsAllowRetrieval.setProperty(PropertyKey.sslMode.getKeyName(), SslMode.DISABLED.name());
        assertThrows(SQLException.class, "Public Key Retrieval is not allowed", () -> getConnectionWithProps(dbUrl, propsNoRetrieval));
        assertCurrentUser(dbUrl, propsNoRetrievalNoPassword, "wl5602nopassword", false);
        if (withRSA) {
            assertCurrentUser(dbUrl, propsAllowRetrieval, "wl5602user", false);
        } else {
            assertThrows(SQLException.class, "Access denied for user 'wl5602user'.*", () -> getConnectionWithProps(dbUrl, propsAllowRetrieval));
        }
        assertCurrentUser(dbUrl, propsAllowRetrievalNoPassword, "wl5602nopassword", false);
        // 1.2. over SSL
        propsNoRetrieval.setProperty(PropertyKey.sslMode.getKeyName(), SslMode.REQUIRED.name());
        propsNoRetrievalNoPassword.setProperty(PropertyKey.sslMode.getKeyName(), SslMode.REQUIRED.name());
        propsAllowRetrieval.setProperty(PropertyKey.sslMode.getKeyName(), SslMode.REQUIRED.name());
        propsAllowRetrievalNoPassword.setProperty(PropertyKey.sslMode.getKeyName(), SslMode.REQUIRED.name());
        assertCurrentUser(dbUrl, propsNoRetrieval, "wl5602user", true);
        assertCurrentUser(dbUrl, propsNoRetrievalNoPassword, "wl5602nopassword", false);
        assertCurrentUser(dbUrl, propsAllowRetrieval, "wl5602user", true);
        assertCurrentUser(dbUrl, propsAllowRetrievalNoPassword, "wl5602nopassword", false);
        // 2. with client-default Sha256PasswordPlugin
        propsNoRetrieval.setProperty(PropertyKey.defaultAuthenticationPlugin.getKeyName(), Sha256PasswordPlugin.class.getName());
        propsNoRetrievalNoPassword.setProperty(PropertyKey.defaultAuthenticationPlugin.getKeyName(), Sha256PasswordPlugin.class.getName());
        propsAllowRetrieval.setProperty(PropertyKey.defaultAuthenticationPlugin.getKeyName(), Sha256PasswordPlugin.class.getName());
        propsAllowRetrievalNoPassword.setProperty(PropertyKey.defaultAuthenticationPlugin.getKeyName(), Sha256PasswordPlugin.class.getName());
        // 2.1. RSA
        propsNoRetrieval.setProperty(PropertyKey.sslMode.getKeyName(), SslMode.DISABLED.name());
        propsNoRetrievalNoPassword.setProperty(PropertyKey.sslMode.getKeyName(), SslMode.DISABLED.name());
        propsAllowRetrieval.setProperty(PropertyKey.sslMode.getKeyName(), SslMode.DISABLED.name());
        propsAllowRetrievalNoPassword.setProperty(PropertyKey.sslMode.getKeyName(), SslMode.DISABLED.name());
        assertThrows(SQLException.class, "Public Key Retrieval is not allowed", () -> getConnectionWithProps(dbUrl, propsNoRetrieval));
        assertCurrentUser(dbUrl, propsNoRetrievalNoPassword, "wl5602nopassword", false);
        if (withRSA) {
            assertCurrentUser(dbUrl, propsAllowRetrieval, "wl5602user", false);
        } else {
            assertThrows(SQLException.class, "Access denied for user 'wl5602user'.*", () -> getConnectionWithProps(dbUrl, propsAllowRetrieval));
        }
        assertCurrentUser(dbUrl, propsAllowRetrievalNoPassword, "wl5602nopassword", false);
        // 2.2. over SSL
        propsNoRetrieval.setProperty(PropertyKey.sslMode.getKeyName(), SslMode.REQUIRED.name());
        propsNoRetrievalNoPassword.setProperty(PropertyKey.sslMode.getKeyName(), SslMode.REQUIRED.name());
        propsAllowRetrieval.setProperty(PropertyKey.sslMode.getKeyName(), SslMode.REQUIRED.name());
        propsAllowRetrievalNoPassword.setProperty(PropertyKey.sslMode.getKeyName(), SslMode.REQUIRED.name());
        assertCurrentUser(dbUrl, propsNoRetrieval, "wl5602user", true);
        assertCurrentUser(dbUrl, propsNoRetrievalNoPassword, "wl5602nopassword", false);
        assertCurrentUser(dbUrl, propsAllowRetrieval, "wl5602user", false);
        assertCurrentUser(dbUrl, propsAllowRetrievalNoPassword, "wl5602nopassword", false);
        // 3. with serverRSAPublicKeyFile specified
        propsNoRetrieval.setProperty(PropertyKey.serverRSAPublicKeyFile.getKeyName(), "src/test/config/ssl-test-certs/mykey.pub");
        propsNoRetrievalNoPassword.setProperty(PropertyKey.serverRSAPublicKeyFile.getKeyName(), "src/test/config/ssl-test-certs/mykey.pub");
        propsAllowRetrieval.setProperty(PropertyKey.serverRSAPublicKeyFile.getKeyName(), "src/test/config/ssl-test-certs/mykey.pub");
        propsAllowRetrievalNoPassword.setProperty(PropertyKey.serverRSAPublicKeyFile.getKeyName(), "src/test/config/ssl-test-certs/mykey.pub");
        // 3.1. RSA
        propsNoRetrieval.setProperty(PropertyKey.sslMode.getKeyName(), SslMode.DISABLED.name());
        propsNoRetrievalNoPassword.setProperty(PropertyKey.sslMode.getKeyName(), SslMode.DISABLED.name());
        propsAllowRetrieval.setProperty(PropertyKey.sslMode.getKeyName(), SslMode.DISABLED.name());
        propsAllowRetrievalNoPassword.setProperty(PropertyKey.sslMode.getKeyName(), SslMode.DISABLED.name());
        if (withRSA && withTestRsaKeys) {
            assertCurrentUser(dbUrl, propsNoRetrieval, "wl5602user", false);
            assertCurrentUser(dbUrl, propsAllowRetrieval, "wl5602user", false);
        } else {
            assertThrows(SQLException.class, "Access denied for user 'wl5602user'.*", () -> getConnectionWithProps(dbUrl, propsNoRetrieval));
            assertThrows(SQLException.class, "Access denied for user 'wl5602user'.*", () -> getConnectionWithProps(dbUrl, propsAllowRetrieval));
        }
        assertCurrentUser(dbUrl, propsNoRetrievalNoPassword, "wl5602nopassword", false);
        assertCurrentUser(dbUrl, propsAllowRetrievalNoPassword, "wl5602nopassword", false);
        // 3.2. Runtime setServerRSAPublicKeyFile must be denied
        if (withRSA && withTestRsaKeys) {
            final Connection c2 = getConnectionWithProps(dbUrl, propsNoRetrieval);
            assertThrows(PropertyNotModifiableException.class, "Dynamic change of ''serverRSAPublicKeyFile'' is not allowed.", () -> {
                ((JdbcConnection) c2).getPropertySet().getProperty(PropertyKey.serverRSAPublicKeyFile).setValue("src/test/config/ssl-test-certs/mykey.pub");
                return null;
            });
            c2.close();
        }
        // 3.4. over SSL
        propsNoRetrieval.setProperty(PropertyKey.sslMode.getKeyName(), SslMode.REQUIRED.name());
        propsNoRetrievalNoPassword.setProperty(PropertyKey.sslMode.getKeyName(), SslMode.REQUIRED.name());
        propsAllowRetrieval.setProperty(PropertyKey.sslMode.getKeyName(), SslMode.REQUIRED.name());
        propsAllowRetrievalNoPassword.setProperty(PropertyKey.sslMode.getKeyName(), SslMode.REQUIRED.name());
        assertCurrentUser(dbUrl, propsNoRetrieval, "wl5602user", true);
        assertCurrentUser(dbUrl, propsNoRetrievalNoPassword, "wl5602nopassword", false);
        assertCurrentUser(dbUrl, propsAllowRetrieval, "wl5602user", true);
        assertCurrentUser(dbUrl, propsAllowRetrievalNoPassword, "wl5602nopassword", false);
        // 4. with wrong serverRSAPublicKeyFile specified
        propsNoRetrieval.setProperty(PropertyKey.serverRSAPublicKeyFile.getKeyName(), "unexistant/dummy.pub");
        propsNoRetrievalNoPassword.setProperty(PropertyKey.serverRSAPublicKeyFile.getKeyName(), "unexistant/dummy.pub");
        propsAllowRetrieval.setProperty(PropertyKey.serverRSAPublicKeyFile.getKeyName(), "unexistant/dummy.pub");
        propsAllowRetrievalNoPassword.setProperty(PropertyKey.serverRSAPublicKeyFile.getKeyName(), "unexistant/dummy.pub");
        // 4.1. RSA
        propsNoRetrieval.setProperty(PropertyKey.sslMode.getKeyName(), SslMode.DISABLED.name());
        propsNoRetrievalNoPassword.setProperty(PropertyKey.sslMode.getKeyName(), SslMode.DISABLED.name());
        propsAllowRetrieval.setProperty(PropertyKey.sslMode.getKeyName(), SslMode.DISABLED.name());
        propsAllowRetrievalNoPassword.setProperty(PropertyKey.sslMode.getKeyName(), SslMode.DISABLED.name());
        propsNoRetrieval.setProperty(PropertyKey.paranoid.getKeyName(), "false");
        propsNoRetrievalNoPassword.setProperty(PropertyKey.paranoid.getKeyName(), "false");
        propsAllowRetrieval.setProperty(PropertyKey.paranoid.getKeyName(), "false");
        propsAllowRetrievalNoPassword.setProperty(PropertyKey.paranoid.getKeyName(), "false");
        assertThrows(SQLException.class, "Unable to read public key 'unexistant/dummy.pub'.*", () -> getConnectionWithProps(dbUrl, propsNoRetrieval));
        assertThrows(SQLException.class, "Unable to read public key 'unexistant/dummy.pub'.*", () -> getConnectionWithProps(dbUrl, propsNoRetrievalNoPassword));
        assertThrows(SQLException.class, "Unable to read public key 'unexistant/dummy.pub'.*", () -> getConnectionWithProps(dbUrl, propsAllowRetrieval));
        assertThrows(SQLException.class, "Unable to read public key 'unexistant/dummy.pub'.*", () -> getConnectionWithProps(dbUrl, propsAllowRetrievalNoPassword));
        propsNoRetrieval.setProperty(PropertyKey.paranoid.getKeyName(), "true");
        propsNoRetrievalNoPassword.setProperty(PropertyKey.paranoid.getKeyName(), "true");
        propsAllowRetrieval.setProperty(PropertyKey.paranoid.getKeyName(), "true");
        propsAllowRetrievalNoPassword.setProperty(PropertyKey.paranoid.getKeyName(), "true");
        assertThrows(SQLException.class, "Unable to read public key ", () -> getConnectionWithProps(dbUrl, propsNoRetrieval));
        assertThrows(SQLException.class, "Unable to read public key ", () -> getConnectionWithProps(dbUrl, propsNoRetrievalNoPassword));
        assertThrows(SQLException.class, "Unable to read public key ", () -> getConnectionWithProps(dbUrl, propsAllowRetrieval));
        assertThrows(SQLException.class, "Unable to read public key ", () -> getConnectionWithProps(dbUrl, propsAllowRetrievalNoPassword));
        // 4.2. over SSL
        propsNoRetrieval.setProperty(PropertyKey.sslMode.getKeyName(), SslMode.REQUIRED.name());
        propsNoRetrievalNoPassword.setProperty(PropertyKey.sslMode.getKeyName(), SslMode.REQUIRED.name());
        propsAllowRetrieval.setProperty(PropertyKey.sslMode.getKeyName(), SslMode.REQUIRED.name());
        propsAllowRetrievalNoPassword.setProperty(PropertyKey.sslMode.getKeyName(), SslMode.REQUIRED.name());
        propsNoRetrieval.setProperty(PropertyKey.paranoid.getKeyName(), "false");
        propsNoRetrievalNoPassword.setProperty(PropertyKey.paranoid.getKeyName(), "false");
        propsAllowRetrieval.setProperty(PropertyKey.paranoid.getKeyName(), "false");
        propsAllowRetrievalNoPassword.setProperty(PropertyKey.paranoid.getKeyName(), "false");
        assertThrows(SQLException.class, "Unable to read public key 'unexistant/dummy.pub'.*", () -> getConnectionWithProps(dbUrl, propsNoRetrieval));
        assertThrows(SQLException.class, "Unable to read public key 'unexistant/dummy.pub'.*", () -> getConnectionWithProps(dbUrl, propsNoRetrievalNoPassword));
        assertThrows(SQLException.class, "Unable to read public key 'unexistant/dummy.pub'.*", () -> getConnectionWithProps(dbUrl, propsAllowRetrieval));
        assertThrows(SQLException.class, "Unable to read public key 'unexistant/dummy.pub'.*", () -> getConnectionWithProps(dbUrl, propsAllowRetrievalNoPassword));
        propsNoRetrieval.setProperty(PropertyKey.paranoid.getKeyName(), "true");
        propsNoRetrievalNoPassword.setProperty(PropertyKey.paranoid.getKeyName(), "true");
        propsAllowRetrieval.setProperty(PropertyKey.paranoid.getKeyName(), "true");
        propsAllowRetrievalNoPassword.setProperty(PropertyKey.paranoid.getKeyName(), "true");
        assertThrows(SQLException.class, "Unable to read public key ", new Callable<Void>() {

            @SuppressWarnings("synthetic-access")
            public Void call() throws Exception {
                getConnectionWithProps(dbUrl, propsNoRetrieval);
                return null;
            }
        });
        assertThrows(SQLException.class, "Unable to read public key ", () -> getConnectionWithProps(dbUrl, propsNoRetrievalNoPassword));
        assertThrows(SQLException.class, "Unable to read public key ", () -> getConnectionWithProps(dbUrl, propsAllowRetrieval));
        assertThrows(SQLException.class, "Unable to read public key ", () -> getConnectionWithProps(dbUrl, propsAllowRetrievalNoPassword));
    } finally {
        if (!((MysqlConnection) this.conn).getSession().versionMeetsMinimum(8, 0, 5)) {
            this.stmt.executeUpdate("SET GLOBAL old_passwords = @current_old_passwords");
        }
    }
}
Also used : ReplicationConnection(com.mysql.cj.jdbc.ha.ReplicationConnection) MysqlPooledConnection(com.mysql.cj.jdbc.MysqlPooledConnection) SuspendableXAConnection(com.mysql.cj.jdbc.SuspendableXAConnection) Connection(java.sql.Connection) XAConnection(javax.sql.XAConnection) PooledConnection(javax.sql.PooledConnection) MysqlXAConnection(com.mysql.cj.jdbc.MysqlXAConnection) JdbcConnection(com.mysql.cj.jdbc.JdbcConnection) MysqlConnection(com.mysql.cj.MysqlConnection) MysqlConnection(com.mysql.cj.MysqlConnection) JdbcConnection(com.mysql.cj.jdbc.JdbcConnection) Sha256PasswordPlugin(com.mysql.cj.protocol.a.authentication.Sha256PasswordPlugin) Properties(java.util.Properties) MysqlNativePasswordPlugin(com.mysql.cj.protocol.a.authentication.MysqlNativePasswordPlugin) SQLFeatureNotSupportedException(java.sql.SQLFeatureNotSupportedException) SQLTransientException(java.sql.SQLTransientException) InvocationTargetException(java.lang.reflect.InvocationTargetException) XAException(javax.transaction.xa.XAException) SocketException(java.net.SocketException) SQLClientInfoException(java.sql.SQLClientInfoException) SQLException(java.sql.SQLException) SocketTimeoutException(java.net.SocketTimeoutException) IOException(java.io.IOException) PasswordExpiredException(com.mysql.cj.exceptions.PasswordExpiredException) ExecutionException(java.util.concurrent.ExecutionException) TimeoutException(java.util.concurrent.TimeoutException) SQLNonTransientConnectionException(java.sql.SQLNonTransientConnectionException) CommunicationsException(com.mysql.cj.jdbc.exceptions.CommunicationsException) CertificateException(java.security.cert.CertificateException) ClosedOnExpiredPasswordException(com.mysql.cj.exceptions.ClosedOnExpiredPasswordException) PropertyNotModifiableException(com.mysql.cj.exceptions.PropertyNotModifiableException) Test(org.junit.jupiter.api.Test)

Aggregations

MysqlConnection (com.mysql.cj.MysqlConnection)70 Test (org.junit.jupiter.api.Test)65 Properties (java.util.Properties)57 Connection (java.sql.Connection)55 JdbcConnection (com.mysql.cj.jdbc.JdbcConnection)42 TimeZone (java.util.TimeZone)26 XAConnection (javax.sql.XAConnection)24 ReplicationConnection (com.mysql.cj.jdbc.ha.ReplicationConnection)23 PooledConnection (javax.sql.PooledConnection)22 MysqlPooledConnection (com.mysql.cj.jdbc.MysqlPooledConnection)21 MysqlXAConnection (com.mysql.cj.jdbc.MysqlXAConnection)21 SuspendableXAConnection (com.mysql.cj.jdbc.SuspendableXAConnection)21 ZonedDateTime (java.time.ZonedDateTime)21 SQLException (java.sql.SQLException)18 PreparedStatement (java.sql.PreparedStatement)16 Statement (java.sql.Statement)16 CommunicationsException (com.mysql.cj.jdbc.exceptions.CommunicationsException)14 IOException (java.io.IOException)14 ExecutionException (java.util.concurrent.ExecutionException)14 TimeoutException (java.util.concurrent.TimeoutException)14