You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ro...@apache.org on 2013/04/12 18:16:12 UTC

svn commit: r1467334 [2/3] - in /qpid/trunk/qpid/java: broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/ broker-plugins/management-http/src/main/java/resources/ broker-plugins/management-http/src/main/java/resources...

Modified: qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/treeView.js
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/treeView.js?rev=1467334&r1=1467333&r2=1467334&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/treeView.js (original)
+++ qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/treeView.js Fri Apr 12 16:16:09 2013
@@ -277,8 +277,11 @@ define(["dojo/_base/xhr",
                    controller.show("groupprovider", details.groupprovider, {broker: {type:"broker", name:""}});
                } else if (details.type == 'group') {
                    controller.show("group", details.group, { type: "groupprovider", name: details.groupprovider, parent: {broker: {type:"broker", name:""}}});
+               } else if (details.type == 'keystore') {
+                 controller.show("keystore", details.keystore, {broker: {type:"broker", name:""}});
+               } else if (details.type == 'truststore') {
+                 controller.show("truststore", details.truststore, {broker: {type:"broker", name:""}});
                }
-
            };
 
            TreeViewModel.prototype.update = function () {

Modified: qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/showBroker.html
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/showBroker.html?rev=1467334&r1=1467333&r2=1467334&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/showBroker.html (original)
+++ qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/showBroker.html Fri Apr 12 16:16:09 2013
@@ -69,20 +69,6 @@
                 <div class="formLabel-labelCell" style="float:left; width: 250px;">Group file location:</div>
                 <div id="brokerAttribute.groupFile" style="float:left;"></div>
             </div>
-            <div id="brokerAttribute.keyStorePath.container" style="display: none; clear:both">
-                <div class="formLabel-labelCell" style="float:left; width: 250px;">Path to keystore:</div>
-                <div id="brokerAttribute.keyStorePath" style="float:left;"></div><br/>
-                <div class="formLabel-labelCell" style="float:left; width: 250px;">Keystore certificate alias:</div>
-                <div id="brokerAttribute.keyStoreCertAlias" style="float:left;"></div>
-            </div>
-            <div id="brokerAttribute.trustStorePath.container" style="display: none; clear:both">
-                <div class="formLabel-labelCell" style="float:left; width: 250px;">Path to truststore:</div>
-                <div id="brokerAttribute.trustStorePath" style="float:left;"></div>
-            </div>
-            <div id="brokerAttribute.peerStorePath.container" style="display: none; clear:both">
-                <div class="formLabel-labelCell" style="float:left; width: 250px;">Path to peerstore:</div>
-                <div id="brokerAttribute.peerStorePath" style="float:left;"></div>
-            </div>
             <div id="brokerAttribute.statisticsReportingPeriod.container" style="display: none; clear:both">
                 <div class="formLabel-labelCell" style="float:left; width: 250px;">Statistics reporting period:</div>
                 <div id="brokerAttribute.statisticsReportingPeriod" style="float:left;"></div>
@@ -191,6 +177,18 @@
         <button data-dojo-type="dijit.form.Button" class="deleteAuthenticationProvider">Delete Provider</button>
     </div>
     <br/>
+    <div data-dojo-type="dijit.TitlePane" data-dojo-props="title: 'Key stores'">
+        <div class="broker-key-stores"></div>
+        <button data-dojo-type="dijit.form.Button" class="addKeystore">Add Key Store</button>
+        <button data-dojo-type="dijit.form.Button" class="deleteKeystore">Delete Key Store</button>
+    </div>
+    <br/>
+    <div data-dojo-type="dijit.TitlePane" data-dojo-props="title: 'Trust stores'">
+        <div class="broker-trust-stores"></div>
+        <button data-dojo-type="dijit.form.Button" class="addTruststore">Add Trust Store</button>
+        <button data-dojo-type="dijit.form.Button" class="deleteTruststore">Delete Trust Store</button>
+    </div>
+    <br/>
     <div data-dojo-type="dijit.TitlePane" data-dojo-props="title: 'Log File',  open: false">
         <div class="broker-logfile"></div>
     </div>

Added: qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/showKeyStore.html
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/showKeyStore.html?rev=1467334&view=auto
==============================================================================
--- qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/showKeyStore.html (added)
+++ qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/showKeyStore.html Fri Apr 12 16:16:09 2013
@@ -0,0 +1,47 @@
+<!--
+ -
+ - 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.
+ -
+ -->
+<div class="keystore">
+    <div class="keyStoreContainer">
+
+       <div class="formLabel-labelCell" style="float:left; width: 250px;">Name:</div>
+       <div class="nameValue" style="float:left;"></div><br/>
+
+       <div class="formLabel-labelCell" style="float:left; width: 250px;">Type:</div>
+       <div class="typeValue" style="float:left;"></div><br/>
+
+       <div class="formLabel-labelCell" style="float:left; width: 250px;">Key Manager Factory Algorithm:</div>
+       <div class="keyManagerFactoryAlgorithmValue" style="float:left;"></div><br/>
+
+       <div class="formLabel-labelCell" style="float:left; width: 250px;">Path:</div>
+       <div class="pathValue" style="float:left;"></div><br/>
+
+       <div class="certificateAlias">
+          <div class="formLabel-labelCell" style="float:left; width: 250px;">Certificate alias:</div>
+          <div class="certificateAliasValue" style="float:left;"></div><br>
+       </div>
+
+    </div>
+    <br/>
+    <div class="dijitDialogPaneActionBar">
+        <button data-dojo-type="dijit.form.Button" class="editKeyStoreButton" type="button">Edit</button>
+        <button data-dojo-type="dijit.form.Button" class="deleteKeyStoreButton" type="button">Delete</button>
+    </div>
+</div>

Added: qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/showTrustStore.html
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/showTrustStore.html?rev=1467334&view=auto
==============================================================================
--- qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/showTrustStore.html (added)
+++ qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/showTrustStore.html Fri Apr 12 16:16:09 2013
@@ -0,0 +1,47 @@
+<!--
+ -
+ - 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.
+ -
+ -->
+<div class="truststore">
+    <div class="trustStoreContainer">
+
+       <div class="formLabel-labelCell" style="float:left; width: 250px;">Name:</div>
+       <div class="nameValue" style="float:left;"></div><br/>
+
+       <div class="formLabel-labelCell" style="float:left; width: 250px;">Type:</div>
+       <div class="typeValue" style="float:left;"></div><br/>
+
+       <div class="formLabel-labelCell" style="float:left; width: 250px;">Trust Manager Factory Algorithm:</div>
+       <div class="trustManagerFactoryAlgorithmValue" style="float:left;"></div><br/>
+
+       <div class="formLabel-labelCell" style="float:left; width: 250px;">Path:</div>
+       <div class="pathValue" style="float:left;"></div><br/>
+
+       <div class="peersOnly">
+          <div class="formLabel-labelCell" style="float:left; width: 250px;">Peer store:</div>
+          <div class="peersOnlyValue" style="float:left;"></div>
+       </div>
+
+    </div>
+    <br/>
+    <div class="dijitDialogPaneActionBar">
+        <button data-dojo-type="dijit.form.Button" class="editTrustStoreButton" type="button">Edit</button>
+        <button data-dojo-type="dijit.form.Button" class="deleteTrustStoreButton" type="button">Delete</button>
+    </div>
+</div>

Modified: qpid/trunk/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagedObjectRegistry.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagedObjectRegistry.java?rev=1467334&r1=1467333&r2=1467334&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagedObjectRegistry.java (original)
+++ qpid/trunk/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagedObjectRegistry.java Fri Apr 12 16:16:09 2013
@@ -26,10 +26,12 @@ import org.apache.qpid.server.configurat
 import org.apache.qpid.server.logging.actors.CurrentActor;
 import org.apache.qpid.server.logging.messages.ManagementConsoleMessages;
 import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.KeyStore;
 import org.apache.qpid.server.model.Port;
 import org.apache.qpid.server.model.Transport;
 
 import org.apache.qpid.server.security.auth.rmi.RMIPasswordAuthenticator;
+import org.apache.qpid.ssl.SSLContextFactory;
 
 import javax.management.JMException;
 import javax.management.MBeanServer;
@@ -39,6 +41,7 @@ import javax.management.remote.JMXConnec
 import javax.management.remote.JMXServiceURL;
 import javax.management.remote.MBeanServerForwarder;
 import javax.management.remote.rmi.RMIConnectorServer;
+import javax.net.ssl.SSLContext;
 import javax.rmi.ssl.SslRMIClientSocketFactory;
 import javax.rmi.ssl.SslRMIServerSocketFactory;
 import java.io.File;
@@ -57,6 +60,7 @@ import java.rmi.registry.Registry;
 import java.rmi.server.RMIClientSocketFactory;
 import java.rmi.server.RMIServerSocketFactory;
 import java.rmi.server.UnicastRemoteObject;
+import java.security.GeneralSecurityException;
 import java.util.HashMap;
 
 /**
@@ -122,16 +126,32 @@ public class JMXManagedObjectRegistry im
 
         if (connectorSslEnabled)
         {
-            String keyStorePath = System.getProperty("javax.net.ssl.keyStore");
-            String keyStorePassword = System.getProperty("javax.net.ssl.keyStorePassword");
+            KeyStore keyStore = _connectorPort.getKeyStore();
 
-            validateKeyStoreProperties(keyStorePath, keyStorePassword);
+            String keyStorePath = (String) keyStore.getAttribute(KeyStore.PATH);
+            String keyStorePassword = keyStore.getPassword();
+            String keyStoreType = (String) keyStore.getAttribute(KeyStore.TYPE);
+            String keyManagerFactoryAlgorithm = (String) keyStore.getAttribute(KeyStore.KEY_MANAGER_FACTORY_ALGORITHM);
+
+            SSLContext sslContext;
+            try
+            {
+                sslContext = SSLContextFactory.buildServerContext(keyStorePath, keyStorePassword, keyStoreType, keyManagerFactoryAlgorithm);
+            }
+            catch (GeneralSecurityException e)
+            {
+                throw new RuntimeException("Unable to create SSLContext for key or trust store", e);
+            }
+            catch (IOException e)
+            {
+                throw new RuntimeException("Unable to create SSLContext - unable to load key/trust store", e);
+            }
 
             CurrentActor.get().message(ManagementConsoleMessages.SSL_KEYSTORE(keyStorePath));
 
             //create the SSL RMI socket factories
             csf = new SslRMIClientSocketFactory();
-            ssf = new SslRMIServerSocketFactory();
+            ssf = new QpidSslRMIServerSocketFactory(sslContext);
         }
         else
         {
@@ -262,31 +282,6 @@ public class JMXManagedObjectRegistry im
         return rmiRegistry;
     }
 
-    private void validateKeyStoreProperties(String keyStorePath, String keyStorePassword) throws FileNotFoundException
-    {
-        if (keyStorePath == null)
-        {
-            throw new IllegalConfigurationException("JVM system property 'javax.net.ssl.keyStore' is not set, "
-                    + "unable to start requested SSL protected JMX connector");
-        }
-        if (keyStorePassword == null)
-        {
-            throw new IllegalConfigurationException( "JVM system property 'javax.net.ssl.keyStorePassword' is not set, "
-                    + "unable to start requested SSL protected JMX connector");
-        }
-
-        File ksf = new File(keyStorePath);
-        if (!ksf.exists())
-        {
-            throw new FileNotFoundException("Cannot find SSL keystore file for JMX management: " + ksf);
-        }
-        if (!ksf.canRead())
-        {
-            throw new FileNotFoundException("Cannot read SSL keystore file for JMX management: "
-                                            + ksf +  ". Check permissions.");
-        }
-    }
-
     @Override
     public void registerObject(ManagedObject managedObject) throws JMException
     {

Added: qpid/trunk/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/QpidSslRMIServerSocketFactory.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/QpidSslRMIServerSocketFactory.java?rev=1467334&view=auto
==============================================================================
--- qpid/trunk/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/QpidSslRMIServerSocketFactory.java (added)
+++ qpid/trunk/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/QpidSslRMIServerSocketFactory.java Fri Apr 12 16:16:09 2013
@@ -0,0 +1,85 @@
+package org.apache.qpid.server.jmx;
+
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.net.Socket;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+import javax.rmi.ssl.SslRMIServerSocketFactory;
+
+public class QpidSslRMIServerSocketFactory extends SslRMIServerSocketFactory
+{
+    private final SSLContext _sslContext;
+
+    /**
+     * SslRMIServerSocketFactory which creates the ServerSocket using the
+     * supplied SSLContext rather than the system default context normally
+     * used by the superclass, allowing us to use a configuration-specified
+     * key store.
+     *
+     * @param sslContext previously created sslContext using the desired key store.
+     * @throws NullPointerException if the provided {@link SSLContext} is null.
+     */
+    public QpidSslRMIServerSocketFactory(SSLContext sslContext) throws NullPointerException
+    {
+        super();
+
+        if(sslContext == null)
+        {
+            throw new NullPointerException("The provided SSLContext must not be null");
+        }
+
+        _sslContext = sslContext;
+
+        //TODO: settings + implementation for SSL client auth, updating equals and hashCode appropriately.
+    }
+
+    @Override
+    public ServerSocket createServerSocket(int port) throws IOException
+    {
+        final SSLSocketFactory factory = _sslContext.getSocketFactory();
+
+        return new ServerSocket(port)
+        {
+            public Socket accept() throws IOException
+            {
+                Socket socket = super.accept();
+
+                SSLSocket sslSocket =
+                    (SSLSocket) factory.createSocket(socket,
+                                                     socket.getInetAddress().getHostName(),
+                                                     socket.getPort(),
+                                                     true);
+                sslSocket.setUseClientMode(false);
+
+                return sslSocket;
+            }
+        };
+    }
+
+    /**
+     * One QpidSslRMIServerSocketFactory is equal to
+     * another if their (non-null) SSLContext are equal.
+     */
+    @Override
+    public boolean equals(Object object)
+    {
+        if (!(object instanceof QpidSslRMIServerSocketFactory))
+        {
+            return false;
+        }
+
+        QpidSslRMIServerSocketFactory that = (QpidSslRMIServerSocketFactory) object;
+
+        return _sslContext.equals(that._sslContext);
+    }
+
+    @Override
+    public int hashCode()
+    {
+        return _sslContext.hashCode();
+    }
+
+}

