Skip to content

Commit

Permalink
WriteSocketTimeoutTest fails on JDK 8u201 - fix #375
Browse files Browse the repository at this point in the history
  • Loading branch information
bshannon committed Mar 12, 2019
1 parent 36a4c8d commit 1e29579
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 57 deletions.
2 changes: 2 additions & 0 deletions doc/release/CHANGES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ E 369 javax.mail.internet.GetLocalAddressTest fails when host has no name
E 370 Exchange sometimes returns entire message for a partial fetch
E 371 Cannot allow UTF-8 headers in MimeMultipart
E 372 Add QUIT support on session rejection
E 375 WriteSocketTimeoutTest fails on JDK 8u201


CHANGES IN THE 1.6.3 RELEASE
----------------------------
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2019 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
Expand Down Expand Up @@ -123,7 +123,7 @@ public synchronized KeyManager[] getKeyManagers() {
* @param keyManagers the keyManagers to set
* @throws GeneralSecurityException for security errors
*/
public synchronized void setKeyManagers(KeyManager[] keyManagers)
public synchronized void setKeyManagers(KeyManager... keyManagers)
throws GeneralSecurityException {
this.keyManagers = keyManagers.clone();
newAdapteeFactory();
Expand Down Expand Up @@ -157,7 +157,7 @@ public synchronized TrustManager[] getTrustManagers() {
* @param trustManagers the trustManagers to set
* @throws GeneralSecurityException for security errors
*/
public synchronized void setTrustManagers(TrustManager[] trustManagers)
public synchronized void setTrustManagers(TrustManager... trustManagers)
throws GeneralSecurityException {
this.trustManagers = trustManagers;
newAdapteeFactory();
Expand Down Expand Up @@ -190,7 +190,7 @@ public synchronized String[] getTrustedHosts() {
/**
* @param trustedHosts the hosts to trust
*/
public synchronized void setTrustedHosts(String[] trustedHosts) {
public synchronized void setTrustedHosts(String... trustedHosts) {
if (trustedHosts == null)
this.trustedHosts = null;
else
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2019 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
Expand All @@ -22,8 +22,11 @@

import javax.net.ssl.*;

import com.sun.mail.util.MailSSLSocketFactory;

/**
* An SSL socket factory for testing that tracks whether it's being used.
* Always trusts the server "localhost".
* <p>
*
* An instance of this factory can be set as the value of the
Expand Down Expand Up @@ -67,7 +70,9 @@ public TestSSLSocketFactory(String protocol)
throws GeneralSecurityException {

// Get the default SSLSocketFactory to delegate all API-calls to.
defaultFactory = (SSLSocketFactory)SSLSocketFactory.getDefault();
// Use a MailSSLSocketFactory so that we can trust "localhost".
defaultFactory = new MailSSLSocketFactory();
((MailSSLSocketFactory)defaultFactory).setTrustedHosts("localhost");
}

/**
Expand Down
50 changes: 35 additions & 15 deletions mail/src/test/java/com/sun/mail/test/TestServer.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2009, 2018 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2009, 2019 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
Expand All @@ -22,13 +22,17 @@
import java.net.ServerSocket;
import java.net.Socket;
import java.net.InetSocketAddress;
import java.security.*;
import javax.net.ssl.*;

/**
* A simple server for testing.
*
* Inspired by, and derived from, POP3Server by sbo.
*
* For SSL/TLS support, depends on a keystore with a single X509 certificate in
* mail/src/test/resources/com/sun/mail/test/keystore.jks.
*
* @author sbo
* @author Bill Shannon
*/
Expand Down Expand Up @@ -85,34 +89,50 @@ public TestServer(final ProtocolHandler handler, final boolean isSSL)
return;
} catch (IOException ex) {
// ignore
} catch (GeneralSecurityException ex) {
System.out.println(ex);
// ignore
}
}
throw new RuntimeException("Can't find unused port");
}

private static ServerSocket createServerSocket(int port, boolean isSSL)
throws IOException {
throws IOException, GeneralSecurityException {
ServerSocket ss;
if (isSSL) {
SSLServerSocketFactory sf =
(SSLServerSocketFactory)SSLServerSocketFactory.getDefault();
SSLContext sslContext = createSSLContext();
SSLServerSocketFactory sf = sslContext.getServerSocketFactory();
ss = sf.createServerSocket(port);
// enable only the anonymous cipher suites so we don't have to
// create a server certificate
List<String> anon = new ArrayList<>();
String[] suites = sf.getSupportedCipherSuites();
for (int i = 0; i < suites.length; i++) {
if (suites[i].indexOf("_anon_") >= 0) {
anon.add(suites[i]);
}
}
((SSLServerSocket)ss).setEnabledCipherSuites(
anon.toArray(new String[anon.size()]));
} else
ss = new ServerSocket(port);
return ss;
}

private static SSLContext createSSLContext()
throws IOException, GeneralSecurityException {
KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(
TestServer.class.getResourceAsStream("keystore.jks"),
"changeit".toCharArray());

// Create key manager
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(keyStore, "changeit".toCharArray());
KeyManager[] km = kmf.getKeyManagers();

// Create trust manager
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
tmf.init(keyStore);
TrustManager[] tm = tmf.getTrustManagers();

// Initialize SSLContext
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(km, tm, null);

return sslContext;
}

/**
* Return the port the server is listening on.
*/
Expand Down
42 changes: 6 additions & 36 deletions mail/src/test/java/com/sun/mail/util/WriteTimeoutSocketTest.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2009, 2018 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2009, 2019 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
Expand Down Expand Up @@ -92,10 +92,7 @@ public void testSSL() {
properties.setProperty("mail.imap.host", "localhost");
properties.setProperty("mail.imap.writetimeout", "" + TIMEOUT);
properties.setProperty("mail.imap.ssl.enable", "true");
// enable only the anonymous cipher suites since there's no
// server certificate
properties.setProperty("mail.imap.ssl.ciphersuites",
getAnonCipherSuites());
properties.setProperty("mail.imap.ssl.trust", "localhost");
test(properties, true);
}

Expand All @@ -108,15 +105,14 @@ public void testSSLSocketFactory() throws Exception {
properties.setProperty("mail.imap.host", "localhost");
properties.setProperty("mail.imap.writetimeout", "" + TIMEOUT);
properties.setProperty("mail.imap.ssl.enable", "true");
// TestSSLSocketFactory always trusts "localhost"; setting
// this property would cause MailSSLSocketFactory to be used instead
// of TestSSLSocketFactory, which we don't want.
//properties.setProperty("mail.imap.ssl.trust", "localhost");
TestSSLSocketFactory sf = new TestSSLSocketFactory();
sf.setDefaultCipherSuites(getAnonCipherSuitesArray());
properties.put("mail.imap.ssl.socketFactory", sf);
// don't fall back to non-SSL
properties.setProperty("mail.imap.socketFactory.fallback", "false");
// enable only the anonymous cipher suites since there's no
// server certificate
properties.setProperty("mail.imap.ssl.ciphersuites",
getAnonCipherSuites());
test(properties, true);
// make sure our socket factory was actually used
assertTrue(sf.getSocketWrapped() || sf.getSocketCreated());
Expand Down Expand Up @@ -156,32 +152,6 @@ public void testOverrides() throws Exception {
assertTrue(socketMethods.isEmpty());
}

private static String[] getAnonCipherSuitesArray() {
SSLSocketFactory sf = (SSLSocketFactory)SSLSocketFactory.getDefault();
List<String> anon = new ArrayList<>();
String[] suites = sf.getSupportedCipherSuites();
for (int i = 0; i < suites.length; i++) {
if (suites[i].indexOf("_anon_") >= 0) {
anon.add(suites[i]);
}
}
return anon.toArray(new String[anon.size()]);
}

private static String getAnonCipherSuites() {
SSLSocketFactory sf = (SSLSocketFactory)SSLSocketFactory.getDefault();
StringBuilder anon = new StringBuilder();
String[] suites = sf.getSupportedCipherSuites();
for (int i = 0; i < suites.length; i++) {
if (suites[i].indexOf("_anon_") >= 0) {
if (anon.length() > 0)
anon.append(" ");
anon.append(suites[i]);
}
}
return anon.toString();
}

private void test(Properties properties, boolean isSSL) {
TestServer server = null;
try {
Expand Down
Binary file not shown.

0 comments on commit 1e29579

Please sign in to comment.