You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by kw...@apache.org on 2013/10/21 13:48:53 UTC

svn commit: r1534105 - in /qpid/trunk/qpid/java: ./ broker-core/ broker-core/src/main/java/org/apache/qpid/server/configuration/startup/ broker-core/src/main/java/org/apache/qpid/server/model/adapter/ broker-core/src/main/java/org/apache/qpid/server/pl...

Author: kwall
Date: Mon Oct 21 11:48:52 2013
New Revision: 1534105

URL: http://svn.apache.org/r1534105
Log:
QPID-4463: [Java Broker] Change SimpleLDAPAuthManager to accept trust store model object in order to conveniently connect to a Directory secured by certificate signed by private-CA (or using self-signed cert).

* SimpleLDAPAuthManager can be associated with a truststore model object via the
* SSLSocketFactory classes generated on the fly (associated with the truststore) in order to work around limitations in the javax.naming API.
* In the Management UI, the user currently needs to enter the name of the truststore configured object (rather than select from a dropdown)

Added:
    qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/ldap/
    qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/ldap/AbstractLDAPSSLSocketFactory.java
    qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/ldap/LDAPSSLSocketFactoryGenerator.java
    qpid/trunk/qpid/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/ldap/
    qpid/trunk/qpid/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/ldap/LDAPSSLSocketFactoryGeneratorTest.java
    qpid/trunk/qpid/java/lib/poms/bcel-5.2.xml
Modified:
    qpid/trunk/qpid/java/broker-core/pom.xml
    qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/configuration/startup/BrokerRecoverer.java
    qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderAdapter.java
    qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderFactory.java
    qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/plugin/AuthenticationManagerFactory.java
    qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/AbstractPrincipalDatabaseAuthManagerFactory.java
    qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/AnonymousAuthenticationManagerFactory.java
    qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManagerFactory.java
    qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/KerberosAuthenticationManagerFactory.java
    qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManager.java
    qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManagerFactory.java
    qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationProviderAttributeDescriptions.properties
    qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/util/StringUtil.java
    qpid/trunk/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/adapter/AuthenticationProviderFactoryTest.java
    qpid/trunk/qpid/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/Base64MD5PasswordFileAuthenticationManagerFactoryTest.java
    qpid/trunk/qpid/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/PlainPasswordFileAuthenticationManagerFactoryTest.java
    qpid/trunk/qpid/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManagerFactoryTest.java
    qpid/trunk/qpid/java/broker-core/src/test/java/org/apache/qpid/server/util/StringUtilTest.java
    qpid/trunk/qpid/java/build.deps
    qpid/trunk/qpid/java/ivy.retrieve.xml

Modified: qpid/trunk/qpid/java/broker-core/pom.xml
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-core/pom.xml?rev=1534105&r1=1534104&r2=1534105&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker-core/pom.xml (original)
+++ qpid/trunk/qpid/java/broker-core/pom.xml Mon Oct 21 11:48:52 2013
@@ -147,6 +147,20 @@
       <scope>compile</scope>
     </dependency>
 
+    <dependency>
+      <groupId>org.apache.bcel</groupId>
+      <artifactId>bcel</artifactId>
+      <version>5.2</version>
+      <scope>compile</scope>
+      <exclusions>
+        <exclusion>
+          <!--  Qpid doesn't require BCEL InstructionFinder, so does not need jakarta-regexp. -->
+          <artifactId>jakarta-regexp</artifactId>
+          <groupId>jakarta-regexp</groupId>
+        </exclusion>
+      </exclusions>
+    </dependency>
+
      <!-- test dependencies -->
      <dependency>
       <groupId>org.apache.qpid</groupId>

Modified: qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/configuration/startup/BrokerRecoverer.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/configuration/startup/BrokerRecoverer.java?rev=1534105&r1=1534104&r2=1534105&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/configuration/startup/BrokerRecoverer.java (original)
+++ qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/configuration/startup/BrokerRecoverer.java Mon Oct 21 11:48:52 2013
@@ -21,10 +21,14 @@
 package org.apache.qpid.server.configuration.startup;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.regex.Pattern;
 
 import org.apache.qpid.server.BrokerOptions;
@@ -88,7 +92,6 @@ public class BrokerRecoverer implements 
     @Override
     public Broker create(RecovererProvider recovererProvider, ConfigurationEntry entry, ConfiguredObject... parents)
     {
-        //Map<String, Object> attributes = entry.getAttributes();
         Map<String, Object> attributesCopy = validateAttributes(entry);
 
         attributesCopy.put(Broker.MODEL_VERSION, Model.MODEL_VERSION);
@@ -99,29 +102,11 @@ public class BrokerRecoverer implements 
 
         broker.addChangeListener(_storeChangeListener);
 
-        //Recover the SSL keystores / truststores first, then others that depend on them
         Map<String, Collection<ConfigurationEntry>> childEntries = new HashMap<String, Collection<ConfigurationEntry>>(entry.getChildren());
-        Map<String, Collection<ConfigurationEntry>> priorityChildEntries = new HashMap<String, Collection<ConfigurationEntry>>(childEntries);
-        List<String> types = new ArrayList<String>(childEntries.keySet());
 
-        for(String type : types)
-        {
-            if(KeyStore.class.getSimpleName().equals(type) || TrustStore.class.getSimpleName().equals(type)
-                        || AuthenticationProvider.class.getSimpleName().equals(type))
-            {
-                childEntries.remove(type);
-            }
-            else
-            {
-                priorityChildEntries.remove(type);
-            }
-        }
+        List<String> types = makePrioritisedListOfTypes(childEntries.keySet(), TrustStore.class.getSimpleName(), KeyStore.class.getSimpleName(), AuthenticationProvider.class.getSimpleName());
 
-        for (String type : priorityChildEntries.keySet())
-        {
-            recoverType(recovererProvider, _storeChangeListener, broker, priorityChildEntries, type);
-        }
-        for (String type : childEntries.keySet())
+        for (String type : types)
         {
             recoverType(recovererProvider, _storeChangeListener, broker, childEntries, type);
         }
@@ -129,6 +114,24 @@ public class BrokerRecoverer implements 
         return broker;
     }
 
