You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@karaf.apache.org by jb...@apache.org on 2016/08/22 09:30:12 UTC

[14/50] [abbrv] karaf git commit: [KARAF-4607] Fix pooling scenarion with ldaps:// and default Sun provider

[KARAF-4607] Fix pooling scenarion with ldaps:// and default Sun provider

(cherry picked from commit a0bb5cf1debff797ccd4da471ce12663c17bfbfe)


Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/b317effe
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/b317effe
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/b317effe

Branch: refs/heads/master
Commit: b317effe18a3e254979a815c66461fe51b544d46
Parents: 92b2f06
Author: Grzegorz Grzybek <gr...@gmail.com>
Authored: Tue Jul 5 09:28:29 2016 +0200
Committer: Jean-Baptiste Onofr� <jb...@apache.org>
Committed: Mon Aug 22 11:29:19 2016 +0200

----------------------------------------------------------------------
 jaas/modules/pom.xml                            |   5 +
 .../karaf/jaas/modules/ldap/LDAPOptions.java    |   2 +-
 .../modules/ldap/ManagedSSLSocketFactory.java   |  68 +++++++++-
 .../jaas/modules/ldap/LdapPoolingTest.java      | 136 +++++++++++++++++++
 .../apache/karaf/jaas/modules/ldap/ldaps.jks    | Bin 0 -> 1295 bytes
 5 files changed, 209 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/karaf/blob/b317effe/jaas/modules/pom.xml
----------------------------------------------------------------------
diff --git a/jaas/modules/pom.xml b/jaas/modules/pom.xml
index 6550ccc..54ca79a 100644
--- a/jaas/modules/pom.xml
+++ b/jaas/modules/pom.xml
@@ -65,6 +65,11 @@
             <artifactId>slf4j-api</artifactId>
             <scope>provided</scope>
         </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-log4j12</artifactId>
+            <scope>test</scope>
+        </dependency>
 
         <dependency>
             <groupId>org.osgi</groupId>

http://git-wip-us.apache.org/repos/asf/karaf/blob/b317effe/jaas/modules/src/main/java/org/apache/karaf/jaas/modules/ldap/LDAPOptions.java
----------------------------------------------------------------------
diff --git a/jaas/modules/src/main/java/org/apache/karaf/jaas/modules/ldap/LDAPOptions.java b/jaas/modules/src/main/java/org/apache/karaf/jaas/modules/ldap/LDAPOptions.java
index 3342636..390cbb3 100644
--- a/jaas/modules/src/main/java/org/apache/karaf/jaas/modules/ldap/LDAPOptions.java
+++ b/jaas/modules/src/main/java/org/apache/karaf/jaas/modules/ldap/LDAPOptions.java
@@ -172,7 +172,7 @@ public class LDAPOptions {
             SSLSocketFactory factory = manager.createSSLFactory(
                     getSslProvider(), getSslProtocol(), getSslAlgorithm(), getSslKeystore(),
                     getSslKeyAlias(), getSslTrustStore(), getSslTimeout());
-            ManagedSSLSocketFactory.setSocketFactory(factory);
+            ManagedSSLSocketFactory.setSocketFactory(new ManagedSSLSocketFactory(factory));
             Thread.currentThread().setContextClassLoader(ManagedSSLSocketFactory.class.getClassLoader());
         } catch (Exception e) {
             throw new NamingException("Unable to setup SSL support for LDAP: " + e.getMessage());

http://git-wip-us.apache.org/repos/asf/karaf/blob/b317effe/jaas/modules/src/main/java/org/apache/karaf/jaas/modules/ldap/ManagedSSLSocketFactory.java
----------------------------------------------------------------------
diff --git a/jaas/modules/src/main/java/org/apache/karaf/jaas/modules/ldap/ManagedSSLSocketFactory.java b/jaas/modules/src/main/java/org/apache/karaf/jaas/modules/ldap/ManagedSSLSocketFactory.java
index c7593ce..3796068 100644
--- a/jaas/modules/src/main/java/org/apache/karaf/jaas/modules/ldap/ManagedSSLSocketFactory.java
+++ b/jaas/modules/src/main/java/org/apache/karaf/jaas/modules/ldap/ManagedSSLSocketFactory.java
@@ -14,9 +14,13 @@
  */
 package org.apache.karaf.jaas.modules.ldap;
 
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.util.Comparator;
 import javax.net.ssl.SSLSocketFactory;
 
-public abstract class ManagedSSLSocketFactory extends SSLSocketFactory {
+public class ManagedSSLSocketFactory extends SSLSocketFactory implements Comparator<Object> {
 
     private static final ThreadLocal<SSLSocketFactory> factories = new ThreadLocal<SSLSocketFactory>();
 
@@ -32,4 +36,66 @@ public abstract class ManagedSSLSocketFactory extends SSLSocketFactory {
         return factory;
     }
 
+    private SSLSocketFactory delegate;
+
+    // When <code>java.naming.ldap.factory.socket</code> property configures custom
+    // {@link SSLSocketFactory}, LdapCtx invokes special compare method to enable pooling.
+
+    public ManagedSSLSocketFactory(SSLSocketFactory delegate) {
+        this.delegate = delegate;
+    }
+
+    public String[] getDefaultCipherSuites() {
+        return delegate.getDefaultCipherSuites();
+    }
+
+    public String[] getSupportedCipherSuites() {
+        return delegate.getSupportedCipherSuites();
+    }
+
+    public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
+        return delegate.createSocket(s, host, port, autoClose);
+    }
+
+    public Socket createSocket(String host, int port) throws IOException {
+        return delegate.createSocket(host, port);
+    }
+
+    public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException {
+        return delegate.createSocket(host, port, localHost, localPort);
+    }
+
+    public Socket createSocket(InetAddress host, int port) throws IOException {
+        return delegate.createSocket(host, port);
+    }
+
+    public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
+        return delegate.createSocket(address, port, localAddress, localPort);
+    }
+
+    /**
+     * For com.sun.jndi.ldap.ClientId#invokeComparator(com.sun.jndi.ldap.ClientId, com.sun.jndi.ldap.ClientId)
+     * @param f1
+     * @param f2
+     * @return
+     */
+    public int compare(Object f1, Object f2) {
+        if (f1 == null && f2 == null) {
+            return 0;
+        }
+        if (f1 == null) {
+            return 1;
+        }
+        if (f2 == null) {
+            return -1;
+        }
+        // com.sun.jndi.ldap.ClientId#invokeComparator() passes com.sun.jndi.ldap.ClientId.socketFactory as f1 and f2
+        // these are String values
+        if (f1 instanceof String && f2 instanceof String) {
+            return ((String) f1).compareTo((String) f2);
+        }
+        // fallback to undefined behavior
+        return f1.toString().compareTo(f2.toString());
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/karaf/blob/b317effe/jaas/modules/src/test/java/org/apache/karaf/jaas/modules/ldap/LdapPoolingTest.java
----------------------------------------------------------------------
diff --git a/jaas/modules/src/test/java/org/apache/karaf/jaas/modules/ldap/LdapPoolingTest.java b/jaas/modules/src/test/java/org/apache/karaf/jaas/modules/ldap/LdapPoolingTest.java
new file mode 100644
index 0000000..cdedc75
--- /dev/null
+++ b/jaas/modules/src/test/java/org/apache/karaf/jaas/modules/ldap/LdapPoolingTest.java
@@ -0,0 +1,136 @@
+/*
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *  under the License.
+ */
+package org.apache.karaf.jaas.modules.ldap;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.net.Socket;
+import java.security.KeyStore;
+import java.security.SecureRandom;
+import java.util.Hashtable;
+import javax.naming.directory.InitialDirContext;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManagerFactory;
+
+import org.apache.directory.server.annotations.CreateLdapServer;
+import org.apache.directory.server.annotations.CreateTransport;
+import org.apache.directory.server.core.annotations.ApplyLdifFiles;
+import org.apache.directory.server.core.annotations.CreateDS;
+import org.apache.directory.server.core.annotations.CreatePartition;
+import org.apache.directory.server.core.integ.AbstractLdapTestUnit;
+import org.apache.directory.server.core.integ.FrameworkRunner;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.junit.Assert.assertThat;
+
+@RunWith ( FrameworkRunner.class )
+@CreateLdapServer(transports = {@CreateTransport(protocol = "LDAPS", ssl = true)},
+ keyStore = "src/test/resources/org/apache/karaf/jaas/modules/ldap/ldaps.jks", certificatePassword = "123456")
+@CreateDS(name = "LdapPoolingTest-class",
+ partitions = { @CreatePartition(name = "example", suffix = "dc=example,dc=com") })
+@ApplyLdifFiles(
+   "org/apache/karaf/jaas/modules/ldap/example.com.ldif"
+)
+public class LdapPoolingTest extends AbstractLdapTestUnit {
+
+    private SSLContext sslContext;
+
+    @Before
+    public void keystore() throws Exception {
+        KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
+        TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
+        KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
+        ks.load(new FileInputStream("src/test/resources/org/apache/karaf/jaas/modules/ldap/ldaps.jks"), "123456".toCharArray());
+        kmf.init(ks, "123456".toCharArray());
+        tmf.init(ks);
+
+        sslContext = SSLContext.getInstance("TLSv1.2");
+        sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), new SecureRandom());
+    }
+
+    /**
+     * @see <a href="http://docs.oracle.com/javase/jndi/tutorial/ldap/connect/config.html">LDAP connection pool</a>
+     * @throws Exception
+     */
+    @Test
+    public void testSSLConnectionPool() throws Exception {
+        System.setProperty("com.sun.jndi.ldap.connect.pool.maxsize", "2");
+        System.setProperty("com.sun.jndi.ldap.connect.pool.protocol", "ssl");
+        System.setProperty("com.sun.jndi.ldap.connect.pool.debug", "all");
+        Hashtable<String, String> env = new Hashtable<String, String>();
+        env.put("com.sun.jndi.ldap.connect.pool", "true");
+        env.put("java.naming.factory.initial", "com.sun.jndi.ldap.LdapCtxFactory");
+        env.put("java.naming.provider.url", "ldaps://localhost:" + getLdapServer().getPortSSL() + "/ou=system");
+        env.put("java.naming.ldap.factory.socket", ManagedSSLSocketFactory.class.getName());
+        env.put("java.naming.security.protocol", "ssl");
+        env.put("java.naming.security.principal", "uid=admin,ou=system");
+        env.put("java.naming.security.credentials", "secret");
+        env.put("java.naming.security.authentication", "simple");
+
+        final int[] socketsCreated = new int[] { 0 };
+        ManagedSSLSocketFactory.setSocketFactory(new ManagedSSLSocketFactory(sslContext.getSocketFactory()) {
+            @Override
+            public Socket createSocket(String host, int port) throws IOException {
+                socketsCreated[0]++;
+                return super.createSocket(host, port);
+            }
+        });
+        InitialDirContext context = new InitialDirContext(env);
+        context.close();
+        new InitialDirContext(env);
+        context.close();
+        ManagedSSLSocketFactory.setSocketFactory(null);
+
+        assertThat(socketsCreated[0], equalTo(1));
+    }
+
+    @Test
+    public void testSSLConnectionWithoutPool() throws Exception {
+        System.setProperty("com.sun.jndi.ldap.connect.pool.maxsize", "2");
+        System.setProperty("com.sun.jndi.ldap.connect.pool.protocol", "ssl");
+        System.setProperty("com.sun.jndi.ldap.connect.pool.debug", "all");
+        Hashtable<String, String> env = new Hashtable<String, String>();
+        env.put("com.sun.jndi.ldap.connect.pool", "false");
+        env.put("java.naming.factory.initial", "com.sun.jndi.ldap.LdapCtxFactory");
+        env.put("java.naming.provider.url", "ldaps://localhost:" + getLdapServer().getPortSSL() + "/ou=system");
+        env.put("java.naming.ldap.factory.socket", ManagedSSLSocketFactory.class.getName());
+        env.put("java.naming.security.protocol", "ssl");
+        env.put("java.naming.security.principal", "uid=admin,ou=system");
+        env.put("java.naming.security.credentials", "secret");
+        env.put("java.naming.security.authentication", "simple");
+
+        final int[] socketsCreated = new int[] { 0 };
+        ManagedSSLSocketFactory.setSocketFactory(new ManagedSSLSocketFactory(sslContext.getSocketFactory()) {
+            @Override
+            public Socket createSocket(String host, int port) throws IOException {
+                socketsCreated[0]++;
+                return super.createSocket(host, port);
+            }
+        });
+        InitialDirContext context = new InitialDirContext(env);
+        context.close();
+        new InitialDirContext(env);
+        context.close();
+        ManagedSSLSocketFactory.setSocketFactory(null);
+
+        assertThat(socketsCreated[0], equalTo(2));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/karaf/blob/b317effe/jaas/modules/src/test/resources/org/apache/karaf/jaas/modules/ldap/ldaps.jks
----------------------------------------------------------------------
diff --git a/jaas/modules/src/test/resources/org/apache/karaf/jaas/modules/ldap/ldaps.jks b/jaas/modules/src/test/resources/org/apache/karaf/jaas/modules/ldap/ldaps.jks
new file mode 100644
index 0000000..c2e95aa
Binary files /dev/null and b/jaas/modules/src/test/resources/org/apache/karaf/jaas/modules/ldap/ldaps.jks differ