mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

Ludovic Poitou
06.54.2011 186bd2316566ca49ccdb96deec27f092782dacfe
Fix OPENDJ-269 : Add support for SSL connection between DSML gateway and LDAP server.
There are now several new params in the web.xml file to specify:
- A DN and Password to provide default authentication between the DSML gateway and the LDAP server.
- whether to use SSL (on LDAPS port) or StartTLS (against LDAP port)
- whether TLS server certificate must be blindly trust.
- Or the truststore and password to trust it

All combinations tested with GlassFish 3.1 as the container, OpenDJ 2.5-SNAPSHOT as the LDAP server.
2 files modified
133 ■■■■■ changed files
opends/resource/dsml/webapp/web.xml 51 ●●●●● patch | view | raw | blame | history
opends/src/dsml/org/opends/dsml/protocol/DSMLServlet.java 82 ●●●●● patch | view | raw | blame | history
opends/resource/dsml/webapp/web.xml
@@ -9,13 +9,62 @@
    <param-name>ldap.host</param-name>
    <param-value>localhost</param-value>
  </context-param>
  <context-param>
    <description>The port number of the OpenDS server; e.g., 389</description>
    <param-name>ldap.port</param-name>
    <param-value>389</param-value>
  </context-param>
<!-- Uncomment and fill if you want a default authentication between the DSML
     gateway and the LDAP server when DSML request have no Basic HTTP authentication
  <context-param>
    <description>The user DN for authentication (optional)</description>
    <param-name>ldap.userdn</param-name>
    <param-value>cn=Directory Manager</param-value>
  </context-param>
  <context-param>
    <description>The password for authentication (if ldap.userdn is set)</description>
    <param-name>ldap.userpassword</param-name>
    <param-value>secret12</param-value>
  </context-param>
-->
  <context-param>
    <description>A flag to specify if the ldap.port is the SSL secured port</description>
    <param-name>ldap.usessl</param-name>
    <param-value>false</param-value>
  </context-param>
  <context-param>
    <description>A flag to specify if StartTLS should be use to secure connections to the ldap.port</description>
    <param-name>ldap.usestarttls</param-name>
    <param-value>false</param-value>
  </context-param>
  <context-param>
    <description>A flag to specify is all certificates should be blindly trusted</description>
    <param-name>ldap.trustall</param-name>
    <param-value>false</param-value>
  </context-param>
<!-- Uncomment and fill if you enable SSL or StartTLS and want to verify
     the LDAP server certificate
  <context-param>
    <description>The path to the truststore when ssl or starttls is enabled</description>
    <param-name>ldap.truststore.path</param-name>
    <param-value></param-value>
  </context-param>
  <context-param>
    <description>The password of the truststore when ssl or starttls is enabled</description>
    <param-name>ldap.truststore.password</param-name>
    <param-value></param-value>
  </context-param>
-->
  <servlet>
    <servlet-name>DSMLServlet</servlet-name>
    <servlet-class>org.opends.dsml.protocol.DSMLServlet</servlet-class>
opends/src/dsml/org/opends/dsml/protocol/DSMLServlet.java
@@ -23,6 +23,7 @@
 *
 *
 *      Copyright 2006-2010 Sun Microsystems, Inc.
 *      Portions Copyright 2011 ForgeRock AS
 */
package org.opends.dsml.protocol;
@@ -63,6 +64,8 @@
import java.util.concurrent.atomic.AtomicInteger;
import javax.xml.validation.SchemaFactory;
import org.opends.server.tools.LDAPConnectionException;
import org.opends.server.tools.SSLConnectionException;
import org.opends.server.tools.SSLConnectionFactory;
import org.opends.server.types.LDAPException;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
@@ -82,6 +85,13 @@
  private static final String PKG_NAME = "org.opends.dsml.protocol";
  private static final String PORT = "ldap.port";
  private static final String HOST = "ldap.host";
  private static final String USERDN = "ldap.userdn";
  private static final String USERPWD = "ldap.userpassword";
  private static final String USESSL = "ldap.usessl";
  private static final String USESTARTTLS = "ldap.usestarttls";
  private static final String TRUSTSTOREPATH = "ldap.truststore.path";
  private static final String TRUSTSTOREPASSWORD = "ldap.truststore.password";
  private static final String TRUSTALLCERTS = "ldap.trustall";
  private static final long serialVersionUID = -3748022009593442973L;
  private static final AtomicInteger nextMessageID = new AtomicInteger(1);
