Author: tripod
Date: Thu Feb 20 06:50:09 2014
New Revision: 1570090

URL: http://svn.apache.org/r1570090
Log:
OAK-1439 LDAP: SSL/TLS support

- adding TLS support
- adding relaxed certification trustmanager

Modified:
    jackrabbit/oak/trunk/oak-auth-ldap/pom.xml
    
jackrabbit/oak/trunk/oak-auth-ldap/src/main/java/org/apache/jackrabbit/oak/security/authentication/ldap/impl/DebugTimer.java
    
jackrabbit/oak/trunk/oak-auth-ldap/src/main/java/org/apache/jackrabbit/oak/security/authentication/ldap/impl/LdapIdentityProvider.java
    
jackrabbit/oak/trunk/oak-auth-ldap/src/main/java/org/apache/jackrabbit/oak/security/authentication/ldap/impl/LdapProviderConfig.java
    
jackrabbit/oak/trunk/oak-auth-ldap/src/main/java/org/apache/jackrabbit/oak/security/authentication/ldap/impl/PoolableUnboundConnectionFactory.java

Modified: jackrabbit/oak/trunk/oak-auth-ldap/pom.xml
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-auth-ldap/pom.xml?rev=1570090&r1=1570089&r2=1570090&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-auth-ldap/pom.xml (original)
+++ jackrabbit/oak/trunk/oak-auth-ldap/pom.xml Thu Feb 20 06:50:09 2014
@@ -39,14 +39,14 @@
                 <configuration>
                     <instructions>
                         <Import-Package>
-                            !antlr.*,
                             !org.dom4j.*,
                             !org.xmlpull.v1,
                             *
                         </Import-Package>
                         <Embed-Dependency>
-                            api-all,commons-pool,commons-lang,mina-core
+                            api-all,commons-pool,commons-lang,mina-core,antlr
                         </Embed-Dependency>
+                        <Embed-Transitive>true</Embed-Transitive>
                     </instructions>
                 </configuration>
             </plugin>
@@ -94,6 +94,12 @@
             <version>2.0.7</version>
             <scope>provided</scope>
         </dependency>
+        <dependency>
+            <groupId>antlr</groupId>
+            <artifactId>antlr</artifactId>
+            <version>2.7.7</version>
+            <scope>provided</scope>
+        </dependency>
 
         <dependency>
             <groupId>biz.aQute.bnd</groupId>

Modified: 
jackrabbit/oak/trunk/oak-auth-ldap/src/main/java/org/apache/jackrabbit/oak/security/authentication/ldap/impl/DebugTimer.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-auth-ldap/src/main/java/org/apache/jackrabbit/oak/security/authentication/ldap/impl/DebugTimer.java?rev=1570090&r1=1570089&r2=1570090&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-auth-ldap/src/main/java/org/apache/jackrabbit/oak/security/authentication/ldap/impl/DebugTimer.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-auth-ldap/src/main/java/org/apache/jackrabbit/oak/security/authentication/ldap/impl/DebugTimer.java
 Thu Feb 20 06:50:09 2014
@@ -44,10 +44,12 @@ public class DebugTimer {
         if (timestamps.isEmpty()) {
             return "";
         }
-        StringBuilder b = new StringBuilder("(");
+        StringBuilder b = new StringBuilder();
         for (TimeStamp t: timestamps) {
             if (b.length() > 0) {
                 b.append(", ");
+            } else {
+                b.append("(");
             }
             int u = 0;
             double time = t.time;
@@ -55,7 +57,7 @@ public class DebugTimer {
                 time = time / 1000;
                 u++;
             }
-            b.append(String.format("%s=%f.2%s", t.msg, time, units[u]));
+            b.append(String.format("%s=%.2f%s", t.msg, time, units[u]));
         }
         return b.append(')').toString();
     }

Modified: 
jackrabbit/oak/trunk/oak-auth-ldap/src/main/java/org/apache/jackrabbit/oak/security/authentication/ldap/impl/LdapIdentityProvider.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-auth-ldap/src/main/java/org/apache/jackrabbit/oak/security/authentication/ldap/impl/LdapIdentityProvider.java?rev=1570090&r1=1570089&r2=1570090&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-auth-ldap/src/main/java/org/apache/jackrabbit/oak/security/authentication/ldap/impl/LdapIdentityProvider.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-auth-ldap/src/main/java/org/apache/jackrabbit/oak/security/authentication/ldap/impl/LdapIdentityProvider.java
 Thu Feb 20 06:50:09 2014