Modified: qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/BrokerRecoverer.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/BrokerRecoverer.java?rev=1467334&r1=1467333&r2=1467334&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/BrokerRecoverer.java (original)
+++ qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/BrokerRecoverer.java Fri Apr 12 16:16:09 2013
@@ -1,23 +1,28 @@
 package org.apache.qpid.server.configuration.startup;
 
+import java.util.ArrayList;
 import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 import org.apache.qpid.server.configuration.ConfigurationEntry;
 import org.apache.qpid.server.configuration.ConfiguredObjectRecoverer;
 import org.apache.qpid.server.configuration.IllegalConfigurationException;
 import org.apache.qpid.server.configuration.RecovererProvider;
+import org.apache.qpid.server.configuration.store.StoreConfigurationChangeListener;
+import org.apache.qpid.server.configuration.updater.TaskExecutor;
 import org.apache.qpid.server.logging.LogRecorder;
 import org.apache.qpid.server.logging.RootMessageLogger;
 import org.apache.qpid.server.model.AuthenticationProvider;
 import org.apache.qpid.server.model.Broker;
 import org.apache.qpid.server.model.ConfiguredObject;
+import org.apache.qpid.server.model.KeyStore;
 import org.apache.qpid.server.model.Port;
+import org.apache.qpid.server.model.TrustStore;
 import org.apache.qpid.server.model.adapter.AuthenticationProviderFactory;
 import org.apache.qpid.server.model.adapter.BrokerAdapter;
 import org.apache.qpid.server.model.adapter.PortFactory;
-import org.apache.qpid.server.configuration.store.StoreConfigurationChangeListener;
-import org.apache.qpid.server.configuration.updater.TaskExecutor;
 import org.apache.qpid.server.stats.StatisticsGatherer;
 import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
 
@@ -52,31 +57,62 @@ public class BrokerRecoverer implements 
                 _logRecorder, _rootMessageLogger, _authenticationProviderFactory, _portFactory, _taskExecutor, entry.getStore());
 
         broker.addChangeListener(storeChangeListener);
-        Map<String, Collection<ConfigurationEntry>> childEntries = entry.getChildren();
-        for (String type : childEntries.keySet())
+
+        //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>> sslChildEntries = new HashMap<String, Collection<ConfigurationEntry>>(childEntries);
+        List<String> types = new ArrayList<String>(childEntries.keySet());
+
+        for(String type : types)
         {
-            ConfiguredObjectRecoverer<?> recoverer = recovererProvider.getRecoverer(type);
-            if (recoverer == null)
+            if(KeyStore.class.getSimpleName().equals(type) || TrustStore.class.getSimpleName().equals(type))
             {
-                throw new IllegalConfigurationException("Cannot recover entry for the type '" + type + "' from broker");
+                childEntries.remove(type);
             }
-            Collection<ConfigurationEntry> entries = childEntries.get(type);
-            for (ConfigurationEntry childEntry : entries)
+            else
             {
-                ConfiguredObject object = recoverer.create(recovererProvider, childEntry, broker);
-                if (object == null)
-                {
-                    throw new IllegalConfigurationException("Cannot create configured object for the entry " + childEntry);
-                }
-                broker.recoverChild(object);
-                object.addChangeListener(storeChangeListener);
+                sslChildEntries.remove(type);
             }
         }
+
+        for (String type : sslChildEntries.keySet())
+        {
+            recoverType(recovererProvider, storeChangeListener, broker, sslChildEntries, type);
+        }
+        for (String type : childEntries.keySet())
+        {
+            recoverType(recovererProvider, storeChangeListener, broker, childEntries, type);
+        }
+
         wireUpConfiguredObjects(broker, entry.getAttributes());
 
         return broker;
     }
 
