Skip to content

Commit

Permalink
Fix for Bug#77924 (25710160), JDBC SOCKS SHOULD NOT PERFORM LOCAL DNS
Browse files Browse the repository at this point in the history
RESOLUTION.
  • Loading branch information
soklakov committed Feb 24, 2022
1 parent 830b551 commit 0e0f658
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 9 deletions.
2 changes: 2 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

Version 8.0.29

- Fix for Bug#77924 (25710160), JDBC SOCKS SHOULD NOT PERFORM LOCAL DNS RESOLUTION.

- Fix for Bug#82084 (23743938), YEAR DATA TYPE RETURNS INCORRECT VALUE FOR JDBC GETCOLUMNTYPE().

- Fix for Bug#106441 (33850155), Add charset mapping for utf8mb3.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,9 @@ public enum DatabaseTerm {
new IntegerPropertyDefinition(PropertyKey.socksProxyPort, 1080, RUNTIME_MODIFIABLE, Messages.getString("ConnectionProperties.socksProxyPort"),
"5.1.34", CATEGORY_NETWORK, 2, 0, 65535),

new BooleanPropertyDefinition(PropertyKey.socksProxyRemoteDns, DEFAULT_VALUE_FALSE, RUNTIME_MODIFIABLE,
Messages.getString("ConnectionProperties.socksProxyRemoteDns"), "8.0.29", CATEGORY_NETWORK, Integer.MIN_VALUE),

new IntegerPropertyDefinition(PropertyKey.socketTimeout, 0, RUNTIME_MODIFIABLE, Messages.getString("ConnectionProperties.socketTimeout"),
"3.0.1", CATEGORY_NETWORK, 10, 0, Integer.MAX_VALUE),

