From 186bd2316566ca49ccdb96deec27f092782dacfe Mon Sep 17 00:00:00 2001
From: Ludovic Poitou <ludovic.poitou@forgerock.com>
Date: Tue, 06 Sep 2011 15:54:57 +0000
Subject: [PATCH] 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

---
 opends/resource/dsml/webapp/web.xml                       |   51 ++++++++++++++++
 opends/src/dsml/org/opends/dsml/protocol/DSMLServlet.java |   82 ++++++++++++++++++++++++++-
 2 files changed, 129 insertions(+), 4 deletions(-)

diff --git a/opends/resource/dsml/webapp/web.xml b/opends/resource/dsml/webapp/web.xml
index 0ab7ce7..2557a11 100644
--- a/opends/resource/dsml/webapp/web.xml
+++ b/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>
diff --git a/opends/src/dsml/org/opends/dsml/protocol/DSMLServlet.java b/opends/src/dsml/org/opends/dsml/protocol/DSMLServlet.java
index 4f21c2d..1984ef7 100644
--- a/opends/src/dsml/org/opends/dsml/protocol/DSMLServlet.java
+++ b/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)

--
Gitblit v1.10.0