+    private void recoverType(RecovererProvider recovererProvider,
+                             StoreConfigurationChangeListener storeChangeListener,
+                             BrokerAdapter broker,
+                             Map<String, Collection<ConfigurationEntry>> childEntries,
+                             String type)
+    {
+        ConfiguredObjectRecoverer<?> recoverer = recovererProvider.getRecoverer(type);
+        if (recoverer == null)
+        {
+            throw new IllegalConfigurationException("Cannot recover entry for the type '" + type + "' from broker");
+        }
+        Collection<ConfigurationEntry> entries = childEntries.get(type);
+        for (ConfigurationEntry childEntry : entries)
+        {
+            ConfiguredObject object = recoverer.create(recovererProvider, childEntry, broker);
+            if (object == null)
+            {
+                throw new IllegalConfigurationException("Cannot create configured object for the entry " + childEntry);
+            }
+            broker.recoverChild(object);
+            object.addChangeListener(storeChangeListener);
+        }
+    }
+
     private void wireUpConfiguredObjects(BrokerAdapter broker, Map<String, Object> brokerAttributes)
     {
         AuthenticationProvider defaultAuthenticationProvider = null;

Modified: qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Broker.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Broker.java?rev=1467334&r1=1467333&r2=1467334&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Broker.java (original)
+++ qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Broker.java Fri Apr 12 16:16:09 2013
@@ -88,18 +88,6 @@ public interface Broker extends Configur
     String ACL_FILE = "aclFile";
 
     /*
-     * A temporary attributes to set the broker default key/trust stores.
-     * TODO: Remove them after adding a full support to configure KeyStore/TrustStore via management layers.
-     */
-    String KEY_STORE_PATH = "keyStorePath";
-    String KEY_STORE_PASSWORD = "keyStorePassword";
-    String KEY_STORE_CERT_ALIAS = "keyStoreCertAlias";
-    String TRUST_STORE_PATH = "trustStorePath";
-    String TRUST_STORE_PASSWORD = "trustStorePassword";
-    String PEER_STORE_PATH = "peerStorePath";
-    String PEER_STORE_PASSWORD = "peerStorePassword";
-
-    /*
      * A temporary attributes to set the broker group file.
      * TODO: Remove them after adding a full support to configure authorization providers via management layers.
      */
@@ -148,16 +136,8 @@ public interface Broker extends Configur
                               VIRTUALHOST_STORE_TRANSACTION_IDLE_TIMEOUT_WARN,
                               VIRTUALHOST_STORE_TRANSACTION_OPEN_TIMEOUT_CLOSE,
                               VIRTUALHOST_STORE_TRANSACTION_OPEN_TIMEOUT_WARN,
-
-                              ACL_FILE,
-                              KEY_STORE_PATH,
-                              KEY_STORE_PASSWORD,
-                              KEY_STORE_CERT_ALIAS,
-                              TRUST_STORE_PATH,
-                              TRUST_STORE_PASSWORD,
-                              PEER_STORE_PATH,
-                              PEER_STORE_PASSWORD,
-                              GROUP_FILE
+                              GROUP_FILE,
+                              ACL_FILE
                               ));
 
     //children
@@ -194,6 +174,10 @@ public interface Broker extends Configur
 
     VirtualHost findVirtualHostByName(String name);
 
+    KeyStore findKeyStoreByName(String name);
+
+    TrustStore findTrustStoreByName(String name);
+
     /**
      * Get the SubjectCreator for the given socket address.
      * TODO: move the authentication related functionality into host aliases and AuthenticationProviders
@@ -211,10 +195,6 @@ public interface Broker extends Configur
      */
     VirtualHostRegistry getVirtualHostRegistry();
 
-    KeyStore getDefaultKeyStore();
-
-    TrustStore getDefaultTrustStore();
-
     TaskExecutor getTaskExecutor();
 
     boolean isManagementMode();

Modified: qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/KeyStore.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/KeyStore.java?rev=1467334&r1=1467333&r2=1467334&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/KeyStore.java (original)
+++ qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/KeyStore.java Fri Apr 12 16:16:09 2013
@@ -24,10 +24,23 @@ import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 
-public interface KeyStore extends TrustStore
+public interface KeyStore extends ConfiguredObject
 {
+    String ID = "id";
+    String NAME = "name";
+    String DURABLE = "durable";
+    String LIFETIME_POLICY = "lifetimePolicy";
+    String STATE = "state";
+    String TIME_TO_LIVE = "timeToLive";
+    String CREATED = "created";
+    String UPDATED = "updated";
+    String DESCRIPTION = "description";
 
+    String PATH = "path";
+    String PASSWORD = "password";
+    String TYPE = "type";
     String CERTIFICATE_ALIAS = "certificateAlias";
+    String KEY_MANAGER_FACTORY_ALGORITHM = "keyManagerFactoryAlgorithm";
 
     public static final Collection<String> AVAILABLE_ATTRIBUTES =
             Collections.unmodifiableList(
@@ -44,8 +57,11 @@ public interface KeyStore extends TrustS
                               PATH,
                               PASSWORD,
                               TYPE,
-                              KEY_MANAGER_FACTORY_ALGORITHM,
-                              CERTIFICATE_ALIAS
+                              CERTIFICATE_ALIAS,
+                              KEY_MANAGER_FACTORY_ALGORITHM
                               ));
 
+    public String getPassword();
+
+    public void setPassword(String password);
 }

Modified: qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Port.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Port.java?rev=1467334&r1=1467333&r2=1467334&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Port.java (original)
+++ qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Port.java Fri Apr 12 16:16:09 2013
@@ -45,6 +45,8 @@ public interface Port extends Configured
     String NEED_CLIENT_AUTH                     = "needClientAuth";
     String WANT_CLIENT_AUTH                     = "wantClientAuth";
     String AUTHENTICATION_PROVIDER              = "authenticationProvider";
+    String KEY_STORE                            = "keyStore";
+    String TRUST_STORES                         = "trustStores";
 
     // Attributes
     public static final Collection<String> AVAILABLE_ATTRIBUTES =
@@ -67,7 +69,9 @@ public interface Port extends Configured
                             RECEIVE_BUFFER_SIZE,
                             NEED_CLIENT_AUTH,
                             WANT_CLIENT_AUTH,
-                            AUTHENTICATION_PROVIDER
+                            AUTHENTICATION_PROVIDER,
+                            KEY_STORE,
+                            TRUST_STORES
                                  ));
 
 
@@ -75,6 +79,10 @@ public interface Port extends Configured
 
     int getPort();
 
+    KeyStore getKeyStore();
+
+    Collection<TrustStore> getTrustStores();
+
     Collection<Transport> getTransports();
 
     void addTransport(Transport transport) throws IllegalStateException,

Modified: qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/TrustStore.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/TrustStore.java?rev=1467334&r1=1467333&r2=1467334&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/TrustStore.java (original)
+++ qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/TrustStore.java Fri Apr 12 16:16:09 2013
@@ -38,9 +38,9 @@ public interface TrustStore extends Conf
 
     String PATH = "path";
     String PASSWORD = "password";
-    String PEERS_ONLY = "peersOnly";
     String TYPE = "type";
-    String KEY_MANAGER_FACTORY_ALGORITHM = "keyManagerFactoryAlgorithm";
+    String PEERS_ONLY = "peersOnly";
+    String TRUST_MANAGER_FACTORY_ALGORITHM = "trustManagerFactoryAlgorithm";
 
     public static final Collection<String> AVAILABLE_ATTRIBUTES =
             Collections.unmodifiableList(
@@ -56,9 +56,9 @@ public interface TrustStore extends Conf
                               DESCRIPTION,
                               PATH,
                               PASSWORD,
-                              PEERS_ONLY,
                               TYPE,
-                              KEY_MANAGER_FACTORY_ALGORITHM
+                              PEERS_ONLY,
+                              TRUST_MANAGER_FACTORY_ALGORITHM
                               ));
 
     public String getPassword();

Modified: qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AbstractAdapter.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AbstractAdapter.java?rev=1467334&r1=1467333&r2=1467334&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AbstractAdapter.java (original)
+++ qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AbstractAdapter.java Fri Apr 12 16:16:09 2013
@@ -63,6 +63,7 @@ abstract class AbstractAdapter implement
             {
                 if (attributes.containsKey(name))
                 {
+                    //TODO: dont put nulls
                     _attributes.put(name, attributes.get(name));
                 }
             }
@@ -254,6 +255,7 @@ abstract class AbstractAdapter implement
             if((currentValue == null && expected == null)
                || (currentValue != null && currentValue.equals(expected)))
             {
+                //TODO: dont put nulls
                 _attributes.put(name, desired);
                 return true;
             }
@@ -397,4 +399,51 @@ abstract class AbstractAdapter implement
     {
         return _defaultAttributes;
     }
+
+    /**
+     * Returns a map of effective attribute values that would result
+     * if applying the supplied changes. Does not apply the changes.
+     */
+    protected Map<String, Object> generateEffectiveAttributes(Map<String,Object> changedValues)
+    {
+        //Build a new set of effective attributes that would be
+        //the result of applying the attribute changes, so we
+        //can validate the configuration that would result
+
+        Map<String, Object> defaultValues = getDefaultAttributes();
+        Map<String, Object> existingActualValues = getActualAttributes();
+
+        //create a new merged map, starting with the defaults
+        Map<String, Object> merged =  new HashMap<String, Object>(defaultValues);
+
+        for(String name : getAttributeNames())
+        {
+            if(changedValues.containsKey(name))
+            {
+                Object changedValue = changedValues.get(name);
+                if(changedValue != null)
+                {
+                    //use the new non-null value for the merged values
+                    merged.put(name, changedValue);
+                }
+                else
+                {
+                    //we just use the default (if there was one) since the changed
+                    //value is null and effectively clears any existing actual value
+                }
+            }
+            else if(existingActualValues.get(name) != null)
+            {
+                //Use existing non-null actual value for the merge
+                merged.put(name, existingActualValues.get(name));
+            }
+            else
+            {
+                //There was neither a change or an existing non-null actual
+                //value, so just use the default value (if there was one).
+            }
+        }
+
+        return merged;
+    }
 }

