The fix for JDK-806769 breaks some ldap usages.

Xuelei Fan xuelei.fan at oracle.com
Fri Oct 16 02:46:09 UTC 2015


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.mullan at oracle.com
> <mailto:sean.mullan at 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.



More information about the security-dev mailing list