From e50b79850923484252c328b421a4100968601407 Mon Sep 17 00:00:00 2001
From: Matthew Swift <matthew.swift@forgerock.com>
Date: Fri, 05 Jul 2013 12:40:13 +0000
Subject: [PATCH] Fix OPENDJ-1033: The Rest2LDAP servlet does not support SSL
---
opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Rest2LDAP.java | 72 ++++++++++++++++++++++++++++++++++--
1 files changed, 68 insertions(+), 4 deletions(-)
diff --git a/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Rest2LDAP.java b/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Rest2LDAP.java
index 7c97bcd..b9cbbe1 100644
--- a/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Rest2LDAP.java
+++ b/opendj3/opendj-rest2ldap/src/main/java/org/forgerock/opendj/rest2ldap/Rest2LDAP.java
@@ -21,6 +21,8 @@
import static org.forgerock.opendj.rest2ldap.ReadOnUpdatePolicy.CONTROLS;
import static org.forgerock.opendj.rest2ldap.Utils.ensureNotNull;
+import java.io.IOException;
+import java.security.GeneralSecurityException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashMap;
@@ -52,13 +54,16 @@
import org.forgerock.opendj.ldap.FailoverLoadBalancingAlgorithm;
import org.forgerock.opendj.ldap.Filter;
import org.forgerock.opendj.ldap.LDAPConnectionFactory;
+import org.forgerock.opendj.ldap.LDAPOptions;
import org.forgerock.opendj.ldap.LinkedAttribute;
import org.forgerock.opendj.ldap.MultipleEntriesFoundException;
import org.forgerock.opendj.ldap.RDN;
import org.forgerock.opendj.ldap.ResultCode;
import org.forgerock.opendj.ldap.RoundRobinLoadBalancingAlgorithm;
+import org.forgerock.opendj.ldap.SSLContextBuilder;
import org.forgerock.opendj.ldap.SearchScope;
import org.forgerock.opendj.ldap.TimeoutResultException;
+import org.forgerock.opendj.ldap.TrustManagers;
import org.forgerock.opendj.ldap.requests.BindRequest;
import org.forgerock.opendj.ldap.requests.Requests;
import org.forgerock.opendj.ldap.requests.SearchRequest;
@@ -70,6 +75,23 @@
* collections.
*/
public final class Rest2LDAP {
+
+ /**
+ * Indicates whether or not LDAP client connections should use SSL or
+ * StartTLS.
+ */
+ private enum ConnectionSecurity {
+ NONE, SSL, STARTTLS
+ }
+
+ /**
+ * Specifies the mechanism which should be used for trusting certificates
+ * presented by the LDAP server.
+ */
+ private enum TrustManagerType {
+ TRUSTALL, JVM, FILE
+ }
+
/**
* A builder for incrementally constructing LDAP resource collections.
*/
@@ -965,6 +987,48 @@
bindRequest = null;
}
+ // Parse SSL/StartTLS parameters.
+ final ConnectionSecurity connectionSecurity =
+ configuration.get("connectionSecurity").defaultTo(ConnectionSecurity.NONE).asEnum(
+ ConnectionSecurity.class);
+ final LDAPOptions options = new LDAPOptions();
+ if (connectionSecurity != ConnectionSecurity.NONE) {
+ try {
+ // Configure SSL.
+ final SSLContextBuilder builder = new SSLContextBuilder();
+
+ // Parse trust store configuration.
+ final TrustManagerType trustManagerType =
+ configuration.get("trustManager").defaultTo(TrustManagerType.TRUSTALL)
+ .asEnum(TrustManagerType.class);
+ switch (trustManagerType) {
+ case TRUSTALL:
+ builder.setTrustManager(TrustManagers.trustAll());
+ break;
+ case JVM:
+ // Do nothing: JVM trust manager is the default.
+ break;
+ case FILE:
+ final String fileName =
+ configuration.get("fileBasedTrustManagerFile").required().asString();
+ final String password =
+ configuration.get("fileBasedTrustManagerPassword").asString();
+ final String type = configuration.get("fileBasedTrustManagerType").asString();
+ builder.setTrustManager(TrustManagers.checkUsingTrustStore(fileName,
+ password != null ? password.toCharArray() : null, type));
+ break;
+ }
+ options.setSSLContext(builder.getSSLContext());
+ options.setUseStartTLS(connectionSecurity == ConnectionSecurity.STARTTLS);
+ } catch (GeneralSecurityException e) {
+ // Rethrow as unchecked exception.
+ throw new IllegalArgumentException(e);
+ } catch (IOException e) {
+ // Rethrow as unchecked exception.
+ throw new IllegalArgumentException(e);
+ }
+ }
+
// Parse primary data center.
final JsonValue primaryLDAPServers = configuration.get("primaryLDAPServers");
if (!primaryLDAPServers.isList() || primaryLDAPServers.size() == 0) {
@@ -972,7 +1036,7 @@
}
final ConnectionFactory primary =
parseLDAPServers(primaryLDAPServers, bindRequest, connectionPoolSize,
- heartBeatIntervalSeconds);
+ heartBeatIntervalSeconds, options);
// Parse secondary data center(s).
final JsonValue secondaryLDAPServers = configuration.get("secondaryLDAPServers");
@@ -981,7 +1045,7 @@
if (secondaryLDAPServers.size() > 0) {
secondary =
parseLDAPServers(secondaryLDAPServers, bindRequest, connectionPoolSize,
- heartBeatIntervalSeconds);
+ heartBeatIntervalSeconds, options);
} else {
secondary = null;
}
@@ -1029,12 +1093,12 @@
private static ConnectionFactory parseLDAPServers(final JsonValue config,
final BindRequest bindRequest, final int connectionPoolSize,
- final int heartBeatIntervalSeconds) {
+ final int heartBeatIntervalSeconds, final LDAPOptions options) {
final List<ConnectionFactory> servers = new ArrayList<ConnectionFactory>(config.size());
for (final JsonValue server : config) {
final String host = server.get("hostname").required().asString();
final int port = server.get("port").required().asInteger();
- ConnectionFactory factory = new LDAPConnectionFactory(host, port);
+ ConnectionFactory factory = new LDAPConnectionFactory(host, port, options);
if (bindRequest != null) {
factory = Connections.newAuthenticatedConnectionFactory(factory, bindRequest);
}
--
Gitblit v1.10.0