Modified: qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AbstractKeyStoreAdapter.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AbstractKeyStoreAdapter.java?rev=1467334&r1=1467333&r2=1467334&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AbstractKeyStoreAdapter.java (original)
+++ qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AbstractKeyStoreAdapter.java Fri Apr 12 16:16:09 2013
@@ -37,20 +37,21 @@ import org.apache.qpid.server.util.MapVa
 
 public abstract class AbstractKeyStoreAdapter extends AbstractAdapter
 {
+    public static final String DUMMY_PASSWORD_MASK = "********";
+    public static final String DEFAULT_KEYSTORE_TYPE = java.security.KeyStore.getDefaultType();
+
     private String _name;
     private String _password;
 
-    protected AbstractKeyStoreAdapter(UUID id, Broker broker, Map<String, Object> attributes)
+    protected AbstractKeyStoreAdapter(UUID id, Broker broker, Map<String, Object> defaults,
+                                      Map<String, Object> attributes)
     {
-        super(id, broker.getTaskExecutor());
+        super(id, defaults, attributes, broker.getTaskExecutor());
         addParent(Broker.class, broker);
+
         _name = MapValueConverter.getStringAttribute(TrustStore.NAME, attributes);
         _password = MapValueConverter.getStringAttribute(TrustStore.PASSWORD, attributes);
-        setMandatoryAttribute(TrustStore.PATH, attributes);
-        setOptionalAttribute(TrustStore.PEERS_ONLY, attributes);
-        setOptionalAttribute(TrustStore.TYPE, attributes);
-        setOptionalAttribute(TrustStore.KEY_MANAGER_FACTORY_ALGORITHM, attributes);
-        setOptionalAttribute(TrustStore.DESCRIPTION, attributes);
+        MapValueConverter.assertMandatoryAttribute(KeyStore.PATH, attributes);
     }
 
     @Override
@@ -163,15 +164,16 @@ public abstract class AbstractKeyStoreAd
         }
         else if(KeyStore.PASSWORD.equals(name))
         {
-            return null; // for security reasons we don't expose the password
+            // For security reasons we don't expose the password
+            if (getPassword() != null)
+            {
+                return DUMMY_PASSWORD_MASK;
+            }
+
+            return null;
         }
-        return super.getAttribute(name);
-    }
 
-    @Override
-    protected boolean setState(State currentState, State desiredState)
-    {
-        return false;
+        return super.getAttribute(name);
     }
 
     public String getPassword()
@@ -183,25 +185,4 @@ public abstract class AbstractKeyStoreAd
     {
         _password = password;
     }
-
-    private void setMandatoryAttribute(String name, Map<String, Object> attributeValues)
-    {
-        changeAttribute(name, null, MapValueConverter.getStringAttribute(name, attributeValues));
-    }
-
-    private void setOptionalAttribute(String name, Map<String, Object> attributeValues)
-    {
-        Object attrValue = attributeValues.get(name);
-        if (attrValue != null)
-        {
-            if (attrValue instanceof Boolean)
-            {
-                changeAttribute(name, null, MapValueConverter.getBooleanAttribute(name, attributeValues));
-            }
-            else
-            {
-                changeAttribute(name, null, MapValueConverter.getStringAttribute(name, attributeValues));
-            }
-        }
-    }
 }