+    private List<String> makePrioritisedListOfTypes(Set<String> allTypes, String... priorityOrderedTypes)
+    {
+        List<String> prioritisedList = new ArrayList<String>(allTypes.size());
+        Set<String> remainder = new HashSet<String>(allTypes);
+
+        for (String type : priorityOrderedTypes)
+        {
+            Set<String> singleton = Collections.singleton(type);
+            Set<String> intersection = new HashSet<String>(allTypes);
+            intersection.retainAll(singleton);
+            remainder.removeAll(singleton);
+            prioritisedList.addAll(intersection);
+        }
+
+        prioritisedList.addAll(remainder);
+        return prioritisedList;
+    }
+
     private Map<String, Object> validateAttributes(ConfigurationEntry entry)
     {
         Map<String, Object> attributes = entry.getAttributes();

Modified: qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderAdapter.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderAdapter.java?rev=1534105&r1=1534104&r2=1534105&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderAdapter.java (original)
+++ qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderAdapter.java Mon Oct 21 11:48:52 2013
@@ -379,7 +379,7 @@ public abstract class AuthenticationProv
         {
             throw new IllegalConfigurationException("Cannot find authentication provider factory for type " + newType);
         }
-        AuthenticationManager manager = managerFactory.createInstance(attributes);
+        AuthenticationManager manager = managerFactory.createInstance(_broker, attributes);
         if (manager == null)
         {
             throw new IllegalConfigurationException("Cannot change authentication provider " + newName + " of type " + newType + " with the given attributes");

Modified: qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderFactory.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderFactory.java?rev=1534105&r1=1534104&r2=1534105&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderFactory.java (original)
+++ qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderFactory.java Mon Oct 21 11:48:52 2013
@@ -80,7 +80,7 @@ public class AuthenticationProviderFacto
     {
         for (AuthenticationManagerFactory factory : _factories)
         {
-            AuthenticationManager manager = factory.createInstance(attributes);
+            AuthenticationManager manager = factory.createInstance(broker, attributes);
             if (manager != null)
             {
                 AuthenticationProviderAdapter<?> authenticationProvider;

Modified: qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/plugin/AuthenticationManagerFactory.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/plugin/AuthenticationManagerFactory.java?rev=1534105&r1=1534104&r2=1534105&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/plugin/AuthenticationManagerFactory.java (original)
+++ qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/plugin/AuthenticationManagerFactory.java Mon Oct 21 11:48:52 2013
@@ -22,6 +22,7 @@ import java.util.Collection;
 import java.util.Map;
 
 import org.apache.qpid.server.model.AuthenticationProvider;
+import org.apache.qpid.server.model.Broker;
 import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
 
 public interface AuthenticationManagerFactory extends Pluggable
@@ -36,15 +37,17 @@ public interface AuthenticationManagerFa
 
     /**
      * Creates authentication manager from the provided attributes
-     *
+     * @param broker
+     *            broker model object
      * @param attributes
      *            attributes to create authentication manager
+     *
      * @return authentication manager instance
      */
-    AuthenticationManager createInstance(Map<String, Object> attributes);
+    AuthenticationManager createInstance(Broker broker, Map<String, Object> attributes);
 
     /**
-     * Get the names of attributes the authentication manager which can be passed into {@link #createInstance(Map)} to create the
+     * Get the names of attributes the authentication manager which can be passed into {@link #createInstance(Broker, Map)} to create the
      * authentication manager
      *
      * @return the collection of attribute names

Modified: qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/AbstractPrincipalDatabaseAuthManagerFactory.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/AbstractPrincipalDatabaseAuthManagerFactory.java?rev=1534105&r1=1534104&r2=1534105&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/AbstractPrincipalDatabaseAuthManagerFactory.java (original)
+++ qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/AbstractPrincipalDatabaseAuthManagerFactory.java Mon Oct 21 11:48:52 2013
@@ -25,6 +25,7 @@ import java.util.Collections;
 import java.util.Map;
 
 import org.apache.log4j.Logger;
+import org.apache.qpid.server.model.Broker;
 import org.apache.qpid.server.plugin.AuthenticationManagerFactory;
 import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
 
@@ -46,7 +47,7 @@ public abstract class AbstractPrincipalD
 
 
     @Override
-    public AuthenticationManager createInstance(Map<String, Object> attributes)
+    public AuthenticationManager createInstance(Broker broker, Map<String, Object> attributes)
     {
         if (attributes == null || !getType().equals(attributes.get(ATTRIBUTE_TYPE)))
         {

Modified: qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/AnonymousAuthenticationManagerFactory.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/AnonymousAuthenticationManagerFactory.java?rev=1534105&r1=1534104&r2=1534105&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/AnonymousAuthenticationManagerFactory.java (original)
+++ qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/AnonymousAuthenticationManagerFactory.java Mon Oct 21 11:48:52 2013
@@ -23,6 +23,7 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.Map;
 
+import org.apache.qpid.server.model.Broker;
 import org.apache.qpid.server.plugin.AuthenticationManagerFactory;
 
 public class AnonymousAuthenticationManagerFactory implements AuthenticationManagerFactory
@@ -30,7 +31,7 @@ public class AnonymousAuthenticationMana
     public static final String PROVIDER_TYPE = "Anonymous";
 
     @Override
-    public AuthenticationManager createInstance(Map<String, Object> attributes)
+    public AuthenticationManager createInstance(Broker broker, Map<String, Object> attributes)
     {
         if (attributes != null && PROVIDER_TYPE.equals(attributes.get(ATTRIBUTE_TYPE)))
         {

Modified: qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManagerFactory.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManagerFactory.java?rev=1534105&r1=1534104&r2=1534105&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManagerFactory.java (original)
+++ qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManagerFactory.java Mon Oct 21 11:48:52 2013
@@ -24,6 +24,7 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.Map;
 
+import org.apache.qpid.server.model.Broker;
 import org.apache.qpid.server.plugin.AuthenticationManagerFactory;
 import org.apache.qpid.server.util.ResourceBundleLoader;
 
@@ -38,7 +39,7 @@ public class ExternalAuthenticationManag
             ATTRIBUTE_USE_FULL_DN));
 
     @Override
-    public AuthenticationManager createInstance(Map<String, Object> attributes)
+    public AuthenticationManager createInstance(Broker broker, Map<String, Object> attributes)
     {
         if (attributes != null && PROVIDER_TYPE.equals(attributes.get(ATTRIBUTE_TYPE)))
         {

Modified: qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/KerberosAuthenticationManagerFactory.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/KerberosAuthenticationManagerFactory.java?rev=1534105&r1=1534104&r2=1534105&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/KerberosAuthenticationManagerFactory.java (original)
+++ qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/KerberosAuthenticationManagerFactory.java Mon Oct 21 11:48:52 2013
@@ -23,6 +23,7 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.Map;
 
+import org.apache.qpid.server.model.Broker;
 import org.apache.qpid.server.plugin.AuthenticationManagerFactory;
 
 public class KerberosAuthenticationManagerFactory implements AuthenticationManagerFactory
@@ -30,7 +31,7 @@ public class KerberosAuthenticationManag
     public static final String PROVIDER_TYPE = "Kerberos";
 
     @Override
-    public AuthenticationManager createInstance(Map<String, Object> attributes)
+    public AuthenticationManager createInstance(Broker broker, Map<String, Object> attributes)
     {
         if (attributes != null && PROVIDER_TYPE.equals(attributes.get(ATTRIBUTE_TYPE)))
         {

Modified: qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManager.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManager.java?rev=1534105&r1=1534104&r2=1534105&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManager.java (original)
+++ qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManager.java Mon Oct 21 11:48:52 2013
@@ -27,10 +27,11 @@ import javax.naming.AuthenticationExcept
 import javax.naming.Context;
 import javax.naming.NamingEnumeration;
 import javax.naming.NamingException;
-import javax.naming.directory.DirContext;
 import javax.naming.directory.InitialDirContext;
 import javax.naming.directory.SearchControls;
 import javax.naming.directory.SearchResult;
+import javax.net.SocketFactory;
+import javax.net.ssl.SSLContext;
 import javax.security.auth.callback.Callback;
 import javax.security.auth.callback.CallbackHandler;
 import javax.security.auth.callback.NameCallback;
@@ -38,35 +39,63 @@ import javax.security.auth.callback.Unsu
 import javax.security.sasl.AuthorizeCallback;
 import javax.security.sasl.SaslException;
 import javax.security.sasl.SaslServer;
+
 import org.apache.log4j.Logger;
+import org.apache.qpid.server.model.TrustStore;
 import org.apache.qpid.server.security.auth.AuthenticationResult;
 import org.apache.qpid.server.security.auth.AuthenticationResult.AuthenticationStatus;
 import org.apache.qpid.server.security.auth.UsernamePrincipal;
+import org.apache.qpid.server.security.auth.manager.ldap.AbstractLDAPSSLSocketFactory;
+import org.apache.qpid.server.security.auth.manager.ldap.LDAPSSLSocketFactoryGenerator;
 import org.apache.qpid.server.security.auth.sasl.plain.PlainPasswordCallback;
 import org.apache.qpid.server.security.auth.sasl.plain.PlainSaslServer;
+import org.apache.qpid.server.util.StringUtil;
+import org.apache.qpid.ssl.SSLContextFactory;
 
 public class SimpleLDAPAuthenticationManager implements AuthenticationManager
 {
     private static final Logger _logger = Logger.getLogger(SimpleLDAPAuthenticationManager.class);
 
+    /**
+     * Environment key to instruct {@link InitialDirContext} to override the socket factory.
+     */
+    private static final String JAVA_NAMING_LDAP_FACTORY_SOCKET = "java.naming.ldap.factory.socket";
+
+    private final String _authManagerName;
     private final String _providerSearchURL;
     private final String _providerAuthURL;
     private final String _searchContext;
     private final String _searchFilter;
     private final String _ldapContextFactory;
 
-    SimpleLDAPAuthenticationManager(String providerSearchUrl, String providerAuthUrl, String searchContext, String searchFilter, String ldapContextFactory)
+    /**
+     * Trust store - typically used when the Directory has been secured with a certificate signed by a
+     * private CA (or self-signed certificate).
+     */
+    private final TrustStore _trustStore;
+
+    /**
+     * Dynamically created SSL Socket Factory implementation used in the case where user has specified a trust store.
+     */
+    private Class<? extends SocketFactory> _sslSocketFactoryOverride;
+
+
+    SimpleLDAPAuthenticationManager(String authManagerName, String providerSearchUrl, String providerAuthUrl, String searchContext, String searchFilter, String ldapContextFactory, TrustStore trustStore)
     {
+        _authManagerName = authManagerName;
         _providerSearchURL = providerSearchUrl;
         _providerAuthURL = providerAuthUrl;
         _searchContext = searchContext;
         _searchFilter = searchFilter;
         _ldapContextFactory = ldapContextFactory;
+        _trustStore = trustStore;
     }
 
     @Override
     public void initialise()
     {
+        _sslSocketFactoryOverride = createSslSocketFactoryOverride();
+
         validateInitialDirContext();
     }
 
@@ -145,19 +174,16 @@ public class SimpleLDAPAuthenticationMan
             return new AuthenticationResult(AuthenticationStatus.CONTINUE);
         }
 
-        Hashtable<Object,Object> env = new Hashtable<Object,Object>();
-        env.put(Context.INITIAL_CONTEXT_FACTORY, _ldapContextFactory);
-        env.put(Context.PROVIDER_URL, _providerAuthURL);
+        Hashtable<String, Object> env = createInitialDirContentEnvironment(_providerAuthURL);
 
         env.put(Context.SECURITY_AUTHENTICATION, "simple");
-
         env.put(Context.SECURITY_PRINCIPAL, name);
         env.put(Context.SECURITY_CREDENTIALS, password);
 
-        DirContext ctx = null;
+        InitialDirContext ctx = null;
         try
         {
-            ctx = new InitialDirContext(env);
+            ctx = createInitialDirContext(env);
 
             //Authentication succeeded
             return new AuthenticationResult(new UsernamePrincipal(name));
@@ -176,14 +202,7 @@ public class SimpleLDAPAuthenticationMan
         {
             if(ctx != null)
             {
-                try
-                {
-                    ctx.close();
-                }
-                catch (Exception e)
-                {
-                    _logger.warn("Exception closing InitialDirContext", e);
-                }
+                closeSafely(ctx);
             }
         }
     }
@@ -193,26 +212,94 @@ public class SimpleLDAPAuthenticationMan
     {
     }
 
-    private void validateInitialDirContext()
+    private Hashtable<String, Object> createInitialDirContentEnvironment(String providerUrl)
     {
-        Hashtable<String,Object> env = new Hashtable<String, Object>();
+        Hashtable<String,Object> env = new Hashtable<String,Object>();
         env.put(Context.INITIAL_CONTEXT_FACTORY, _ldapContextFactory);
-        env.put(Context.PROVIDER_URL, _providerSearchURL);
+        env.put(Context.PROVIDER_URL, providerUrl);
+        return env;
+    }
+
+    private InitialDirContext createInitialDirContext(Hashtable<String, Object> env) throws NamingException
+    {
+        ClassLoader existingContextClassloader = null;
+
+        boolean isLdaps = ((String)env.get(Context.PROVIDER_URL)).startsWith("ldaps:");
+
+        boolean revertContentClassLoader = false;
+        try
+        {
+            if (isLdaps && _sslSocketFactoryOverride != null)
+            {
+                existingContextClassloader = Thread.currentThread().getContextClassLoader();
+                env.put(JAVA_NAMING_LDAP_FACTORY_SOCKET, _sslSocketFactoryOverride.getName());
+                Thread.currentThread().setContextClassLoader(_sslSocketFactoryOverride.getClassLoader());
+                revertContentClassLoader = true;
+            }
+            return new InitialDirContext(env);
+        }
+        finally
+        {
+            if (revertContentClassLoader)
+            {
+                Thread.currentThread().setContextClassLoader(existingContextClassloader);
+            }
+        }
+    }
+
+    /**
+     * If a trust store has been specified, create a {@link SSLContextFactory} class that is
+     * associated with the {@link SSLContext} generated from that trust store.
+     *
+     * @return generated socket factory class
+     */
+    private Class<? extends SocketFactory> createSslSocketFactoryOverride()
+    {
+        if (_trustStore != null)
+        {
+            String clazzName = new StringUtil().createUniqueJavaName(_authManagerName);
+            SSLContext sslContext = null;
+            try
+            {
+                sslContext = SSLContext.getInstance("TLS");
+                sslContext.init(null, _trustStore.getTrustManagers(), null);
+            }
+            catch (Exception e)
+            {
+                _logger.error("Exception creating SSLContext", e);
+                throw new RuntimeException(e);
+            }
+            Class<? extends AbstractLDAPSSLSocketFactory> clazz = LDAPSSLSocketFactoryGenerator.createSubClass(clazzName, sslContext.getSocketFactory());
+            _logger.debug("Connection to Directory will use custom SSL socket factory : " +  clazz);
+            return clazz;
+        }
+
+        return null;
+    }
+
+    private void validateInitialDirContext()
+    {
+        Hashtable<String,Object> env = createInitialDirContentEnvironment(_providerSearchURL);
         env.put(Context.SECURITY_AUTHENTICATION, "none");
 
+        InitialDirContext ctx = null;
         try
         {
-            new InitialDirContext(env).close();
+            ctx = createInitialDirContext(env);
         }
         catch (NamingException e)
         {
             throw new RuntimeException("Unable to establish anonymous connection to the ldap server at " + _providerSearchURL, e);
         }
+        finally
+        {
+            closeSafely(ctx);
+        }
     }
 
+
     private class SimpleLDAPPlainCallbackHandler implements CallbackHandler
     {
-
         @Override
         public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException
         {
@@ -263,14 +350,10 @@ public class SimpleLDAPAuthenticationMan
 
     private String getNameFromId(String id) throws NamingException
     {
-        Hashtable<Object,Object> env = new Hashtable<Object,Object>();
-        env.put(Context.INITIAL_CONTEXT_FACTORY, _ldapContextFactory);
-        env.put(Context.PROVIDER_URL, _providerSearchURL);
+        Hashtable<String,Object> env = createInitialDirContentEnvironment(_providerSearchURL);
 
         env.put(Context.SECURITY_AUTHENTICATION, "none");
-        DirContext ctx = null;
-
-        ctx = new InitialDirContext(env);
+        InitialDirContext ctx = createInitialDirContext(env);
 
         try
         {
@@ -291,18 +374,23 @@ public class SimpleLDAPAuthenticationMan
         }
         finally
         {
-            try
-            {
-                ctx.close();
-            }
-            catch (Exception e)
-            {
-                _logger.warn("Exception closing InitialDirContext", e);
-            }
+            closeSafely(ctx);
         }
 
     }
 
+    private void closeSafely(InitialDirContext ctx)
+    {
+        try
+        {
+            ctx.close();
+        }
+        catch (Exception e)
+        {
+            _logger.warn("Exception closing InitialDirContext", e);
+        }
+    }
+
     @Override
     public void onCreate()
     {

Modified: qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManagerFactory.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManagerFactory.java?rev=1534105&r1=1534104&r2=1534105&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManagerFactory.java (original)
+++ qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManagerFactory.java Mon Oct 21 11:48:52 2013
@@ -24,6 +24,9 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.Map;
 
+import org.apache.qpid.server.configuration.IllegalConfigurationException;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.TrustStore;
 import org.apache.qpid.server.plugin.AuthenticationManagerFactory;
 import org.apache.qpid.server.util.ResourceBundleLoader;
 
@@ -34,9 +37,11 @@ public class SimpleLDAPAuthenticationMan
 
     public static final String PROVIDER_TYPE = "SimpleLDAP";
 
+    public static final String ATTRIBUTE_NAME = "name";
     public static final String ATTRIBUTE_LDAP_CONTEXT_FACTORY = "ldapContextFactory";
     public static final String ATTRIBUTE_SEARCH_FILTER = "searchFilter";
     public static final String ATTRIBUTE_SEARCH_CONTEXT = "searchContext";
+    public static final String ATTRIBUTE_TRUST_STORE = "trustStore";
     public static final String ATTRIBUTE_PROVIDER_AUTH_URL = "providerAuthUrl";
     public static final String ATTRIBUTE_PROVIDER_URL = "providerUrl";
 
@@ -45,19 +50,23 @@ public class SimpleLDAPAuthenticationMan
             ATTRIBUTE_PROVIDER_URL,
             ATTRIBUTE_SEARCH_CONTEXT,
             ATTRIBUTE_SEARCH_FILTER,
+            ATTRIBUTE_TRUST_STORE,
             ATTRIBUTE_PROVIDER_AUTH_URL,
             ATTRIBUTE_LDAP_CONTEXT_FACTORY
             ));
 
     @Override
-    public AuthenticationManager createInstance(Map<String, Object> attributes)
+    public AuthenticationManager createInstance(Broker broker, Map<String, Object> attributes)
     {
         if (attributes == null || !PROVIDER_TYPE.equals(attributes.get(ATTRIBUTE_TYPE)))
         {
             return null;
         }
+
+        String name = (String) attributes.get(ATTRIBUTE_NAME);
         String providerUrl = (String) attributes.get(ATTRIBUTE_PROVIDER_URL);
         String providerAuthUrl = (String) attributes.get(ATTRIBUTE_PROVIDER_AUTH_URL);
+
         if (providerAuthUrl == null)
         {
             providerAuthUrl = providerUrl;
@@ -65,13 +74,24 @@ public class SimpleLDAPAuthenticationMan
         String searchContext = (String) attributes.get(ATTRIBUTE_SEARCH_CONTEXT);
         String searchFilter = (String) attributes.get(ATTRIBUTE_SEARCH_FILTER);
         String ldapContextFactory = (String) attributes.get(ATTRIBUTE_LDAP_CONTEXT_FACTORY);
+        String trustStoreName = (String) attributes.get(ATTRIBUTE_TRUST_STORE);
         if (ldapContextFactory == null)
         {
             ldapContextFactory = DEFAULT_LDAP_CONTEXT_FACTORY;
         }
 
-        return new SimpleLDAPAuthenticationManager(providerUrl, providerAuthUrl, searchContext, searchFilter,
-                ldapContextFactory);
+        TrustStore trustStore = null;
+        if (trustStoreName != null)
+        {
+            trustStore = broker.findTrustStoreByName(trustStoreName);
+            if (trustStore == null)
+            {
+                throw new IllegalConfigurationException("Can't find truststore with name '" + trustStoreName + "'");
+            }
+        }
+
+        return new SimpleLDAPAuthenticationManager(name, providerUrl, providerAuthUrl, searchContext,
+                searchFilter, ldapContextFactory, trustStore);
     }
 
     @Override

Modified: qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationProviderAttributeDescriptions.properties
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationProviderAttributeDescriptions.properties?rev=1534105&r1=1534104&r2=1534105&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationProviderAttributeDescriptions.properties (original)
+++ qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationProviderAttributeDescriptions.properties Mon Oct 21 11:48:52 2013
@@ -20,4 +20,5 @@ ldapContextFactory= LDAP context factory
 searchFilter=Search filter*
 searchContext=Search context*
 providerAuthUrl=LDAP authentication URL
-providerUrl=LDAP server URL*
\ No newline at end of file
+providerUrl=LDAP server URL*
+trustStore=Truststore name

Added: qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/ldap/AbstractLDAPSSLSocketFactory.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/ldap/AbstractLDAPSSLSocketFactory.java?rev=1534105&view=auto
==============================================================================
--- qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/ldap/AbstractLDAPSSLSocketFactory.java (added)
+++ qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/ldap/AbstractLDAPSSLSocketFactory.java Mon Oct 21 11:48:52 2013
@@ -0,0 +1,117 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ *
+ */
+package org.apache.qpid.server.security.auth.manager.ldap;
+
+import static org.apache.qpid.server.security.auth.manager.ldap.LDAPSSLSocketFactoryGenerator.getStaticFieldByReflection;
+import static org.apache.qpid.server.security.auth.manager.ldap.LDAPSSLSocketFactoryGenerator.SSL_SOCKET_FACTORY_FIELD;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.net.UnknownHostException;
+
+import javax.net.ssl.SSLSocketFactory;
+
+/**
+ * Abstract base class for all LDAPSSLSocketFactory implementations.
+ * <p>
+ * Concrete implementations of this class are <b>generated dynamically</b> at runtime by
+ * the {@link LDAPSSLSocketFactoryGenerator#createSubClass(String, SSLSocketFactory)} method.
+ * </p>
+ * <p>
+ * Callers will create new instances of the concrete implementations by using the static
+ * <code>#getDefault()</code> method. This will return an instance of the sub-class that is
+ * associated with the {@link SSLSocketFactory}.
+ * </p>
+ * <p>
+ * If callers are passing the sub-class to an API via class-name (i.e. String), the caller
+ * <b>must</b> ensure that the context classloader of the thread to set to the classloader
+ * of sub-class for the duration of the API call(s).
+ * </p>
+ * For more details  see {@link LDAPSSLSocketFactoryGenerator}.
+ * </p>
+ */
+public abstract class AbstractLDAPSSLSocketFactory extends SSLSocketFactory
+{
+    /** Socket factory to which this factory will delegate */
+    private final SSLSocketFactory _delegate;
+
+    protected AbstractLDAPSSLSocketFactory()
+    {
+        super();
+        _delegate = getStaticFieldByReflection(getClass(), SSL_SOCKET_FACTORY_FIELD);
+        if (_delegate == null)
+        {
+            throw new IllegalStateException("Delegate cannot be null - static field initialisation problem?");
+        }
+    }
+
+    @Override
+    public String[] getDefaultCipherSuites()
+    {
+        return _delegate.getDefaultCipherSuites();
+    }
+
+    @Override
+    public String[] getSupportedCipherSuites()
+    {
+        return _delegate.getSupportedCipherSuites();
+    }
+
+    @Override
+    public Socket createSocket() throws IOException
+    {
+        return _delegate.createSocket();
+    }
+
+    @Override
+    public Socket createSocket(String host, int port) throws IOException, UnknownHostException
+    {
+        return _delegate.createSocket(host, port);
+    }
+
+    @Override
+    public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException
+    {
+        return _delegate.createSocket(socket, host, port, autoClose);
+    }
+
+    @Override
+    public Socket createSocket(String host, int port, InetAddress localHost, int localPort)
+            throws IOException, UnknownHostException
+    {
+        return _delegate.createSocket(host, port, localHost, localPort);
+    }
+
+    @Override
+    public Socket createSocket(InetAddress host, int port) throws IOException
+    {
+        return _delegate.createSocket(host, port);
+    }
+
+    @Override
+    public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException
+    {
+        return _delegate.createSocket(address, port, localAddress, localPort);
+    }
+
+
+}

Added: qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/ldap/LDAPSSLSocketFactoryGenerator.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/ldap/LDAPSSLSocketFactoryGenerator.java?rev=1534105&view=auto
==============================================================================
--- qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/ldap/LDAPSSLSocketFactoryGenerator.java (added)
+++ qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/ldap/LDAPSSLSocketFactoryGenerator.java Mon Oct 21 11:48:52 2013
@@ -0,0 +1,298 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ *
+ */
+package org.apache.qpid.server.security.auth.manager.ldap;
+
+import static org.apache.bcel.Constants.ACC_PRIVATE;
+import static org.apache.bcel.Constants.ACC_PUBLIC;
+import static org.apache.bcel.Constants.ACC_STATIC;
+import static org.apache.bcel.Constants.ACC_SUPER;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.lang.reflect.Field;
+
+import javax.net.SocketFactory;
+import javax.net.ssl.SSLSocketFactory;
+
+import org.apache.bcel.Constants;
+import org.apache.bcel.classfile.JavaClass;
+import org.apache.bcel.generic.ClassGen;
+import org.apache.bcel.generic.ConstantPoolGen;
+import org.apache.bcel.generic.FieldGen;
+import org.apache.bcel.generic.InstructionConstants;
+import org.apache.bcel.generic.InstructionFactory;
+import org.apache.bcel.generic.InstructionList;
+import org.apache.bcel.generic.MethodGen;
+import org.apache.bcel.generic.Type;
+
+/**
+ * This class provides a single method, {@link #createSubClass(String, SSLSocketFactory)}.  This creates a
+ * sub-class of {@link AbstractLDAPSSLSocketFactory} and associates it with the {@link SSLSocketFactory} instance..
+ * <p>
+ * The sub-classes are <b>generated dynamically</b>.
+ * </p>
+ * <p>This approach is required in order to overcome a limitation in the javax.naming.directory API.  It offers
+ * {@link SSLSocketFactory} customization only at the class level only (via the <code>java.naming.ldap.factory.socket</code>
+ * directory context environment parameter). For this reason, a mechanism that can produce distinct
+ * {@link AbstractLDAPSSLSocketFactory} classes each associated with a different SSLSocketFactory instance is required.
+ * </p>
+ * @see <a href="http://docs.oracle.com/javase/jndi/tutorial/ldap/security/ssl.html">Java LDAP SSL and Custom Sockets</a>
+ */
+public class LDAPSSLSocketFactoryGenerator
+{
+    /**
+     * The name of field used to hold the delegate {@link SSLSocketFactory}. A field with
+     * this name is created on each generated sub-class.
+     */
+    static final String SSL_SOCKET_FACTORY_FIELD = "_sslSocketFactory";
+
+    /** Target package names used for the subclass - needs to exist */
+    static final String TARGET_PACKAGE_NAME = LDAPSSLSocketFactoryGenerator.class.getPackage().getName();
+
+    public static Class<? extends AbstractLDAPSSLSocketFactory> createSubClass(String simpleName, final SSLSocketFactory sslSocketFactory)
+    {
+        final String fqcn = TARGET_PACKAGE_NAME + "." + simpleName;
+        final byte[] classBytes = createSubClassByteCode(fqcn);
+
+        try
+        {
+            final ClassLoader classLoader = new LDAPSSLSocketFactoryAwareDelegatingClassloader(fqcn, classBytes, sslSocketFactory);
+            Class<? extends AbstractLDAPSSLSocketFactory> clazz = (Class<? extends AbstractLDAPSSLSocketFactory>) classLoader.loadClass(fqcn);
+            return clazz;
+        }
+        catch (ClassNotFoundException cnfe)
+        {
+            throw new IllegalArgumentException("Could not resolve dynamically generated class " + fqcn, cnfe);
+        }
+    }
+
+    /**
+     * Creates the LDAPSocketFactoryImpl class (subclass of {@link AbstractLDAPSSLSocketFactory}.
+     * A static method #getDefaulta, a static field _sslContent and no-arg constructor are added
+     * to the class.
+     *
+     * @param className
+     *
+     * @return byte code
+     */
+    private static byte[] createSubClassByteCode(final String className)
+    {
+        ClassGen classGen = new ClassGen(className,
+                AbstractLDAPSSLSocketFactory.class.getName(),
+                "<generated>",
+                ACC_PUBLIC | ACC_SUPER,
+                null);
+        ConstantPoolGen constantPoolGen = classGen.getConstantPool();
+        InstructionFactory factory = new InstructionFactory(classGen);
+
+        createSslContextStaticField(classGen, constantPoolGen);
+        createGetDefaultStaticMethod(classGen, constantPoolGen, factory);
+
+        classGen.addEmptyConstructor(Constants.ACC_PROTECTED);
+
+        JavaClass javaClass = classGen.getJavaClass();
+        ByteArrayOutputStream out = null;
+        try
+        {
+            out = new ByteArrayOutputStream();
+            javaClass.dump(out);
+            return out.toByteArray();
+        }
+        catch (IOException ioex)
+        {
+            throw new IllegalStateException("Could not write to a ByteArrayOutputStream - should not happen", ioex);
+        }
+        finally
+        {
+            closeSafely(out);
+        }
+    }
+
+    /**
+     * Creates a static field _sslContext of type {@link SSLSocketFactory}.
+     *
+     * @param classGen
+     * @param constantPoolGen
+     */
+    private static void createSslContextStaticField(ClassGen classGen, ConstantPoolGen constantPoolGen)
+    {
+        FieldGen fieldGen = new FieldGen(ACC_PRIVATE | ACC_STATIC,
+                                         Type.getType(SSLSocketFactory.class),
+                                         SSL_SOCKET_FACTORY_FIELD,
+                                         constantPoolGen);
+        classGen.addField(fieldGen.getField());
+    }
+
+    /**
+     * Create a static method 'getDefault' returning {@link SocketFactory}
+     * that creates a new instance of the sub-class and calls its no-argument
+     * constructor, the newly created is returned to the caller.
+     *
+     * @param classGen
+     * @param constantPoolGen
+     * @param instructionFactory
+     */
+    private static void createGetDefaultStaticMethod(ClassGen classGen,
+            ConstantPoolGen constantPoolGen, InstructionFactory instructionFactory)
+    {
+        InstructionList il = new InstructionList();
+
+        String methodName = "getDefault";
+        MethodGen mg = new MethodGen(ACC_STATIC | ACC_PUBLIC, // access flags
+                            Type.getType(SSLSocketFactory.class),  // return type
+                            new Type[0],   // argument types - no args
+                            new String[0], // arg names - no args
+                            methodName,
+                            classGen.getClassName(),    // method, class
+                            il,
+                            constantPoolGen);
+
+        il.append(instructionFactory.createNew(classGen.getClassName()));
+        il.append(InstructionConstants.DUP);
+
+        il.append(instructionFactory.createInvoke(classGen.getClassName(), "<init>", Type.VOID,
+                                       new Type[] {},
+                                       Constants.INVOKESPECIAL));
+
+        il.append(InstructionConstants.ARETURN);
+
+        mg.setMaxStack();
+        classGen.addMethod(mg.getMethod());
+        il.dispose();
+    }
+
+    private static void closeSafely(ByteArrayOutputStream out)
+    {
+        if (out != null)
+        {
+            try
+            {
+                out.close();
+            }
+            catch (IOException e)
+            {
+                // Ignore
+            }
+        }
+    }
+
+    private static void setSslSocketFactoryFieldByReflection(Class<? extends AbstractLDAPSSLSocketFactory> clazz, String fieldName, SSLSocketFactory sslSocketFactory)
+    {
+        String exceptionMessage = "Unexpected error setting generated static field "
+                 + fieldName + "on generated class " + clazz.getName();
+        try
+        {
+            Field declaredField = clazz.getDeclaredField(fieldName);
+            boolean accessible = declaredField.isAccessible();
+            try
+            {
+                declaredField.setAccessible(true);
+                declaredField.set(null, sslSocketFactory);
+            }
+            finally
+            {
+                declaredField.setAccessible(accessible);
+            }
+        }
+        catch (IllegalArgumentException e)
+        {
+            throw new RuntimeException(exceptionMessage, e);
+        }
+        catch (IllegalAccessException e)
+        {
+            throw new RuntimeException(exceptionMessage, e);
+        }
+        catch (NoSuchFieldException e)
+        {
+            throw new RuntimeException(exceptionMessage, e);
+        }
+        catch (SecurityException e)
+        {
+            throw new RuntimeException(exceptionMessage, e);
+        }
+    }
+
+    static SSLSocketFactory getStaticFieldByReflection(Class<? extends AbstractLDAPSSLSocketFactory> clazz, String fieldName)
+    {
+        String exceptionMessage = "Unexpected error getting generated static field "
+                + fieldName + "on generated class " + clazz.getName();
+
+        Field declaredField;
+        try
+        {
+            declaredField = clazz.getDeclaredField(fieldName);
+            boolean accessible = declaredField.isAccessible();
+            try
+            {
+                declaredField.setAccessible(true);
+                return (SSLSocketFactory) declaredField.get(null);
+            }
+            finally
+            {
+                declaredField.setAccessible(accessible);
+            }
+        }
+        catch (NoSuchFieldException e)
+        {
+            throw new RuntimeException(exceptionMessage, e);
+        }
+        catch (SecurityException e)
+        {
+            throw new RuntimeException(exceptionMessage, e);
+        }
+        catch (IllegalArgumentException e)
+        {
+            throw new RuntimeException(exceptionMessage, e);
+        }
+        catch (IllegalAccessException e)
+        {
+            throw new RuntimeException(exceptionMessage, e);
+        }
+    }
+
+    private static final class LDAPSSLSocketFactoryAwareDelegatingClassloader extends ClassLoader
+    {
+        private final String _className;
+        private final Class<? extends AbstractLDAPSSLSocketFactory> _clazz;
+
+        private LDAPSSLSocketFactoryAwareDelegatingClassloader(String className,
+                byte[] classBytes, SSLSocketFactory sslSocketFactory)
+        {
+            super(LDAPSSLSocketFactoryGenerator.class.getClassLoader());
+            _className = className;
+            _clazz = (Class<? extends AbstractLDAPSSLSocketFactory>) defineClass(className, classBytes, 0, classBytes.length);
+            setSslSocketFactoryFieldByReflection(_clazz, SSL_SOCKET_FACTORY_FIELD, sslSocketFactory);
+        }
+
+        @Override
+        protected Class<?> findClass(String fqcn) throws ClassNotFoundException
+        {
+            if (fqcn.equals(_className))
+            {
+                return _clazz;
+            }
+            else
+            {
+                return getParent().loadClass(fqcn);
+            }
+        }
+    }
+}

Modified: qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/util/StringUtil.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/util/StringUtil.java?rev=1534105&r1=1534104&r2=1534105&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/util/StringUtil.java (original)
+++ qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/util/StringUtil.java Mon Oct 21 11:48:52 2013
@@ -22,6 +22,8 @@ package org.apache.qpid.server.util;
 
 import java.util.Random;
 
+import org.apache.commons.codec.digest.DigestUtils;
+
 public class StringUtil
 {
     private static final String NUMBERS = "0123456789";
@@ -41,4 +43,33 @@ public class StringUtil
         return new String(result);
     }
 
+    /**
+     * Builds a legal java name, based on manager name if possible,
+     * this is unique for the given input.
+     *
+     * @param managerName
+     * @return unique java name
+     */
+    public String createUniqueJavaName(String managerName)
+    {
+        StringBuilder builder = new StringBuilder();
+        boolean initialChar = true;
+        for (int i = 0; i < managerName.length(); i++)
+        {
+            char c = managerName.charAt(i);
+            if ((initialChar && Character.isJavaIdentifierStart(c))
+                    || (!initialChar && Character.isJavaIdentifierPart(c)))
+            {
+                builder.append(c);
+                initialChar = false;
+            }
+        }
+        if (builder.length() > 0)
+        {
+            builder.append("_");
+        }
+        builder.append(DigestUtils.md5Hex(managerName));
+        return builder.toString();
+    }
+
 }

Modified: qpid/trunk/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/adapter/AuthenticationProviderFactoryTest.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/adapter/AuthenticationProviderFactoryTest.java?rev=1534105&r1=1534104&r2=1534105&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/adapter/AuthenticationProviderFactoryTest.java (original)
+++ qpid/trunk/qpid/java/broker-core/src/test/java/org/apache/qpid/server/model/adapter/AuthenticationProviderFactoryTest.java Mon Oct 21 11:48:52 2013
@@ -93,7 +93,7 @@ public class AuthenticationProviderFacto
 
         when(authManagerFactoryServiceLoader.atLeastOneInstanceOf(AuthenticationManagerFactory.class)).thenReturn(
                 Collections.singleton(authenticationManagerFactory));
-        when(authenticationManagerFactory.createInstance(attributes)).thenReturn(authenticationManager);
+        when(authenticationManagerFactory.createInstance(broker, attributes)).thenReturn(authenticationManager);
 
         AuthenticationProviderFactory providerFactory = new AuthenticationProviderFactory(authManagerFactoryServiceLoader);
 
@@ -121,7 +121,7 @@ public class AuthenticationProviderFacto
 
         QpidServiceLoader<AuthenticationManagerFactory> loader = mock(QpidServiceLoader.class);
         AuthenticationManagerFactory managerFactory = mock(AuthenticationManagerFactory.class);
-        when(managerFactory.createInstance(any(Map.class))).thenReturn(mock(PrincipalDatabaseAuthenticationManager.class));
+        when(managerFactory.createInstance(any(Broker.class), any(Map.class))).thenReturn(mock(PrincipalDatabaseAuthenticationManager.class));
         when(loader.atLeastOneInstanceOf(AuthenticationManagerFactory.class)).thenReturn(Collections.singleton(managerFactory));
 
         AuthenticationProviderFactory providerFactory = new AuthenticationProviderFactory(loader);
@@ -142,7 +142,7 @@ public class AuthenticationProviderFacto
 
         QpidServiceLoader<AuthenticationManagerFactory> loader = mock(QpidServiceLoader.class);
         AuthenticationManagerFactory managerFactory = mock(AuthenticationManagerFactory.class);
-        when(managerFactory.createInstance(any(Map.class))).thenReturn(mock(AuthenticationManager.class));
+        when(managerFactory.createInstance(any(Broker.class), any(Map.class))).thenReturn(mock(AuthenticationManager.class));
         when(loader.atLeastOneInstanceOf(AuthenticationManagerFactory.class)).thenReturn(Collections.singleton(managerFactory));
 
         AuthenticationProviderFactory providerFactory = new AuthenticationProviderFactory(loader);

Modified: qpid/trunk/qpid/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/Base64MD5PasswordFileAuthenticationManagerFactoryTest.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/Base64MD5PasswordFileAuthenticationManagerFactoryTest.java?rev=1534105&r1=1534104&r2=1534105&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/Base64MD5PasswordFileAuthenticationManagerFactoryTest.java (original)
+++ qpid/trunk/qpid/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/Base64MD5PasswordFileAuthenticationManagerFactoryTest.java Mon Oct 21 11:48:52 2013
@@ -19,6 +19,8 @@
  */
 package org.apache.qpid.server.security.auth.manager;
 
+import static org.mockito.Mockito.mock;
+
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.util.HashMap;
@@ -26,6 +28,7 @@ import java.util.Map;
 
 import junit.framework.TestCase;
 
+import org.apache.qpid.server.model.Broker;
 import org.apache.qpid.server.plugin.AuthenticationManagerFactory;
 import org.apache.qpid.server.security.auth.database.Base64MD5PasswordFilePrincipalDatabase;
 
@@ -34,6 +37,7 @@ public class Base64MD5PasswordFileAuthen
     AuthenticationManagerFactory _factory = new Base64MD5PasswordFileAuthenticationManagerFactory();
     private Map<String, Object> _configuration = new HashMap<String, Object>();
     private File _emptyPasswordFile;
+    private Broker _broker = mock(Broker.class);
 
     @Override
     protected void setUp() throws Exception
@@ -48,7 +52,7 @@ public class Base64MD5PasswordFileAuthen
         _configuration.put(AbstractPrincipalDatabaseAuthManagerFactory.ATTRIBUTE_TYPE, Base64MD5PasswordFileAuthenticationManagerFactory.PROVIDER_TYPE);
         _configuration.put(AbstractPrincipalDatabaseAuthManagerFactory.ATTRIBUTE_PATH, _emptyPasswordFile.getAbsolutePath());
 
-        AuthenticationManager manager = _factory.createInstance(_configuration);
+        AuthenticationManager manager = _factory.createInstance(_broker, _configuration);
         assertNotNull(manager);
         assertTrue(manager instanceof PrincipalDatabaseAuthenticationManager);
         assertTrue(((PrincipalDatabaseAuthenticationManager)manager).getPrincipalDatabase() instanceof Base64MD5PasswordFilePrincipalDatabase);
@@ -64,7 +68,7 @@ public class Base64MD5PasswordFileAuthen
 
         try
         {
-            _factory.createInstance(_configuration);
+            _factory.createInstance(_broker, _configuration);
         }
         catch (RuntimeException re)
         {
@@ -74,14 +78,14 @@ public class Base64MD5PasswordFileAuthen
 
     public void testReturnsNullWhenNoConfig() throws Exception
     {
-        AuthenticationManager manager = _factory.createInstance(_configuration);
+        AuthenticationManager manager = _factory.createInstance(_broker, _configuration);
         assertNull(manager);
     }
 
     public void testReturnsNullWhenConfigForOtherAuthManagerType() throws Exception
     {
         _configuration.put(AbstractPrincipalDatabaseAuthManagerFactory.ATTRIBUTE_TYPE, "other-auth-manager");
-        AuthenticationManager manager = _factory.createInstance(_configuration);
+        AuthenticationManager manager = _factory.createInstance(_broker, _configuration);
         assertNull(manager);
     }
 
@@ -89,7 +93,7 @@ public class Base64MD5PasswordFileAuthen
     {
         _configuration.put(AbstractPrincipalDatabaseAuthManagerFactory.ATTRIBUTE_TYPE, Base64MD5PasswordFileAuthenticationManagerFactory.PROVIDER_TYPE);
 
-        AuthenticationManager manager = _factory.createInstance(_configuration);
+        AuthenticationManager manager = _factory.createInstance(_broker, _configuration);
         assertNull(manager);
     }
 

Modified: qpid/trunk/qpid/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/PlainPasswordFileAuthenticationManagerFactoryTest.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/PlainPasswordFileAuthenticationManagerFactoryTest.java?rev=1534105&r1=1534104&r2=1534105&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/PlainPasswordFileAuthenticationManagerFactoryTest.java (original)
+++ qpid/trunk/qpid/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/PlainPasswordFileAuthenticationManagerFactoryTest.java Mon Oct 21 11:48:52 2013
@@ -19,12 +19,15 @@
  */
 package org.apache.qpid.server.security.auth.manager;
 
+import static org.mockito.Mockito.mock;
+
 import java.io.File;
 import java.util.HashMap;
 import java.util.Map;
 
 import junit.framework.TestCase;
 
+import org.apache.qpid.server.model.Broker;
 import org.apache.qpid.server.plugin.AuthenticationManagerFactory;
 import org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase;
 
@@ -33,6 +36,7 @@ public class PlainPasswordFileAuthentica
     AuthenticationManagerFactory _factory = new PlainPasswordFileAuthenticationManagerFactory();
     private Map<String, Object> _configuration = new HashMap<String, Object>();
     private File _emptyPasswordFile;
+    private Broker _broker = mock(Broker.class);
 
     @Override
     protected void setUp() throws Exception
@@ -47,7 +51,7 @@ public class PlainPasswordFileAuthentica
         _configuration.put(AbstractPrincipalDatabaseAuthManagerFactory.ATTRIBUTE_TYPE, PlainPasswordFileAuthenticationManagerFactory.PROVIDER_TYPE);
         _configuration.put(AbstractPrincipalDatabaseAuthManagerFactory.ATTRIBUTE_PATH, _emptyPasswordFile.getAbsolutePath());
 
-        AuthenticationManager manager = _factory.createInstance(_configuration);
+        AuthenticationManager manager = _factory.createInstance(_broker, _configuration);
         assertNotNull(manager);
         assertTrue(manager instanceof PrincipalDatabaseAuthenticationManager);
         assertTrue(((PrincipalDatabaseAuthenticationManager)manager).getPrincipalDatabase() instanceof PlainPasswordFilePrincipalDatabase);
@@ -61,7 +65,7 @@ public class PlainPasswordFileAuthentica
         _configuration.put(AbstractPrincipalDatabaseAuthManagerFactory.ATTRIBUTE_TYPE, PlainPasswordFileAuthenticationManagerFactory.PROVIDER_TYPE);
         _configuration.put(AbstractPrincipalDatabaseAuthManagerFactory.ATTRIBUTE_PATH, _emptyPasswordFile.getAbsolutePath());
 
-        AuthenticationManager manager = _factory.createInstance(_configuration);
+        AuthenticationManager manager = _factory.createInstance(_broker, _configuration);
 
         assertNotNull(manager);
         assertTrue(manager instanceof PrincipalDatabaseAuthenticationManager);
@@ -70,14 +74,14 @@ public class PlainPasswordFileAuthentica
 
     public void testReturnsNullWhenNoConfig() throws Exception
     {
-        AuthenticationManager manager = _factory.createInstance(_configuration);
+        AuthenticationManager manager = _factory.createInstance(_broker, _configuration);
         assertNull(manager);
     }
 
     public void testReturnsNullWhenConfigForOtherAuthManagerType() throws Exception
     {
         _configuration.put(AbstractPrincipalDatabaseAuthManagerFactory.ATTRIBUTE_TYPE, "other-auth-manager");
-        AuthenticationManager manager = _factory.createInstance(_configuration);
+        AuthenticationManager manager = _factory.createInstance(_broker, _configuration);
         assertNull(manager);
     }
 
@@ -85,7 +89,7 @@ public class PlainPasswordFileAuthentica
     {
         _configuration.put(AbstractPrincipalDatabaseAuthManagerFactory.ATTRIBUTE_TYPE, PlainPasswordFileAuthenticationManagerFactory.PROVIDER_TYPE);
 
-        AuthenticationManager manager = _factory.createInstance(_configuration);
+        AuthenticationManager manager = _factory.createInstance(_broker, _configuration);
         assertNull(manager);
     }
 

Modified: qpid/trunk/qpid/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManagerFactoryTest.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManagerFactoryTest.java?rev=1534105&r1=1534104&r2=1534105&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManagerFactoryTest.java (original)
+++ qpid/trunk/qpid/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManagerFactoryTest.java Mon Oct 21 11:48:52 2013
@@ -19,9 +19,18 @@
  */
 package org.apache.qpid.server.security.auth.manager;
 
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.verifyZeroInteractions;
+
 import java.util.HashMap;
 import java.util.Map;
 
+import org.apache.qpid.server.configuration.IllegalConfigurationException;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.TrustStore;
+
 
 import junit.framework.TestCase;
 
@@ -29,20 +38,69 @@ public class SimpleLDAPAuthenticationMan
 {
     private SimpleLDAPAuthenticationManagerFactory _factory = new SimpleLDAPAuthenticationManagerFactory();
     private Map<String, Object> _configuration = new HashMap<String, Object>();
+    private Broker _broker = mock(Broker.class);
+    private TrustStore _trustStore = mock(TrustStore.class);
 
-    public void testInstanceCreated() throws Exception
+    public void testLdapInstanceCreated() throws Exception
+    {
+        _configuration.put(SimpleLDAPAuthenticationManagerFactory.ATTRIBUTE_TYPE, SimpleLDAPAuthenticationManagerFactory.PROVIDER_TYPE);
+        _configuration.put("providerUrl", "ldap://example.com:389/");
+        _configuration.put("searchContext", "dc=example");
+
+        AuthenticationManager manager = _factory.createInstance(_broker, _configuration);
+        assertNotNull(manager);
+
+        verifyZeroInteractions(_broker);
+    }
+
+    public void testLdapsInstanceCreated() throws Exception
     {
         _configuration.put(SimpleLDAPAuthenticationManagerFactory.ATTRIBUTE_TYPE, SimpleLDAPAuthenticationManagerFactory.PROVIDER_TYPE);
         _configuration.put("providerUrl", "ldaps://example.com:636/");
         _configuration.put("searchContext", "dc=example");
 
-        AuthenticationManager manager = _factory.createInstance(_configuration);
+        AuthenticationManager manager = _factory.createInstance(_broker, _configuration);
         assertNotNull(manager);
+
+        verifyZeroInteractions(_broker);
+    }
+
+    public void testLdapsWithTrustStoreInstanceCreated() throws Exception
+    {
+        when(_broker.findTrustStoreByName("mytruststore")).thenReturn(_trustStore);
+
+        _configuration.put(SimpleLDAPAuthenticationManagerFactory.ATTRIBUTE_TYPE, SimpleLDAPAuthenticationManagerFactory.PROVIDER_TYPE);
+        _configuration.put("providerUrl", "ldaps://example.com:636/");
+        _configuration.put("searchContext", "dc=example");
+        _configuration.put("trustStore", "mytruststore");
+
+        AuthenticationManager manager = _factory.createInstance(_broker, _configuration);
+        assertNotNull(manager);
+    }
+
+    public void testLdapsWhenTrustStoreNotFound() throws Exception
+    {
+        when(_broker.findTrustStoreByName("notfound")).thenReturn(null);
+
+        _configuration.put(SimpleLDAPAuthenticationManagerFactory.ATTRIBUTE_TYPE, SimpleLDAPAuthenticationManagerFactory.PROVIDER_TYPE);
+        _configuration.put("providerUrl", "ldaps://example.com:636/");
+        _configuration.put("searchContext", "dc=example");
+        _configuration.put("trustStore", "notfound");
+
+        try
+        {
+            _factory.createInstance(_broker, _configuration);
+            fail("Exception not thrown");
+        }
+        catch(IllegalConfigurationException e)
+        {
+            assertEquals("Can't find truststore with name 'notfound'", e.getMessage());
+        }
     }
 
     public void testReturnsNullWhenNoConfig() throws Exception
     {
-        AuthenticationManager manager = _factory.createInstance(_configuration);
+        AuthenticationManager manager = _factory.createInstance(_broker, _configuration);
         assertNull(manager);
     }
 }

Added: qpid/trunk/qpid/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/ldap/LDAPSSLSocketFactoryGeneratorTest.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/ldap/LDAPSSLSocketFactoryGeneratorTest.java?rev=1534105&view=auto
==============================================================================
--- qpid/trunk/qpid/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/ldap/LDAPSSLSocketFactoryGeneratorTest.java (added)
+++ qpid/trunk/qpid/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/ldap/LDAPSSLSocketFactoryGeneratorTest.java Mon Oct 21 11:48:52 2013
@@ -0,0 +1,88 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ *
+ */
+package org.apache.qpid.server.security.auth.manager.ldap;
+
+import static org.apache.qpid.server.security.auth.manager.ldap.LDAPSSLSocketFactoryGenerator.TARGET_PACKAGE_NAME;
+
+import static org.mockito.Mockito.mock;
+
+import javax.net.SocketFactory;
+import javax.net.ssl.SSLSocketFactory;
+
+import junit.framework.TestCase;
+
+public class LDAPSSLSocketFactoryGeneratorTest extends TestCase
+{
+    private SSLSocketFactory _sslSocketFactory = mock(SSLSocketFactory.class);
+
+    public void testPackageAndClassName() throws Exception
+    {
+        Class<? extends SocketFactory> socketFactoryClass = LDAPSSLSocketFactoryGenerator.createSubClass("MyNewClass", _sslSocketFactory);
+        assertEquals("MyNewClass", socketFactoryClass.getSimpleName());
+        assertEquals(TARGET_PACKAGE_NAME, socketFactoryClass.getPackage().getName());
+    }
+
+    public void testLoadingWithClassForName() throws Exception
+    {
+        Class<? extends AbstractLDAPSSLSocketFactory> socketFactoryClass = LDAPSSLSocketFactoryGenerator.createSubClass("MyNewClass", _sslSocketFactory);
+        String fqcn = socketFactoryClass.getName();
+
+        try
+        {
+            Class.forName(fqcn);
+            fail("Class loading by name should not have been successful");
+        }
+        catch (ClassNotFoundException cnfe)
+        {
+           // PASS
+        }
+
+        final ClassLoader sfClassloader = socketFactoryClass.getClassLoader();
+        // Note: Oracle's com.sun.jndi.ldap.LdapClient uses the following form passing the context loader
+        Class<?> loaded = Class.forName(fqcn, true, sfClassloader);
+        assertEquals(socketFactoryClass, loaded);
+    }
+
+    public void testClassloaderDelegatesToParent() throws Exception
+    {
+        ClassLoader classLoader = LDAPSSLSocketFactoryGenerator.createSubClass("MyNewClass", _sslSocketFactory).getClassLoader();
+        assertEquals(String.class, classLoader.loadClass("java.lang.String"));
+        assertEquals(TestClassForLoading.class, classLoader.loadClass(TestClassForLoading.class.getName()));
+    }
+
+    public void testGetDefaultCreatesInstance() throws Exception
+    {
+        Class<? extends AbstractLDAPSSLSocketFactory> socketFactoryClass = LDAPSSLSocketFactoryGenerator.createSubClass("MyNewClass", _sslSocketFactory);
+
+        AbstractLDAPSSLSocketFactory socketFactory = invokeGetDefaultMethod(socketFactoryClass);
+        assertTrue(socketFactory instanceof AbstractLDAPSSLSocketFactory);
+        assertEquals("MyNewClass", socketFactory.getClass().getSimpleName());
+    }
+
+    private AbstractLDAPSSLSocketFactory invokeGetDefaultMethod(Class<? extends AbstractLDAPSSLSocketFactory> socketFactoryClass) throws Exception
+    {
+        return (AbstractLDAPSSLSocketFactory) socketFactoryClass.getMethod("getDefault").invoke(null);
+    }
+
+    class TestClassForLoading
+    {
+    }
+}

Modified: qpid/trunk/qpid/java/broker-core/src/test/java/org/apache/qpid/server/util/StringUtilTest.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-core/src/test/java/org/apache/qpid/server/util/StringUtilTest.java?rev=1534105&r1=1534104&r2=1534105&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker-core/src/test/java/org/apache/qpid/server/util/StringUtilTest.java (original)
+++ qpid/trunk/qpid/java/broker-core/src/test/java/org/apache/qpid/server/util/StringUtilTest.java Mon Oct 21 11:48:52 2013
@@ -55,4 +55,13 @@ public class StringUtilTest extends Qpid
         }
     }
 
+    public void testCreateUniqueJavaName()
+    {
+        assertEquals("MyName_973de1b4e26b629d4817c8255090e58e", _util.createUniqueJavaName("MyName"));
+        assertEquals("ContaisIllegalJavaCharacters_a68b2484f2eb790558d6527e56c595fa", _util.createUniqueJavaName("Contais+Illegal-Java*Characters"));
+        assertEquals("StartsWithIllegalInitial_93031eec569608c60c6a98ac9e84a0a7", _util.createUniqueJavaName("9StartsWithIllegalInitial"));
+        assertEquals("97b247ba19ff869340d3797cc73ca065", _util.createUniqueJavaName("1++++----"));
+        assertEquals("d41d8cd98f00b204e9800998ecf8427e", _util.createUniqueJavaName(""));
+    }
+
 }

Modified: qpid/trunk/qpid/java/build.deps
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/build.deps?rev=1534105&r1=1534104&r2=1534105&view=diff
==============================================================================
--- qpid/trunk/qpid/java/build.deps (original)
+++ qpid/trunk/qpid/java/build.deps Mon Oct 21 11:48:52 2013
@@ -26,6 +26,8 @@ commons-digester=lib/required/commons-di
 commons-lang=lib/required/commons-lang-2.6.jar
 commons-logging=lib/required/commons-logging-1.1.1.jar
 
+bcel=lib/required/bcel-5.2.jar
+
 derby-db=lib/required/derby-10.8.2.2.jar
 
 geronimo-jms=lib/required/geronimo-jms_1.1_spec-1.0.jar
@@ -75,7 +77,7 @@ amqp-1-0-client-jms.libs=${geronimo-jms}
 tools.libs=${commons-configuration.libs} ${log4j}
 broker-core.libs=${commons-cli} ${commons-logging} ${log4j} ${slf4j-log4j} \
     ${xalan} ${derby-db} ${commons-configuration.libs} \
-    ${jackson-core} ${jackson-mapper} ${jetty} ${jetty-continuation} ${jetty-security} ${jetty-http} ${jetty-io} ${jetty-servlet} ${jetty-util} ${servlet-api} ${jetty-websocket}
+    ${jackson-core} ${jackson-mapper} ${jetty} ${jetty-continuation} ${jetty-security} ${jetty-http} ${jetty-io} ${jetty-servlet} ${jetty-util} ${servlet-api} ${jetty-websocket} ${bcel}
 
 #Borrow the broker-core libs, hack for release binary generation
 broker.libs=${broker-core.libs}

Modified: qpid/trunk/qpid/java/ivy.retrieve.xml
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/ivy.retrieve.xml?rev=1534105&r1=1534104&r2=1534105&view=diff
==============================================================================
--- qpid/trunk/qpid/java/ivy.retrieve.xml (original)
+++ qpid/trunk/qpid/java/ivy.retrieve.xml Mon Oct 21 11:48:52 2013
@@ -42,6 +42,7 @@
     <dependency org="commons-digester" name="commons-digester" rev="1.8.1" transitive="false"/>
     <dependency org="commons-lang" name="commons-lang" rev="2.6" transitive="false"/>
     <dependency org="commons-logging" name="commons-logging" rev="1.1.1" transitive="false"/>
+    <dependency org="org.apache.bcel" name="bcel" rev="5.2" transitive="false"/>
     <dependency org="org.apache.derby" name="derby" rev="10.8.2.2" transitive="false"/>
     <dependency org="org.apache.geronimo.framework" name="geronimo-kernel" rev="2.2.1" transitive="false"/>
     <dependency org="org.apache.geronimo.specs" name="geronimo-ejb_3.0_spec" rev="1.0.1" transitive="false"/>

Added: qpid/trunk/qpid/java/lib/poms/bcel-5.2.xml
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/lib/poms/bcel-5.2.xml?rev=1534105&view=auto
==============================================================================
--- qpid/trunk/qpid/java/lib/poms/bcel-5.2.xml (added)
+++ qpid/trunk/qpid/java/lib/poms/bcel-5.2.xml Mon Oct 21 11:48:52 2013
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You 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.
+-->
+<dep>
+  <groupId>org.apache.bcel</groupId>
+  <artifactId>bcel</artifactId>
+  <version>5.2</version>
+</dep>



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org