Expand Down
1 change: 1 addition & 0 deletions src/main/core-api/java/com/mysql/cj/conf/PropertyKey.java
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ public enum PropertyKey {
socketTimeout("socketTimeout", true), //
socksProxyHost("socksProxyHost", true), //
socksProxyPort("socksProxyPort", true), //
socksProxyRemoteDns("socksProxyRemoteDns", true), //
sslMode("sslMode", true), //
strictUpdates("strictUpdates", true), //
tcpKeepAlive("tcpKeepAlive", true), //
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, 2020, Oracle and/or its affiliates.
* Copyright (c) 2014, 2022, Oracle and/or its affiliates.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, version 2.0, as published by the
Expand Down Expand Up @@ -29,9 +29,13 @@

package com.mysql.cj.protocol;

import java.io.Closeable;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.Socket;
import java.net.SocketException;

import com.mysql.cj.conf.PropertyKey;
import com.mysql.cj.conf.PropertySet;
Expand All @@ -47,4 +51,52 @@ protected Socket createSocket(PropertySet props) {
int socksProxyPort = props.getIntegerProperty(PropertyKey.socksProxyPort).getValue();
return new Socket(new Proxy(Proxy.Type.SOCKS, new InetSocketAddress(socksProxyHost, socksProxyPort)));
}

@Override
@SuppressWarnings("unchecked")
public <T extends Closeable> T connect(String hostname, int portNumber, PropertySet pset, int loginTimeout) throws IOException {
if (!pset.getBooleanProperty(PropertyKey.socksProxyRemoteDns).getValue()) {
// fall back to the parent connection procedure
return super.connect(hostname, portNumber, pset, loginTimeout);
}

// proceed without local DNS resolution
this.loginTimeoutCountdown = loginTimeout;

if (pset != null && hostname != null) {
this.host = hostname;
this.port = portNumber;

String localSocketHostname = pset.getStringProperty(PropertyKey.localSocketAddress).getValue();
InetSocketAddress localSockAddr = localSocketHostname != null && localSocketHostname.length() > 0
? new InetSocketAddress(InetAddress.getByName(localSocketHostname), 0)
: null;
int connectTimeout = pset.getIntegerProperty(PropertyKey.connectTimeout).getValue();

// save last exception to propagate to caller if connection fails
try {
this.rawSocket = createSocket(pset);
configureSocket(this.rawSocket, pset);

// bind to the local port if not using the ephemeral port
if (localSockAddr != null) {
this.rawSocket.bind(localSockAddr);
}

this.rawSocket.connect(InetSocketAddress.createUnresolved(this.host, this.port), getRealTimeout(connectTimeout));

} catch (SocketException ex) {
this.rawSocket = null;
throw ex;
}

resetLoginTimeCountdown();

this.sslSocket = this.rawSocket;
return (T) this.rawSocket;
}

throw new SocketException("Unable to create socket");
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2002, 2021, Oracle and/or its affiliates.
* Copyright (c) 2002, 2022, Oracle and/or its affiliates.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, version 2.0, as published by the
Expand Down Expand Up @@ -91,7 +91,7 @@ protected Socket createSocket(PropertySet props) {
* @throws IOException
* if an error occurs
*/
private void configureSocket(Socket sock, PropertySet pset) throws SocketException, IOException {
protected void configureSocket(Socket sock, PropertySet pset) throws SocketException, IOException {
sock.setTcpNoDelay(pset.getBooleanProperty(PropertyKey.tcpNoDelay).getValue());
sock.setKeepAlive(pset.getBooleanProperty(PropertyKey.tcpKeepAlive).getValue());

Expand All @@ -118,15 +118,12 @@ public <T extends Closeable> T connect(String hostname, int portNumber, Property

if (pset != null) {
this.host = hostname;

this.port = portNumber;

String localSocketHostname = pset.getStringProperty(PropertyKey.localSocketAddress).getValue();
InetSocketAddress localSockAddr = null;
if (localSocketHostname != null && localSocketHostname.length() > 0) {
localSockAddr = new InetSocketAddress(InetAddress.getByName(localSocketHostname), 0);
}

InetSocketAddress localSockAddr = localSocketHostname != null && localSocketHostname.length() > 0
? new InetSocketAddress(InetAddress.getByName(localSocketHostname), 0)
: null;
int connectTimeout = pset.getIntegerProperty(PropertyKey.connectTimeout).getValue();

if (this.host != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -955,6 +955,7 @@ ConnectionProperties.socketFactory=The name of the class that the driver should
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.socksProxyRemoteDns=When using a SOCKS proxy, whether the DNS lookup for the database host should be performed locally or through the SOCKS proxy.
ConnectionProperties.sslMode=By default, network connections are SSL encrypted; this property permits secure connections to be turned off, or a different levels of security to be chosen. The following values are allowed: "DISABLED" - Establish unencrypted connections; "PREFERRED" - (default) Establish encrypted connections if the server enabled them, otherwise fall back to unencrypted connections; "REQUIRED" - Establish secure connections if the server enabled them, fail otherwise; "VERIFY_CA" - Like "REQUIRED" but additionally verify the server TLS certificate against the configured Certificate Authority (CA) certificates; "VERIFY_IDENTITY" - Like "VERIFY_CA", but additionally verify that the server certificate matches the host to which the connection is attempted.[CR] This property replaced the deprecated legacy properties "useSSL", "requireSSL", and "verifyServerCertificate", which are still accepted but translated into a value for "sslMode" if "sslMode" is not explicitly set: "useSSL=false" is translated to "sslMode=DISABLED"; '{'"useSSL=true", "requireSSL=false", "verifyServerCertificate=false"'}' is translated to "sslMode=PREFERRED"; '{'"useSSL=true", "requireSSL=true", "verifyServerCertificate=false"'}' is translated to "sslMode=REQUIRED"; '{'"useSSL=true" AND "verifyServerCertificate=true"'}' is translated to "sslMode=VERIFY_CA". There is no equivalent legacy settings for "sslMode=VERIFY_IDENTITY". Note that, for ALL server versions, the default setting of "sslMode" is "PREFERRED", and it is equivalent to the legacy settings of "useSSL=true", "requireSSL=false", and "verifyServerCertificate=false", which are different from their default settings for Connector/J 8.0.12 and earlier in some situations. Applications that continue to use the legacy properties and rely on their old default settings should be reviewed.[CR] The legacy properties are ignored if "sslMode" is set explicitly. If none of "sslMode" or "useSSL" is set explicitly, the default setting of "sslMode=PREFERRED" applies.
ConnectionProperties.strictUpdates=Should the driver do strict checking (all primary keys selected) of updatable result sets (true, false, defaults to ''true'')?
ConnectionProperties.tcpKeepAlive=If connecting using TCP/IP, should the driver set SO_KEEPALIVE?
Expand Down

0 comments on commit 0e0f658

Please sign in to comment.