Modified: qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AmqpPortAdapter.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AmqpPortAdapter.java?rev=1467334&r1=1467333&r2=1467334&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AmqpPortAdapter.java (original)
+++ qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AmqpPortAdapter.java Fri Apr 12 16:16:09 2013
@@ -133,15 +133,11 @@ public class AmqpPortAdapter extends Por
 
     private SSLContext createSslContext()
     {
-        KeyStore keyStore = _broker.getDefaultKeyStore();
-        if (keyStore == null)
-        {
-            throw new IllegalConfigurationException("SSL was requested on AMQP port '"
-                    + this.getName() + "' but no key store defined");
-        }
+        KeyStore keyStore = getKeyStore();
 
-        Collection<TrustStore> trustStores = _broker.getTrustStores();
-        if (((Boolean)getAttribute(NEED_CLIENT_AUTH) || (Boolean)getAttribute(WANT_CLIENT_AUTH)) && trustStores.isEmpty())
+        Collection<TrustStore> trustStores = getTrustStores();
+        boolean needClientCert = (Boolean)getAttribute(NEED_CLIENT_AUTH) || (Boolean)getAttribute(WANT_CLIENT_AUTH);
+        if (needClientCert && trustStores.isEmpty())
         {
             throw new IllegalConfigurationException("Client certificate authentication is enabled on AMQP port '"
                     + this.getName() + "' but no trust store defined");
@@ -165,7 +161,7 @@ public class AmqpPortAdapter extends Por
                                                                              trustStore.getPassword(),
                                                                              (String)trustStore.getAttribute(TrustStore.TYPE),
                                                                              (Boolean) trustStore.getAttribute(TrustStore.PEERS_ONLY),
-                                                                             (String)trustStore.getAttribute(TrustStore.KEY_MANAGER_FACTORY_ALGORITHM)));
+                                                                             (String)trustStore.getAttribute(TrustStore.TRUST_MANAGER_FACTORY_ALGORITHM)));
                 }
                 sslContext = SSLContextFactory.buildClientContext(trstWrappers, keystorePath,
                                                                   keystorePassword, keystoreType,

Modified: qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java?rev=1467334&r1=1467333&r2=1467334&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java (original)
+++ qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java Fri Apr 12 16:16:09 2013
@@ -24,7 +24,6 @@ import java.lang.reflect.Type;
 import java.net.InetSocketAddress;
 import java.net.SocketAddress;
 import java.security.AccessControlException;
-import java.security.KeyStoreException;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -32,13 +31,12 @@ import java.util.HashMap;
 import java.util.Map;
 import java.util.UUID;
 
-import javax.net.ssl.KeyManagerFactory;
-import java.security.cert.Certificate;
-
 import org.apache.log4j.Logger;
 import org.apache.qpid.common.QpidProperties;
 import org.apache.qpid.server.configuration.ConfigurationEntryStore;
 import org.apache.qpid.server.configuration.IllegalConfigurationException;
+import org.apache.qpid.server.configuration.store.ManagementModeStoreHandler;
+import org.apache.qpid.server.configuration.updater.TaskExecutor;
 import org.apache.qpid.server.logging.LogRecorder;
 import org.apache.qpid.server.logging.RootMessageLogger;
 import org.apache.qpid.server.logging.actors.BrokerActor;
@@ -58,22 +56,18 @@ import org.apache.qpid.server.model.Stat
 import org.apache.qpid.server.model.TrustStore;
 import org.apache.qpid.server.model.UUIDGenerator;
 import org.apache.qpid.server.model.VirtualHost;
-import org.apache.qpid.server.configuration.store.ManagementModeStoreHandler;
-import org.apache.qpid.server.configuration.updater.TaskExecutor;
+import org.apache.qpid.server.security.SecurityManager;
+import org.apache.qpid.server.security.SubjectCreator;
 import org.apache.qpid.server.security.access.Operation;
 import org.apache.qpid.server.security.group.FileGroupManager;
 import org.apache.qpid.server.security.group.GroupManager;
-import org.apache.qpid.server.security.SecurityManager;
-import org.apache.qpid.server.security.SubjectCreator;
 import org.apache.qpid.server.stats.StatisticsGatherer;
 import org.apache.qpid.server.store.MessageStoreCreator;
 import org.apache.qpid.server.util.MapValueConverter;
 import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
-import org.apache.qpid.transport.network.security.ssl.SSLUtil;
 
 public class BrokerAdapter extends AbstractAdapter implements Broker, ConfigurationChangeListener
 {
-
     private static final Logger LOGGER = Logger.getLogger(BrokerAdapter.class);
 
     @SuppressWarnings("serial")
@@ -100,13 +94,6 @@ public class BrokerAdapter extends Abstr
         put(DEFAULT_VIRTUAL_HOST, String.class);
         put(DEFAULT_AUTHENTICATION_PROVIDER, String.class);
 
-        put(KEY_STORE_PATH, String.class);
-        put(KEY_STORE_PASSWORD, String.class);
-        put(KEY_STORE_CERT_ALIAS, String.class);
-        put(TRUST_STORE_PATH, String.class);
-        put(TRUST_STORE_PASSWORD, String.class);
-        put(PEER_STORE_PATH, String.class);
-        put(PEER_STORE_PASSWORD, String.class);
         put(GROUP_FILE, String.class);
         put(VIRTUALHOST_STORE_TRANSACTION_IDLE_TIMEOUT_CLOSE, Long.class);
         put(VIRTUALHOST_STORE_TRANSACTION_IDLE_TIMEOUT_WARN, Long.class);
@@ -133,12 +120,7 @@ public class BrokerAdapter extends Abstr
     public static final long DEFAULT_STORE_TRANSACTION_IDLE_TIMEOUT_WARN = 0l;
     public static final long DEFAULT_STORE_TRANSACTION_OPEN_TIMEOUT_CLOSE = 0l;
     public static final long DEFAULT_STORE_TRANSACTION_OPEN_TIMEOUT_WARN = 0l;
-    private static final String DEFAULT_KEY_STORE_NAME = "defaultKeyStore";
-    private static final String DEFAULT_TRUST_STORE_NAME = "defaultTrustStore";
     private static final String DEFAULT_GROUP_PROVIDER_NAME = "defaultGroupProvider";
-    private static final String DEFAULT_PEER_STORE_NAME = "defaultPeerStore";
-
-    private static final String DUMMY_PASSWORD_MASK = "********";
 
     @SuppressWarnings("serial")
     private static final Map<String, Object> DEFAULTS = Collections.unmodifiableMap(new HashMap<String, Object>(){{
@@ -182,16 +164,14 @@ public class BrokerAdapter extends Abstr
     private final Map<UUID, AuthenticationProvider> _authenticationProviders = new HashMap<UUID, AuthenticationProvider>();
     private final Map<String, GroupProvider> _groupProviders = new HashMap<String, GroupProvider>();
     private final Map<UUID, ConfiguredObject> _plugins = new HashMap<UUID, ConfiguredObject>();
-    private final Map<UUID, KeyStore> _keyStores = new HashMap<UUID, KeyStore>();
-    private final Map<UUID, TrustStore> _trustStores = new HashMap<UUID, TrustStore>();
+    private final Map<String, KeyStore> _keyStores = new HashMap<String, KeyStore>();
+    private final Map<String, TrustStore> _trustStores = new HashMap<String, TrustStore>();
 
     private final AuthenticationProviderFactory _authenticationProviderFactory;
     private AuthenticationProvider _defaultAuthenticationProvider;
 
     private final PortFactory _portFactory;
     private final SecurityManager _securityManager;
-    private final UUID _defaultKeyStoreId;
-    private final UUID _defaultTrustStoreId;
 
     private final Collection<String> _supportedStoreTypes;
     private final ConfigurationEntryStore _brokerStore;
@@ -212,8 +192,6 @@ public class BrokerAdapter extends Abstr
         _portFactory = portFactory;
         _securityManager = new SecurityManager((String)getAttribute(ACL_FILE));
         addChangeListener(_securityManager);
-        _defaultKeyStoreId = UUIDGenerator.generateBrokerChildUUID(KeyStore.class.getSimpleName(), DEFAULT_KEY_STORE_NAME);
-        _defaultTrustStoreId = UUIDGenerator.generateBrokerChildUUID(TrustStore.class.getSimpleName(), DEFAULT_TRUST_STORE_NAME);
         createBrokerChildrenFromAttributes();
         _supportedStoreTypes = new MessageStoreCreator().getStoreTypes();
         _brokerStore = brokerStore;
@@ -226,9 +204,6 @@ public class BrokerAdapter extends Abstr
     private void createBrokerChildrenFromAttributes()
     {
         createGroupProvider();
-        createKeyStore();
-        createTrustStore();
-        createPeerStore();
     }
 
     private void createGroupProvider()
@@ -248,80 +223,12 @@ public class BrokerAdapter extends Abstr
         }
     }
 
-    private void createKeyStore()
-    {
-        Map<String, Object> actualAttributes = getActualAttributes();
-        String keyStorePath = (String) getAttribute(KEY_STORE_PATH);
-        if (keyStorePath != null)
-        {
-            Map<String, Object> keyStoreAttributes = new HashMap<String, Object>();
-            keyStoreAttributes.put(KeyStore.NAME, DEFAULT_KEY_STORE_NAME);
-            keyStoreAttributes.put(KeyStore.PATH, keyStorePath);
-            keyStoreAttributes.put(KeyStore.PASSWORD, (String) actualAttributes.get(KEY_STORE_PASSWORD));
-            keyStoreAttributes.put(KeyStore.TYPE, java.security.KeyStore.getDefaultType());
-            keyStoreAttributes.put(KeyStore.CERTIFICATE_ALIAS, getAttribute(KEY_STORE_CERT_ALIAS));
-            keyStoreAttributes.put(KeyStore.KEY_MANAGER_FACTORY_ALGORITHM, KeyManagerFactory.getDefaultAlgorithm());
-            KeyStoreAdapter keyStoreAdapter = new KeyStoreAdapter(_defaultKeyStoreId, this, keyStoreAttributes);
-            _keyStores.put(keyStoreAdapter.getId(), keyStoreAdapter);
-        }
-        else
-        {
-            _keyStores.remove(_defaultKeyStoreId);
-        }
-    }
-
-    private void createTrustStore()
-    {
-        Map<String, Object> actualAttributes = getActualAttributes();
-        String trustStorePath = (String) getAttribute(TRUST_STORE_PATH);
-        if (trustStorePath != null)
-        {
-            Map<String, Object> trsustStoreAttributes = new HashMap<String, Object>();
-            trsustStoreAttributes.put(TrustStore.NAME, DEFAULT_TRUST_STORE_NAME);
-            trsustStoreAttributes.put(TrustStore.PATH, trustStorePath);
-            trsustStoreAttributes.put(TrustStore.PEERS_ONLY, Boolean.FALSE);
-            trsustStoreAttributes.put(TrustStore.PASSWORD, (String) actualAttributes.get(TRUST_STORE_PASSWORD));
-            trsustStoreAttributes.put(TrustStore.TYPE, java.security.KeyStore.getDefaultType());
-            trsustStoreAttributes.put(TrustStore.KEY_MANAGER_FACTORY_ALGORITHM, KeyManagerFactory.getDefaultAlgorithm());
-            TrustStoreAdapter trustStore = new TrustStoreAdapter(_defaultTrustStoreId, this, trsustStoreAttributes);
-            _trustStores.put(trustStore.getId(), trustStore);
-        }
-        else
-        {
-            _trustStores.remove(_defaultTrustStoreId);
-        }
-    }
-
-    private void createPeerStore()
-    {
-        Map<String, Object> actualAttributes = getActualAttributes();
-        String peerStorePath = (String) getAttribute(PEER_STORE_PATH);
-        UUID peerStoreId = UUIDGenerator.generateBrokerChildUUID(TrustStore.class.getSimpleName(), DEFAULT_PEER_STORE_NAME);
-        if (peerStorePath != null)
-        {
-            Map<String, Object> peerStoreAttributes = new HashMap<String, Object>();
-            peerStoreAttributes.put(TrustStore.NAME, peerStoreId.toString());
-            peerStoreAttributes.put(TrustStore.PATH, peerStorePath);
-            peerStoreAttributes.put(TrustStore.PEERS_ONLY, Boolean.TRUE);
-            peerStoreAttributes.put(TrustStore.PASSWORD, (String) actualAttributes.get(PEER_STORE_PASSWORD));
-            peerStoreAttributes.put(TrustStore.TYPE, java.security.KeyStore.getDefaultType());
-            peerStoreAttributes.put(TrustStore.KEY_MANAGER_FACTORY_ALGORITHM, KeyManagerFactory.getDefaultAlgorithm());
-            TrustStoreAdapter trustStore = new TrustStoreAdapter(peerStoreId, this, peerStoreAttributes);
-            _trustStores.put(trustStore.getId(), trustStore);
-        }
-        else
-        {
-            _trustStores.remove(peerStoreId);
-        }
-    }
-
     public Collection<VirtualHost> getVirtualHosts()
     {
         synchronized(_vhostAdapters)
         {
             return new ArrayList<VirtualHost>(_vhostAdapters.values());
         }
-
     }
 
     public Collection<Port> getPorts()
@@ -354,6 +261,22 @@ public class BrokerAdapter extends Abstr
         return null;
     }
 
+    public KeyStore findKeyStoreByName(String keyStoreName)
+    {
+        synchronized(_keyStores)
+        {
+            return _keyStores.get(keyStoreName);
+        }
+    }
+
+    public TrustStore findTrustStoreByName(String trustStoreName)
+    {
+        synchronized(_trustStores)
+        {
+            return _trustStores.get(trustStoreName);
+        }
+    }
+
     @Override
     public AuthenticationProvider getDefaultAuthenticationProvider()
     {
@@ -396,14 +319,14 @@ public class BrokerAdapter extends Abstr
 
         // permission has already been granted to create the virtual host
         // disable further access check on other operations, e.g. create exchange
-        _securityManager.setAccessChecksDisabled(true);
+        SecurityManager.setAccessChecksDisabled(true);
         try
         {
             virtualHostAdapter.setDesiredState(State.INITIALISING, State.ACTIVE);
         }
         finally
         {
-            _securityManager.setAccessChecksDisabled(false);
+            SecurityManager.setAccessChecksDisabled(false);
         }
         return virtualHostAdapter;
     }
@@ -526,6 +449,14 @@ public class BrokerAdapter extends Abstr
         {
             return (C) createAuthenticationProvider(attributes);
         }
+        else if(childClass == KeyStore.class)
+        {
+            return (C) createKeyStore(attributes);
+        }
+        else if(childClass == TrustStore.class)
+        {
+            return (C) createTrustStore(attributes);
+        }
         else
         {
             throw new IllegalArgumentException("Cannot create child of class " + childClass.getSimpleName());
@@ -618,40 +549,76 @@ public class BrokerAdapter extends Abstr
         throw new UnsupportedOperationException("Not implemented yet!");
     }
 
+    private KeyStore createKeyStore(Map<String, Object> attributes)
+    {
+        KeyStore keyStore = new KeyStoreAdapter(UUIDGenerator.generateRandomUUID(), this, attributes);
+        addKeyStore(keyStore);
+
+        return keyStore;
+    }
+
+    private TrustStore createTrustStore(Map<String, Object> attributes)
+    {
+        TrustStore trustStore = new TrustStoreAdapter(UUIDGenerator.generateRandomUUID(), this, attributes);
+        addTrustStore(trustStore);
+
+        return trustStore;
+    }
+
     private void addKeyStore(KeyStore keyStore)
     {
         synchronized (_keyStores)
         {
-            if(_keyStores.containsKey(keyStore.getId()))
+            if(_keyStores.containsKey(keyStore.getName()))
             {
-                throw new IllegalConfigurationException("Cannot add KeyStore because one with id " + keyStore.getId() + " already exists");
+                throw new IllegalConfigurationException("Can't add KeyStore because one with name " + keyStore.getName() + " already exists");
             }
-            _keyStores.put(keyStore.getId(), keyStore);
+            _keyStores.put(keyStore.getName(), keyStore);
         }
         keyStore.addChangeListener(this);
     }
 
     private boolean deleteKeyStore(KeyStore object)
     {
-        throw new UnsupportedOperationException("Not implemented yet!");
+        synchronized(_keyStores)
+        {
+            String name = object.getName();
+            KeyStore removedKeyStore = _keyStores.remove(name);
+            if(removedKeyStore != null)
+            {
+                removedKeyStore.removeChangeListener(this);
+            }
+
+            return removedKeyStore != null;
+        }
     }
 
     private void addTrustStore(TrustStore trustStore)
     {
         synchronized (_trustStores)
         {
-            if(_trustStores.containsKey(trustStore.getId()))
+            if(_trustStores.containsKey(trustStore.getName()))
             {
-                throw new IllegalConfigurationException("Cannot add TrustStore because one with id " + trustStore.getId() + " already exists");
+                throw new IllegalConfigurationException("Can't add TrustStore because one with name " + trustStore.getName() + " already exists");
             }
-            _trustStores.put(trustStore.getId(), trustStore);
+            _trustStores.put(trustStore.getName(), trustStore);
         }
         trustStore.addChangeListener(this);
     }
 
     private boolean deleteTrustStore(TrustStore object)
     {
-        throw new UnsupportedOperationException("Not implemented yet!");
+        synchronized(_trustStores)
+        {
+            String name = object.getName();
+            TrustStore removedTrustStore = _trustStores.remove(name);
+            if(removedTrustStore != null)
+            {
+                removedTrustStore.removeChangeListener(this);
+            }
+
+            return removedTrustStore != null;
+        }
     }
 
     @Override
@@ -726,14 +693,6 @@ public class BrokerAdapter extends Abstr
         {
             return _authenticationProviderFactory.getSupportedAuthenticationProviders();
         }
-        else if (KEY_STORE_PASSWORD.equals(name) || TRUST_STORE_PASSWORD.equals(name) || PEER_STORE_PASSWORD.equals(name))
-        {
-            if (getActualAttributes().get(name) != null)
-            {
-                return DUMMY_PASSWORD_MASK;
-            }
-            return null;
-        }
         else if (MODEL_VERSION.equals(name))
         {
             return Model.MODEL_MAJOR_VERSION + "." + Model.MODEL_MINOR_VERSION;
@@ -885,6 +844,7 @@ public class BrokerAdapter extends Abstr
             {
                 childDeleted = deleteTrustStore((TrustStore)object);
             }
+
             if(childDeleted)
             {
                 childRemoved(object);
@@ -1034,18 +994,6 @@ public class BrokerAdapter extends Abstr
     }
 
     @Override
-    public KeyStore getDefaultKeyStore()
-    {
-        return _keyStores.get(_defaultKeyStoreId);
-    }
-
-    @Override
-    public TrustStore getDefaultTrustStore()
-    {
-        return _trustStores.get(_defaultTrustStoreId);
-    }
-
-    @Override
     public TaskExecutor getTaskExecutor()
     {
         return super.getTaskExecutor();
@@ -1058,9 +1006,6 @@ public class BrokerAdapter extends Abstr
         Map<String, Object> convertedAttributes = MapValueConverter.convert(attributes, ATTRIBUTE_TYPES);
         validateAttributes(convertedAttributes);
 
-        boolean keyStoreChanged = false;
-        boolean trustStoreChanged = false;
-        boolean peerStoreChanged = false;
         Collection<String> names = AVAILABLE_ATTRIBUTES;
         for (String name : names)
         {
@@ -1081,34 +1026,11 @@ public class BrokerAdapter extends Abstr
                             _defaultAuthenticationProvider = findAuthenticationProviderByName((String)desired);
                         }
                     }
-                    else if (KEY_STORE_PATH.equals(name) || KEY_STORE_PASSWORD.equals(name) || KEY_STORE_CERT_ALIAS.equals(name))
-                    {
-                        keyStoreChanged = true;
-                    }
-                    else if (TRUST_STORE_PATH.equals(name) || TRUST_STORE_PASSWORD.equals(name))
-                    {
-                        trustStoreChanged = true;
-                    }
-                    else if (PEER_STORE_PATH.equals(name) || PEER_STORE_PASSWORD.equals(name))
-                    {
-                        peerStoreChanged = true;
-                    }
+
                     attributeSet(name, expected, desired);
                 }
             }
         }