@@ -111,13 +121,20 @@
  private String hostName;
  private Integer port;
  private String userDN;
  private String userPassword;
  private Boolean useSSL;
  private Boolean useStartTLS;
  private String trustStorePathValue;
  private String trustStorePasswordValue;
  private Boolean trustAll;
  /**
   * This method will be called by the Servlet Container when
   * this servlet is being placed into service.
   *
   * @param config - the <CODE>ServletConfig</CODE> object that
   *               contains configutation information for this servlet.
   *               contains configuration information for this servlet.
   * @throws ServletException If an error occurs during processing.
   */
  public void init(ServletConfig config) throws ServletException {
@@ -127,6 +144,25 @@
      port = new Integer(config.getServletContext().getInitParameter(PORT));
      userDN = config.getServletContext().getInitParameter(USERDN);
      userPassword = config.getServletContext().getInitParameter(USERPWD);
      useSSL = Boolean.valueOf(
          config.getServletContext().getInitParameter(USESSL));
      useStartTLS = Boolean.valueOf(
          config.getServletContext().getInitParameter(USESTARTTLS));
      trustStorePathValue =
          config.getServletContext().getInitParameter(TRUSTSTOREPATH);
      trustStorePasswordValue =
          config.getServletContext().getInitParameter(TRUSTSTOREPASSWORD);
      trustAll = Boolean.valueOf(
          config.getServletContext().getInitParameter(TRUSTALLCERTS));
      if(jaxbContext==null)
        jaxbContext = JAXBContext.newInstance(PKG_NAME,
                this.getClass().getClassLoader());
@@ -167,6 +203,9 @@
  public void doPost(HttpServletRequest req, HttpServletResponse res)
  throws ServletException, IOException {
    LDAPConnectionOptions connOptions = new LDAPConnectionOptions();
    connOptions.setUseSSL(useSSL);
    connOptions.setStartTLS(useStartTLS);
    LDAPConnection connection = null;
    BatchRequest batchRequest = null;
@@ -185,6 +224,25 @@
    List<JAXBElement<?>> batchResponses = batchResponse.getBatchResponses();
    Document doc = db.newDocument();
    if (useSSL || useStartTLS)
    {
      SSLConnectionFactory sslConnectionFactory = new SSLConnectionFactory();
      try
      {
        sslConnectionFactory.init(trustAll, null, null, null,
                                  trustStorePathValue, trustStorePasswordValue);
      }
      catch(SSLConnectionException e)
      {
        batchResponses.add(
          createErrorResponse(
            new LDAPException(LDAPResultCode.CLIENT_SIDE_CONNECT_ERROR,
              Message.raw(
              "Invalid SSL or TLS configuration to connect to LDAP server."))));
      }
      connOptions.setSSLConnectionFactory(sslConnectionFactory);
    }
    SOAPBody soapBody = null;
    MimeHeaders mimeHeaders = new MimeHeaders();
@@ -224,8 +282,26 @@
    if ( ! authorizationInHeader ) {
      // if no authorization, set default user
      bindDN = "";
      bindPassword = "";
      if (userDN != null)
      {
        bindDN = userDN;
        if (userPassword != null)
        {
          bindPassword = userPassword;
        }
        else
        {
          batchResponses.add(
              createErrorResponse(
                    new LDAPException(LDAPResultCode.INVALID_CREDENTIALS,
                    Message.raw("Invalid configured credentials."))));
        }
      }
      else
      {
        bindDN = "";
        bindPassword = "";
      }
    } else {
      // otherwise if DN or password is null, send back an error
      if ( (bindDN == null || bindPassword == null)