Hi David, Thanks for reporting the issue. I filed a bug for the tracking:
https://bugs.openjdk.java.net/browse/JDK-8139721 Thanks, Xuelei On 9/26/2015 4:39 PM, David Black wrote: > > > On Saturday, 26 September 2015, Sean Mullan <sean.mul...@oracle.com > <mailto:sean.mul...@oracle.com>> wrote: > > JDK-806769 doesn't exist, can you double-check what issue you think > caused this? Looks like you are missing a digit. > > > Hi Sean, hmm I don't know how I managed that ... the complete issue id > is JDK-8067695. > > > > > On 9/24/15 10:46 PM, David Black wrote: > > As I do not have an account on https://bugs.openjdk.java.net, > yes I have > submitted a standard oracle java bug report, I thought it might > be of > interest to those on this mailing list to forward information on how > some java ldap users since the JDK-806769 fix may encounter invalid > ldaps hostname issues. > > When an "ldaps" provider url is set in the environment and a custom > SocketFactory, which sets the SSLSocket endpoint identification > algorithm to "LDAPS", is set in the ldap environment hostname > because of > the way the fix for JDK-806769 was implemented some clients > encounter a > CertificateException. This occurs because the code inside the > com.sun.jndi.ldap.Connection class createSocket method[0] > "prefers" to > invoke the socketFactory.createSocket() method instead of > socketFactory.createSocket(String host, int port) when a connection > timeout is set, which results in the host not being set in the > created > ssl socket instance. > > Steps to reproduce: > 1. git clone > https://bitbucket.org/atlassian/cwd-4444-java-bug-reproducer.git > 2. build the code - `cd src/main/java && javac Broken.java Main.java > Working.java` > 3. run the Main class and provide an ldaps url - `java Main > ldaps://example.java:10636` > 4. Observe that when the "Broken" SocketFactory is in use a hostname > verification error occurs. > > Workaround: > Naturally, one can workaround the Connection class's > "preference" for > the no argument createSocket method by not having such a method > in the > SocketFactory set in the ldap environment. > > > Untested potential patch: > --- Connection.java.orig2015-09-25 11:39:26.323117929 +1000 > +++ Connection.java2015-09-25 12:41:04.175068697 +1000 > @@ -33,6 +33,7 @@ > import java.io.InputStream; > import java.net.Socket; > import javax.net.ssl.SSLSocket; > +import javax.net.ssl.SSLSocketFactory; > import javax.naming.CommunicationException; > import javax.naming.ServiceUnavailableException; > @@ -287,7 +288,40 @@ > Method createSocket = null; > - if (connectTimeout > 0) { > + if (connectTimeout > 0 && socketFactoryClass instanceof > SSLSocketFactory) { > + > + try { > + Socket sock = null; > + createSocket = > socketFactoryClass.getMethod("createSocket", > + new Class<?>[]{Socket.class, > String.class, > + int.class, boolean.class}); > + Constructor<Socket> socketCons = > + Socket.class.getConstructor(new > Class<?>[]{}); > + > + Method connect = > Socket.class.getMethod("connect", > + new > Class<?>[]{Class.forName("java.net.SocketAddress"), > + int.class}); > + Object endpoint = > createInetSocketAddress(host, port); > + > + // unconnected underlying socket > + sock = socketCons.newInstance(new Object[]{}); > + > + if (debug) { > + System.err.println("Connection: > creating socket > with " + > + "a timeout"); > + } > + // connect the underlying socket > + connect.invoke(sock, new Object[]{ > + endpoint, new Integer(connectTimeout)}); > + // connect the ssl socket > + socket = createSocket(sock, host, port, true); > + > + } catch (NoSuchMethodException e) { > + // continue > + } > + } > + > + if (connectTimeout > 0 && socket == null) { > try { > createSocket = > socketFactoryClass.getMethod("createSocket", > > > > [0] > > http://hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/7d1d5f4d019a/src/share/classes/com/sun/jndi/ldap/Connection.java#l272 > > -- > David Black / Security Engineer. > > > > -- > David Black / Security Engineer.