-        if (keyStoreChanged)
-        {
-            createKeyStore();
-        }
-        if (trustStoreChanged)
-        {
-            createTrustStore();
-        }
-        if (peerStoreChanged)
-        {
-            createPeerStore();
-        }
     }
 
     private void validateAttributes(Map<String, Object> convertedAttributes)
@@ -1125,9 +1047,7 @@ public class BrokerAdapter extends Abstr
             // create a group manager to validate the groups specified in file
             new FileGroupManager(groupFile);
         }
-        validateKeyStoreAttributes(convertedAttributes, "key store", KEY_STORE_PATH, KEY_STORE_PASSWORD, KEY_STORE_CERT_ALIAS);
-        validateKeyStoreAttributes(convertedAttributes, "trust store", TRUST_STORE_PATH, TRUST_STORE_PASSWORD, null);
-        validateKeyStoreAttributes(convertedAttributes, "peer store", PEER_STORE_PATH, PEER_STORE_PASSWORD, null);
+
         String defaultAuthenticationProvider = (String) convertedAttributes.get(DEFAULT_AUTHENTICATION_PROVIDER);
         if (defaultAuthenticationProvider != null)
         {
@@ -1176,59 +1096,6 @@ public class BrokerAdapter extends Abstr
         }
     }
 
-    private void validateKeyStoreAttributes(Map<String, Object> convertedAttributes, String type, String pathAttribute,
-            String passwordAttribute, String aliasAttribute)
-    {
-        String keyStoreFile = (String) convertedAttributes.get(pathAttribute);
-        String password = (String) convertedAttributes.get(passwordAttribute);
-        String alias = aliasAttribute!= null? (String) convertedAttributes.get(aliasAttribute) : null;
-        if (keyStoreFile != null || password != null || alias != null)
-        {
-            if (keyStoreFile == null)
-            {
-                keyStoreFile  = (String) getActualAttributes().get(pathAttribute);
-            }
-            if (password == null)
-            {
-                password = (String) getActualAttributes().get(passwordAttribute);
-            }
-            java.security.KeyStore keyStore = null;
-            try
-            {
-                keyStore = SSLUtil.getInitializedKeyStore(keyStoreFile, password, java.security.KeyStore.getDefaultType());
-            }
-            catch (Exception e)
-            {
-                throw new IllegalConfigurationException("Cannot instantiate " + type + " at " + keyStoreFile, e);
-            }
-            if (aliasAttribute != null)
-            {
-                if (alias == null)
-                {
-                    alias  = (String) getActualAttributes().get(aliasAttribute);
-                }
-                if (alias != null)
-                {
-                    Certificate cert = null;
-                    try
-                    {
-                        cert = keyStore.getCertificate(alias);
-                    }
-                    catch (KeyStoreException e)
-                    {
-                        // key store should be initialized above
-                        throw new RuntimeException("Key store has not been initialized", e);
-                    }
-                    if (cert == null)
-                    {
-                        throw new IllegalConfigurationException("Cannot find a certificate with alias " + alias + "in " + type
-                                + " : " + keyStoreFile);
-                    }
-                }
-            }
-        }
-    }
-
     @Override
     protected void authoriseSetAttribute(String name, Object expected, Object desired) throws AccessControlException
     {

Modified: qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/KeyStoreAdapter.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/KeyStoreAdapter.java?rev=1467334&r1=1467333&r2=1467334&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/KeyStoreAdapter.java (original)
+++ qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/KeyStoreAdapter.java Fri Apr 12 16:16:09 2013
@@ -20,23 +20,63 @@
  */
 package org.apache.qpid.server.model.adapter;
 
+import java.lang.reflect.Type;
+import java.security.AccessControlException;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.Certificate;
+import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
 import java.util.Map;
 import java.util.UUID;
 
+import javax.net.ssl.KeyManagerFactory;
+
+import org.apache.qpid.server.configuration.IllegalConfigurationException;
 import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.IntegrityViolationException;
 import org.apache.qpid.server.model.KeyStore;
+import org.apache.qpid.server.model.Port;
+import org.apache.qpid.server.model.State;
+import org.apache.qpid.server.security.access.Operation;
+import org.apache.qpid.server.util.MapValueConverter;
+import org.apache.qpid.transport.network.security.ssl.SSLUtil;
 
 public class KeyStoreAdapter extends AbstractKeyStoreAdapter implements KeyStore
 {
+    @SuppressWarnings("serial")
+    public static final Map<String, Type> ATTRIBUTE_TYPES = Collections.unmodifiableMap(new HashMap<String, Type>(){{
+        put(NAME, String.class);
+        put(PATH, String.class);
+        put(PASSWORD, String.class);
+        put(TYPE, String.class);
+        put(CERTIFICATE_ALIAS, String.class);
+        put(KEY_MANAGER_FACTORY_ALGORITHM, String.class);
+    }});
+
+    @SuppressWarnings("serial")
+    public static final Map<String, Object> DEFAULTS = Collections.unmodifiableMap(new HashMap<String, Object>(){{
+        put(KeyStore.TYPE, DEFAULT_KEYSTORE_TYPE);
+        put(KeyStore.KEY_MANAGER_FACTORY_ALGORITHM, KeyManagerFactory.getDefaultAlgorithm());
+    }});
+
+    private Broker _broker;
 
     public KeyStoreAdapter(UUID id, Broker broker, Map<String, Object> attributes)
     {
-        super(id, broker, attributes);
-        if (attributes.get(CERTIFICATE_ALIAS) != null)
-        {
-            changeAttribute(CERTIFICATE_ALIAS, null, attributes.get(CERTIFICATE_ALIAS));
-        }
+        super(id, broker, DEFAULTS, MapValueConverter.convert(attributes, ATTRIBUTE_TYPES));
+        _broker = broker;
+
+        String keyStorePath = (String)getAttribute(KeyStore.PATH);
+        String keyStorePassword = getPassword();
+        String keyStoreType = (String)getAttribute(KeyStore.TYPE);
+        String keyManagerFactoryAlgorithm = (String)getAttribute(KeyStore.KEY_MANAGER_FACTORY_ALGORITHM);
+        String certAlias = (String)getAttribute(KeyStore.CERTIFICATE_ALIAS);
+
+        validateKeyStoreAttributes(keyStoreType, keyStorePath, keyStorePassword,
+                                   certAlias, keyManagerFactoryAlgorithm);
     }
 
     @Override
@@ -45,4 +85,129 @@ public class KeyStoreAdapter extends Abs
         return AVAILABLE_ATTRIBUTES;
     }
 
+    @Override
+    protected boolean setState(State currentState, State desiredState)
+    {
+        if(desiredState == State.DELETED)
+        {
+            // verify that it is not in use
+            String storeName = getName();
+
+            Collection<Port> ports = new ArrayList<Port>(_broker.getPorts());
+            for (Port port : ports)
+            {
+                if (storeName.equals(port.getAttribute(Port.KEY_STORE)))
+                {
+                    throw new IntegrityViolationException("Key store '" + storeName + "' can't be deleted as it is in use by a port:" + port.getName());
+                }
+            }
+
+            return true;
+        }
+
+        return false;
+    }
+
+    @Override
+    protected void authoriseSetDesiredState(State currentState, State desiredState) throws AccessControlException
+    {
+        if(desiredState == State.DELETED)
+        {
+            if (!_broker.getSecurityManager().authoriseConfiguringBroker(getName(), KeyStore.class, Operation.DELETE))
+            {
+                throw new AccessControlException("Deletion of key store is denied");
+            }
+        }
+    }
+
+    @Override
+    protected void authoriseSetAttribute(String name, Object expected, Object desired) throws AccessControlException
+    {
+        authoriseSetAttribute();
+    }
+
+    @Override
+    protected void authoriseSetAttributes(Map<String, Object> attributes) throws AccessControlException
+    {
+        authoriseSetAttribute();
+    }
+
+    private void authoriseSetAttribute()
+    {
+        if (!_broker.getSecurityManager().authoriseConfiguringBroker(getName(), KeyStore.class, Operation.UPDATE))
+        {
+            throw new AccessControlException("Setting key store attributes is denied");
+        }
+    }
+
+    @Override
+    protected void changeAttributes(Map<String, Object> attributes)
+    {
+        Map<String, Object> changedValues = MapValueConverter.convert(attributes, ATTRIBUTE_TYPES);
+        if(changedValues.containsKey(KeyStore.NAME))
+        {
+            String newName = (String) changedValues.get(KeyStore.NAME);
+            if(!getName().equals(newName))
+            {
+                throw new IllegalConfigurationException("Changing the key store name is not allowed");
+            }
+        }
+
+        Map<String, Object> merged = generateEffectiveAttributes(changedValues);
+
+        String keyStorePath = (String)merged.get(KeyStore.PATH);
+        String keyStorePassword = (String) merged.get(KeyStore.PASSWORD);
+        String keyStoreType = (String)merged.get(KeyStore.TYPE);
+        String keyManagerFactoryAlgorithm = (String)merged.get(KeyStore.KEY_MANAGER_FACTORY_ALGORITHM);
+        String certAlias = (String)merged.get(KeyStore.CERTIFICATE_ALIAS);
+
+        validateKeyStoreAttributes(keyStoreType, keyStorePath, keyStorePassword,
+                                   certAlias, keyManagerFactoryAlgorithm);
+
+        super.changeAttributes(changedValues);
+    }
+
+    private void validateKeyStoreAttributes(String type, String keyStorePath,
+                                            String keyStorePassword, String alias,
+                                            String keyManagerFactoryAlgorithm)
+    {
+        java.security.KeyStore keyStore = null;
+        try
+        {
+            keyStore = SSLUtil.getInitializedKeyStore(keyStorePath, keyStorePassword, type);
+        }
+        catch (Exception e)
+        {
+            throw new IllegalConfigurationException("Cannot instantiate key store at " + keyStorePath, e);
+        }
+
+        if (alias != null)
+        {
+            Certificate cert = null;
+            try
+            {
+                cert = keyStore.getCertificate(alias);
+            }
+            catch (KeyStoreException e)
+            {
+                // key store should be initialized above
+                throw new RuntimeException("Key store has not been initialized", e);
+            }
+            if (cert == null)
+            {
+                throw new IllegalConfigurationException("Cannot find a certificate with alias " + alias
+                        + "in key store : " + keyStorePath);
+            }
+        }
+
+        try
+        {
+            KeyManagerFactory.getInstance(keyManagerFactoryAlgorithm);
+        }
+        catch (NoSuchAlgorithmException e)
+        {
+            throw new IllegalConfigurationException("Unknown keyManagerFactoryAlgorithm: "
+                    + keyManagerFactoryAlgorithm);
+        }
+    }
 }

