Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/AuthenticationPlugin.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -rccfe08930c8c33a8f96900a64475229049441f6c --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/AuthenticationPlugin.java (.../AuthenticationPlugin.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/AuthenticationPlugin.java (.../AuthenticationPlugin.java) (revision ccfe08930c8c33a8f96900a64475229049441f6c) @@ -1,5 +1,5 @@ /* - Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -110,4 +110,8 @@ */ boolean nextAuthenticationStep(Buffer fromServer, List toServer) throws SQLException; -} + /** + * Resets the authentication steps sequence. + */ + void reset(); +} \ No newline at end of file Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/CharsetMapping.java =================================================================== diff -u -r5a8831deff620b6d7419f54d9e45d3a54c76af18 -rccfe08930c8c33a8f96900a64475229049441f6c --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/CharsetMapping.java (.../CharsetMapping.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/CharsetMapping.java (.../CharsetMapping.java) (revision ccfe08930c8c33a8f96900a64475229049441f6c) @@ -509,7 +509,6 @@ collation[275] = new Collation(275, "utf8mb4_hr_0900_ai_ci", 0, MYSQL_CHARSET_NAME_utf8mb4); collation[277] = new Collation(277, "utf8mb4_vi_0900_ai_ci", 0, MYSQL_CHARSET_NAME_utf8mb4); - collation[278] = new Collation(278, "utf8mb4_0900_as_cs", 0, MYSQL_CHARSET_NAME_utf8mb4); collation[279] = new Collation(279, "utf8mb4_de_pb_0900_as_cs", 0, MYSQL_CHARSET_NAME_utf8mb4); collation[280] = new Collation(280, "utf8mb4_is_0900_as_cs", 0, MYSQL_CHARSET_NAME_utf8mb4); @@ -535,6 +534,10 @@ collation[300] = new Collation(300, "utf8mb4_vi_0900_as_cs", 0, MYSQL_CHARSET_NAME_utf8mb4); collation[303] = new Collation(303, "utf8mb4_ja_0900_as_cs", 0, MYSQL_CHARSET_NAME_utf8mb4); + collation[304] = new Collation(304, "utf8mb4_ja_0900_as_cs_ks", 0, MYSQL_CHARSET_NAME_utf8mb4); + collation[305] = new Collation(305, "utf8mb4_0900_as_ci", 0, MYSQL_CHARSET_NAME_utf8mb4); + collation[306] = new Collation(306, "utf8mb4_ru_0900_ai_ci", 0, MYSQL_CHARSET_NAME_utf8mb4); + collation[307] = new Collation(307, "utf8mb4_ru_0900_as_cs", 0, MYSQL_CHARSET_NAME_utf8mb4); collation[326] = new Collation(326, "utf8mb4_test_ci", 0, MYSQL_CHARSET_NAME_utf8mb4); collation[327] = new Collation(327, "utf16_test_ci", 0, MYSQL_CHARSET_NAME_utf16); Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/ConnectionImpl.java =================================================================== diff -u -r5a8831deff620b6d7419f54d9e45d3a54c76af18 -rccfe08930c8c33a8f96900a64475229049441f6c --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/ConnectionImpl.java (.../ConnectionImpl.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/ConnectionImpl.java (.../ConnectionImpl.java) (revision ccfe08930c8c33a8f96900a64475229049441f6c) @@ -1,5 +1,5 @@ /* - Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -190,18 +190,20 @@ * names soon will, so current catalog is a (hidden) component of the name. */ static class CompoundCacheKey { - String componentOne; + final String componentOne; - String componentTwo; + final String componentTwo; - int hashCode; + final int hashCode; CompoundCacheKey(String partOne, String partTwo) { this.componentOne = partOne; this.componentTwo = partTwo; - // Handle first component (in most cases, currentCatalog being NULL.... - this.hashCode = (((this.componentOne != null) ? this.componentOne : "") + this.componentTwo).hashCode(); + int hc = 17; + hc = 31 * hc + (this.componentOne != null ? this.componentOne.hashCode() : 0); + hc = 31 * hc + (this.componentTwo != null ? this.componentTwo.hashCode() : 0); + this.hashCode = hc; } /* @@ -211,20 +213,15 @@ */ @Override public boolean equals(Object obj) { - if (obj instanceof CompoundCacheKey) { + if (this == obj) { + return true; + } + if (obj != null && CompoundCacheKey.class.isAssignableFrom(obj.getClass())) { CompoundCacheKey another = (CompoundCacheKey) obj; - - boolean firstPartEqual = false; - - if (this.componentOne == null) { - firstPartEqual = (another.componentOne == null); - } else { - firstPartEqual = this.componentOne.equals(another.componentOne); + if (this.componentOne == null ? another.componentOne == null : this.componentOne.equals(another.componentOne)) { + return this.componentTwo == null ? another.componentTwo == null : this.componentTwo.equals(another.componentTwo); } - - return (firstPartEqual && this.componentTwo.equals(another.componentTwo)); } - return false; } @@ -440,7 +437,7 @@ * synchronization and at the same time save memory (each charset converter * takes approx 65K of static data). */ - private Map charsetConverterMap = new HashMap(CharsetMapping.getNumberOfCharsetsConfigured()); + private final Map charsetConverterMap = new HashMap(CharsetMapping.getNumberOfCharsetsConfigured()); /** The point in time when this connection was created */ private long connectionCreationTimeMillis = 0; @@ -554,7 +551,7 @@ */ private final CopyOnWriteArrayList openStatements = new CopyOnWriteArrayList(); - private LRUCache parsedCallableStatementCache; + private LRUCache parsedCallableStatementCache; private boolean parserKnowsUnicode = false; @@ -581,7 +578,7 @@ private boolean readOnly = false; /** Cache of ResultSet metadata */ - protected LRUCache resultSetMetadataCache; + protected LRUCache resultSetMetadataCache; /** The timezone of the server */ private TimeZone serverTimezoneTZ = null; @@ -614,8 +611,8 @@ */ private boolean useServerPreparedStmts = false; - private LRUCache serverSideStatementCheckCache; - private LRUCache serverSideStatementCache; + private LRUCache serverSideStatementCheckCache; + private LRUCache serverSideStatementCache; private Calendar sessionCalendar; private Calendar utcCalendar; @@ -1009,7 +1006,7 @@ if (getCachePreparedStatements()) { synchronized (this.serverSideStatementCheckCache) { - Boolean flag = (Boolean) this.serverSideStatementCheckCache.get(sql); + Boolean flag = this.serverSideStatementCheckCache.get(sql); if (flag != null) { return flag.booleanValue(); @@ -1280,16 +1277,11 @@ * @throws SQLException */ private void checkTransactionIsolationLevel() throws SQLException { - String txIsolationName = null; - - if (versionMeetsMinimum(4, 0, 3)) { - txIsolationName = "tx_isolation"; - } else { - txIsolationName = "transaction_isolation"; + String s = this.serverVariables.get("transaction_isolation"); + if (s == null) { + s = this.serverVariables.get("tx_isolation"); } - String s = this.serverVariables.get(txIsolationName); - if (s != null) { Integer intTI = mapTransIsolationNameToValue.get(s); @@ -2319,22 +2311,22 @@ } if (getUseServerPreparedStmts()) { - this.serverSideStatementCheckCache = new LRUCache(cacheSize); + this.serverSideStatementCheckCache = new LRUCache(cacheSize); - this.serverSideStatementCache = new LRUCache(cacheSize) { + this.serverSideStatementCache = new LRUCache(cacheSize) { private static final long serialVersionUID = 7692318650375988114L; @Override - protected boolean removeEldestEntry(java.util.Map.Entry eldest) { + protected boolean removeEldestEntry(java.util.Map.Entry eldest) { if (this.maxElements <= 1) { return false; } boolean removeIt = super.removeEldestEntry(eldest); if (removeIt) { - ServerPreparedStatement ps = (ServerPreparedStatement) eldest.getValue(); + ServerPreparedStatement ps = eldest.getValue(); ps.isCached = false; ps.setClosed(false); @@ -2469,7 +2461,7 @@ this.lastQueryFinishedTime = 0; // we're busy! - if ((getHighAvailability()) && (this.autoCommit || getAutoReconnectForPools()) && this.needsPing && !isBatch) { + if (getHighAvailability() && (this.autoCommit || getAutoReconnectForPools()) && this.needsPing && !isBatch) { try { pingInternal(false, 0); @@ -2506,19 +2498,23 @@ sqlE = appendMessageToException(sqlE, messageBuf.toString(), getExceptionInterceptor()); } - if ((getHighAvailability())) { - this.needsPing = true; - } else { - String sqlState = sqlE.getSQLState(); - - if ((sqlState != null) && sqlState.equals(SQLError.SQL_STATE_COMMUNICATION_LINK_FAILURE)) { - cleanup(sqlE); + if (getHighAvailability()) { + if (SQLError.SQL_STATE_COMMUNICATION_LINK_FAILURE.equals(sqlE.getSQLState())) { + // IO may be dirty or damaged beyond repair, force close it. + this.io.forceClose(); } + this.needsPing = true; + } else if (SQLError.SQL_STATE_COMMUNICATION_LINK_FAILURE.equals(sqlE.getSQLState())) { + cleanup(sqlE); } throw sqlE; } catch (Exception ex) { if (getHighAvailability()) { + if (ex instanceof IOException) { + // IO may be dirty or damaged beyond repair, force close it. + this.io.forceClose(); + } this.needsPing = true; } else if (ex instanceof IOException) { cleanup(ex); @@ -2900,11 +2896,13 @@ } public java.sql.Statement getMetadataSafeStatement() throws SQLException { + return getMetadataSafeStatement(0); + } + + public java.sql.Statement getMetadataSafeStatement(int maxRows) throws SQLException { java.sql.Statement stmt = createStatement(); - if (stmt.getMaxRows() != 0) { - stmt.setMaxRows(0); - } + stmt.setMaxRows(maxRows == -1 ? 0 : maxRows); stmt.setEscapeProcessing(false); @@ -2997,30 +2995,20 @@ java.sql.ResultSet rs = null; try { - stmt = getMetadataSafeStatement(); - - String query = null; - - int offset = 0; - - if (versionMeetsMinimum(4, 0, 3)) { - query = "SELECT @@session.tx_isolation"; - offset = 1; - } else { - query = "SHOW VARIABLES LIKE 'transaction_isolation'"; - offset = 2; - } - + stmt = getMetadataSafeStatement(this.sessionMaxRows); + String query = versionMeetsMinimum(8, 0, 3) || (versionMeetsMinimum(5, 7, 20) && !versionMeetsMinimum(8, 0, 0)) + ? "SELECT @@session.transaction_isolation" : "SELECT @@session.tx_isolation"; rs = stmt.executeQuery(query); if (rs.next()) { - String s = rs.getString(offset); + String s = rs.getString(1); if (s != null) { Integer intTI = mapTransIsolationNameToValue.get(s); if (intTI != null) { - return intTI.intValue(); + this.isolationLevel = intTI.intValue(); + return this.isolationLevel; } } @@ -3169,15 +3157,15 @@ } if (getCacheCallableStatements()) { - this.parsedCallableStatementCache = new LRUCache(getCallableStatementCacheSize()); + this.parsedCallableStatementCache = new LRUCache(getCallableStatementCacheSize()); } if (getAllowMultiQueries()) { setCacheResultSetMetadata(false); // we don't handle this yet } if (getCacheResultSetMetadata()) { - this.resultSetMetadataCache = new LRUCache(getMetadataCacheSize()); + this.resultSetMetadataCache = new LRUCache(getMetadataCacheSize()); } if (getSocksProxyHost() != null) { @@ -3248,6 +3236,7 @@ for (int i = 1; i < CharsetMapping.COLLATION_INDEX_TO_COLLATION_NAME.length; i++) { if (CharsetMapping.COLLATION_INDEX_TO_COLLATION_NAME[i].equals(collationServer)) { this.io.serverCharsetIndex = i; + break; } } } else { @@ -3399,8 +3388,7 @@ } public boolean isQueryCacheEnabled() { - return "YES".equalsIgnoreCase(this.serverVariables.get("have_query_cache")) && "ON".equalsIgnoreCase(this.serverVariables.get("query_cache_type")) - && !"0".equalsIgnoreCase(this.serverVariables.get("query_cache_size")); + return "ON".equalsIgnoreCase(this.serverVariables.get("query_cache_type")) && !"0".equalsIgnoreCase(this.serverVariables.get("query_cache_size")); } private int getServerVariableAsInt(String variableName, int fallbackValue) throws SQLException { @@ -3546,9 +3534,10 @@ try { try { - stmt = getMetadataSafeStatement(); + stmt = getMetadataSafeStatement(this.sessionMaxRows); - rs = stmt.executeQuery("select @@session.tx_read_only"); + rs = stmt.executeQuery(versionMeetsMinimum(8, 0, 3) || (versionMeetsMinimum(5, 7, 20) && !versionMeetsMinimum(8, 0, 0)) + ? "select @@session.transaction_read_only" : "select @@session.tx_read_only"); if (rs.next()) { return rs.getInt(1) != 0; // mysql has a habit of tri+ state booleans } @@ -3758,6 +3747,9 @@ this.serverVariables = new HashMap(); + boolean currentJdbcComplTrunc = this.getJdbcCompliantTruncation(); + setJdbcCompliantTruncation(false); // Temporarily disabling data truncation check avoids unnecessary SHOW WARNINGS on deprecated vars. + try { if (versionMeetsMinimum(5, 1, 0)) { StringBuilder queryBuf = new StringBuilder(versionComment).append("SELECT"); @@ -3777,11 +3769,18 @@ queryBuf.append(", @@max_allowed_packet AS max_allowed_packet"); queryBuf.append(", @@net_buffer_length AS net_buffer_length"); queryBuf.append(", @@net_write_timeout AS net_write_timeout"); - queryBuf.append(", @@have_query_cache AS have_query_cache"); + if (!versionMeetsMinimum(8, 0, 3)) { + queryBuf.append(", @@query_cache_size AS query_cache_size"); + queryBuf.append(", @@query_cache_type AS query_cache_type"); + } queryBuf.append(", @@sql_mode AS sql_mode"); queryBuf.append(", @@system_time_zone AS system_time_zone"); queryBuf.append(", @@time_zone AS time_zone"); - queryBuf.append(", @@tx_isolation AS tx_isolation"); + if (versionMeetsMinimum(8, 0, 3) || (versionMeetsMinimum(5, 7, 20) && !versionMeetsMinimum(8, 0, 0))) { + queryBuf.append(", @@transaction_isolation AS transaction_isolation"); + } else { + queryBuf.append(", @@tx_isolation AS transaction_isolation"); + } queryBuf.append(", @@wait_timeout AS wait_timeout"); results = stmt.executeQuery(queryBuf.toString()); @@ -3791,18 +3790,6 @@ this.serverVariables.put(rsmd.getColumnLabel(i), results.getString(i)); } } - - if ("YES".equalsIgnoreCase(this.serverVariables.get("have_query_cache"))) { - results.close(); - results = stmt.executeQuery("SELECT @@query_cache_size AS query_cache_size, @@query_cache_type AS query_cache_type"); - if (results.next()) { - ResultSetMetaData rsmd = results.getMetaData(); - for (int i = 1; i <= rsmd.getColumnCount(); i++) { - this.serverVariables.put(rsmd.getColumnLabel(i), results.getString(i)); - } - } - } - } else { results = stmt.executeQuery(versionComment + "SHOW VARIABLES"); while (results.next()) { @@ -3816,6 +3803,8 @@ if (ex.getErrorCode() != MysqlErrorNumbers.ER_MUST_CHANGE_PASSWORD || getDisconnectOnExpiredPasswords()) { throw ex; } + } finally { + setJdbcCompliantTruncation(currentJdbcComplTrunc); } if (getCacheServerConfiguration()) { @@ -3970,8 +3959,7 @@ synchronized (this.parsedCallableStatementCache) { CompoundCacheKey key = new CompoundCacheKey(getCatalog(), sql); - CallableStatement.CallableStatementParamInfo cachedParamInfo = (CallableStatement.CallableStatementParamInfo) this.parsedCallableStatementCache - .get(key); + CallableStatement.CallableStatementParamInfo cachedParamInfo = this.parsedCallableStatementCache.get(key); if (cachedParamInfo != null) { cStmt = CallableStatement.getInstance(getMultiHostSafeProxy(), cachedParamInfo); @@ -4083,8 +4071,7 @@ if (this.useServerPreparedStmts && canServerPrepare) { if (this.getCachePreparedStatements()) { synchronized (this.serverSideStatementCache) { - pStmt = (com.mysql.jdbc.ServerPreparedStatement) this.serverSideStatementCache - .remove(makePreparedStatementCacheKey(this.database, sql)); + pStmt = this.serverSideStatementCache.remove(new CompoundCacheKey(this.database, sql)); if (pStmt != null) { ((com.mysql.jdbc.ServerPreparedStatement) pStmt).setClosed(false); @@ -4274,20 +4261,14 @@ } - private String makePreparedStatementCacheKey(String catalog, String query) { - StringBuilder key = new StringBuilder(); - key.append("/*").append(catalog).append("*/"); - key.append(query); - return key.toString(); - } - public void recachePreparedStatement(ServerPreparedStatement pstmt) throws SQLException { synchronized (getConnectionMutex()) { if (getCachePreparedStatements() && pstmt.isPoolable()) { synchronized (this.serverSideStatementCache) { - Object oldServerPrepStmt = this.serverSideStatementCache.put(makePreparedStatementCacheKey(pstmt.currentCatalog, pstmt.originalSql), pstmt); - if (oldServerPrepStmt != null) { + Object oldServerPrepStmt = this.serverSideStatementCache.put(new CompoundCacheKey(pstmt.currentCatalog, pstmt.originalSql), pstmt); + if (oldServerPrepStmt != null && oldServerPrepStmt != pstmt) { ((ServerPreparedStatement) oldServerPrepStmt).isCached = false; + ((ServerPreparedStatement) oldServerPrepStmt).setClosed(false); ((ServerPreparedStatement) oldServerPrepStmt).realClose(true, true); } } @@ -4299,7 +4280,7 @@ synchronized (getConnectionMutex()) { if (getCachePreparedStatements() && pstmt.isPoolable()) { synchronized (this.serverSideStatementCache) { - this.serverSideStatementCache.remove(makePreparedStatementCacheKey(pstmt.currentCatalog, pstmt.originalSql)); + this.serverSideStatementCache.remove(new CompoundCacheKey(pstmt.currentCatalog, pstmt.originalSql)); } } } @@ -5229,7 +5210,7 @@ public CachedResultSetMetaData getCachedMetaData(String sql) { if (this.resultSetMetadataCache != null) { synchronized (this.resultSetMetadataCache) { - return (CachedResultSetMetaData) this.resultSetMetadataCache.get(sql); + return this.resultSetMetadataCache.get(sql); } } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/ConnectionProperties.java =================================================================== diff -u -r5a8831deff620b6d7419f54d9e45d3a54c76af18 -rccfe08930c8c33a8f96900a64475229049441f6c --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/ConnectionProperties.java (.../ConnectionProperties.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/ConnectionProperties.java (.../ConnectionProperties.java) (revision ccfe08930c8c33a8f96900a64475229049441f6c) @@ -1426,6 +1426,10 @@ public void setEnabledSSLCipherSuites(String cipherSuites); + public String getEnabledTLSProtocols(); + + public void setEnabledTLSProtocols(String protocols); + public boolean getEnableEscapeProcessing(); public void setEnableEscapeProcessing(boolean flag); Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/ConnectionPropertiesImpl.java =================================================================== diff -u -r5a8831deff620b6d7419f54d9e45d3a54c76af18 -rccfe08930c8c33a8f96900a64475229049441f6c --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/ConnectionPropertiesImpl.java (.../ConnectionPropertiesImpl.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/ConnectionPropertiesImpl.java (.../ConnectionPropertiesImpl.java) (revision ccfe08930c8c33a8f96900a64475229049441f6c) @@ -1,5 +1,5 @@ /* - Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -878,7 +878,7 @@ Messages.getString("ConnectionProperties.loadBalanceStrategy"), "5.0.6", PERFORMANCE_CATEGORY, Integer.MIN_VALUE); private StringConnectionProperty serverAffinityOrder = new StringConnectionProperty("serverAffinityOrder", "", null, - Messages.getString("ConnectionProperties.serverAffinityOrder"), "5.1.4.", PERFORMANCE_CATEGORY, Integer.MIN_VALUE); + Messages.getString("ConnectionProperties.serverAffinityOrder"), "5.1.43", PERFORMANCE_CATEGORY, Integer.MIN_VALUE); private IntegerConnectionProperty loadBalanceBlacklistTimeout = new IntegerConnectionProperty("loadBalanceBlacklistTimeout", 0, 0, Integer.MAX_VALUE, Messages.getString("ConnectionProperties.loadBalanceBlacklistTimeout"), "5.1.0", MISC_CATEGORY, Integer.MIN_VALUE); @@ -980,7 +980,7 @@ private BooleanConnectionProperty nullNamePatternMatchesAll = new BooleanConnectionProperty("nullNamePatternMatchesAll", true, Messages.getString("ConnectionProperties.nullNamePatternMatchesAll"), "3.1.8", MISC_CATEGORY, Integer.MIN_VALUE); - private IntegerConnectionProperty packetDebugBufferSize = new IntegerConnectionProperty("packetDebugBufferSize", 20, 0, Integer.MAX_VALUE, + private IntegerConnectionProperty packetDebugBufferSize = new IntegerConnectionProperty("packetDebugBufferSize", 20, 1, Integer.MAX_VALUE, Messages.getString("ConnectionProperties.packetDebugBufferSize"), "3.1.3", DEBUGING_PROFILING_CATEGORY, 7); private BooleanConnectionProperty padCharsWithSpace = new BooleanConnectionProperty("padCharsWithSpace", false, @@ -1334,6 +1334,9 @@ private StringConnectionProperty enabledSSLCipherSuites = new StringConnectionProperty("enabledSSLCipherSuites", null, Messages.getString("ConnectionProperties.enabledSSLCipherSuites"), "5.1.35", SECURITY_CATEGORY, 11); + private StringConnectionProperty enabledTLSProtocols = new StringConnectionProperty("enabledTLSProtocols", null, + Messages.getString("ConnectionProperties.enabledTLSProtocols"), "5.1.44", SECURITY_CATEGORY, 12); + private BooleanConnectionProperty enableEscapeProcessing = new BooleanConnectionProperty("enableEscapeProcessing", true, Messages.getString("ConnectionProperties.enableEscapeProcessing"), "5.1.37", PERFORMANCE_CATEGORY, Integer.MIN_VALUE); @@ -1392,6 +1395,32 @@ return info; } + public Properties exposeAsProperties(Properties props, boolean explicitOnly) throws SQLException { + if (props == null) { + props = new Properties(); + } + + int numPropertiesToSet = PROPERTY_LIST.size(); + + for (int i = 0; i < numPropertiesToSet; i++) { + java.lang.reflect.Field propertyField = PROPERTY_LIST.get(i); + + try { + ConnectionProperty propToGet = (ConnectionProperty) propertyField.get(this); + + Object propValue = propToGet.getValueAsObject(); + + if (propValue != null && (!explicitOnly || propToGet.isExplicitlySet())) { + props.setProperty(propToGet.getPropertyName(), propValue.toString()); + } + } catch (IllegalAccessException iae) { + throw SQLError.createSQLException("Internal properties failure", SQLError.SQL_STATE_GENERAL_ERROR, iae, getExceptionInterceptor()); + } + } + + return props; + } + class XmlMap { protected Map> ordered = new TreeMap>(); protected Map alpha = new TreeMap(); @@ -4948,6 +4977,14 @@ this.enabledSSLCipherSuites.setValue(cipherSuites); } + public String getEnabledTLSProtocols() { + return this.enabledTLSProtocols.getValueAsString(); + } + + public void setEnabledTLSProtocols(String protocols) { + this.enabledTLSProtocols.setValue(protocols); + } + public boolean getEnableEscapeProcessing() { return this.enableEscapeProcessing.getValueAsBoolean(); } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/ExportControlled.java =================================================================== diff -u -r5a8831deff620b6d7419f54d9e45d3a54c76af18 -rccfe08930c8c33a8f96900a64475229049441f6c --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/ExportControlled.java (.../ExportControlled.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/ExportControlled.java (.../ExportControlled.java) (revision ccfe08930c8c33a8f96900a64475229049441f6c) @@ -1,5 +1,5 @@ /* - Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -76,6 +76,10 @@ */ public class ExportControlled { private static final String SQL_STATE_BAD_SSL_PARAMS = "08000"; + private static final String TLSv1 = "TLSv1"; + private static final String TLSv1_1 = "TLSv1.1"; + private static final String TLSv1_2 = "TLSv1.2"; + private static final String[] TLS_PROTOCOLS = new String[] { TLSv1_2, TLSv1_1, TLSv1 }; protected static boolean enabled() { // we may wish to un-static-ify this class this static method call may be removed entirely by the compiler @@ -101,11 +105,30 @@ try { mysqlIO.mysqlConnection = sslFact.connect(mysqlIO.host, mysqlIO.port, null); + String[] tryProtocols = null; + + // If enabledTLSProtocols configuration option is set then override the default TLS version restrictions. This allows enabling TLSv1.2 for + // self-compiled MySQL versions supporting it, as well as the ability for users to restrict TLS connections to approved protocols (e.g., prohibiting + // TLSv1) on the client side. + // Note that it is problematic to enable TLSv1.2 on the client side when the server is compiled with yaSSL. When client attempts to connect with + // TLSv1.2 yaSSL just closes the socket instead of re-attempting handshake with lower TLS version. + String enabledTLSProtocols = mysqlIO.connection.getEnabledTLSProtocols(); + if (enabledTLSProtocols != null && enabledTLSProtocols.length() > 0) { + tryProtocols = enabledTLSProtocols.split("\\s*,\\s*"); + } else if (mysqlIO.versionMeetsMinimum(8, 0, 4) || mysqlIO.versionMeetsMinimum(5, 6, 0) && Util.isEnterpriseEdition(mysqlIO.getServerVersion())) { + // allow all known TLS versions for this subset of server versions by default + tryProtocols = TLS_PROTOCOLS; + } else { + // allow TLSv1 and TLSv1.1 for all server versions by default + tryProtocols = new String[] { TLSv1_1, TLSv1 }; + + } + + List configuredProtocols = new ArrayList(Arrays.asList(tryProtocols)); + List jvmSupportedProtocols = Arrays.asList(((SSLSocket) mysqlIO.mysqlConnection).getSupportedProtocols()); List allowedProtocols = new ArrayList(); - List supportedProtocols = Arrays.asList(((SSLSocket) mysqlIO.mysqlConnection).getSupportedProtocols()); - for (String protocol : (mysqlIO.versionMeetsMinimum(5, 6, 0) && Util.isEnterpriseEdition(mysqlIO.getServerVersion()) - ? new String[] { "TLSv1.2", "TLSv1.1", "TLSv1" } : new String[] { "TLSv1.1", "TLSv1" })) { - if (supportedProtocols.contains(protocol)) { + for (String protocol : TLS_PROTOCOLS) { + if (jvmSupportedProtocols.contains(protocol) && configuredProtocols.contains(protocol)) { allowedProtocols.add(protocol); } } @@ -484,14 +507,13 @@ } } - public static byte[] encryptWithRSAPublicKey(byte[] source, RSAPublicKey key, ExceptionInterceptor interceptor) throws SQLException { + public static byte[] encryptWithRSAPublicKey(byte[] source, RSAPublicKey key, String transformation, ExceptionInterceptor interceptor) throws SQLException { try { - Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-1AndMGF1Padding"); + Cipher cipher = Cipher.getInstance(transformation); cipher.init(Cipher.ENCRYPT_MODE, key); return cipher.doFinal(source); } catch (Exception ex) { throw SQLError.createSQLException(ex.getMessage(), SQLError.SQL_STATE_ILLEGAL_ARGUMENT, ex, interceptor); } } - } \ No newline at end of file Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/LoadBalancedAutoCommitInterceptor.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -rccfe08930c8c33a8f96900a64475229049441f6c --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/LoadBalancedAutoCommitInterceptor.java (.../LoadBalancedAutoCommitInterceptor.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/LoadBalancedAutoCommitInterceptor.java (.../LoadBalancedAutoCommitInterceptor.java) (revision ccfe08930c8c33a8f96900a64475229049441f6c) @@ -1,5 +1,5 @@ /* - Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2010, 2018, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -33,6 +33,8 @@ private ConnectionImpl conn; private LoadBalancedConnectionProxy proxy = null; + private boolean countStatements = false; + public void destroy() { // do nothing here } @@ -73,44 +75,49 @@ public ResultSetInternalMethods postProcess(String sql, Statement interceptedStatement, ResultSetInternalMethods originalResultSet, Connection connection, int warningCount, boolean noIndexUsed, boolean noGoodIndexUsed, SQLException statementException) throws SQLException { - // don't care if auto-commit is not enabled + // Don't count SETs neither SHOWs. Those are mostly used internally and must not trigger a connection switch. + if (!this.countStatements || StringUtils.startsWithIgnoreCase(sql, "SET") || StringUtils.startsWithIgnoreCase(sql, "SHOW")) { + return originalResultSet; + } + + // Don't care if auto-commit is not enabled. if (!this.conn.getAutoCommit()) { this.matchingAfterStatementCount = 0; - // auto-commit is enabled: - } else { + return originalResultSet; + } - if (this.proxy == null && this.conn.isProxySet()) { - MySQLConnection lcl_proxy = this.conn.getMultiHostSafeProxy(); - while (lcl_proxy != null && !(lcl_proxy instanceof LoadBalancedMySQLConnection)) { - lcl_proxy = lcl_proxy.getMultiHostSafeProxy(); - } - if (lcl_proxy != null) { - this.proxy = ((LoadBalancedMySQLConnection) lcl_proxy).getThisAsProxy(); - } - + if (this.proxy == null && this.conn.isProxySet()) { + MySQLConnection lcl_proxy = this.conn.getMultiHostSafeProxy(); + while (lcl_proxy != null && !(lcl_proxy instanceof LoadBalancedMySQLConnection)) { + lcl_proxy = lcl_proxy.getMultiHostSafeProxy(); } - - if (this.proxy != null) { - // increment the match count if no regex specified, or if matches: - if (this.matchingAfterStatementRegex == null || sql.matches(this.matchingAfterStatementRegex)) { - this.matchingAfterStatementCount++; - } + if (lcl_proxy != null) { + this.proxy = ((LoadBalancedMySQLConnection) lcl_proxy).getThisAsProxy(); } - // trigger rebalance if count exceeds threshold: - if (this.matchingAfterStatementCount >= this.matchingAfterStatementThreshold) { - this.matchingAfterStatementCount = 0; - try { - if (this.proxy != null) { - this.proxy.pickNewConnection(); - } - } catch (SQLException e) { - // eat this exception, the auto-commit statement completed, but we could not rebalance for some reason. User may get exception when using - // connection next. - } + } + + // Connection is not ready to rebalance yet. + if (this.proxy == null) { + return originalResultSet; + } + + // Increment the match count if no regex specified, or if matches. + if (this.matchingAfterStatementRegex == null || sql.matches(this.matchingAfterStatementRegex)) { + this.matchingAfterStatementCount++; + } + + // Trigger rebalance if count exceeds threshold. + if (this.matchingAfterStatementCount >= this.matchingAfterStatementThreshold) { + this.matchingAfterStatementCount = 0; + try { + this.proxy.pickNewConnection(); + } catch (SQLException e) { + // eat this exception, the auto-commit statement completed, but we could not rebalance for some reason. User may get exception when using + // connection next. } } - // always return the original result set. + return originalResultSet; } @@ -119,4 +126,11 @@ return null; } + void pauseCounters() { + this.countStatements = false; + } + + void resumeCounters() { + this.countStatements = true; + } } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/LoadBalancedConnectionProxy.java =================================================================== diff -u -r5a8831deff620b6d7419f54d9e45d3a54c76af18 -rccfe08930c8c33a8f96900a64475229049441f6c --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/LoadBalancedConnectionProxy.java (.../LoadBalancedConnectionProxy.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/LoadBalancedConnectionProxy.java (.../LoadBalancedConnectionProxy.java) (revision ccfe08930c8c33a8f96900a64475229049441f6c) @@ -1,5 +1,5 @@ /* - Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -376,9 +376,32 @@ this.totalPhysicalConnections++; + for (StatementInterceptorV2 stmtInterceptor : conn.getStatementInterceptorsInstances()) { + if (stmtInterceptor instanceof LoadBalancedAutoCommitInterceptor) { + ((LoadBalancedAutoCommitInterceptor) stmtInterceptor).resumeCounters(); + break; + } + } + return conn; } + @Override + void syncSessionState(Connection source, Connection target, boolean readOnly) throws SQLException { + LoadBalancedAutoCommitInterceptor lbAutoCommitStmtInterceptor = null; + for (StatementInterceptorV2 stmtInterceptor : ((MySQLConnection) target).getStatementInterceptorsInstances()) { + if (stmtInterceptor instanceof LoadBalancedAutoCommitInterceptor) { + lbAutoCommitStmtInterceptor = (LoadBalancedAutoCommitInterceptor) stmtInterceptor; + lbAutoCommitStmtInterceptor.pauseCounters(); + break; + } + } + super.syncSessionState(source, target, readOnly); + if (lbAutoCommitStmtInterceptor != null) { + lbAutoCommitStmtInterceptor.resumeCounters(); + } + } + /** * Closes all live connections. */ Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/LocalizedErrorMessages.properties =================================================================== diff -u -r5a8831deff620b6d7419f54d9e45d3a54c76af18 -rccfe08930c8c33a8f96900a64475229049441f6c --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/LocalizedErrorMessages.properties (.../LocalizedErrorMessages.properties) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/LocalizedErrorMessages.properties (.../LocalizedErrorMessages.properties) (revision ccfe08930c8c33a8f96900a64475229049441f6c) @@ -577,14 +577,14 @@ ConnectionProperties.roundRobinLoadBalance=When autoReconnect is enabled, and failoverReadonly is false, should we pick hosts to connect to on a round-robin basis? ConnectionProperties.runningCTS13=Enables workarounds for bugs in Sun's JDBC compliance testsuite version 1.3 ConnectionProperties.secondsBeforeRetryMaster=How long should the driver wait, when failed over, before attempting to reconnect to the primary host? Whichever condition is met first, 'queriesBeforeRetryMaster' or 'secondsBeforeRetryMaster' will cause an attempt to be made to reconnect to the master. Setting both properties to 0 disables the automatic fall back to the primary host at transaction boundaries. Time in seconds, defaults to 30 -ConnectionProperties.selfDestructOnPingSecondsLifetime=If set to a non-zero value, the driver will report close the connection and report failure when Connection.ping() or Connection.isValid(int) is called if the connection's lifetime exceeds this value. -ConnectionProperties.selfDestructOnPingMaxOperations==If set to a non-zero value, the driver will report close the connection and report failure when Connection.ping() or Connection.isValid(int) is called if the connection's count of commands sent to the server exceeds this value. +ConnectionProperties.selfDestructOnPingSecondsLifetime=If set to a non-zero value, the driver will close the connection and report failure when Connection.ping() or Connection.isValid(int) is called if the connection's lifetime exceeds this value (in milliseconds). +ConnectionProperties.selfDestructOnPingMaxOperations=If set to a non-zero value, the driver will report close the connection and report failure when Connection.ping() or Connection.isValid(int) is called if the connection's count of commands sent to the server exceeds this value. ConnectionProperties.serverTimezone=Override detection/mapping of time zone. Used when time zone from server doesn't map to Java time zone ConnectionProperties.sessionVariables=A comma or semicolon separated list of name=value pairs to be sent as SET [SESSION] ... to the server when the driver connects. ConnectionProperties.slowQueryThresholdMillis=If 'logSlowQueries' is enabled, how long should a query (in ms) before it is logged as 'slow'? ConnectionProperties.slowQueryThresholdNanos=If 'useNanosForElapsedTime' is set to true, and this property is set to a non-zero value, the driver will use this threshold (in nanosecond units) to determine if a query was slow. ConnectionProperties.socketFactory=The name of the class that the driver should use for creating socket connections to the server. This class must implement the interface 'com.mysql.jdbc.SocketFactory' and have public no-args constructor. -ConnectionProperties.socketTimeout=Timeout on network socket operations (0, the default means no timeout). +ConnectionProperties.socketTimeout=Timeout (in milliseconds) on network socket operations (0, the default means no timeout). ConnectionProperties.socksProxyHost=Name or IP address of SOCKS host to connect through. ConnectionProperties.socksProxyPort=Port of SOCKS server. ConnectionProperties.statementInterceptors=A comma-delimited list of classes that implement "com.mysql.jdbc.StatementInterceptor" that should be placed "in between" query execution to influence the results. StatementInterceptors are "chainable", the results returned by the "current" interceptor will be passed on to the next in in the chain, from left-to-right order, as specified in this property. @@ -664,6 +664,7 @@ ConnectionProperties.dontCheckOnDuplicateKeyUpdateInSQL=Stops checking if every INSERT statement contains the "ON DUPLICATE KEY UPDATE" clause. As a side effect, obtaining the statement's generated keys information will return a list where normally it wouldn't. Also be aware that, in this case, the list of generated keys returned may not be accurate. The effect of this property is canceled if set simultaneously with 'rewriteBatchedStatements=true'. ConnectionProperties.readOnlyPropagatesToServer=Should the driver issue appropriate statements to implicitly set the transaction access mode on server side when Connection.setReadOnly() is called? Setting this property to 'true' enables InnoDB read-only potential optimizations but also requires an extra roundtrip to set the right transaction state. Even if this property is set to 'false', the driver will do its best effort to prevent the execution of database-state-changing queries. Requires minimum of MySQL 5.6. ConnectionProperties.enabledSSLCipherSuites=If "useSSL" is set to "true", overrides the cipher suites enabled for use on the underlying SSL sockets. This may be required when using external JSSE providers or to specify cipher suites compatible with both MySQL server and used JVM. +ConnectionProperties.enabledTLSProtocols=If "useSSL" is set to "true", overrides the TLS protocols enabled for use on the underlying SSL sockets. This may be used to restrict connections to specific TLS versions. ConnectionProperties.enableEscapeProcessing=Sets the default escape processing behavior for Statement objects. The method Statement.setEscapeProcessing() can be used to specify the escape processing behavior for an individual Statement object. Default escape processing behavior in prepared statements must be defined with the property 'processEscapeCodesForPrepStmts'. # Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/MultiHostConnectionProxy.java =================================================================== diff -u -r5a8831deff620b6d7419f54d9e45d3a54c76af18 -rccfe08930c8c33a8f96900a64475229049441f6c --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/MultiHostConnectionProxy.java (.../MultiHostConnectionProxy.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/MultiHostConnectionProxy.java (.../MultiHostConnectionProxy.java) (revision ccfe08930c8c33a8f96900a64475229049441f6c) @@ -1,5 +1,5 @@ /* - Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -166,7 +166,6 @@ } this.localProps.remove(NonRegisteringDriver.NUM_HOSTS_PROPERTY_KEY); - this.localProps.setProperty("useLocalSessionState", "true"); return numHosts; } @@ -359,11 +358,17 @@ * @param target * The connection where to set state. */ - static void syncSessionState(Connection source, Connection target) throws SQLException { + void syncSessionState(Connection source, Connection target) throws SQLException { if (source == null || target == null) { return; } - syncSessionState(source, target, source.isReadOnly()); + + boolean prevUseLocalSessionState = source.getUseLocalSessionState(); + source.setUseLocalSessionState(true); + boolean readOnly = source.isReadOnly(); + source.setUseLocalSessionState(prevUseLocalSessionState); + + syncSessionState(source, target, readOnly); } /** @@ -376,18 +381,24 @@ * @param readOnly * The new read-only status. */ - static void syncSessionState(Connection source, Connection target, boolean readOnly) throws SQLException { + void syncSessionState(Connection source, Connection target, boolean readOnly) throws SQLException { if (target != null) { target.setReadOnly(readOnly); } if (source == null || target == null) { return; } + + boolean prevUseLocalSessionState = source.getUseLocalSessionState(); + source.setUseLocalSessionState(true); + target.setAutoCommit(source.getAutoCommit()); target.setCatalog(source.getCatalog()); target.setTransactionIsolation(source.getTransactionIsolation()); target.setSessionMaxRows(source.getSessionMaxRows()); + + source.setUseLocalSessionState(prevUseLocalSessionState); } /** Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/MultiHostMySQLConnection.java =================================================================== diff -u -r5a8831deff620b6d7419f54d9e45d3a54c76af18 -rccfe08930c8c33a8f96900a64475229049441f6c --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/MultiHostMySQLConnection.java (.../MultiHostMySQLConnection.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/MultiHostMySQLConnection.java (.../MultiHostMySQLConnection.java) (revision ccfe08930c8c33a8f96900a64475229049441f6c) @@ -2479,6 +2479,14 @@ getActiveMySQLConnection().setEnabledSSLCipherSuites(cipherSuites); } + public String getEnabledTLSProtocols() { + return getActiveMySQLConnection().getEnabledTLSProtocols(); + } + + public void setEnabledTLSProtocols(String protocols) { + getActiveMySQLConnection().setEnabledTLSProtocols(protocols); + } + public boolean getEnableEscapeProcessing() { return getActiveMySQLConnection().getEnableEscapeProcessing(); } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/MysqlIO.java =================================================================== diff -u -r5a8831deff620b6d7419f54d9e45d3a54c76af18 -rccfe08930c8c33a8f96900a64475229049441f6c --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/MysqlIO.java (.../MysqlIO.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/MysqlIO.java (.../MysqlIO.java) (revision ccfe08930c8c33a8f96900a64475229049441f6c) @@ -1,5 +1,5 @@ /* - Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -54,6 +54,7 @@ import java.util.Properties; import java.util.zip.Deflater; +import com.mysql.jdbc.authentication.CachingSha2PasswordPlugin; import com.mysql.jdbc.authentication.MysqlClearPasswordPlugin; import com.mysql.jdbc.authentication.MysqlNativePasswordPlugin; import com.mysql.jdbc.authentication.MysqlOldPasswordPlugin; @@ -480,7 +481,7 @@ } // We do this to break the chain between MysqlIO and Connection, so that we can have PhantomReferences on connections that let the driver clean up the - // socket connection without having to use finalize() somewhere (which although more straightforward, is horribly inefficent). + // socket connection without having to use finalize() somewhere (which although more straightforward, is horribly inefficient). protected NetworkResources getNetworkResources() { return new NetworkResources(this.mysqlConnection, this.mysqlInput, this.mysqlOutput); } @@ -824,7 +825,7 @@ changeUserPacket.writeByte((byte) MysqlDefs.COM_CHANGE_USER); if (versionMeetsMinimum(4, 1, 1)) { - secureAuth411(changeUserPacket, packLength, userName, password, database, false); + secureAuth411(changeUserPacket, packLength, userName, password, database, false, true); } else { secureAuth(changeUserPacket, packLength, userName, password, database, false); } @@ -846,9 +847,6 @@ if (localUseConnectWithDb) { packet.writeString(database); - } else { - //Not needed, old server does not require \0 - //packet.writeString(""); } send(packet, packet.getPosition()); @@ -1275,7 +1273,7 @@ this.clientParam |= CLIENT_SECURE_CONNECTION; if ((versionMeetsMinimum(4, 1, 1) || ((this.protocolVersion > 9) && (this.serverCapabilities & CLIENT_PROTOCOL_41) != 0))) { - secureAuth411(null, packLength, user, password, database, true); + secureAuth411(null, packLength, user, password, database, true, false); } else { secureAuth(null, packLength, user, password, database, true); } @@ -1322,9 +1320,9 @@ if ((this.serverCapabilities & CLIENT_SECURE_CONNECTION) != 0) { if (versionMeetsMinimum(4, 1, 1)) { - secureAuth411(null, packLength, user, password, database, true); + secureAuth411(null, packLength, user, password, database, true, false); } else { - secureAuth411(null, packLength, user, password, database, true); + secureAuth411(null, packLength, user, password, database, true, false); } } else { @@ -1468,6 +1466,12 @@ defaultIsFound = true; } + plugin = new CachingSha2PasswordPlugin(); + plugin.init(this.connection, this.connection.getProperties()); + if (addAuthenticationPlugin(plugin)) { + defaultIsFound = true; + } + // plugins from authenticationPluginClasses connection parameter String authenticationPluginClasses = this.connection.getAuthenticationPlugins(); if (authenticationPluginClasses != null && !"".equals(authenticationPluginClasses)) { @@ -1746,6 +1750,8 @@ throw SQLError.createSQLException(Messages.getString("Connection.BadAuthenticationPlugin", new Object[] { pluginName }), getExceptionInterceptor()); } + } else { + plugin.reset(); } checkConfidentiality(plugin); @@ -1856,9 +1862,6 @@ if (this.useConnectWithDb) { last_sent.writeString(database, enc, this.connection); - } else { - /* For empty database */ - last_sent.writeByte((byte) 0); } if ((this.serverCapabilities & CLIENT_PLUGIN_AUTH) != 0) { @@ -4185,7 +4188,9 @@ void scanForAndThrowDataTruncation() throws SQLException { if ((this.streamingData == null) && versionMeetsMinimum(4, 1, 0) && this.connection.getJdbcCompliantTruncation() && this.warningCount > 0) { + int warningCountOld = this.warningCount; SQLError.convertShowWarningsToSQLWarnings(this.connection, this.warningCount, true); + this.warningCount = warningCountOld; } } @@ -4332,10 +4337,12 @@ * @param password * @param database * @param writeClientParams + * @param forChangeUser * * @throws SQLException */ - void secureAuth411(Buffer packet, int packLength, String user, String password, String database, boolean writeClientParams) throws SQLException { + void secureAuth411(Buffer packet, int packLength, String user, String password, String database, boolean writeClientParams, boolean forChangeUser) + throws SQLException { String enc = getEncodingForHandshake(); // SERVER: public_seed=create_random_string() // send(public_seed) @@ -4403,7 +4410,7 @@ if (this.useConnectWithDb) { packet.writeString(database, enc, this.connection); - } else { + } else if (forChangeUser) { /* For empty database */ packet.writeByte((byte) 0); } @@ -4433,6 +4440,10 @@ /* Read what server thinks about out new auth message report */ checkErrorPacket(); } + + if (!this.useConnectWithDb) { + changeDatabaseTo(database); + } } /** Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/PerConnectionLRUFactory.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -rccfe08930c8c33a8f96900a64475229049441f6c --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/PerConnectionLRUFactory.java (.../PerConnectionLRUFactory.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/PerConnectionLRUFactory.java (.../PerConnectionLRUFactory.java) (revision ccfe08930c8c33a8f96900a64475229049441f6c) @@ -1,5 +1,5 @@ /* - Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -40,13 +40,13 @@ class PerConnectionLRU implements CacheAdapter { private final int cacheSqlLimit; - private final LRUCache cache; + private final LRUCache cache; private final Connection conn; protected PerConnectionLRU(Connection forConnection, int cacheMaxSize, int maxKeySize) { final int cacheSize = cacheMaxSize; this.cacheSqlLimit = maxKeySize; - this.cache = new LRUCache(cacheSize); + this.cache = new LRUCache(cacheSize); this.conn = forConnection; } @@ -56,7 +56,7 @@ } synchronized (this.conn.getConnectionMutex()) { - return (ParseInfo) this.cache.get(key); + return this.cache.get(key); } } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/ReplicationConnectionProxy.java =================================================================== diff -u -r5a8831deff620b6d7419f54d9e45d3a54c76af18 -rccfe08930c8c33a8f96900a64475229049441f6c --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/ReplicationConnectionProxy.java (.../ReplicationConnectionProxy.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/ReplicationConnectionProxy.java (.../ReplicationConnectionProxy.java) (revision ccfe08930c8c33a8f96900a64475229049441f6c) @@ -1,5 +1,5 @@ /* - Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -264,6 +264,20 @@ } @Override + void syncSessionState(Connection source, Connection target, boolean readOnly) throws SQLException { + try { + super.syncSessionState(source, target, readOnly); + } catch (SQLException e1) { + try { + // Try again. It may happen that the connection had recovered in the meantime but the right syncing wasn't done yet. + super.syncSessionState(source, target, readOnly); + } catch (SQLException e2) { + } + // Swallow both exceptions. Replication connections must continue to "work" after swapping between masters and slaves. + } + } + + @Override void doClose() throws SQLException { if (this.masterConnection != null) { this.masterConnection.close(); Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/ResultSetImpl.java =================================================================== diff -u -r5a8831deff620b6d7419f54d9e45d3a54c76af18 -rccfe08930c8c33a8f96900a64475229049441f6c --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/ResultSetImpl.java (.../ResultSetImpl.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/ResultSetImpl.java (.../ResultSetImpl.java) (revision ccfe08930c8c33a8f96900a64475229049441f6c) @@ -875,7 +875,10 @@ // public ResultSetInternalMethods copy() throws SQLException { synchronized (checkClosed().getConnectionMutex()) { - ResultSetInternalMethods rs = ResultSetImpl.getInstance(this.catalog, this.fields, this.rowData, this.connection, this.owningStatement, false); // note, doesn't work for updatable result sets + ResultSetImpl rs = ResultSetImpl.getInstance(this.catalog, this.fields, this.rowData, this.connection, this.owningStatement, false); // note, doesn't work for updatable result sets + if (this.isBinaryEncoded) { + rs.setBinaryEncoded(); + } return rs; } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/SQLError.java =================================================================== diff -u -r5a8831deff620b6d7419f54d9e45d3a54c76af18 -rccfe08930c8c33a8f96900a64475229049441f6c --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/SQLError.java (.../SQLError.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/SQLError.java (.../SQLError.java) (revision ccfe08930c8c33a8f96900a64475229049441f6c) @@ -684,6 +684,7 @@ try { if (warningCountIfKnown < 100) { stmt = connection.createStatement(); + stmt.setFetchSize(0); // turns off cursor based fetch, in case the connection was set up to use them. if (stmt.getMaxRows() != 0) { stmt.setMaxRows(0); Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/Security.java =================================================================== diff -u -r5a8831deff620b6d7419f54d9e45d3a54c76af18 -rccfe08930c8c33a8f96900a64475229049441f6c --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/Security.java (.../Security.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/Security.java (.../Security.java) (revision ccfe08930c8c33a8f96900a64475229049441f6c) @@ -1,5 +1,5 @@ /* - Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -24,6 +24,7 @@ package com.mysql.jdbc; import java.io.UnsupportedEncodingException; +import java.security.DigestException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; @@ -35,6 +36,8 @@ private static final int SHA1_HASH_SIZE = 20; + private static int CACHING_SHA2_DIGEST_LENGTH = 32; + /** * Returns hex value for given char */ @@ -44,7 +47,7 @@ /* * Convert password in salted form to binary string password and hash-salt - * For old password this involes one more hashing + * For old password this involves one more hashing * * SYNOPSIS get_hash_and_password() salt IN Salt to convert from pversion IN * Password version to use hash OUT Store zero ended hash here bin_password @@ -208,7 +211,7 @@ /** * Encrypt/Decrypt function used for password encryption in authentication * - * Simple XOR is used here but it is OK as we crypt random strings + * Simple XOR is used here but it is OK as we encrypt random strings * * @param from * IN Data for encryption @@ -326,6 +329,57 @@ } /** + * Scrambling for caching_sha2_password plugin. + * + *
+     * Scramble = XOR(SHA2(password), SHA2(SHA2(SHA2(password)), Nonce))
+     * 
+ * + * @throws DigestException + */ + public static byte[] scrambleCachingSha2(byte[] password, byte[] seed) throws DigestException { + /* + * Server does it in 4 steps (see sql/auth/sha2_password_common.cc Generate_scramble::scramble method): + * + * SHA2(src) => digest_stage1 + * SHA2(digest_stage1) => digest_stage2 + * SHA2(digest_stage2, m_rnd) => scramble_stage1 + * XOR(digest_stage1, scramble_stage1) => scramble + */ + MessageDigest md; + try { + md = MessageDigest.getInstance("SHA-256"); + } catch (NoSuchAlgorithmException ex) { + throw new AssertionFailedException(ex); + } + + byte[] dig1 = new byte[CACHING_SHA2_DIGEST_LENGTH]; + byte[] dig2 = new byte[CACHING_SHA2_DIGEST_LENGTH]; + byte[] scramble1 = new byte[CACHING_SHA2_DIGEST_LENGTH]; + + // SHA2(src) => digest_stage1 + md.update(password, 0, password.length); + md.digest(dig1, 0, CACHING_SHA2_DIGEST_LENGTH); + md.reset(); + + // SHA2(digest_stage1) => digest_stage2 + md.update(dig1, 0, dig1.length); + md.digest(dig2, 0, CACHING_SHA2_DIGEST_LENGTH); + md.reset(); + + // SHA2(digest_stage2, m_rnd) => scramble_stage1 + md.update(dig2, 0, dig1.length); + md.update(seed, 0, seed.length); + md.digest(scramble1, 0, CACHING_SHA2_DIGEST_LENGTH); + + // XOR(digest_stage1, scramble_stage1) => scramble + byte[] mysqlScrambleBuff = new byte[CACHING_SHA2_DIGEST_LENGTH]; + xorString(dig1, mysqlScrambleBuff, scramble1, CACHING_SHA2_DIGEST_LENGTH); + + return mysqlScrambleBuff; + } + + /** * Prevent construction. */ private Security() { Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/ServerPreparedStatement.java =================================================================== diff -u -r5a8831deff620b6d7419f54d9e45d3a54c76af18 -rccfe08930c8c33a8f96900a64475229049441f6c --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/ServerPreparedStatement.java (.../ServerPreparedStatement.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/ServerPreparedStatement.java (.../ServerPreparedStatement.java) (revision ccfe08930c8c33a8f96900a64475229049441f6c) @@ -571,6 +571,7 @@ return; } + this.isClosed = false; realClose(true, true); } } @@ -1014,6 +1015,7 @@ if (this.isCached) { this.connection.decachePreparedStatement(this); + this.isCached = false; } super.realClose(calledExplicitly, closeOpenResults); Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/authentication/CachingSha2PasswordPlugin.java =================================================================== diff -u --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/authentication/CachingSha2PasswordPlugin.java (revision 0) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/authentication/CachingSha2PasswordPlugin.java (revision ccfe08930c8c33a8f96900a64475229049441f6c) @@ -0,0 +1,167 @@ +/* + Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + + The MySQL Connector/J is licensed under the terms of the GPLv2 + , like most MySQL Connectors. + There are special exceptions to the terms and conditions of the GPLv2 as it is applied to + this software, see the FOSS License Exception + . + + This program is free software; you can redistribute it and/or modify it under the terms + of the GNU General Public License as published by the Free Software Foundation; version 2 + of the License. + + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; + without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with this + program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth + Floor, Boston, MA 02110-1301 USA + + */ + +package com.mysql.jdbc.authentication; + +import java.io.UnsupportedEncodingException; +import java.security.DigestException; +import java.sql.SQLException; +import java.util.List; +import java.util.Properties; + +import com.mysql.jdbc.Buffer; +import com.mysql.jdbc.Connection; +import com.mysql.jdbc.Messages; +import com.mysql.jdbc.MySQLConnection; +import com.mysql.jdbc.MysqlIO; +import com.mysql.jdbc.SQLError; +import com.mysql.jdbc.Security; +import com.mysql.jdbc.StringUtils; + +public class CachingSha2PasswordPlugin extends Sha256PasswordPlugin { + public static String PLUGIN_NAME = "caching_sha2_password"; + + public enum AuthStage { + FAST_AUTH_SEND_SCRAMBLE, FAST_AUTH_READ_RESULT, FAST_AUTH_COMPLETE, FULL_AUTH; + } + + private AuthStage stage = AuthStage.FAST_AUTH_SEND_SCRAMBLE; + + @Override + public void init(Connection conn, Properties props) throws SQLException { + super.init(conn, props); + this.stage = AuthStage.FAST_AUTH_SEND_SCRAMBLE; + } + + @Override + public void destroy() { + this.stage = AuthStage.FAST_AUTH_SEND_SCRAMBLE; + super.destroy(); + } + + @Override + public String getProtocolPluginName() { + return PLUGIN_NAME; + } + + @Override + public boolean nextAuthenticationStep(Buffer fromServer, List toServer) throws SQLException { + toServer.clear(); + + if (this.password == null || this.password.length() == 0 || fromServer == null) { + // no password + Buffer bresp = new Buffer(new byte[] { 0 }); + toServer.add(bresp); + + } else { + if (this.stage == AuthStage.FAST_AUTH_SEND_SCRAMBLE) { + // send a scramble for fast auth + this.seed = fromServer.readString(); + try { + toServer.add(new Buffer(Security.scrambleCachingSha2(StringUtils.getBytes(this.password, this.connection.getPasswordCharacterEncoding()), + this.seed.getBytes()))); + } catch (DigestException e) { + throw SQLError.createSQLException(e.getMessage(), SQLError.SQL_STATE_GENERAL_ERROR, e, null); + } catch (UnsupportedEncodingException e) { + throw SQLError.createSQLException(e.getMessage(), SQLError.SQL_STATE_GENERAL_ERROR, e, null); + } + this.stage = AuthStage.FAST_AUTH_READ_RESULT; + return true; + + } else if (this.stage == AuthStage.FAST_AUTH_READ_RESULT) { + int fastAuthResult = fromServer.getByteBuffer()[0]; + switch (fastAuthResult) { + case 3: + this.stage = AuthStage.FAST_AUTH_COMPLETE; + return true; + case 4: + this.stage = AuthStage.FULL_AUTH; + break; + default: + throw SQLError.createSQLException("Unknown server response after fast auth.", SQLError.SQL_STATE_UNABLE_TO_CONNECT_TO_DATASOURCE, + this.connection.getExceptionInterceptor()); + } + } + + if (((MySQLConnection) this.connection).getIO().isSSLEstablished()) { + // allow plain text over SSL + Buffer bresp; + try { + bresp = new Buffer(StringUtils.getBytes(this.password, this.connection.getPasswordCharacterEncoding())); + } catch (UnsupportedEncodingException e) { + throw SQLError.createSQLException( + Messages.getString("Sha256PasswordPlugin.3", new Object[] { this.connection.getPasswordCharacterEncoding() }), + SQLError.SQL_STATE_GENERAL_ERROR, null); + } + bresp.setPosition(bresp.getBufLength()); + int oldBufLength = bresp.getBufLength(); + bresp.writeByte((byte) 0); + bresp.setBufLength(oldBufLength + 1); + bresp.setPosition(0); + toServer.add(bresp); + + } else if (this.connection.getServerRSAPublicKeyFile() != null) { + // encrypt with given key, don't use "Public Key Retrieval" + Buffer bresp = new Buffer(encryptPassword()); + toServer.add(bresp); + + } else { + if (!this.connection.getAllowPublicKeyRetrieval()) { + throw SQLError.createSQLException(Messages.getString("Sha256PasswordPlugin.2"), SQLError.SQL_STATE_UNABLE_TO_CONNECT_TO_DATASOURCE, + this.connection.getExceptionInterceptor()); + } + + // We must request the public key from the server to encrypt the password + if (this.publicKeyRequested && fromServer.getBufLength() > MysqlIO.SEED_LENGTH) { + // Servers affected by Bug#70865 could send Auth Switch instead of key after Public Key Retrieval, + // so we check payload length to detect that. + + // read key response + this.publicKeyString = fromServer.readString(); + Buffer bresp = new Buffer(encryptPassword()); + toServer.add(bresp); + this.publicKeyRequested = false; + } else { + // build and send Public Key Retrieval packet + Buffer bresp = new Buffer(new byte[] { 2 }); //was 1 in sha256_password + toServer.add(bresp); + this.publicKeyRequested = true; + } + } + } + return true; + } + + @Override + protected byte[] encryptPassword() throws SQLException { + if (this.connection.versionMeetsMinimum(8, 0, 5)) { + return super.encryptPassword(); + } + return super.encryptPassword("RSA/ECB/PKCS1Padding"); + } + + @Override + public void reset() { + this.stage = AuthStage.FAST_AUTH_SEND_SCRAMBLE; + } +} Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/authentication/MysqlClearPasswordPlugin.java =================================================================== diff -u -r5a8831deff620b6d7419f54d9e45d3a54c76af18 -rccfe08930c8c33a8f96900a64475229049441f6c --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/authentication/MysqlClearPasswordPlugin.java (.../MysqlClearPasswordPlugin.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/authentication/MysqlClearPasswordPlugin.java (.../MysqlClearPasswordPlugin.java) (revision ccfe08930c8c33a8f96900a64475229049441f6c) @@ -1,5 +1,5 @@ /* - Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -90,4 +90,7 @@ toServer.add(bresp); return true; } + + public void reset() { + } } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/authentication/MysqlNativePasswordPlugin.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -rccfe08930c8c33a8f96900a64475229049441f6c --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/authentication/MysqlNativePasswordPlugin.java (.../MysqlNativePasswordPlugin.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/authentication/MysqlNativePasswordPlugin.java (.../MysqlNativePasswordPlugin.java) (revision ccfe08930c8c33a8f96900a64475229049441f6c) @@ -1,5 +1,5 @@ /* - Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -95,4 +95,6 @@ return true; } + public void reset() { + } } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/authentication/MysqlOldPasswordPlugin.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -rccfe08930c8c33a8f96900a64475229049441f6c --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/authentication/MysqlOldPasswordPlugin.java (.../MysqlOldPasswordPlugin.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/authentication/MysqlOldPasswordPlugin.java (.../MysqlOldPasswordPlugin.java) (revision ccfe08930c8c33a8f96900a64475229049441f6c) @@ -1,5 +1,5 @@ /* - Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -91,4 +91,6 @@ return true; } + public void reset() { + } } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/authentication/Sha256PasswordPlugin.java =================================================================== diff -u -r5a8831deff620b6d7419f54d9e45d3a54c76af18 -rccfe08930c8c33a8f96900a64475229049441f6c --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/authentication/Sha256PasswordPlugin.java (.../Sha256PasswordPlugin.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/authentication/Sha256PasswordPlugin.java (.../Sha256PasswordPlugin.java) (revision ccfe08930c8c33a8f96900a64475229049441f6c) @@ -1,5 +1,5 @@ /* - Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -49,11 +49,11 @@ public class Sha256PasswordPlugin implements AuthenticationPlugin { public static String PLUGIN_NAME = "sha256_password"; - private Connection connection; - private String password = null; - private String seed = null; - private boolean publicKeyRequested = false; - private String publicKeyString = null; + protected Connection connection; + protected String password = null; + protected String seed = null; + protected boolean publicKeyRequested = false; + protected String publicKeyString = null; public void init(Connection conn, Properties props) throws SQLException { this.connection = conn; @@ -113,7 +113,7 @@ } else if (this.connection.getServerRSAPublicKeyFile() != null) { // encrypt with given key, don't use "Public Key Retrieval" this.seed = fromServer.readString(); - Buffer bresp = new Buffer(encryptPassword(this.password, this.seed, this.connection, this.publicKeyString)); + Buffer bresp = new Buffer(encryptPassword()); toServer.add(bresp); } else { @@ -128,7 +128,8 @@ // so we check payload length to detect that. // read key response - Buffer bresp = new Buffer(encryptPassword(this.password, this.seed, this.connection, fromServer.readString())); + this.publicKeyString = fromServer.readString(); + Buffer bresp = new Buffer(encryptPassword()); toServer.add(bresp); this.publicKeyRequested = false; } else { @@ -142,19 +143,24 @@ return true; } - private static byte[] encryptPassword(String password, String seed, Connection connection, String key) throws SQLException { + protected byte[] encryptPassword() throws SQLException { + return encryptPassword("RSA/ECB/OAEPWithSHA-1AndMGF1Padding"); + } + + protected byte[] encryptPassword(String transformation) throws SQLException { byte[] input = null; try { - input = password != null ? StringUtils.getBytesNullTerminated(password, connection.getPasswordCharacterEncoding()) : new byte[] { 0 }; + input = this.password != null ? StringUtils.getBytesNullTerminated(this.password, this.connection.getPasswordCharacterEncoding()) + : new byte[] { 0 }; } catch (UnsupportedEncodingException e) { - throw SQLError.createSQLException(Messages.getString("Sha256PasswordPlugin.3", new Object[] { connection.getPasswordCharacterEncoding() }), + throw SQLError.createSQLException(Messages.getString("Sha256PasswordPlugin.3", new Object[] { this.connection.getPasswordCharacterEncoding() }), SQLError.SQL_STATE_GENERAL_ERROR, null); } byte[] mysqlScrambleBuff = new byte[input.length]; - Security.xorString(input, mysqlScrambleBuff, seed.getBytes(), input.length); + Security.xorString(input, mysqlScrambleBuff, this.seed.getBytes(), input.length); return ExportControlled.encryptWithRSAPublicKey(mysqlScrambleBuff, - ExportControlled.decodeRSAPublicKey(key, ((MySQLConnection) connection).getExceptionInterceptor()), - ((MySQLConnection) connection).getExceptionInterceptor()); + ExportControlled.decodeRSAPublicKey(this.publicKeyString, this.connection.getExceptionInterceptor()), transformation, + this.connection.getExceptionInterceptor()); } private static String readRSAKey(Connection connection, String pkPath) throws SQLException { @@ -201,4 +207,6 @@ return res; } + public void reset() { + } } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/ConnectionWrapper.java =================================================================== diff -u -r5a8831deff620b6d7419f54d9e45d3a54c76af18 -rccfe08930c8c33a8f96900a64475229049441f6c --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/ConnectionWrapper.java (.../ConnectionWrapper.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/ConnectionWrapper.java (.../ConnectionWrapper.java) (revision ccfe08930c8c33a8f96900a64475229049441f6c) @@ -2882,6 +2882,14 @@ this.mc.setEnabledSSLCipherSuites(cipherSuites); } + public String getEnabledTLSProtocols() { + return this.mc.getEnabledTLSProtocols(); + } + + public void setEnabledTLSProtocols(String protocols) { + this.mc.setEnabledTLSProtocols(protocols); + } + public boolean getEnableEscapeProcessing() { return this.mc.getEnableEscapeProcessing(); } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/MysqlDataSource.java =================================================================== diff -u -r5a8831deff620b6d7419f54d9e45d3a54c76af18 -rccfe08930c8c33a8f96900a64475229049441f6c --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/MysqlDataSource.java (.../MysqlDataSource.java) (revision 5a8831deff620b6d7419f54d9e45d3a54c76af18) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/jdbc2/optional/MysqlDataSource.java (.../MysqlDataSource.java) (revision ccfe08930c8c33a8f96900a64475229049441f6c) @@ -1,5 +1,5 @@ /* - Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -435,4 +435,9 @@ // public T unwrap(Class iface) throws SQLException { // throw SQLError.createSQLFeatureNotSupportedException(); // } + + @Override + public Properties exposeAsProperties(Properties props) throws SQLException { + return exposeAsProperties(props, true); + } } Index: 3rdParty_sources/mysql-connector/com/mysql/jdbc/util/LRUCache.java =================================================================== diff -u -r345648e21e2c2b088c907ed812175477dd9b78f2 -rccfe08930c8c33a8f96900a64475229049441f6c --- 3rdParty_sources/mysql-connector/com/mysql/jdbc/util/LRUCache.java (.../LRUCache.java) (revision 345648e21e2c2b088c907ed812175477dd9b78f2) +++ 3rdParty_sources/mysql-connector/com/mysql/jdbc/util/LRUCache.java (.../LRUCache.java) (revision ccfe08930c8c33a8f96900a64475229049441f6c) @@ -1,5 +1,5 @@ /* - Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved. The MySQL Connector/J is licensed under the terms of the GPLv2 , like most MySQL Connectors. @@ -26,7 +26,7 @@ import java.util.LinkedHashMap; import java.util.Map.Entry; -public class LRUCache extends LinkedHashMap { +public class LRUCache extends LinkedHashMap { private static final long serialVersionUID = 1L; protected int maxElements; @@ -41,7 +41,7 @@ * @see java.util.LinkedHashMap#removeEldestEntry(java.util.Map.Entry) */ @Override - protected boolean removeEldestEntry(Entry eldest) { + protected boolean removeEldestEntry(Entry eldest) { return (size() > this.maxElements); } } Index: 3rdParty_sources/versions.txt =================================================================== diff -u -rd56c495a6cbaa84d3ddc29ee952cf933015e1855 -rccfe08930c8c33a8f96900a64475229049441f6c --- 3rdParty_sources/versions.txt (.../versions.txt) (revision d56c495a6cbaa84d3ddc29ee952cf933015e1855) +++ 3rdParty_sources/versions.txt (.../versions.txt) (revision ccfe08930c8c33a8f96900a64475229049441f6c) @@ -35,7 +35,7 @@ JSP API 2.3 -MySQL Connector/J 5.1.43 +MySQL Connector/J 5.1.46 oauth 20100527 Index: lams_build/lib/mysql/mysql-connector-java.module.xml =================================================================== diff -u -r0ab9309cccfdcf25489a69466dd3ef9243e9aad1 -rccfe08930c8c33a8f96900a64475229049441f6c --- lams_build/lib/mysql/mysql-connector-java.module.xml (.../mysql-connector-java.module.xml) (revision 0ab9309cccfdcf25489a69466dd3ef9243e9aad1) +++ lams_build/lib/mysql/mysql-connector-java.module.xml (.../mysql-connector-java.module.xml) (revision ccfe08930c8c33a8f96900a64475229049441f6c) @@ -24,7 +24,7 @@ - +