diff options
| author | Alex Rudyy <orudyy@apache.org> | 2013-04-17 10:53:55 +0000 |
|---|---|---|
| committer | Alex Rudyy <orudyy@apache.org> | 2013-04-17 10:53:55 +0000 |
| commit | 532bc2b78fb4a136fe035d68e3146ec7b2fa40aa (patch) | |
| tree | 11a46855f979d79063eb2d61a7fceac31e727041 /qpid/java/broker/src/main | |
| parent | b4af6b6cd3abbbbde7ce1c2799ffde2a1bbcff91 (diff) | |
| download | qpid-python-532bc2b78fb4a136fe035d68e3146ec7b2fa40aa.tar.gz | |
QPID-4746, QPID-4747: remove the defaultAuthenticationProvider attribute from broker and add an overriding authentication provider for management mode
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1468830 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'qpid/java/broker/src/main')
18 files changed, 388 insertions, 135 deletions
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/Broker.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/Broker.java index 5f0c7c7d3c..dd0fde5f7a 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/Broker.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/Broker.java @@ -134,7 +134,7 @@ public class Broker _applicationRegistry = new ApplicationRegistry(store); try { - _applicationRegistry.initialise(); + _applicationRegistry.initialise(options); } catch(Exception e) { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/BrokerOptions.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/BrokerOptions.java index 8a8f7606a2..5c2a8fd090 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/BrokerOptions.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/BrokerOptions.java @@ -25,6 +25,7 @@ import java.io.File; import org.apache.qpid.server.configuration.BrokerProperties; import org.apache.qpid.server.configuration.ConfigurationEntryStore; import org.apache.qpid.server.configuration.store.MemoryConfigurationEntryStore; +import org.apache.qpid.server.util.StringUtil; public class BrokerOptions { @@ -34,6 +35,8 @@ public class BrokerOptions public static final String DEFAULT_LOG_CONFIG_FILE = "etc/log4j.xml"; public static final String DEFAULT_INITIAL_CONFIG_LOCATION = BrokerOptions.class.getClassLoader().getResource(DEFAULT_INITIAL_CONFIG_NAME).toExternalForm(); + public static final String MANAGEMENT_MODE_USER_NAME = "mm_admin"; + private static final int MANAGEMENT_MODE_PASSWORD_LENGTH = 10; private String _logConfigFile; private Integer _logWatchFrequency = 0; @@ -48,6 +51,7 @@ public class BrokerOptions private int _managementModeRmiPort; private int _managementModeConnectorPort; private int _managementModeHttpPort; + private String _managementModePassword; private String _workingDir; private boolean _skipLoggingConfiguration; private boolean _overwriteConfigurationStore; @@ -57,6 +61,21 @@ public class BrokerOptions return _logConfigFile; } + public String getManagementModePassword() + { + if(_managementModePassword == null) + { + _managementModePassword = new StringUtil().randomAlphaNumericString(MANAGEMENT_MODE_PASSWORD_LENGTH); + } + + return _managementModePassword; + } + + public void setManagementModePassword(String managementModePassword) + { + _managementModePassword = managementModePassword; + } + public void setLogConfigFile(final String logConfigFile) { _logConfigFile = logConfigFile; diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/Main.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/Main.java index 28827a8bb5..46612613dd 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/Main.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/Main.java @@ -81,6 +81,8 @@ public class Main .withDescription("override jmx connector port in management mode").withLongOpt("management-mode-jmx-connector-port").create("mmjmx"); private static final Option OPTION_MM_HTTP_PORT = OptionBuilder.withArgName("port").hasArg() .withDescription("override http management port in management mode").withLongOpt("management-mode-http-port").create("mmhttp"); + private static final Option OPTION_MM_PASSWORD = OptionBuilder.withArgName("password").hasArg() + .withDescription("Set the password for the management mode user " + BrokerOptions.MANAGEMENT_MODE_USER_NAME).withLongOpt("management-mode-password").create("mmpass"); private static final Options OPTIONS = new Options(); @@ -100,6 +102,7 @@ public class Main OPTIONS.addOption(OPTION_MM_RMI_PORT); OPTIONS.addOption(OPTION_MM_CONNECTOR_PORT); OPTIONS.addOption(OPTION_MM_HTTP_PORT); + OPTIONS.addOption(OPTION_MM_PASSWORD); } protected CommandLine _commandLine; @@ -256,6 +259,12 @@ public class Main boolean quiesceVhosts = _commandLine.hasOption(OPTION_MM_QUIESCE_VHOST.getOpt()); options.setManagementModeQuiesceVirtualHosts(quiesceVhosts); + + String password = _commandLine.getOptionValue(OPTION_MM_PASSWORD.getOpt()); + if (password != null) + { + options.setManagementModePassword(password); + } } setExceptionHandler(); diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/BrokerRecoverer.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/BrokerRecoverer.java index 7251abfab0..be75b4d2e9 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/BrokerRecoverer.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/BrokerRecoverer.java @@ -26,6 +26,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import org.apache.qpid.server.BrokerOptions; import org.apache.qpid.server.configuration.ConfigurationEntry; import org.apache.qpid.server.configuration.ConfiguredObjectRecoverer; import org.apache.qpid.server.configuration.IllegalConfigurationException; @@ -55,10 +56,11 @@ public class BrokerRecoverer implements ConfiguredObjectRecoverer<Broker> private final AuthenticationProviderFactory _authenticationProviderFactory; private final PortFactory _portFactory; private final TaskExecutor _taskExecutor; + private final BrokerOptions _brokerOptions; public BrokerRecoverer(AuthenticationProviderFactory authenticationProviderFactory, PortFactory portFactory, StatisticsGatherer statisticsGatherer, VirtualHostRegistry virtualHostRegistry, LogRecorder logRecorder, - RootMessageLogger rootMessageLogger, TaskExecutor taskExecutor) + RootMessageLogger rootMessageLogger, TaskExecutor taskExecutor, BrokerOptions brokerOptions) { _portFactory = portFactory; _authenticationProviderFactory = authenticationProviderFactory; @@ -67,6 +69,7 @@ public class BrokerRecoverer implements ConfiguredObjectRecoverer<Broker> _logRecorder = logRecorder; _rootMessageLogger = rootMessageLogger; _taskExecutor = taskExecutor; + _brokerOptions = brokerOptions; } @Override @@ -74,38 +77,37 @@ public class BrokerRecoverer implements ConfiguredObjectRecoverer<Broker> { StoreConfigurationChangeListener storeChangeListener = new StoreConfigurationChangeListener(entry.getStore()); BrokerAdapter broker = new BrokerAdapter(entry.getId(), entry.getAttributes(), _statisticsGatherer, _virtualHostRegistry, - _logRecorder, _rootMessageLogger, _authenticationProviderFactory, _portFactory, _taskExecutor, entry.getStore()); + _logRecorder, _rootMessageLogger, _authenticationProviderFactory, _portFactory, _taskExecutor, entry.getStore(), _brokerOptions); 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>> sslChildEntries = new HashMap<String, Collection<ConfigurationEntry>>(childEntries); + 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)) + if(KeyStore.class.getSimpleName().equals(type) || TrustStore.class.getSimpleName().equals(type) + || AuthenticationProvider.class.getSimpleName().equals(type)) { childEntries.remove(type); } else { - sslChildEntries.remove(type); + priorityChildEntries.remove(type); } } - for (String type : sslChildEntries.keySet()) + for (String type : priorityChildEntries.keySet()) { - recoverType(recovererProvider, storeChangeListener, broker, sslChildEntries, type); + recoverType(recovererProvider, storeChangeListener, broker, priorityChildEntries, type); } for (String type : childEntries.keySet()) { recoverType(recovererProvider, storeChangeListener, broker, childEntries, type); } - wireUpConfiguredObjects(broker, entry.getAttributes()); - return broker; } @@ -132,58 +134,4 @@ public class BrokerRecoverer implements ConfiguredObjectRecoverer<Broker> object.addChangeListener(storeChangeListener); } } - - private void wireUpConfiguredObjects(BrokerAdapter broker, Map<String, Object> brokerAttributes) - { - AuthenticationProvider defaultAuthenticationProvider = null; - Collection<AuthenticationProvider> authenticationProviders = broker.getAuthenticationProviders(); - int numberOfAuthenticationProviders = authenticationProviders.size(); - if (numberOfAuthenticationProviders == 0) - { - throw new IllegalConfigurationException("No authentication provider was configured"); - } - else if (numberOfAuthenticationProviders == 1) - { - defaultAuthenticationProvider = authenticationProviders.iterator().next(); - } - else - { - String name = (String) brokerAttributes.get(Broker.DEFAULT_AUTHENTICATION_PROVIDER); - if (name == null) - { - throw new IllegalConfigurationException("Multiple authentication providers defined, but no default was configured."); - } - - defaultAuthenticationProvider = getAuthenticationProviderByName(broker, name); - } - broker.setDefaultAuthenticationProvider(defaultAuthenticationProvider); - - Collection<Port> ports = broker.getPorts(); - for (Port port : ports) - { - String authenticationProviderName = (String) port.getAttribute(Port.AUTHENTICATION_PROVIDER); - AuthenticationProvider provider = null; - if (authenticationProviderName != null) - { - provider = getAuthenticationProviderByName(broker, authenticationProviderName); - } - else - { - provider = defaultAuthenticationProvider; - } - port.setAuthenticationProvider(provider); - } - } - - private AuthenticationProvider getAuthenticationProviderByName(BrokerAdapter broker, String authenticationProviderName) - { - AuthenticationProvider provider = broker.findAuthenticationProviderByName(authenticationProviderName); - if (provider == null) - { - throw new IllegalConfigurationException("Cannot find the authentication provider with name: " - + authenticationProviderName); - } - return provider; - } - } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/DefaultRecovererProvider.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/DefaultRecovererProvider.java index 15cb229d8a..35209e5b41 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/DefaultRecovererProvider.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/startup/DefaultRecovererProvider.java @@ -20,6 +20,7 @@ */ package org.apache.qpid.server.configuration.startup; +import org.apache.qpid.server.BrokerOptions; import org.apache.qpid.server.configuration.ConfiguredObjectRecoverer; import org.apache.qpid.server.configuration.RecovererProvider; import org.apache.qpid.server.logging.LogRecorder; @@ -54,9 +55,10 @@ public class DefaultRecovererProvider implements RecovererProvider private final QpidServiceLoader<GroupManagerFactory> _groupManagerServiceLoader; private final QpidServiceLoader<PluginFactory> _pluginFactoryServiceLoader; private final TaskExecutor _taskExecutor; + private final BrokerOptions _brokerOptions; public DefaultRecovererProvider(StatisticsGatherer brokerStatisticsGatherer, VirtualHostRegistry virtualHostRegistry, - LogRecorder logRecorder, RootMessageLogger rootMessageLogger, TaskExecutor taskExecutor) + LogRecorder logRecorder, RootMessageLogger rootMessageLogger, TaskExecutor taskExecutor, BrokerOptions brokerOptions) { _authenticationProviderFactory = new AuthenticationProviderFactory(new QpidServiceLoader<AuthenticationManagerFactory>()); _portFactory = new PortFactory(); @@ -67,6 +69,7 @@ public class DefaultRecovererProvider implements RecovererProvider _groupManagerServiceLoader = new QpidServiceLoader<GroupManagerFactory>(); _pluginFactoryServiceLoader = new QpidServiceLoader<PluginFactory>(); _taskExecutor = taskExecutor; + _brokerOptions = brokerOptions; } @Override @@ -75,7 +78,7 @@ public class DefaultRecovererProvider implements RecovererProvider if (Broker.class.getSimpleName().equals(type)) { return new BrokerRecoverer(_authenticationProviderFactory, _portFactory, _brokerStatisticsGatherer, _virtualHostRegistry, - _logRecorder, _rootMessageLogger, _taskExecutor); + _logRecorder, _rootMessageLogger, _taskExecutor, _brokerOptions); } else if(VirtualHost.class.getSimpleName().equals(type)) { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandler.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandler.java index 6733c8ee2d..24d5edf00f 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandler.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/configuration/store/ManagementModeStoreHandler.java @@ -26,6 +26,7 @@ public class ManagementModeStoreHandler implements ConfigurationEntryStore private static final String PORT_TYPE = Port.class.getSimpleName(); private static final String VIRTUAL_HOST_TYPE = VirtualHost.class.getSimpleName(); private static final String ATTRIBUTE_STATE = VirtualHost.STATE; + private static final Object MANAGEMENT_MODE_AUTH_PROVIDER = "mm-auth"; private final ConfigurationEntryStore _store; private final Map<UUID, ConfigurationEntry> _cliEntries; @@ -208,6 +209,10 @@ public class ManagementModeStoreHandler implements ConfigurationEntryStore attributes.put(Port.PORT, port); attributes.put(Port.PROTOCOLS, Collections.singleton(protocol)); attributes.put(Port.NAME, MANAGEMENT_MODE_PORT_PREFIX + protocol.name()); + if (protocol != Protocol.RMI) + { + attributes.put(Port.AUTHENTICATION_PROVIDER, MANAGEMENT_MODE_AUTH_PROVIDER); + } ConfigurationEntry portEntry = new ConfigurationEntry(UUID.randomUUID(), PORT_TYPE, attributes, Collections.<UUID> emptySet(), this); if (LOGGER.isDebugEnabled()) diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/Broker_logmessages.properties b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/Broker_logmessages.properties index 1aa7815c39..76c1fa1b5b 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/Broker_logmessages.properties +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/logging/messages/Broker_logmessages.properties @@ -45,4 +45,6 @@ STATS_MSGS = BRK-1009 : {0,choice,0#delivered|1#received} : {1,number,#.###} msg PLATFORM = BRK-1010 : Platform : JVM : {0} version: {1} OS : {2} version: {3} arch: {4} # 0 Maximum Memory -MAX_MEMORY = BRK-1011 : Maximum Memory : {0,number} bytes
\ No newline at end of file +MAX_MEMORY = BRK-1011 : Maximum Memory : {0,number} bytes + +MANAGEMENT_MODE = BRK-1012 : Management Mode : User Details : {0} / {1}
\ No newline at end of file diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Broker.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Broker.java index 0e230bd552..712b53f627 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Broker.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Broker.java @@ -53,7 +53,6 @@ public interface Broker extends ConfiguredObject String STATE = "state"; String TIME_TO_LIVE = "timeToLive"; String UPDATED = "updated"; - String DEFAULT_AUTHENTICATION_PROVIDER = "defaultAuthenticationProvider"; String DEFAULT_VIRTUAL_HOST = "defaultVirtualHost"; String STATISTICS_REPORTING_PERIOD = "statisticsReportingPeriod"; String STATISTICS_REPORTING_RESET_ENABLED = "statisticsReportingResetEnabled"; @@ -112,7 +111,6 @@ public interface Broker extends ConfiguredObject STATE, TIME_TO_LIVE, UPDATED, - DEFAULT_AUTHENTICATION_PROVIDER, DEFAULT_VIRTUAL_HOST, QUEUE_ALERT_THRESHOLD_MESSAGE_AGE, QUEUE_ALERT_THRESHOLD_QUEUE_DEPTH_MESSAGES, @@ -151,8 +149,6 @@ public interface Broker extends ConfiguredObject LifetimePolicy lifetime, long ttl, Map<String, Object> attributes) throws AccessControlException, IllegalArgumentException; - AuthenticationProvider getDefaultAuthenticationProvider(); - Collection<GroupProvider> getGroupProviders(); /** @@ -172,6 +168,8 @@ public interface Broker extends ConfiguredObject */ LogRecorder getLogRecorder(); + AuthenticationProvider findAuthenticationProviderByName(String authenticationProviderName); + VirtualHost findVirtualHostByName(String name); KeyStore findKeyStoreByName(String name); diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Port.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Port.java index 7ff5f04ee7..60d62e3f27 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Port.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/Port.java @@ -93,7 +93,6 @@ public interface Port extends ConfiguredObject AccessControlException, IllegalArgumentException; - Collection<Protocol> getProtocols(); void addProtocol(Protocol protocol) throws IllegalStateException, @@ -104,12 +103,9 @@ public interface Port extends ConfiguredObject AccessControlException, IllegalArgumentException; + AuthenticationProvider getAuthenticationProvider(); //children Collection<VirtualHostAlias> getVirtualHostBindings(); Collection<Connection> getConnections(); - - AuthenticationProvider getAuthenticationProvider(); - - void setAuthenticationProvider(AuthenticationProvider authenticationProvider); } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderAdapter.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderAdapter.java index f788923b3a..8d601460ad 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderAdapter.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/AuthenticationProviderAdapter.java @@ -219,10 +219,6 @@ public abstract class AuthenticationProviderAdapter<T extends AuthenticationMana String providerName = getName(); // verify that provider is not in use - if (providerName.equals(_broker.getAttribute(Broker.DEFAULT_AUTHENTICATION_PROVIDER))) - { - throw new IntegrityViolationException("Authentication provider '" + providerName + "' is set as default and cannot be deleted"); - } Collection<Port> ports = new ArrayList<Port>(_broker.getPorts()); for (Port port : ports) { diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java index ae30f70877..49af66126c 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java @@ -33,14 +33,15 @@ import java.util.UUID; import org.apache.log4j.Logger; import org.apache.qpid.common.QpidProperties; +import org.apache.qpid.server.BrokerOptions; 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; import org.apache.qpid.server.logging.actors.CurrentActor; +import org.apache.qpid.server.logging.messages.BrokerMessages; import org.apache.qpid.server.model.AuthenticationProvider; import org.apache.qpid.server.model.Broker; import org.apache.qpid.server.model.ConfigurationChangeListener; @@ -56,9 +57,12 @@ import org.apache.qpid.server.model.Statistics; 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.model.adapter.AuthenticationProviderAdapter.SimpleAuthenticationProviderAdapter; 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.auth.manager.AuthenticationManager; +import org.apache.qpid.server.security.auth.manager.SimpleAuthenticationManager; import org.apache.qpid.server.security.group.FileGroupManager; import org.apache.qpid.server.security.group.GroupManager; import org.apache.qpid.server.stats.StatisticsGatherer; @@ -92,7 +96,6 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, Configurat put(ACL_FILE, String.class); put(NAME, String.class); put(DEFAULT_VIRTUAL_HOST, String.class); - put(DEFAULT_AUTHENTICATION_PROVIDER, String.class); put(GROUP_FILE, String.class); put(VIRTUALHOST_STORE_TRANSACTION_IDLE_TIMEOUT_CLOSE, Long.class); @@ -168,7 +171,6 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, Configurat 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; @@ -176,11 +178,12 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, Configurat private final Collection<String> _supportedStoreTypes; private final ConfigurationEntryStore _brokerStore; - private boolean _managementMode; + private AuthenticationProvider _managementAuthenticationProvider; + private BrokerOptions _brokerOptions; public BrokerAdapter(UUID id, Map<String, Object> attributes, StatisticsGatherer statisticsGatherer, VirtualHostRegistry virtualHostRegistry, LogRecorder logRecorder, RootMessageLogger rootMessageLogger, AuthenticationProviderFactory authenticationProviderFactory, - PortFactory portFactory, TaskExecutor taskExecutor, ConfigurationEntryStore brokerStore) + PortFactory portFactory, TaskExecutor taskExecutor, ConfigurationEntryStore brokerStore, BrokerOptions brokerOptions) { super(id, DEFAULTS, MapValueConverter.convert(attributes, ATTRIBUTE_TYPES), taskExecutor); _statisticsGatherer = statisticsGatherer; @@ -195,7 +198,15 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, Configurat createBrokerChildrenFromAttributes(); _supportedStoreTypes = new MessageStoreCreator().getStoreTypes(); _brokerStore = brokerStore; - _managementMode = brokerStore instanceof ManagementModeStoreHandler; + _brokerOptions = brokerOptions; + createBrokerChildrenFromAttributes(); + if (_brokerOptions.isManagementMode()) + { + AuthenticationManager authManager = new SimpleAuthenticationManager(BrokerOptions.MANAGEMENT_MODE_USER_NAME, _brokerOptions.getManagementModePassword()); + AuthenticationProvider authenticationProvider = new SimpleAuthenticationProviderAdapter(UUID.randomUUID(), this, + authManager, Collections.<String, Object> emptyMap(), Collections.<String> emptySet()); + _managementAuthenticationProvider = authenticationProvider; + } } /* @@ -204,6 +215,7 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, Configurat private void createBrokerChildrenFromAttributes() { createGroupProvider(); + } private void createGroupProvider() @@ -250,6 +262,10 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, Configurat public AuthenticationProvider findAuthenticationProviderByName(String authenticationProviderName) { + if (isManagementMode()) + { + return _managementAuthenticationProvider; + } Collection<AuthenticationProvider> providers = getAuthenticationProviders(); for (AuthenticationProvider authenticationProvider : providers) { @@ -278,17 +294,6 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, Configurat } @Override - public AuthenticationProvider getDefaultAuthenticationProvider() - { - return _defaultAuthenticationProvider; - } - - public void setDefaultAuthenticationProvider(AuthenticationProvider provider) - { - _defaultAuthenticationProvider = provider; - } - - @Override public Collection<GroupProvider> getGroupProviders() { synchronized (_groupProviders) @@ -766,6 +771,11 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, Configurat changeState(_portAdapters, currentState,State.ACTIVE, false); changeState(_plugins, currentState,State.ACTIVE, false); + + if (isManagementMode()) + { + CurrentActor.get().message(BrokerMessages.MANAGEMENT_MODE(BrokerOptions.MANAGEMENT_MODE_USER_NAME, _brokerOptions.getManagementModePassword())); + } return true; } else if (desiredState == State.STOPPED) @@ -956,7 +966,7 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, Configurat public SubjectCreator getSubjectCreator(SocketAddress localAddress) { InetSocketAddress inetSocketAddress = (InetSocketAddress)localAddress; - AuthenticationProvider provider = _defaultAuthenticationProvider; + AuthenticationProvider provider = null; Collection<Port> ports = getPorts(); for (Port p : ports) { @@ -966,6 +976,12 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, Configurat break; } } + + if(provider == null) + { + throw new IllegalConfigurationException("Unable to determine authentication provider for address: " + localAddress); + } + return provider.getSubjectCreator(); } @@ -1002,7 +1018,6 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, Configurat @Override protected void changeAttributes(Map<String, Object> attributes) { - //TODO: Add management mode check Map<String, Object> convertedAttributes = MapValueConverter.convert(attributes, ATTRIBUTE_TYPES); validateAttributes(convertedAttributes); @@ -1019,13 +1034,6 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, Configurat { createGroupProvider(); } - else if (DEFAULT_AUTHENTICATION_PROVIDER.equals(name)) - { - if (!_defaultAuthenticationProvider.getName().equals(desired)) - { - _defaultAuthenticationProvider = findAuthenticationProviderByName((String)desired); - } - } attributeSet(name, expected, desired); } @@ -1048,16 +1056,6 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, Configurat new FileGroupManager(groupFile); } - String defaultAuthenticationProvider = (String) convertedAttributes.get(DEFAULT_AUTHENTICATION_PROVIDER); - if (defaultAuthenticationProvider != null) - { - AuthenticationProvider provider = findAuthenticationProviderByName(defaultAuthenticationProvider); - if (provider == null) - { - throw new IllegalConfigurationException("Authentication provider with name " + defaultAuthenticationProvider - + " canot be set as a default as it does not exist"); - } - } String defaultVirtualHost = (String) convertedAttributes.get(DEFAULT_VIRTUAL_HOST); if (defaultVirtualHost != null) { @@ -1127,6 +1125,6 @@ public class BrokerAdapter extends AbstractAdapter implements Broker, Configurat @Override public boolean isManagementMode() { - return _managementMode; + return _brokerOptions.isManagementMode(); } } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/PortAdapter.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/PortAdapter.java index 0c1249d20e..af6b1421a7 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/PortAdapter.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/model/adapter/PortAdapter.java @@ -82,6 +82,24 @@ public class PortAdapter extends AbstractAdapter implements Port super(id, defaults, MapValueConverter.convert(attributes, ATTRIBUTE_TYPES), taskExecutor); _broker = broker; State state = MapValueConverter.getEnumAttribute(State.class, STATE, attributes, State.INITIALISING); + + Collection<Protocol> protocols = getProtocols(); + boolean rmiRegistry = protocols != null && protocols.contains(Protocol.RMI); + if (!rmiRegistry) + { + String authProvider = (String)getAttribute(Port.AUTHENTICATION_PROVIDER); + if (authProvider == null) + { + throw new IllegalConfigurationException("An authentication provider must be specified for port : " + getName()); + } + _authenticationProvider = broker.findAuthenticationProviderByName(authProvider); + + if(_authenticationProvider == null) + { + throw new IllegalConfigurationException("The authentication provider '" + authProvider + "' could not be found for port : " + getName()); + } + } + _state = new AtomicReference<State>(state); addParent(Broker.class, broker); } @@ -350,11 +368,6 @@ public class PortAdapter extends AbstractAdapter implements Port return _authenticationProvider; } - public void setAuthenticationProvider(AuthenticationProvider authenticationProvider) - { - _authenticationProvider = authenticationProvider; - } - @Override protected void changeAttributes(Map<String, Object> attributes) { @@ -451,6 +464,14 @@ public class PortAdapter extends AbstractAdapter implements Port + authenticationProviderName + "'"); } } + else + { + if (protocols != null && !protocols.contains(Protocol.RMI)) + { + throw new IllegalConfigurationException("An authentication provider must be specified"); + } + } + super.changeAttributes(converted); } diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java index 1379b375cf..fa5024c1fe 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java @@ -27,6 +27,7 @@ import java.util.TimerTask; import org.apache.log4j.Logger; import org.apache.qpid.common.Closeable; import org.apache.qpid.common.QpidProperties; +import org.apache.qpid.server.BrokerOptions; import org.apache.qpid.server.configuration.BrokerProperties; import org.apache.qpid.server.configuration.ConfigurationEntryStore; import org.apache.qpid.server.configuration.ConfiguredObjectRecoverer; @@ -89,7 +90,7 @@ public class ApplicationRegistry implements IApplicationRegistry initialiseStatistics(); } - public void initialise() throws Exception + public void initialise(BrokerOptions brokerOptions) throws Exception { // Create the RootLogger to be used during broker operation boolean statusUpdatesEnabled = Boolean.parseBoolean(System.getProperty(BrokerProperties.PROPERTY_STATUS_UPDATES, "true")); @@ -112,7 +113,7 @@ public class ApplicationRegistry implements IApplicationRegistry _taskExecutor = new TaskExecutor(); _taskExecutor.start(); - RecovererProvider provider = new DefaultRecovererProvider((StatisticsGatherer)this, _virtualHostRegistry, _logRecorder, _rootMessageLogger, _taskExecutor); + RecovererProvider provider = new DefaultRecovererProvider((StatisticsGatherer)this, _virtualHostRegistry, _logRecorder, _rootMessageLogger, _taskExecutor, brokerOptions); ConfiguredObjectRecoverer<? extends ConfiguredObject> brokerRecoverer = provider.getRecoverer(Broker.class.getSimpleName()); _broker = (Broker) brokerRecoverer.create(provider, _store.getRootEntry()); diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/IApplicationRegistry.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/IApplicationRegistry.java index d12258d194..7341922bd0 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/IApplicationRegistry.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/IApplicationRegistry.java @@ -20,17 +20,14 @@ */ package org.apache.qpid.server.registry; +import org.apache.qpid.server.BrokerOptions; import org.apache.qpid.server.model.Broker; import org.apache.qpid.server.stats.StatisticsGatherer; public interface IApplicationRegistry extends StatisticsGatherer { - /** - * Initialise the application registry. All initialisation must be done in this method so that any components - * that need access to the application registry itself for initialisation are able to use it. Attempting to - * initialise in the constructor will lead to failures since the registry reference will not have been set. - */ - void initialise() throws Exception; + + void initialise(BrokerOptions brokerOptions) throws Exception; /** * Shutdown this Registry diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticator.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/jmx/JMXPasswordAuthenticator.java index abb8677e90..bf8d489e61 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticator.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/jmx/JMXPasswordAuthenticator.java @@ -18,7 +18,7 @@ * under the License. * */ -package org.apache.qpid.server.security.auth.rmi; +package org.apache.qpid.server.security.auth.jmx; import java.net.SocketAddress; @@ -31,7 +31,7 @@ import org.apache.qpid.server.security.auth.SubjectAuthenticationResult; import javax.management.remote.JMXAuthenticator; import javax.security.auth.Subject; -public class RMIPasswordAuthenticator implements JMXAuthenticator +public class JMXPasswordAuthenticator implements JMXAuthenticator { static final String UNABLE_TO_LOOKUP = "The broker was unable to lookup the user details"; static final String SHOULD_BE_STRING_ARRAY = "User details should be String[]"; @@ -45,7 +45,7 @@ public class RMIPasswordAuthenticator implements JMXAuthenticator private final Broker _broker; private final SocketAddress _address; - public RMIPasswordAuthenticator(Broker broker, SocketAddress address) + public JMXPasswordAuthenticator(Broker broker, SocketAddress address) { _broker = broker; _address = address; diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleAuthenticationManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleAuthenticationManager.java new file mode 100644 index 0000000000..903f54dd8e --- /dev/null +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleAuthenticationManager.java @@ -0,0 +1,214 @@ +/* + * 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; + +import java.io.IOException; +import java.security.Principal; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import javax.security.auth.callback.Callback; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.callback.NameCallback; +import javax.security.auth.callback.PasswordCallback; +import javax.security.auth.callback.UnsupportedCallbackException; +import javax.security.sasl.AuthorizeCallback; +import javax.security.sasl.Sasl; +import javax.security.sasl.SaslException; +import javax.security.sasl.SaslServer; + +import org.apache.log4j.Logger; +import org.apache.qpid.server.security.auth.AuthenticationResult; +import org.apache.qpid.server.security.auth.UsernamePrincipal; +import org.apache.qpid.server.security.auth.sasl.plain.PlainPasswordCallback; +import org.apache.qpid.server.security.auth.sasl.plain.PlainSaslServer; + +public class SimpleAuthenticationManager implements AuthenticationManager +{ + private static final Logger _logger = Logger.getLogger(SimpleAuthenticationManager.class); + + private static final String PLAIN_MECHANISM = "PLAIN"; + private static final String CRAM_MD5_MECHANISM = "CRAM-MD5"; + + private Map<String, String> _users; + + public SimpleAuthenticationManager(String userName, String userPassword) + { + this(Collections.singletonMap(userName, userPassword)); + } + + public SimpleAuthenticationManager(Map<String, String> users) + { + _users = new HashMap<String, String>(users); + } + + @Override + public void initialise() + { + } + + @Override + public String getMechanisms() + { + return PLAIN_MECHANISM + " " + CRAM_MD5_MECHANISM; + } + + @Override + public SaslServer createSaslServer(String mechanism, String localFQDN, Principal externalPrincipal) throws SaslException + { + if (PLAIN_MECHANISM.equals(mechanism)) + { + return new PlainSaslServer(new SimplePlainCallbackHandler()); + } + else if (CRAM_MD5_MECHANISM.equals(mechanism)) + { + return Sasl.createSaslServer(mechanism, "AMQP", localFQDN, null, new SimpleCramMd5CallbackHandler()); + } + else + { + throw new SaslException("Unknown mechanism: " + mechanism); + } + } + + @Override + public AuthenticationResult authenticate(SaslServer server, byte[] response) + { + try + { + // Process response from the client + byte[] challenge = server.evaluateResponse(response != null ? response : new byte[0]); + + if (server.isComplete()) + { + String authorizationID = server.getAuthorizationID(); + _logger.debug("Authenticated as " + authorizationID); + + return new AuthenticationResult(new UsernamePrincipal(authorizationID)); + } + else + { + return new AuthenticationResult(challenge, AuthenticationResult.AuthenticationStatus.CONTINUE); + } + } + catch (SaslException e) + { + return new AuthenticationResult(AuthenticationResult.AuthenticationStatus.ERROR, e); + } + } + + @Override + public AuthenticationResult authenticate(String username, String password) + { + if (_users.containsKey(username)) + { + String userPassword = _users.get(username); + if (userPassword.equals(password)) + { + return new AuthenticationResult(new UsernamePrincipal(username)); + } + } + return new AuthenticationResult(AuthenticationResult.AuthenticationStatus.ERROR); + } + + @Override + public void close() + { + } + + @Override + public void onCreate() + { + // nothing to do, no external resource is required + } + + @Override + public void onDelete() + { + // nothing to do, no external resource is used + } + + private class SimpleCramMd5CallbackHandler implements CallbackHandler + { + public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException + { + String username = null; + for (Callback callback : callbacks) + { + if (callback instanceof NameCallback) + { + username = ((NameCallback) callback).getDefaultName(); + } + else if (callback instanceof PasswordCallback) + { + if (_users.containsKey(username)) + { + String password = _users.get(username); + ((PasswordCallback) callback).setPassword(password.toCharArray()); + } + else + { + throw new SaslException("Authentication failed"); + } + } + else if (callback instanceof AuthorizeCallback) + { + ((AuthorizeCallback) callback).setAuthorized(true); + } + else + { + throw new UnsupportedCallbackException(callback); + } + } + } + } + + private class SimplePlainCallbackHandler implements CallbackHandler + { + public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException + { + String username = null; + for (Callback callback : callbacks) + { + if (callback instanceof NameCallback) + { + username = ((NameCallback) callback).getDefaultName(); + } + else if (callback instanceof PlainPasswordCallback) + { + if (_users.containsKey(username)) + { + PlainPasswordCallback plainPasswordCallback = (PlainPasswordCallback) callback; + String password = plainPasswordCallback.getPlainPassword(); + plainPasswordCallback.setAuthenticated(password.equals(_users.get(username))); + } + } + else if (callback instanceof AuthorizeCallback) + { + ((AuthorizeCallback) callback).setAuthorized(true); + } + else + { + throw new UnsupportedCallbackException(callback); + } + } + } + } +} diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/util/StringUtil.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/util/StringUtil.java new file mode 100644 index 0000000000..aa17a9493b --- /dev/null +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/util/StringUtil.java @@ -0,0 +1,44 @@ +/* + * + * 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.util; + +import java.util.Random; + +public class StringUtil +{ + private static final String NUMBERS = "0123456789"; + private static final String LETTERS = "abcdefghijklmnopqrstuvwxwy"; + private static final String OTHERS = "_-"; + private static final char[] CHARACTERS = (NUMBERS + LETTERS + LETTERS.toUpperCase() + OTHERS).toCharArray(); + + private Random _random = new Random(); + + public String randomAlphaNumericString(int maxLength) + { + char[] result = new char[maxLength]; + for (int i = 0; i < maxLength; i++) + { + result[i] = (char) CHARACTERS[_random.nextInt(CHARACTERS.length)]; + } + return new String(result); + } + +} diff --git a/qpid/java/broker/src/main/resources/initial-config.json b/qpid/java/broker/src/main/resources/initial-config.json index 44f8fed789..fde3c3a96e 100644 --- a/qpid/java/broker/src/main/resources/initial-config.json +++ b/qpid/java/broker/src/main/resources/initial-config.json @@ -21,7 +21,6 @@ { "name": "QpidBroker", "storeVersion": 1, - "defaultAuthenticationProvider" : "passwordFile", "defaultVirtualHost" : "default", "authenticationproviders" : [ { "name" : "passwordFile", @@ -30,10 +29,12 @@ } ], "ports" : [ { "name" : "AMQP", - "port" : 5672 + "port" : 5672, + "authenticationProvider" : "passwordFile" }, { "name" : "HTTP", "port" : 8080, + "authenticationProvider" : "passwordFile", "protocols" : [ "HTTP" ] }, { "name" : "RMI_REGISTRY", @@ -42,6 +43,7 @@ }, { "name" : "JMX_CONNECTOR", "port" : 9099, + "authenticationProvider" : "passwordFile", "protocols" : [ "JMX_RMI" ] }], "virtualhosts" : [ { |