@@ -46,6 +46,8 @@ import org.apache.directory.api.ldap.mod
 import org.apache.directory.ldap.client.api.LdapConnection;
 import org.apache.directory.ldap.client.api.LdapConnectionConfig;
 import org.apache.directory.ldap.client.api.LdapConnectionPool;
+import org.apache.directory.ldap.client.api.LdapNetworkConnection;
+import org.apache.directory.ldap.client.api.NoVerificationTrustManager;
 import org.apache.directory.ldap.client.api.PoolableLdapConnectionFactory;
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
@@ -133,30 +135,44 @@ public class LdapIdentityProvider implem
         }
 
         // setup admin connection pool
-        LdapConnectionConfig cc = new LdapConnectionConfig();
-        cc.setLdapHost(config.getHostname());
-        cc.setLdapPort(config.getPort());
+        LdapConnectionConfig cc = createConnectionConfig();
         if (!config.getBindDN().isEmpty()) {
             cc.setName(config.getBindDN());
             cc.setCredentials(config.getBindPassword());
         }
-        cc.setUseSsl(config.useSSL());
+
         PoolableLdapConnectionFactory factory = new 
PoolableLdapConnectionFactory(cc);
         adminPool = new LdapConnectionPool(factory);
         adminPool.setTestOnBorrow(true);
         
adminPool.setWhenExhaustedAction(GenericObjectPool.WHEN_EXHAUSTED_GROW);
 
         // setup unbound connection pool. let's create a new version of the 
