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;
+ }
+ }
}