Skip to content

Commit 0e0f658

Browse files
committed
Fix for Bug#77924 (25710160), JDBC SOCKS SHOULD NOT PERFORM LOCAL DNS
RESOLUTION.
1 parent 830b551 commit 0e0f658

File tree

6 files changed

+65
-9
lines changed

6 files changed

+65
-9
lines changed

CHANGES

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
Version 8.0.29
55

6+
- Fix for Bug#77924 (25710160), JDBC SOCKS SHOULD NOT PERFORM LOCAL DNS RESOLUTION.
7+
68
- Fix for Bug#82084 (23743938), YEAR DATA TYPE RETURNS INCORRECT VALUE FOR JDBC GETCOLUMNTYPE().
79

810
- Fix for Bug#106441 (33850155), Add charset mapping for utf8mb3.

src/main/core-api/java/com/mysql/cj/conf/PropertyDefinitions.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,9 @@ public enum DatabaseTerm {
298298
new IntegerPropertyDefinition(PropertyKey.socksProxyPort, 1080, RUNTIME_MODIFIABLE, Messages.getString("ConnectionProperties.socksProxyPort"),
299299
"5.1.34", CATEGORY_NETWORK, 2, 0, 65535),
300300

301+
new BooleanPropertyDefinition(PropertyKey.socksProxyRemoteDns, DEFAULT_VALUE_FALSE, RUNTIME_MODIFIABLE,
302+
Messages.getString("ConnectionProperties.socksProxyRemoteDns"), "8.0.29", CATEGORY_NETWORK, Integer.MIN_VALUE),
303+
301304
new IntegerPropertyDefinition(PropertyKey.socketTimeout, 0, RUNTIME_MODIFIABLE, Messages.getString("ConnectionProperties.socketTimeout"),
302305
"3.0.1", CATEGORY_NETWORK, 10, 0, Integer.MAX_VALUE),
303306

src/main/core-api/java/com/mysql/cj/conf/PropertyKey.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,7 @@ public enum PropertyKey {
216216
socketTimeout("socketTimeout", true), //
217217
socksProxyHost("socksProxyHost", true), //
218218
socksProxyPort("socksProxyPort", true), //
219+
socksProxyRemoteDns("socksProxyRemoteDns", true), //
219220
sslMode("sslMode", true), //
220221
strictUpdates("strictUpdates", true), //
221222
tcpKeepAlive("tcpKeepAlive", true), //

src/main/core-impl/java/com/mysql/cj/protocol/SocksProxySocketFactory.java

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2014, 2020, Oracle and/or its affiliates.
2+
* Copyright (c) 2014, 2022, Oracle and/or its affiliates.
33
*
44
* This program is free software; you can redistribute it and/or modify it under
55
* the terms of the GNU General Public License, version 2.0, as published by the
@@ -29,9 +29,13 @@
2929

3030
package com.mysql.cj.protocol;
3131

32+
import java.io.Closeable;
33+
import java.io.IOException;
34+
import java.net.InetAddress;
3235
import java.net.InetSocketAddress;
3336
import java.net.Proxy;
3437
import java.net.Socket;
38+
import java.net.SocketException;
3539

3640
import com.mysql.cj.conf.PropertyKey;
3741
import com.mysql.cj.conf.PropertySet;
@@ -47,4 +51,52 @@ protected Socket createSocket(PropertySet props) {
4751
int socksProxyPort = props.getIntegerProperty(PropertyKey.socksProxyPort).getValue();
4852
return new Socket(new Proxy(Proxy.Type.SOCKS, new InetSocketAddress(socksProxyHost, socksProxyPort)));
4953
}
54+
55+
@Override
56+
@SuppressWarnings("unchecked")
57+
public <T extends Closeable> T connect(String hostname, int portNumber, PropertySet pset, int loginTimeout) throws IOException {
58+
if (!pset.getBooleanProperty(PropertyKey.socksProxyRemoteDns).getValue()) {
59+
// fall back to the parent connection procedure
60+
return super.connect(hostname, portNumber, pset, loginTimeout);
61+
}
62+
63+
// proceed without local DNS resolution
64+
this.loginTimeoutCountdown = loginTimeout;
65+
66+
if (pset != null && hostname != null) {
67+
this.host = hostname;
68+
this.port = portNumber;
69+
70+
String localSocketHostname = pset.getStringProperty(PropertyKey.localSocketAddress).getValue();
71+
InetSocketAddress localSockAddr = localSocketHostname != null && localSocketHostname.length() > 0
72+
? new InetSocketAddress(InetAddress.getByName(localSocketHostname), 0)
73+
: null;
74+
int connectTimeout = pset.getIntegerProperty(PropertyKey.connectTimeout).getValue();
75+
76+
// save last exception to propagate to caller if connection fails
77+
try {
78+
this.rawSocket = createSocket(pset);
79+
configureSocket(this.rawSocket, pset);
80+
81+
// bind to the local port if not using the ephemeral port
82+
if (localSockAddr != null) {
83+
this.rawSocket.bind(localSockAddr);
84+
}
85+
86+
this.rawSocket.connect(InetSocketAddress.createUnresolved(this.host, this.port), getRealTimeout(connectTimeout));
87+
88+
} catch (SocketException ex) {
89+
this.rawSocket = null;
90+
throw ex;
91+
}
92+
93+
resetLoginTimeCountdown();
94+
95+
this.sslSocket = this.rawSocket;
96+
return (T) this.rawSocket;
97+
}
98+
99+
throw new SocketException("Unable to create socket");
100+
}
101+
50102
}

src/main/core-impl/java/com/mysql/cj/protocol/StandardSocketFactory.java

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2002, 2021, Oracle and/or its affiliates.
2+
* Copyright (c) 2002, 2022, Oracle and/or its affiliates.
33
*
44
* This program is free software; you can redistribute it and/or modify it under
55
* the terms of the GNU General Public License, version 2.0, as published by the
@@ -91,7 +91,7 @@ protected Socket createSocket(PropertySet props) {
9191
* @throws IOException
9292
* if an error occurs
9393
*/
94-
private void configureSocket(Socket sock, PropertySet pset) throws SocketException, IOException {
94+
protected void configureSocket(Socket sock, PropertySet pset) throws SocketException, IOException {
9595
sock.setTcpNoDelay(pset.getBooleanProperty(PropertyKey.tcpNoDelay).getValue());
9696
sock.setKeepAlive(pset.getBooleanProperty(PropertyKey.tcpKeepAlive).getValue());
9797

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

119119
if (pset != null) {
120120
this.host = hostname;
121-
122121
this.port = portNumber;
123122

124123
String localSocketHostname = pset.getStringProperty(PropertyKey.localSocketAddress).getValue();
125-
InetSocketAddress localSockAddr = null;
126-
if (localSocketHostname != null && localSocketHostname.length() > 0) {
127-
localSockAddr = new InetSocketAddress(InetAddress.getByName(localSocketHostname), 0);
128-
}
129-
124+
InetSocketAddress localSockAddr = localSocketHostname != null && localSocketHostname.length() > 0
125+
? new InetSocketAddress(InetAddress.getByName(localSocketHostname), 0)
126+
: null;
130127
int connectTimeout = pset.getIntegerProperty(PropertyKey.connectTimeout).getValue();
131128

132129
if (this.host != null) {

src/main/resources/com/mysql/cj/LocalizedErrorMessages.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -955,6 +955,7 @@ ConnectionProperties.socketFactory=The name of the class that the driver should
955955
ConnectionProperties.socketTimeout=Timeout (in milliseconds) on network socket operations (0, the default means no timeout).
956956
ConnectionProperties.socksProxyHost=Name or IP address of SOCKS host to connect through.
957957
ConnectionProperties.socksProxyPort=Port of SOCKS server.
958+
ConnectionProperties.socksProxyRemoteDns=When using a SOCKS proxy, whether the DNS lookup for the database host should be performed locally or through the SOCKS proxy.
958959
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.
959960
ConnectionProperties.strictUpdates=Should the driver do strict checking (all primary keys selected) of updatable result sets (true, false, defaults to ''true'')?
960961
ConnectionProperties.tcpKeepAlive=If connecting using TCP/IP, should the driver set SO_KEEPALIVE?

0 commit comments

Comments
 (0)