Modified: qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/PortAdapter.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/PortAdapter.java?rev=1467334&r1=1467333&r2=1467334&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/PortAdapter.java (original)
+++ qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/PortAdapter.java Fri Apr 12 16:16:09 2013
@@ -37,12 +37,14 @@ import org.apache.qpid.server.model.Auth
 import org.apache.qpid.server.model.Broker;
 import org.apache.qpid.server.model.ConfiguredObject;
 import org.apache.qpid.server.model.Connection;
+import org.apache.qpid.server.model.KeyStore;
 import org.apache.qpid.server.model.LifetimePolicy;
 import org.apache.qpid.server.model.Port;
 import org.apache.qpid.server.model.Protocol;
 import org.apache.qpid.server.model.State;
 import org.apache.qpid.server.model.Statistics;
 import org.apache.qpid.server.model.Transport;
+import org.apache.qpid.server.model.TrustStore;
 import org.apache.qpid.server.model.VirtualHost;
 import org.apache.qpid.server.model.VirtualHostAlias;
 import org.apache.qpid.server.security.access.Operation;
@@ -58,6 +60,8 @@ public class PortAdapter extends Abstrac
         put(NAME, String.class);
         put(PROTOCOLS, new ParameterizedTypeImpl(Set.class, Protocol.class));
         put(TRANSPORTS, new ParameterizedTypeImpl(Set.class, Transport.class));
+        put(TRUST_STORES, new ParameterizedTypeImpl(Set.class, String.class));
+        put(KEY_STORE, String.class);
         put(PORT, Integer.class);
         put(TCP_NO_DELAY, Boolean.class);
         put(RECEIVE_BUFFER_SIZE, Integer.class);
@@ -373,16 +377,40 @@ public class PortAdapter extends Abstrac
         boolean requiresCertificate = (needClientCertificate != null && needClientCertificate.booleanValue())
                 || (wantClientCertificate != null && wantClientCertificate.booleanValue());
 
-        if (transports != null && transports.contains(Transport.SSL))
+        String keyStoreName = (String) merged.get(KEY_STORE);
+        boolean hasKeyStore = keyStoreName != null;
+        if(keyStoreName != null)
         {
-            if (_broker.getKeyStores().isEmpty())
+            if (_broker.findKeyStoreByName(keyStoreName) == null)
             {
-                throw new IllegalConfigurationException("Can't create port which requires SSL as the broker has no keystore configured.");
+                throw new IllegalConfigurationException("Can't find key store with name '" + keyStoreName + "' for port " + getName());
+            }
+        }
+
+        Set<String> trustStoreNames = (Set<String>) merged.get(TRUST_STORES);
+        boolean hasTrustStore = trustStoreNames != null && !trustStoreNames.isEmpty();
+        if(hasTrustStore)
+        {
+            for (String trustStoreName : trustStoreNames)
+            {
+                if (_broker.findTrustStoreByName(trustStoreName) == null)
+                {
+                    throw new IllegalConfigurationException("Cannot find trust store with name '" + trustStoreName + "'");
+                }
+            }
+        }
+
+        boolean usesSsl = transports != null && transports.contains(Transport.SSL);
+        if (usesSsl)
+        {
+            if (keyStoreName == null)
+            {
+                throw new IllegalConfigurationException("Can't create port which requires SSL but has no key store configured.");
             }
 
-            if (_broker.getTrustStores().isEmpty() && requiresCertificate)
+            if (!hasTrustStore && requiresCertificate)
             {
-                throw new IllegalConfigurationException("Can't create port which requests SSL client certificates as the broker has no trust/peer stores configured.");
+                throw new IllegalConfigurationException("Can't create port which requests SSL client certificates but has no trust store configured.");
             }
         }
         else
@@ -393,9 +421,14 @@ public class PortAdapter extends Abstrac
             }
         }
 
-        if (protocols != null && protocols.contains(Protocol.HTTPS) && _broker.getKeyStores().isEmpty())
+        if (protocols != null && protocols.contains(Protocol.HTTPS) && !hasKeyStore)
         {
-            throw new IllegalConfigurationException("Can't create port which requires SSL as the broker has no keystore configured.");
+            throw new IllegalConfigurationException("Can't create port which requires SSL but has no key store configured.");
+        }
+
+        if (protocols != null && protocols.contains(Protocol.RMI) && usesSsl)
+        {
+            throw new IllegalConfigurationException("Can't create RMI Registry port which requires SSL.");
         }
 
         String authenticationProviderName = (String)merged.get(AUTHENTICATION_PROVIDER);
@@ -450,4 +483,42 @@ public class PortAdapter extends Abstrac
             throw new AccessControlException("Setting of port attributes is denied");
         }
     }
+
+    @Override
+    public KeyStore getKeyStore()
+    {
+        String keyStoreName = (String)getAttribute(Port.KEY_STORE);
+        KeyStore keyStore = _broker.findKeyStoreByName(keyStoreName);
+
+        if (keyStoreName != null && keyStore == null)
+        {
+            throw new IllegalConfigurationException("Can't find key store with name '" + keyStoreName + "' for port " + getName());
+        }
+
+        return keyStore;
+    }
+
+    @Override
+    public Collection<TrustStore> getTrustStores()
+    {
+        Set<String> trustStoreNames = (Set<String>) getAttribute(TRUST_STORES);
+        boolean hasTrustStoreName = trustStoreNames != null && !trustStoreNames.isEmpty();
+
+        final Collection<TrustStore> trustStores = new ArrayList<TrustStore>();
+        if(hasTrustStoreName)
+        {
+            for (String name : trustStoreNames)
+            {
+                TrustStore trustStore = _broker.findTrustStoreByName(name);
+                if (trustStore == null)
+                {
+                    throw new IllegalConfigurationException("Can't find trust store with name '" + name + "' for port " + getName());
+                }
+
+                trustStores.add(trustStore);
+            }
+        }
+
+        return trustStores;
+    }
 }

