use of com.mysql.cj.MysqlConnection in project aws-mysql-jdbc by awslabs.
the class ConnectionRegressionTest method testBug75670.
/**
* Tests fix for BUG#75670 - Connection fails with "Public Key Retrieval is not allowed" for native auth.
*
* Requires the server to be configured with default-authentication-plugin=sha256_password and RSA encryption enabled.
*
* @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(supportsTestCertificates(this.stmt), "This test requires the server configured with SSL certificates from ConnectorJ/src/test/config/ssl-test-certs");
assumeTrue(supportsTestSha256PasswordKeys(this.stmt), "This test requires the server configured with RSA keys 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");
}
// let --default-authentication-plugin option force sha256_password
createUser(this.stmt, "'bug75670user'@'%'", "");
this.rs = this.stmt.executeQuery("SELECT plugin FROM mysql.user WHERE user='bug75670user'");
assertTrue(this.rs.next());
assumeTrue("sha256_password".equals(this.rs.getString(1)), "This test requires the server configured with default sha256_password plugin");
if (((MysqlConnection) this.conn).getSession().versionMeetsMinimum(5, 7, 6)) {
createUser(this.stmt, "'bug75670user_mnp'@'%'", "IDENTIFIED WITH mysql_native_password BY 'bug75670user_mnp'");
createUser(this.stmt, "'bug75670user_sha'@'%'", "IDENTIFIED WITH sha256_password BY 'bug75670user_sha'");
} else {
if (!((MysqlConnection) this.conn).getSession().versionMeetsMinimum(8, 0, 5)) {
this.stmt.execute("SET @@session.old_passwords = 0");
}
createUser(this.stmt, "'bug75670user_mnp'@'%'", "IDENTIFIED WITH mysql_native_password");
this.stmt.execute("SET PASSWORD FOR 'bug75670user_mnp'@'%' = PASSWORD('bug75670user_mnp')");
if (!((MysqlConnection) this.conn).getSession().versionMeetsMinimum(8, 0, 5)) {
this.stmt.execute("SET @@session.old_passwords = 2");
}
createUser(this.stmt, "'bug75670user_sha'@'%'", "IDENTIFIED WITH sha256_password");
this.stmt.execute("SET PASSWORD FOR 'bug75670user_sha'@'%' = PASSWORD('bug75670user_sha')");
}
this.stmt.execute("GRANT ALL ON *.* TO 'bug75670user_mnp'@'%'");
this.stmt.execute("GRANT ALL ON *.* TO 'bug75670user_sha'@'%'");
System.out.println();
System.out.printf("%-25s : %-18s : %-25s : %-25s : %s%n", "DefAuthPlugin", "AllowPubKeyRet", "User", "Passwd", "Test result");
System.out.println("----------------------------------------------------------------------------------------------------" + "------------------------------");
for (Class<?> defAuthPlugin : new Class<?>[] { MysqlNativePasswordPlugin.class, Sha256PasswordPlugin.class }) {
for (String user : new String[] { "bug75670user_mnp", "bug75670user_sha" }) {
for (String pwd : new String[] { user, "wrong*pwd", "" }) {
for (boolean allowPubKeyRetrieval : new boolean[] { true, false }) {
final Connection testConn;
Statement testStmt;
boolean expectedPubKeyRetrievalFail = (user.endsWith("_sha") || user.endsWith("_mnp") && defAuthPlugin.equals(Sha256PasswordPlugin.class)) && !allowPubKeyRetrieval && pwd.length() > 0;
boolean expectedAccessDeniedFail = !user.equals(pwd);
System.out.printf("%-25s : %-18s : %-25s : %-25s : %s%n", defAuthPlugin.getSimpleName(), allowPubKeyRetrieval, user, pwd, expectedPubKeyRetrievalFail ? "Fail [Pub. Key retrieval]" : expectedAccessDeniedFail ? "Fail [Access denied]" : "Ok");
final Properties props = new Properties();
props.setProperty(PropertyKey.USER.getKeyName(), user);
props.setProperty(PropertyKey.PASSWORD.getKeyName(), pwd);
props.setProperty(PropertyKey.defaultAuthenticationPlugin.getKeyName(), defAuthPlugin.getName());
props.setProperty(PropertyKey.allowPublicKeyRetrieval.getKeyName(), Boolean.toString(allowPubKeyRetrieval));
props.setProperty(PropertyKey.sslMode.getKeyName(), SslMode.DISABLED.name());
if (expectedPubKeyRetrievalFail) {
// connection will fail due to public key retrieval failure
assertThrows(SQLException.class, "Public Key Retrieval is not allowed", new Callable<Void>() {
@SuppressWarnings("synthetic-access")
public Void call() throws Exception {
getConnectionWithProps(dbUrl, props);
return null;
}
});
} else if (expectedAccessDeniedFail) {
// connection will fail due to wrong password
assertThrows(SQLException.class, "Access denied for user '" + user + "'@.*", new Callable<Void>() {
@SuppressWarnings("synthetic-access")
public Void call() throws Exception {
getConnectionWithProps(dbUrl, props);
return null;
}
});
} else {
// connection will succeed
testConn = getConnectionWithProps(dbUrl, props);
testStmt = testConn.createStatement();
this.rs = testStmt.executeQuery("SELECT USER(), CURRENT_USER()");
assertTrue(this.rs.next());
assertTrue(this.rs.getString(1).startsWith(user));
assertTrue(this.rs.getString(2).startsWith(user));
this.rs.close();
testStmt.close();
// change user using same credentials will succeed
System.out.printf("%25s : %-18s : %-25s : %-25s : %s%n", "| ChangeUser (same)", allowPubKeyRetrieval, user, pwd, "Ok");
((JdbcConnection) testConn).changeUser(user, user);
testStmt = testConn.createStatement();
this.rs = testStmt.executeQuery("SELECT USER(), CURRENT_USER()");
assertTrue(this.rs.next());
assertTrue(this.rs.getString(1).startsWith(user));
assertTrue(this.rs.getString(2).startsWith(user));
this.rs.close();
testStmt.close();
// change user using different credentials
final String swapUser = user.indexOf("_sha") == -1 ? "bug75670user_sha" : "bug75670user_mnp";
expectedPubKeyRetrievalFail = swapUser.endsWith("_sha") && !allowPubKeyRetrieval || swapUser.endsWith("_mnp") && defAuthPlugin.equals(Sha256PasswordPlugin.class) && !allowPubKeyRetrieval;
System.out.printf("%25s : %-18s : %-25s : %-25s : %s%n", "| ChangeUser (diff)", allowPubKeyRetrieval, swapUser, swapUser, expectedPubKeyRetrievalFail ? "Fail [Pub. Key retrieval]" : "Ok");
if (expectedPubKeyRetrievalFail) {
// change user will fail due to public key retrieval failure
assertThrows(SQLException.class, "Public Key Retrieval is not allowed", new Callable<Void>() {
public Void call() throws Exception {
((JdbcConnection) testConn).changeUser(swapUser, swapUser);
return null;
}
});
} else {
// change user will succeed
((JdbcConnection) testConn).changeUser(swapUser, swapUser);
testStmt = testConn.createStatement();
this.rs = testStmt.executeQuery("SELECT USER(), CURRENT_USER()");
assertTrue(this.rs.next());
assertTrue(this.rs.getString(1).startsWith(swapUser));
assertTrue(this.rs.getString(2).startsWith(swapUser));
this.rs.close();
}
testConn.close();
}
}
}
}
}
} finally {
if (!((MysqlConnection) this.conn).getSession().versionMeetsMinimum(8, 0, 5)) {
this.stmt.executeUpdate("SET GLOBAL old_passwords = @current_old_passwords");
}
}
}
use of com.mysql.cj.MysqlConnection in project aws-mysql-jdbc by awslabs.
the class ConnectionRegressionTest method testBug11237.
/**
* Tests fix for BUG#11237 useCompression=true and LOAD DATA LOCAL INFILE SQL Command
*
* @throws Exception
*/
@Test
public void testBug11237() throws Exception {
assumeTrue(supportsLoadLocalInfile(this.stmt), "This test requires the server started with --local-infile=ON");
this.rs = this.stmt.executeQuery("SHOW VARIABLES LIKE 'max_allowed_packet'");
this.rs.next();
long defaultMaxAllowedPacket = this.rs.getInt(2);
boolean changeMaxAllowedPacket = defaultMaxAllowedPacket < 4 + 1024 * 1024 * 16 - 1;
int requiredSize = 1024 * 1024 * 300;
int fieldLength = 1023;
int loops = requiredSize / 2 / (fieldLength + 1);
File testFile = File.createTempFile("cj-testloaddata", ".dat");
testFile.deleteOnExit();
// TODO: following cleanup doesn't work correctly during concurrent execution of testsuite
// cleanupTempFiles(testFile, "cj-testloaddata");
BufferedOutputStream bOut = new BufferedOutputStream(new FileOutputStream(testFile));
byte[] bytes1 = new byte[fieldLength];
Arrays.fill(bytes1, (byte) 'a');
byte[] bytes2 = new byte[fieldLength];
Arrays.fill(bytes2, (byte) 'b');
byte tab = '\t';
byte nl = '\n';
for (int i = 0; i < loops; i++) {
bOut.write(bytes1);
bOut.write(tab);
bOut.write(bytes2);
bOut.write(nl);
bOut.flush();
}
bOut.close();
createTable("testBug11237", "(field1 VARCHAR(1024), field2 VARCHAR(1024))");
StringBuilder fileNameBuf = null;
if (File.separatorChar == '\\') {
fileNameBuf = new StringBuilder();
String fileName = testFile.getAbsolutePath();
int fileNameLength = fileName.length();
for (int i = 0; i < fileNameLength; i++) {
char c = fileName.charAt(i);
if (c == '\\') {
fileNameBuf.append("/");
} else {
fileNameBuf.append(c);
}
}
} else {
fileNameBuf = new StringBuilder(testFile.getAbsolutePath());
}
Connection conn1 = null;
try {
if (changeMaxAllowedPacket) {
this.stmt.executeUpdate("SET GLOBAL max_allowed_packet=" + 1024 * 1024 * 17);
}
Properties props = new Properties();
props.setProperty(PropertyKey.sslMode.getKeyName(), SslMode.DISABLED.name());
props.setProperty(PropertyKey.allowPublicKeyRetrieval.getKeyName(), "true");
props.setProperty(PropertyKey.allowLoadLocalInfile.getKeyName(), "true");
props.setProperty(PropertyKey.useCompression.getKeyName(), "true");
conn1 = getConnectionWithProps(props);
Statement stmt1 = conn1.createStatement();
int updateCount = stmt1.executeUpdate("LOAD DATA LOCAL INFILE '" + fileNameBuf.toString() + "' INTO TABLE testBug11237 CHARACTER SET " + CharsetMappingWrapper.getStaticMysqlCharsetForJavaEncoding(((MysqlConnection) this.conn).getPropertySet().getStringProperty(PropertyKey.characterEncoding).getValue(), ((JdbcConnection) conn1).getServerVersion()));
assertTrue(updateCount == loops);
} finally {
if (changeMaxAllowedPacket) {
this.stmt.executeUpdate("SET GLOBAL max_allowed_packet=" + defaultMaxAllowedPacket);
}
if (conn1 != null) {
conn1.close();
}
}
}
use of com.mysql.cj.MysqlConnection in project aws-mysql-jdbc by awslabs.
the class ConnectionRegressionTest method testBug44587.
/**
* Tests fix for BUG#44587, provide last packet sent/received timing in all connection failure errors.
*
* @throws Exception
*/
@Test
public void testBug44587() throws Exception {
Exception e = null;
String msg = ExceptionFactory.createLinkFailureMessageBasedOnHeuristics(((MysqlConnection) this.conn).getPropertySet(), ((MysqlConnection) this.conn).getSession().getServerSession(), new PacketSentTimeHolder() {
@Override
public long getPreviousPacketSentTime() {
return System.currentTimeMillis() - 1000;
}
@Override
public long getLastPacketSentTime() {
return System.currentTimeMillis() - 1000;
}
}, new PacketReceivedTimeHolder() {
@Override
public long getLastPacketReceivedTime() {
return System.currentTimeMillis() - 2000;
}
}, e);
assertTrue(containsMessage(msg, "CommunicationsException.ServerPacketTimingInfo"));
}
use of com.mysql.cj.MysqlConnection in project aws-mysql-jdbc by awslabs.
the class ConnectionRegressionTest method testEnableTLSVersion.
/**
* Tests fix for Bug#87379. This allows TLS version to be overridden through a new configuration option - tlsVersions. When set to some combination
* of TLSv1.2 or TLSv1.3 (comma-separated, no spaces), the default behavior restricting the TLS version based on JRE and MySQL Server version is
* bypassed to enable or restrict specific TLS versions.
*
* @throws Exception
*/
@Test
public void testEnableTLSVersion() 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");
// Find out which TLS protocol versions are supported by this JVM.
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, null, null);
List<String> jvmSupportedProtocols = Arrays.asList(sslContext.createSSLEngine().getSupportedProtocols());
Properties props = new Properties();
props.setProperty(PropertyKey.allowPublicKeyRetrieval.getKeyName(), "true");
props.setProperty(PropertyKey.sslMode.getKeyName(), SslMode.REQUIRED.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");
System.out.println(dbUrl);
System.out.println("JVM version: " + System.getProperty(PropertyDefinitions.SYSP_java_version));
System.out.println("JVM supports TLS protocols: " + jvmSupportedProtocols);
Connection sslConn = getConnectionWithProps(dbUrl, props);
assertTrue(((MysqlConnection) sslConn).getSession().isSSLEstablished());
System.out.println("MySQL version: " + ((MysqlConnection) sslConn).getSession().getServerSession().getServerVersion());
List<String> commonSupportedProtocols = new ArrayList<>();
if (((JdbcConnection) sslConn).getSession().versionMeetsMinimum(5, 7, 10)) {
this.rs = sslConn.createStatement().executeQuery("SHOW GLOBAL VARIABLES LIKE 'tls_version'");
assertTrue(this.rs.next());
List<String> serverSupportedProtocols = Arrays.asList(this.rs.getString(2).trim().split("\\s*,\\s*"));
System.out.println("Server supports TLS protocols: " + serverSupportedProtocols);
commonSupportedProtocols.addAll(serverSupportedProtocols);
commonSupportedProtocols.retainAll(jvmSupportedProtocols);
} else {
commonSupportedProtocols.add("TLSv1.2");
commonSupportedProtocols.add("TLSv1.3");
commonSupportedProtocols.retainAll(jvmSupportedProtocols);
}
String[] testingProtocols = { "TLSv1.2", "TLSv1.3" };
for (String protocol : testingProtocols) {
Properties testProps = new Properties();
testProps.putAll(props);
testProps.setProperty(PropertyKey.tlsVersions.getKeyName(), protocol);
System.out.println("Testing " + protocol + " expecting connection: " + commonSupportedProtocols.contains(protocol));
try {
Connection tlsConn = getConnectionWithProps(dbUrl, testProps);
assertTrue(commonSupportedProtocols.contains(protocol), "Expected to fail connection with " + protocol + " due to lack of jvm/server support.");
ResultSet rset = tlsConn.createStatement().executeQuery("SHOW STATUS LIKE 'ssl_version'");
assertTrue(rset.next());
String tlsVersion = rset.getString(2);
assertEquals(protocol, tlsVersion);
tlsConn.close();
} catch (Exception e) {
if (commonSupportedProtocols.contains(protocol)) {
e.printStackTrace();
fail("Expected to be able to connect with " + protocol + " protocol, but failed.");
}
}
}
System.out.println();
sslConn.close();
}
use of com.mysql.cj.MysqlConnection in project aws-mysql-jdbc by awslabs.
the class ResultSetRegressionTest method tstBug24525461assertResults2.
private void tstBug24525461assertResults2(boolean testJSON, Statement st) throws Exception {
String fAsText = versionMeetsMinimum(5, 6, 1) ? "ST_AsText" : "AsText";
Properties props = new Properties();
props.setProperty(PropertyKey.sslMode.getKeyName(), SslMode.DISABLED.name());
props.setProperty(PropertyKey.allowPublicKeyRetrieval.getKeyName(), "true");
props.setProperty(PropertyKey.connectionTimeZone.getKeyName(), "LOCAL");
Connection testConn = getConnectionWithProps(props);
TimeZone serverTz = ((MysqlConnection) testConn).getSession().getServerSession().getSessionTimeZone();
ZonedDateTime expZdt = LocalDateTime.of(2002, 2, 2, 10, 30).atZone(ZoneId.systemDefault()).withZoneSameInstant(serverTz.toZoneId());
String expTimestamp = expZdt.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.S"));
ResultSet rs2 = st.executeQuery("SELECT *, " + fAsText + "(f30), " + fAsText + "(f31) FROM testBug24525461");
assertTrue(rs2.next());
assertEquals(0, rs2.getInt(1));
assertEquals(BigDecimal.valueOf(20), rs2.getBigDecimal(2));
assertEquals(2, rs2.getInt(3));
assertFalse(rs2.getBoolean(4));
assertEquals(2, rs2.getInt(5));
assertEquals(2, rs2.getInt(6));
assertEquals(Float.valueOf(2), rs2.getFloat(7));
assertEquals(Double.valueOf(2), rs2.getDouble(8));
assertEquals("2002-02-02 10:30:00.0", rs2.getTimestamp(9).toString());
assertEquals(BigDecimal.valueOf(2), rs2.getBigDecimal(10));
assertEquals(2, rs2.getInt(11));
assertEquals("2002-02-02", rs2.getDate(12).toString());
assertEquals("10:30:00", rs2.getTime(13).toString());
assertEquals(expTimestamp, rs2.getTimestamp(14).toString());
assertEquals("2002-01-01", rs2.getDate(15).toString());
assertEquals("bbb", rs2.getString(16));
Blob blob = rs2.getBlob(17);
assertTrue(Arrays.equals(new byte[] { 50 }, blob.getBytes(1, (int) blob.length())));
assertEquals(0, rs2.getInt(18));
assertEquals("y", rs2.getString(19));
assertEquals("b", rs2.getString(20));
blob = rs2.getBlob(21);
assertTrue(Arrays.equals(new byte[] { 50 }, blob.getBytes(1, (int) blob.length())));
assertEquals("2", rs2.getString(22));
blob = rs2.getBlob(23);
assertTrue(Arrays.equals(new byte[] { 50 }, blob.getBytes(1, (int) blob.length())));
assertEquals("2", rs2.getString(24));
blob = rs2.getBlob(25);
assertTrue(Arrays.equals(new byte[] { 50 }, blob.getBytes(1, (int) blob.length())));
assertEquals("2", rs2.getString(26));
blob = rs2.getBlob(27);
assertTrue(Arrays.equals(new byte[] { 50 }, blob.getBytes(1, (int) blob.length())));
assertEquals("2", rs2.getString(28));
assertEquals("2", rs2.getString(29));
blob = rs2.getBlob(30);
assertTrue(Arrays.equals(new byte[] { 50 }, blob.getBytes(1, (int) blob.length())));
assertEquals("bbb", rs2.getString(33));
assertEquals("bbb", rs2.getString(34));
assertEquals("bbb", rs2.getString(35));
assertEquals("bbb", rs2.getString(36));
blob = rs2.getBlob(37);
assertTrue(Arrays.equals(new byte[] { 50 }, blob.getBytes(1, (int) blob.length())));
blob = rs2.getBlob(38);
assertTrue(Arrays.equals(new byte[] { 50 }, blob.getBytes(1, (int) blob.length())));
assertEquals("bbb", rs2.getString(39));
assertEquals("bbb", rs2.getString(40));
assertEquals("bbb", rs2.getString(41));
assertEquals("bbb", rs2.getString(42));
assertEquals("bbb", rs2.getString(43));
assertEquals(null, rs2.getString(44));
SQLXML xml = rs2.getSQLXML(45);
assertEquals("<doc/>", xml.getString());
if (testJSON) {
assertEquals("{\"key2\": \"value2\"}", rs2.getString(46));
assertEquals("POINT(2 2)", rs2.getString(47));
assertEquals("POINT(1 1)", rs2.getString(48));
} else {
assertEquals("POINT(2 2)", rs2.getString(46));
assertEquals("POINT(1 1)", rs2.getString(47));
}
assertFalse(rs2.next());
}
Aggregations