Skip to content

Commit 61a4127

Browse files
committed
8251188: Update LDAP tests not to use wildcard addresses
Reviewed-by: yan, mbalao, andrew Backport-of: a75edc29c6ce41116cc99530aa1710efb62c6d5a
1 parent b4264bc commit 61a4127

File tree

5 files changed

+258
-69
lines changed

5 files changed

+258
-69
lines changed

jdk/test/com/sun/jndi/ldap/BalancedParentheses.java

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,18 +24,23 @@
2424
/**
2525
* @test
2626
* @bug 6449574
27+
* @library /lib/testlibrary
2728
* @summary Invalid ldap filter is accepted and processed
2829
*/
2930

3031
import java.io.*;
3132
import javax.naming.*;
3233
import javax.naming.directory.*;
33-
import java.util.Properties;
34+
import java.net.InetAddress;
35+
import java.net.InetSocketAddress;
36+
import java.net.SocketAddress;
3437
import java.util.Hashtable;
3538

3639
import java.net.Socket;
3740
import java.net.ServerSocket;
3841

42+
import jdk.testlibrary.net.URIBuilder;
43+
3944
public class BalancedParentheses {
4045
// Should we run the client or server in a separate thread?
4146
//
@@ -54,7 +59,13 @@ public class BalancedParentheses {
5459
// If the server prematurely exits, serverReady will be set to true
5560
// to avoid infinite hangs.
5661
void doServerSide() throws Exception {
57-
ServerSocket serverSock = new ServerSocket(serverPort);
62+
// Create unbound server socket
63+
ServerSocket serverSock = new ServerSocket();
64+
65+
// And bind it to the loopback address
66+
SocketAddress sockAddr = new InetSocketAddress(
67+
InetAddress.getLoopbackAddress(), 0);
68+
serverSock.bind(sockAddr);
5869

5970
// signal client, it's ready to accecpt connection
6071
serverPort = serverSock.getLocalPort();
@@ -106,7 +117,13 @@ void doClientSide() throws Exception {
106117
Hashtable<Object, Object> env = new Hashtable<Object, Object>();
107118
env.put(Context.INITIAL_CONTEXT_FACTORY,
108119
"com.sun.jndi.ldap.LdapCtxFactory");
109-
env.put(Context.PROVIDER_URL, "ldap://localhost:" + serverPort);
120+
// Construct the provider URL
121+
String providerURL = URIBuilder.newBuilder()
122+
.scheme("ldap")
123+
.loopback()
124+
.port(serverPort)
125+
.build().toString();
126+
env.put(Context.PROVIDER_URL, providerURL);
110127
env.put("com.sun.jndi.ldap.read.timeout", "1000");
111128

112129
// env.put(Context.SECURITY_AUTHENTICATION, "simple");

jdk/test/com/sun/jndi/ldap/DeadSSLLdapTimeoutTest.java

Lines changed: 113 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -21,34 +21,35 @@
2121
* questions.
2222
*/
2323

24-
/**
24+
/*
2525
* @test
26-
* @run main/othervm DeadSSLLdapTimeoutTest
2726
* @bug 8141370
2827
* @key intermittent
28+
* @library /lib/testlibrary
29+
* @build DeadSSLSocketFactory
30+
* @run main/othervm DeadSSLLdapTimeoutTest
2931
*/
3032

31-
import java.net.Socket;
33+
import java.io.EOFException;
34+
import java.io.IOException;
35+
import java.net.InetAddress;
36+
import java.net.InetSocketAddress;
3237
import java.net.ServerSocket;
38+
import java.net.Socket;
39+
import java.net.SocketAddress;
3340
import java.net.SocketTimeoutException;
34-
import java.io.*;
35-
import javax.naming.*;
36-
import javax.naming.directory.*;
37-
import java.util.List;
41+
import javax.naming.Context;
42+
import javax.naming.InitialContext;
43+
import javax.naming.NamingException;
3844
import java.util.Hashtable;
39-
import java.util.ArrayList;
4045
import java.util.concurrent.Callable;
41-
import java.util.concurrent.ExecutionException;
42-
import java.util.concurrent.Executors;
43-
import java.util.concurrent.ExecutorService;
44-
import java.util.concurrent.Future;
45-
import java.util.concurrent.ScheduledExecutorService;
46-
import java.util.concurrent.ScheduledFuture;
47-
import java.util.concurrent.TimeoutException;
46+
import java.util.concurrent.CountDownLatch;
4847
import java.util.concurrent.TimeUnit;
48+
import javax.naming.directory.InitialDirContext;
4949
import javax.net.ssl.SSLHandshakeException;
5050

51-
import static java.util.concurrent.TimeUnit.MILLISECONDS;
51+
import jdk.testlibrary.net.URIBuilder;
52+
5253
import static java.util.concurrent.TimeUnit.NANOSECONDS;
5354

5455

@@ -57,26 +58,26 @@ class DeadServerTimeoutSSLTest implements Callable {
5758
Hashtable env;
5859
DeadSSLServer server;
5960
boolean passed = false;
60-
private int HANGING_TEST_TIMEOUT = 20_000;
6161

6262
public DeadServerTimeoutSSLTest(Hashtable env) throws IOException {
63-
this.server = new DeadSSLServer();
63+
SocketAddress sockAddr = new InetSocketAddress(
64+
InetAddress.getLoopbackAddress(), 0);
65+
this.server = new DeadSSLServer(sockAddr);
6466
this.env = env;
6567
}
6668

67-
public void performOp(InitialContext ctx) throws NamingException {}
68-
69-
public void handleNamingException(NamingException e, long start, long end) {
69+
public void handleNamingException(NamingException e) {
7070
if (e.getCause() instanceof SocketTimeoutException
7171
|| e.getCause().getCause() instanceof SocketTimeoutException) {
7272
// SSL connect will timeout via readReply using
7373
// SocketTimeoutException
74-
e.printStackTrace();
74+
System.out.println("PASS: Observed expected SocketTimeoutException");
7575
pass();
7676
} else if (e.getCause() instanceof SSLHandshakeException
7777
&& e.getCause().getCause() instanceof EOFException) {
7878
// test seems to be failing intermittently on some
7979
// platforms.
80+
System.out.println("PASS: Observed expected SSLHandshakeException/EOFException");
8081
pass();
8182
} else {
8283
fail(e);
@@ -92,6 +93,7 @@ public void fail() {
9293
}
9394

9495
public void fail(Exception e) {
96+
System.err.println("FAIL: Unexpected exception was observed:" + e.getMessage());
9597
throw new RuntimeException("Test failed", e);
9698
}
9799

@@ -106,55 +108,106 @@ boolean shutItDown(InitialContext ctx) {
106108

107109
public Boolean call() {
108110
InitialContext ctx = null;
109-
ScheduledFuture killer = null;
110-
long start = System.nanoTime();
111111

112112
try {
113-
while(!server.accepting())
114-
Thread.sleep(200); // allow the server to start up
113+
server.serverStarted.await(); // Wait for the server to start-up
115114
Thread.sleep(200); // to be sure
116115

117-
env.put(Context.PROVIDER_URL, "ldap://localhost:" +
118-
server.getLocalPort());
116+
env.put(Context.PROVIDER_URL,
117+
URIBuilder.newBuilder()
118+
.scheme("ldap")
119+
.loopback()
120+
.port(server.getLocalPort())
121+
.buildUnchecked().toString()
122+
);
119123

124+
long start = System.nanoTime();
120125
try {
121126
ctx = new InitialDirContext(env);
122-
performOp(ctx);
123127
fail();
124128
} catch (NamingException e) {
125129
long end = System.nanoTime();
126130
System.out.println(this.getClass().toString() + " - elapsed: "
127131
+ NANOSECONDS.toMillis(end - start));
128-
handleNamingException(e, start, end);
132+
handleNamingException(e);
129133
} finally {
130-
if (killer != null && !killer.isDone())
131-
killer.cancel(true);
134+
// Stop the server side thread
135+
server.testDone.countDown();
132136
shutItDown(ctx);
133137
server.close();
134138
}
135139
return passed;
136-
} catch (IOException|InterruptedException e) {
140+
} catch (IOException | InterruptedException e) {
137141
throw new RuntimeException(e);
138142
}
139143
}
140144
}
141145

142146
class DeadSSLServer extends Thread {
143147
ServerSocket serverSock;
144-
boolean accepting = false;
145-
146-
public DeadSSLServer() throws IOException {
147-
this.serverSock = new ServerSocket(0);
148+
// Latch to be used by client to wait for server to start
149+
CountDownLatch serverStarted = new CountDownLatch(1);
150+
151+
// Latch to be used by server thread to wait for client to finish testing
152+
CountDownLatch testDone = new CountDownLatch(1);
153+
154+
public DeadSSLServer(SocketAddress socketAddress) throws IOException {
155+
// create unbound server socket
156+
ServerSocket srvSock = new ServerSocket();
157+
// bind it to the address provided
158+
srvSock.bind(socketAddress);
159+
this.serverSock = srvSock;
148160
start();
149161
}
150162

151163
public void run() {
152-
while(true) {
153-
try {
154-
accepting = true;
155-
Socket socket = serverSock.accept();
164+
// Signal client to proceed with the test
165+
serverStarted.countDown();
166+
while (true) {
167+
try (Socket acceptedSocket = serverSock.accept()) {
168+
System.err.println("Accepted connection:" + acceptedSocket);
169+
int iteration = 0;
170+
// Wait for socket to get opened by DeadSSLSocketFactory and connected to the test server
171+
while (iteration++ < 20) {
172+
if (DeadSSLSocketFactory.firstCreatedSocket.get() != null &&
173+
DeadSSLSocketFactory.firstCreatedSocket.get().isConnected()) {
174+
break;
175+
}
176+
try {
177+
TimeUnit.MILLISECONDS.sleep(50);
178+
} catch (InterruptedException ie) {
179+
}
180+
}
181+
Socket clientSideSocket = DeadSSLSocketFactory.firstCreatedSocket.get();
182+
System.err.printf("Got SSLSocketFactory connection after %d iterations: %s%n",
183+
iteration, clientSideSocket);
184+
185+
if (clientSideSocket == null || !clientSideSocket.isConnected()) {
186+
// If after 1000 ms client side connection is not opened - probably other local process
187+
// tried to connect to the test server socket. Close current connection and retry accept.
188+
continue;
189+
} else {
190+
// Check if accepted socket is connected to the LDAP client
191+
if (acceptedSocket.getLocalPort() == clientSideSocket.getPort() &&
192+
acceptedSocket.getPort() == clientSideSocket.getLocalPort() &&
193+
acceptedSocket.getInetAddress().equals(clientSideSocket.getLocalAddress())) {
194+
System.err.println("Accepted connection is originated from LDAP client:" + acceptedSocket);
195+
try {
196+
// Give LDAP client time to fully establish the connection.
197+
// When client is done - the accepted socket will be closed
198+
testDone.await();
199+
} catch (InterruptedException e) {
200+
}
201+
break;
202+
} else {
203+
// If accepted socket is not from the LDAP client - the accepted connection will be closed and new
204+
// one will be accepted
205+
System.err.println("SSLSocketFactory connection has been established, but originated not from" +
206+
" the test's LDAP client:" + acceptedSocket);
207+
}
208+
}
156209
} catch (Exception e) {
157-
break;
210+
System.err.println("Server socket. Failure to accept connection:" + e.getMessage());
158211
}
159212
}
160213
}
@@ -163,28 +216,26 @@ public int getLocalPort() {
163216
return serverSock.getLocalPort();
164217
}
165218

166-
public boolean accepting() {
167-
return accepting;
168-
}
169-
170219
public void close() throws IOException {
171220
serverSock.close();
172221
}
173222
}
174223

175224
public class DeadSSLLdapTimeoutTest {
225+
// com.sun.jndi.ldap.connect.timeout value to set
226+
static final String CONNECT_TIMEOUT_MS = "10";
227+
228+
// com.sun.jndi.ldap.read.timeout value to set
229+
static final String READ_TIMEOUT_MS = "3000";
176230

177231
static Hashtable createEnv() {
178232
Hashtable env = new Hashtable(11);
179233
env.put(Context.INITIAL_CONTEXT_FACTORY,
180-
"com.sun.jndi.ldap.LdapCtxFactory");
234+
"com.sun.jndi.ldap.LdapCtxFactory");
181235
return env;
182236
}
183237

184238
public static void main(String[] args) throws Exception {
185-
186-
InitialContext ctx = null;
187-
188239
//
189240
// Running this test serially as it seems to tickle a problem
190241
// on older kernels
@@ -193,19 +244,24 @@ public static void main(String[] args) throws Exception {
193244
// and ssl enabled
194245
// this should exit with a SocketTimeoutException as the root cause
195246
// it should also use the connect timeout instead of the read timeout
196-
System.out.println("Running connect timeout test with 10ms connect timeout, 3000ms read timeout & SSL");
247+
System.out.printf("Running connect timeout test with %sms connect timeout," +
248+
" %sms read timeout & SSL%n",
249+
CONNECT_TIMEOUT_MS, READ_TIMEOUT_MS);
250+
197251
Hashtable sslenv = createEnv();
198-
sslenv.put("com.sun.jndi.ldap.connect.timeout", "10");
199-
sslenv.put("com.sun.jndi.ldap.read.timeout", "3000");
252+
// Setup connect timeout environment property
253+
sslenv.put("com.sun.jndi.ldap.connect.timeout", CONNECT_TIMEOUT_MS);
254+
// Setup read timeout environment property
255+
sslenv.put("com.sun.jndi.ldap.read.timeout", READ_TIMEOUT_MS);
256+
// Setup DeadSSLSocketFactory to track the client's first LDAP connection
257+
sslenv.put("java.naming.ldap.factory.socket", "DeadSSLSocketFactory");
258+
// Use SSL protocol
200259
sslenv.put(Context.SECURITY_PROTOCOL, "ssl");
201-
boolean testFailed =
202-
(new DeadServerTimeoutSSLTest(sslenv).call()) ? false : true;
203260

261+
boolean testFailed = !new DeadServerTimeoutSSLTest(sslenv).call();
204262
if (testFailed) {
205263
throw new AssertionError("some tests failed");
206264
}
207-
208265
}
209-
210266
}
211267

0 commit comments

Comments
 (0)