config
-        cc = new LdapConnectionConfig();
-        cc.setLdapHost(config.getHostname());
-        cc.setLdapPort(config.getPort());
-        cc.setUseSsl(config.useSSL());
+        cc = createConnectionConfig();
         userPool = new UnboundLdapConnectionPool(new 
PoolableUnboundConnectionFactory(cc));
         userPool.setTestOnBorrow(true);
         userPool.setWhenExhaustedAction(GenericObjectPool.WHEN_EXHAUSTED_GROW);
     }
 
     /**
+     * Creates a new connection config based on the config.
+     * @return the connection config.
+     */
+    @Nonnull
+    private LdapConnectionConfig createConnectionConfig() {
+        LdapConnectionConfig cc = new LdapConnectionConfig();
+        cc.setLdapHost(config.getHostname());
+        cc.setLdapPort(config.getPort());
+        cc.setUseSsl(config.useSSL());
+        cc.setUseTls(config.useTLS());
+
+        // todo: implement better trustmanager/keystore management (via 
sling/felix)
+        if (config.noCertCheck()) {
+            cc.setTrustManagers(new NoVerificationTrustManager());
+        }
+        return cc;
+    }
+
+    /**
      * Closes this provider and releases the internal pool. This should be 
called by Non-OSGi users of this provider.
      */
     public void close() {

Modified: 
jackrabbit/oak/trunk/oak-auth-ldap/src/main/java/org/apache/jackrabbit/oak/security/authentication/ldap/impl/LdapProviderConfig.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-auth-ldap/src/main/java/org/apache/jackrabbit/oak/security/authentication/ldap/impl/LdapProviderConfig.java?rev=1570090&r1=1570089&r2=1570090&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-auth-ldap/src/main/java/org/apache/jackrabbit/oak/security/authentication/ldap/impl/LdapProviderConfig.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-auth-ldap/src/main/java/org/apache/jackrabbit/oak/security/authentication/ldap/impl/LdapProviderConfig.java
 Thu Feb 20 06:50:09 2014
@@ -91,12 +91,42 @@ public class LdapProviderConfig {
      */
     @Property(
             label = "Use SSL",
-            description = "Indicates if an SSL connection should be used.",
+            description = "Indicates if an SSL (LDAPs) connection should be 
used.",
             boolValue = PARAM_USE_SSL_DEFAULT
     )
     public static final String PARAM_USE_SSL = "host.ssl";
 
     /**
+     * @see #useTLS()
+     */
+    public static final boolean PARAM_USE_TLS_DEFAULT = false;
+
+    /**
+     * @see #useTLS()
+     */
+    @Property(
+            label = "Use TLS",
+            description = "Indicates if TLS should be started on connections.",
+            boolValue = PARAM_USE_TLS_DEFAULT
+    )
+    public static final String PARAM_USE_TLS = "host.tls";
+
+    /**
+     * @see #noCertCheck()
+     */
+    public static final boolean PARAM_NO_CERT_CHECK_DEFAULT = false;
+
+    /**
+     * @see #noCertCheck()
+     */
+    @Property(
+            label = "Disable certificate checking",
+            description = "Indicates if server certificate validation should 
be disabled.",
+            boolValue = PARAM_NO_CERT_CHECK_DEFAULT
+    )
+    public static final String PARAM_NO_CERT_CHECK = "host.noCertCheck";
+
+    /**
      * @see #getBindDN()
      */
     public static final String PARAM_BIND_DN_DEFAULT = "";
@@ -489,6 +519,8 @@ public class LdapProviderConfig {
                 .setHostname(params.getConfigValue(PARAM_LDAP_HOST, 
PARAM_LDAP_HOST_DEFAULT))
                 .setPort(params.getConfigValue(PARAM_LDAP_PORT, 
PARAM_LDAP_PORT_DEFAULT))
                 .setUseSSL(params.getConfigValue(PARAM_USE_SSL, 
PARAM_USE_SSL_DEFAULT))
+                .setUseTLS(params.getConfigValue(PARAM_USE_TLS, 
PARAM_USE_TLS_DEFAULT))
+                .setNoCertCheck(params.getConfigValue(PARAM_NO_CERT_CHECK, 
PARAM_NO_CERT_CHECK_DEFAULT))
                 .setBindDN(params.getConfigValue(PARAM_BIND_DN, 
PARAM_BIND_DN_DEFAULT))
                 .setBindPassword(params.getConfigValue(PARAM_BIND_PASSWORD, 
PARAM_BIND_PASSWORD_DEFAULT))
                 .setSearchTimeout(params.getConfigValue(PARAM_SEARCH_TIMEOUT, 
PARAM_SEARCH_TIMEOUT_DEFAULT))
@@ -519,6 +551,10 @@ public class LdapProviderConfig {
 
     private boolean useSSL = PARAM_USE_SSL_DEFAULT;
 
+    private boolean useTLS = PARAM_USE_TLS_DEFAULT;
+
+    private boolean noCertCheck = PARAM_NO_CERT_CHECK_DEFAULT;
+
     private String bindDN = PARAM_BIND_DN_DEFAULT;
 
     private String bindPassword = PARAM_BIND_PASSWORD_DEFAULT;
@@ -634,6 +670,50 @@ public class LdapProviderConfig {
     }
 
     /**
+     * Configures whether TLS connections should be used.
+     * The default is {@value #PARAM_USE_TLS_DEFAULT}.
+     *
+     * @return {@code true} if TLS should be used.
+     */
+    public boolean useTLS() {
+        return useTLS;
+    }
+
+    /**
+     * Enables TLS connections.
+     * @param useTLS {@code true} to enable TLS
+     * @return {@code this}
+     * @see #useTLS()
+     */
+    @Nonnull
+    public LdapProviderConfig setUseTLS(boolean useTLS) {
+        this.useTLS = useTLS;
+        return this;
+    }
+
+    /**
+     * Configures whether certificates on SSL/TLS connections should be 
validated.
+     * The default is {@value #PARAM_NO_CERT_CHECK_DEFAULT}.
+     *
+     * @return {@code true} if certificates should not be validated
+     */
+    public boolean noCertCheck() {
+        return noCertCheck;
+    }
+
+    /**
+     * Disables certificate validation.
+     * @param noCertCheck {@code true} to disable certificate validation
+     * @return {@code this}
+     * @see #noCertCheck()
+     */
+    @Nonnull
+    public LdapProviderConfig setNoCertCheck(boolean noCertCheck) {
+        this.noCertCheck = noCertCheck;
+        return this;
+    }
+
+    /**
      * Configures the DN that is used to bind to the LDAP server. If this 
value is {@code null} or an empty string,
      * anonymous connections are used.
      * @return the bind DN or {@code null}.

Modified: 
jackrabbit/oak/trunk/oak-auth-ldap/src/main/java/org/apache/jackrabbit/oak/security/authentication/ldap/impl/PoolableUnboundConnectionFactory.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-auth-ldap/src/main/java/org/apache/jackrabbit/oak/security/authentication/ldap/impl/PoolableUnboundConnectionFactory.java?rev=1570090&r1=1570089&r2=1570090&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-auth-ldap/src/main/java/org/apache/jackrabbit/oak/security/authentication/ldap/impl/PoolableUnboundConnectionFactory.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-auth-ldap/src/main/java/org/apache/jackrabbit/oak/security/authentication/ldap/impl/PoolableUnboundConnectionFactory.java
 Thu Feb 20 06:50:09 2014
@@ -19,11 +19,10 @@ package org.apache.jackrabbit.oak.securi
 
 
 import org.apache.commons.pool.PoolableObjectFactory;
+import org.apache.directory.api.ldap.model.exception.LdapException;
 import org.apache.directory.ldap.client.api.LdapConnection;
 import org.apache.directory.ldap.client.api.LdapConnectionConfig;
 import org.apache.directory.ldap.client.api.LdapNetworkConnection;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 
 /**
@@ -32,11 +31,6 @@ import org.slf4j.LoggerFactory;
 public class PoolableUnboundConnectionFactory implements 
PoolableObjectFactory<LdapConnection> {
 
     /**
-     * the logger
-     */
-    private static final Logger log = 
LoggerFactory.getLogger(PoolableUnboundConnectionFactory.class);
-
-    /**
      * configuration object for the connection
      */
     private LdapConnectionConfig config;
@@ -55,7 +49,6 @@ public class PoolableUnboundConnectionFa
      * {@inheritDoc}
      */
     public void activateObject(LdapConnection connection) throws Exception {
-        log.debug("Activating {}", connection);
     }
 
 
@@ -63,7 +56,6 @@ public class PoolableUnboundConnectionFa
      * {@inheritDoc}
      */
     public void destroyObject(LdapConnection connection) throws Exception {
-        log.debug("Destroying {}", connection);
         connection.close();
     }
 
@@ -72,8 +64,9 @@ public class PoolableUnboundConnectionFa
      * {@inheritDoc}
      */
     public LdapConnection makeObject() throws Exception {
-        log.debug("Creating a LDAP connection");
-        LdapNetworkConnection connection = new LdapNetworkConnection(config);
+        LdapNetworkConnection connection = config.isUseTls()
+                ? new TlsGuardingConnection(config)
+                : new LdapNetworkConnection(config);
         connection.connect();
         return connection;
     }
@@ -83,7 +76,6 @@ public class PoolableUnboundConnectionFa
      * {@inheritDoc}
      */
     public void passivateObject(LdapConnection connection) throws Exception {
-        log.debug("Passivating {}", connection);
     }
 
 
@@ -91,7 +83,30 @@ public class PoolableUnboundConnectionFa
      * {@inheritDoc}
      */
     public boolean validateObject(LdapConnection connection) {
-        log.debug("Validating {}", connection);
         return connection.isConnected();
     }
+
+    /**
+     * internal helper class that guards the original ldap connection from 
starting TLS if already started..
+     * this is to ensure that pooled connections can be 'bind()' several times.
+     *
+     * @see 
org.apache.directory.ldap.client.api.LdapNetworkConnection#bindAsync(org.apache.directory.api.ldap.model.message.BindRequest)
+     */
+    private static class TlsGuardingConnection extends LdapNetworkConnection {
+
+        private boolean tlsStarted;
+
+        private TlsGuardingConnection(LdapConnectionConfig config) {
+            super(config);
+        }
+
+        @Override
+        public void startTls() throws LdapException {
+            if (tlsStarted) {
+                return;
+            }
+            super.startTls();
+            tlsStarted = true;
+        }
+    }
 }


Reply via email to