All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.ldaptive.provider.jndi.JndiStartTLSConnectionFactory Maven / Gradle / Ivy

There is a newer version: 2.4.0
Show newest version
/* See LICENSE for licensing and NOTICE for copyright. */
package org.ldaptive.provider.jndi;

import java.io.IOException;
import java.util.Hashtable;
import java.util.Map;
import javax.naming.NamingException;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapContext;
import javax.naming.ldap.StartTlsRequest;
import javax.naming.ldap.StartTlsResponse;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLSocketFactory;
import org.ldaptive.LdapException;
import org.ldaptive.provider.AbstractProviderConnectionFactory;
import org.ldaptive.provider.ConnectionException;

/**
 * Creates connections using the JNDI {@link InitialLdapContext} class with the startTLS extended operation.
 *
 * @author  Middleware Services
 */
public class JndiStartTLSConnectionFactory extends AbstractProviderConnectionFactory
{

  /** Environment properties. */
  private final Map environment;

  /** SSL socket factory to use for startTLS negotiation. */
  private final SSLSocketFactory sslSocketFactory;

  /** Hostname verifier to use for startTLS negotiation. */
  private final HostnameVerifier hostnameVerifier;


  /**
   * Creates a new jndi startTLS connection factory.
   *
   * @param  url  of the ldap to connect to
   * @param  config  provider configuration
   * @param  env  jndi context environment
   * @param  factory  SSL socket factory
   * @param  verifier  hostname verifier
   */
  public JndiStartTLSConnectionFactory(
    final String url,
    final JndiProviderConfig config,
    final Map env,
    final SSLSocketFactory factory,
    final HostnameVerifier verifier)
  {
    super(url, config);
    environment = env;
    sslSocketFactory = factory;
    hostnameVerifier = verifier;
  }


  @Override
  protected JndiStartTLSConnection createInternal(final String url)
    throws LdapException
  {
    // CheckStyle:IllegalType OFF
    // the JNDI API requires the Hashtable type
    final Hashtable env = new Hashtable<>(environment);
    // CheckStyle:IllegalType ON
    env.put(JndiProvider.PROVIDER_URL, url);

    JndiStartTLSConnection conn = null;
    boolean closeConn = false;
    try {
      conn = new JndiStartTLSConnection(new InitialLdapContext(env, null), getProviderConfig());
      conn.setStartTlsResponse(startTLS(conn.getLdapContext()));
    } catch (NamingException e) {
      closeConn = true;
      throw new ConnectionException(e, NamingExceptionUtils.getResultCode(e.getClass()));
    } catch (IOException e) {
      closeConn = true;
      throw new ConnectionException(e);
    } catch (RuntimeException e) {
      closeConn = true;
      throw e;
    } finally {
      if (closeConn) {
        try {
          if (conn != null) {
            conn.close(null);
          }
        } catch (LdapException e) {
          logger.debug("Problem tearing down connection", e);
        }
      }
    }
    return conn;
  }


  /**
   * This will attempt the startTLS extended operation on the supplied ldap context.
   *
   * @param  ctx  ldap context
   *
   * @return  start tls response
   *
   * @throws  NamingException  if an error occurs while requesting an extended operation
   * @throws  IOException  if an error occurs while negotiating TLS
   */
  protected StartTlsResponse startTLS(final LdapContext ctx)
    throws NamingException, IOException
  {
    final StartTlsResponse tls = (StartTlsResponse) ctx.extendedOperation(new StartTlsRequest());
    if (hostnameVerifier != null) {
      logger.trace("startTLS hostnameVerifier = {}", hostnameVerifier);
      tls.setHostnameVerifier(hostnameVerifier);
    }
    if (sslSocketFactory != null) {
      logger.trace("startTLS sslSocketFactory = {}", sslSocketFactory);
      tls.negotiate(sslSocketFactory);
    } else {
      tls.negotiate();
    }
    return tls;
  }


  @Override
  public String toString()
  {
    return
      String.format(
        "[%s@%d::metadata=%s, environment=%s, providerConfig=%s, " +
        "sslSocketFactory=%s, hostnameVerifier=%s]",
        getClass().getName(),
        hashCode(),
        getMetadata(),
        environment,
        getProviderConfig(),
        sslSocketFactory,
        hostnameVerifier);
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy