10

Good evening,

I have been facing this error for a couple of days by now, and despite looking for a solution all over the web, I coul'd fix this error.

import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.BasicAttribute;
import javax.naming.directory.BasicAttributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;

public class LDAPtest {
public static void main(String[] args) {
    
    try {
        
        String keystorePath = "C:/Program Files/Java/jdk-13.0.2/lib/security/cacerts";
        System.setProperty("javax.net.ssl.keyStore", keystorePath);
         
        System.setProperty("javax.net.ssl.keyStorePassword", "changeit");
        
        Hashtable<String, String> ldapEnv = new Hashtable<>(); 
        ldapEnv.put(Context.INITIAL_CONTEXT_FACTORY,"com.sun.jndi.ldap.LdapCtxFactory");
        ldapEnv.put(Context.PROVIDER_URL, "ldaps://localhost:10636");
        ldapEnv.put(Context.SECURITY_AUTHENTICATION,"simple");
        ldapEnv.put(Context.SECURITY_PRINCIPAL,"uid=admin,ou=system");
        ldapEnv.put(Context.SECURITY_CREDENTIALS,"secret");
        
        DirContext connection = new InitialDirContext(ldapEnv);
        System.out.println("Benvenuto " + connection);
        NamingEnumeration enm = connection.list("");

        while (enm.hasMore()) {
            System.out.println(enm.next());
        }

        enm.close();
        connection.close();
        
        
    }catch(Exception e) {
        e.printStackTrace();
    }
    
}

}

This code is actually working when SSL is not tested, replacing the

ldapEnv.put(Context.PROVIDER_URL, "ldaps://localhost:10636");

with

ldapEnv.put(Context.PROVIDER_URL, "ldap://localhost:10389");

I made the setup for the LDAP server with Apache Directory Studio, and followed this tutorial here in order to get the LDAPS to work: http://directory.apache.org/apacheds/basic-ug/3.3-enabling-ssl.html

So I made the certificate, even installed it and imported it with keytool into cacerts. I enabled portforwarding for the chosen port (10636), but still, I'm getting this exception:

javax.naming.CommunicationException: simple bind failed: localhost:10636 [Root exception is 
java.net.SocketException: Connection or outbound has closed]
at java.naming/com.sun.jndi.ldap.LdapClient.authenticate(LdapClient.java:219)
at java.naming/com.sun.jndi.ldap.LdapCtx.connect(LdapCtx.java:2795)
at java.naming/com.sun.jndi.ldap.LdapCtx.<init>(LdapCtx.java:320)
at java.naming/com.sun.jndi.ldap.LdapCtxFactory.getLdapCtxFromUrl(LdapCtxFactory.java:225)
at java.naming/com.sun.jndi.ldap.LdapCtxFactory.getUsingURL(LdapCtxFactory.java:189)
at java.naming/com.sun.jndi.ldap.LdapCtxFactory.getUsingURLs(LdapCtxFactory.java:243)
at java.naming/com.sun.jndi.ldap.LdapCtxFactory.getLdapCtxInstance(LdapCtxFactory.java:154)
at java.naming/com.sun.jndi.ldap.LdapCtxFactory.getInitialContext(LdapCtxFactory.java:84)
at java.naming/javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:730)
at java.naming/javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:305)
at java.naming/javax.naming.InitialContext.init(InitialContext.java:236)
at java.naming/javax.naming.InitialContext.<init>(InitialContext.java:208)
at java.naming/javax.naming.directory.InitialDirContext.<init>(InitialDirContext.java:130)
at Prova3.main(Prova3.java:31)
Caused by: java.net.SocketException: Connection or outbound has closed
at java.base/sun.security.ssl.SSLSocketImpl$AppOutputStream.write(SSLSocketImpl.java:1246)
at java.base/java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:81)
at java.base/java.io.BufferedOutputStream.flush(BufferedOutputStream.java:142)
at java.naming/com.sun.jndi.ldap.Connection.writeRequest(Connection.java:398)
at java.naming/com.sun.jndi.ldap.Connection.writeRequest(Connection.java:371)
at java.naming/com.sun.jndi.ldap.LdapClient.ldapBind(LdapClient.java:359)
at java.naming/com.sun.jndi.ldap.LdapClient.authenticate(LdapClient.java:214)
... 13 more

Thank you in advance

1

2 Answers 2

15

For Googlers:

simple bind failed errors are almost always related to SSL connection.

With nc or telnet, check whether a connection can be established between client and remote host and port.

With SSLPoke.java (a simple Java class to check SSL connection), check whether certificates are correctly imported and used, also check correct TLS version. Use something like java -Dhttps.protocols=TLSv1,TLSv1.1,TLSv1.2 -Djavax.net.debug=all SSLPoke google.com 443 > log.txt 2>&1.

Look for:

  • Warning: no suitable certificate found - continuing without client authentication = check whether you have set javax.net.ssl.trustStore
  • Fatal (HANDSHAKE_FAILURE): Couldn't kickstart handshaking = could be mismatched TLS versions
  • Also check whether your intermediate CA is expired
Sign up to request clarification or add additional context in comments.

Comments

4

"Connection or outbound has closed" is a general exception with several possible causes. In order to find the main cause you should start your application with the SSL debugging enabled. You can do that by adding the following VM parameter on startup:

-Djavax.net.debug=ssl,handshake

In my case, with the SSL debug mode enabled I got "CertificateException: No name matching localhost found" which is explicit enough. The real problem was that the hostname configured in the self-signed certificate was not the one used to access the host. For the handshake not only the certificate validity is verified, but also the matching of host names.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.