Modified: qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/PortFactory.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/PortFactory.java?rev=1467334&r1=1467333&r2=1467334&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/PortFactory.java (original)
+++ qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/PortFactory.java Fri Apr 12 16:16:09 2013
@@ -106,9 +106,9 @@ public class PortFactory
             port = new AmqpPortAdapter(id, broker, attributes, defaults, broker.getTaskExecutor());
 
             boolean useClientAuth = (Boolean) port.getAttribute(Port.NEED_CLIENT_AUTH) || (Boolean) port.getAttribute(Port.WANT_CLIENT_AUTH);
-            if(useClientAuth && broker.getTrustStores().isEmpty())
+            if(useClientAuth && port.getTrustStores().isEmpty())
             {
-                throw new IllegalConfigurationException("Can't create port which requests SSL client certificates as the broker has no trust/peer stores configured.");
+                throw new IllegalConfigurationException("Can't create port which requests SSL client certificates but has no trust stores configured.");
             }
 
             if(useClientAuth && !port.getTransports().contains(Transport.SSL))
@@ -142,13 +142,19 @@ public class PortFactory
 
             defaults.put(Port.NAME, portValue + "-" + protocol.name());
             port = new PortAdapter(id, broker, attributes, defaults, broker.getTaskExecutor());
+
+            boolean rmiPort = port.getProtocols().contains(Protocol.RMI);
+            if (rmiPort && port.getTransports().contains(Transport.SSL))
+            {
+                throw new IllegalConfigurationException("Can't create RMI registry port which requires SSL");
+            }
         }
 
         if(port.getTransports().contains(Transport.SSL) || port.getProtocols().contains(Protocol.HTTPS))
         {
-            if(broker.getKeyStores().isEmpty())
+            if(port.getKeyStore() == null)
             {
-                throw new IllegalConfigurationException("Can't create port which requires SSL as the broker has no keystore configured.");
+                throw new IllegalConfigurationException("Can't create port which requires SSL but has no key store configured.");
             }
         }
 

Modified: qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/TrustStoreAdapter.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/TrustStoreAdapter.java?rev=1467334&r1=1467333&r2=1467334&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/TrustStoreAdapter.java (original)
+++ qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/TrustStoreAdapter.java Fri Apr 12 16:16:09 2013
@@ -20,18 +20,61 @@
  */
 package org.apache.qpid.server.model.adapter;
 
+import java.lang.reflect.Type;
+import java.security.AccessControlException;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
 import java.util.Map;
 import java.util.UUID;
 
+import javax.net.ssl.TrustManagerFactory;
+
+import org.apache.qpid.server.configuration.IllegalConfigurationException;
 import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.IntegrityViolationException;
+import org.apache.qpid.server.model.Port;
+import org.apache.qpid.server.model.State;
 import org.apache.qpid.server.model.TrustStore;
+import org.apache.qpid.server.security.access.Operation;
+import org.apache.qpid.server.util.MapValueConverter;
+import org.apache.qpid.transport.network.security.ssl.SSLUtil;
 
 public class TrustStoreAdapter extends AbstractKeyStoreAdapter implements TrustStore
 {
+    @SuppressWarnings("serial")
+    public static final Map<String, Type> ATTRIBUTE_TYPES = Collections.unmodifiableMap(new HashMap<String, Type>(){{
+        put(NAME, String.class);
+        put(PATH, String.class);
+        put(PASSWORD, String.class);
+        put(TYPE, String.class);
+        put(PEERS_ONLY, Boolean.class);
+        put(TRUST_MANAGER_FACTORY_ALGORITHM, String.class);
+    }});
+
+    @SuppressWarnings("serial")
+    public static final Map<String, Object> DEFAULTS = Collections.unmodifiableMap(new HashMap<String, Object>(){{
+        put(TrustStore.TYPE, DEFAULT_KEYSTORE_TYPE);
+        put(TrustStore.PEERS_ONLY, Boolean.FALSE);
+        put(TrustStore.TRUST_MANAGER_FACTORY_ALGORITHM, TrustManagerFactory.getDefaultAlgorithm());
+    }});
+
+    private Broker _broker;
+
     public TrustStoreAdapter(UUID id, Broker broker, Map<String, Object> attributes)
     {
-        super(id, broker, attributes);
+        super(id, broker, DEFAULTS, MapValueConverter.convert(attributes, ATTRIBUTE_TYPES));
+        _broker = broker;
+
+        String trustStorePath = (String) getAttribute(TrustStore.PATH);
+        String trustStorePassword = getPassword();
+        String trustStoreType = (String) getAttribute(TrustStore.TYPE);
+        String trustManagerFactoryAlgorithm = (String) getAttribute(TrustStore.TRUST_MANAGER_FACTORY_ALGORITHM);
+
+        validateTrustStoreAttributes(trustStoreType, trustStorePath,
+                trustStorePassword, trustManagerFactoryAlgorithm);
     }
 
     @Override
@@ -40,4 +83,110 @@ public class TrustStoreAdapter extends A
         return AVAILABLE_ATTRIBUTES;
     }
 
+    @Override
+    protected boolean setState(State currentState, State desiredState)
+    {
+        if(desiredState == State.DELETED)
+        {
+            // verify that it is not in use
+            String storeName = getName();
+
+            Collection<Port> ports = new ArrayList<Port>(_broker.getPorts());
+            for (Port port : ports)
+            {
+                Collection<TrustStore> trustStores = port.getTrustStores();
+                for(TrustStore store : trustStores)
+                {
+                    if (storeName.equals(store.getAttribute(TrustStore.NAME)))
+                    {
+                        throw new IntegrityViolationException("Trust store '" + storeName + "' can't be deleted as it is in use by a port: " + port.getName());
+                    }
+                }
+            }
+
+            return true;
+        }
+
+        return false;
+    }
+
+    @Override
+    protected void authoriseSetDesiredState(State currentState, State desiredState) throws AccessControlException
+    {
+        if(desiredState == State.DELETED)
+        {
+            if (!_broker.getSecurityManager().authoriseConfiguringBroker(getName(), TrustStore.class, Operation.DELETE))
+            {
+                throw new AccessControlException("Deletion of key store is denied");
+            }
+        }
+    }
+
+    @Override
+    protected void authoriseSetAttribute(String name, Object expected, Object desired) throws AccessControlException
+    {
+        authoriseSetAttribute();
+    }
+
+    @Override
+    protected void authoriseSetAttributes(Map<String, Object> attributes) throws AccessControlException
+    {
+        authoriseSetAttribute();
+    }
+
+    private void authoriseSetAttribute()
+    {
+        if (!_broker.getSecurityManager().authoriseConfiguringBroker(getName(), TrustStore.class, Operation.UPDATE))
+        {
+            throw new AccessControlException("Setting key store attributes is denied");
+        }
+    }
+
+    @Override
+    protected void changeAttributes(Map<String, Object> attributes)
+    {
+        Map<String, Object> changedValues = MapValueConverter.convert(attributes, ATTRIBUTE_TYPES);
+        if(changedValues.containsKey(TrustStore.NAME))
+        {
+            String newName = (String) changedValues.get(TrustStore.NAME);
+            if(!getName().equals(newName))
+            {
+                throw new IllegalConfigurationException("Changing the trust store name is not allowed");
+            }
+        }
+
+        Map<String, Object> merged = generateEffectiveAttributes(changedValues);
+
+        String trustStorePath = (String)merged.get(TrustStore.PATH);
+        String trustStorePassword = (String) merged.get(TrustStore.PASSWORD);
+        String trustStoreType = (String)merged.get(TrustStore.TYPE);
+        String trustManagerFactoryAlgorithm = (String)merged.get(TrustStore.TRUST_MANAGER_FACTORY_ALGORITHM);
+
+        validateTrustStoreAttributes(trustStoreType, trustStorePath,
+                                     trustStorePassword, trustManagerFactoryAlgorithm);
+
+        super.changeAttributes(changedValues);
+    }
+
+    private void validateTrustStoreAttributes(String type, String trustStorePath,
+                                              String password, String trustManagerFactoryAlgorithm)
+    {
+        try
+        {
+            SSLUtil.getInitializedKeyStore(trustStorePath, password, type);
+        }
+        catch (Exception e)
+        {
+            throw new IllegalConfigurationException("Cannot instantiate trust store at " + trustStorePath, e);
+        }
+
+        try
+        {
+            TrustManagerFactory.getInstance(trustManagerFactoryAlgorithm);
+        }
+        catch (NoSuchAlgorithmException e)
+        {
+            throw new IllegalConfigurationException("Unknown trustManagerFactoryAlgorithm: " + trustManagerFactoryAlgorithm);
+        }
+    }
 }

Modified: qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/util/MapValueConverter.java
URL: http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/util/MapValueConverter.java?rev=1467334&r1=1467333&r2=1467334&view=diff
==============================================================================
--- qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/util/MapValueConverter.java (original)
+++ qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/util/MapValueConverter.java Fri Apr 12 16:16:09 2013
@@ -62,7 +62,7 @@ public class MapValueConverter
         return getStringAttribute(name, attributes, null);
     }
 
-    private static void assertMandatoryAttribute(String name, Map<String, Object> attributes)
+    public static void assertMandatoryAttribute(String name, Map<String, Object> attributes)
     {
         if (!attributes.containsKey(name))
         {
@@ -326,6 +326,10 @@ public class MapValueConverter
 
     public static <T> Set<T> toSet(Object rawValue, Class<T> setItemClass, String attributeName)
     {
+        if (rawValue == null)
+        {
+            return null;
+        }
         HashSet<T> set = new HashSet<T>();
         if (rawValue instanceof Iterable)
         {



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