diff --git a/artemis-protocols/artemis-openwire-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/openwire/OpenWireConnection.java b/artemis-protocols/artemis-openwire-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/openwire/OpenWireConnection.java index 3155794d81..ffe2b38241 100644 --- a/artemis-protocols/artemis-openwire-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/openwire/OpenWireConnection.java +++ b/artemis-protocols/artemis-openwire-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/openwire/OpenWireConnection.java @@ -51,6 +51,7 @@ import org.apache.activemq.artemis.core.protocol.openwire.amq.AMQSingleConsumerB import org.apache.activemq.artemis.core.protocol.openwire.amq.AMQTransaction; import org.apache.activemq.artemis.core.remoting.CloseListener; import org.apache.activemq.artemis.core.remoting.FailureListener; +import org.apache.activemq.artemis.core.security.SecurityAuth; import org.apache.activemq.artemis.core.server.ActiveMQServerLogger; import org.apache.activemq.artemis.spi.core.protocol.RemotingConnection; import org.apache.activemq.artemis.spi.core.remoting.Acceptor; @@ -105,7 +106,7 @@ import org.apache.activemq.wireformat.WireFormat; /** * Represents an activemq connection. */ -public class OpenWireConnection implements RemotingConnection, CommandVisitor { +public class OpenWireConnection implements RemotingConnection, CommandVisitor, SecurityAuth { private final OpenWireProtocolManager protocolManager; @@ -190,6 +191,39 @@ public class OpenWireConnection implements RemotingConnection, CommandVisitor { this.creationTime = System.currentTimeMillis(); } + + // SecurityAuth implementation + @Override + public String getUsername() { + ConnectionInfo info = getConnectionInfo(); + if (info == null) { + return null; + } + return info.getUserName(); + } + + // SecurityAuth implementation + @Override + public String getPassword() { + ConnectionInfo info = getConnectionInfo(); + if (info == null) { + return null; + } + return info.getPassword(); + } + + + private ConnectionInfo getConnectionInfo() { + if (state == null) { + return null; + } + ConnectionInfo info = state.getInfo(); + if (info == null) { + return null; + } + return info; + } + public String getLocalAddress() { return transportConnection.getLocalAddress(); } diff --git a/artemis-protocols/artemis-openwire-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/openwire/OpenWireProtocolManager.java b/artemis-protocols/artemis-openwire-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/openwire/OpenWireProtocolManager.java index 98b41abc0f..007266206f 100644 --- a/artemis-protocols/artemis-openwire-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/openwire/OpenWireProtocolManager.java +++ b/artemis-protocols/artemis-openwire-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/openwire/OpenWireProtocolManager.java @@ -47,14 +47,12 @@ import org.apache.activemq.artemis.core.protocol.openwire.amq.AMQConnectionConte import org.apache.activemq.artemis.core.protocol.openwire.amq.AMQConsumer; import org.apache.activemq.artemis.core.protocol.openwire.amq.AMQPersistenceAdapter; import org.apache.activemq.artemis.core.protocol.openwire.amq.AMQProducerBrokerExchange; -import org.apache.activemq.artemis.core.protocol.openwire.amq.AMQServerSession; import org.apache.activemq.artemis.core.protocol.openwire.amq.AMQSession; import org.apache.activemq.artemis.core.remoting.impl.netty.NettyServerConnection; import org.apache.activemq.artemis.core.security.CheckType; import org.apache.activemq.artemis.core.server.ActiveMQServer; import org.apache.activemq.artemis.core.server.ActiveMQServerLogger; import org.apache.activemq.artemis.core.server.Queue; -import org.apache.activemq.artemis.core.server.impl.ActiveMQServerImpl; import org.apache.activemq.artemis.core.server.management.ManagementService; import org.apache.activemq.artemis.core.server.management.Notification; import org.apache.activemq.artemis.core.server.management.NotificationListener; @@ -583,21 +581,17 @@ public class OpenWireProtocolManager implements ProtocolManager, No ActiveMQDestination dest = info.getDestination(); if (dest.isQueue()) { SimpleString qName = OpenWireUtil.toCoreAddress(dest); - ConnectionState state = connection.getState(); - ConnectionInfo connInfo = state.getInfo(); - if (connInfo != null) { - String user = connInfo.getUserName(); - String pass = connInfo.getPassword(); + if (connection.getState().getInfo() != null) { - AMQServerSession fakeSession = new AMQServerSession(user, pass); CheckType checkType = dest.isTemporary() ? CheckType.CREATE_NON_DURABLE_QUEUE : CheckType.CREATE_DURABLE_QUEUE; - ((ActiveMQServerImpl) server).getSecurityStore().check(qName, checkType, fakeSession); + server.getSecurityStore().check(qName, checkType, connection); - ((ActiveMQServerImpl) server).checkQueueCreationLimit(user); + server.checkQueueCreationLimit(connection.getUsername()); } QueueBinding binding = (QueueBinding) server.getPostOffice().getBinding(qName); if (binding == null) { + ConnectionInfo connInfo = connection.getState().getInfo(); this.server.createQueue(qName, qName, null, connInfo == null ? null : SimpleString.toSimpleString(connInfo.getUserName()), false, dest.isTemporary()); } if (dest.isTemporary()) { diff --git a/artemis-protocols/artemis-openwire-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/openwire/amq/AMQServerSession.java b/artemis-protocols/artemis-openwire-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/openwire/amq/AMQServerSession.java index 4094a823ef..642eda9be5 100644 --- a/artemis-protocols/artemis-openwire-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/openwire/amq/AMQServerSession.java +++ b/artemis-protocols/artemis-openwire-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/openwire/amq/AMQServerSession.java @@ -88,11 +88,6 @@ public class AMQServerSession extends ServerSessionImpl { super(name, username, password, minLargeMessageSize, autoCommitSends, autoCommitAcks, preAcknowledge, persistDeliveryCountBeforeDelivery, xa, connection, storageManager, postOffice, resourceManager, securityStore, managementService, activeMQServerImpl, managementAddress, simpleString, callback, context, new AMQTransactionFactory(), queueCreator); } - //create a fake session just for security check - public AMQServerSession(String user, String pass) { - super(user, pass); - } - protected void doClose(final boolean failed) throws Exception { synchronized (this) { if (tx != null && tx.getXid() == null) { diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/security/SecurityAuth.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/security/SecurityAuth.java new file mode 100644 index 0000000000..1325e3945a --- /dev/null +++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/security/SecurityAuth.java @@ -0,0 +1,26 @@ +/** + * 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.activemq.artemis.core.security; + +public interface SecurityAuth { + + String getUsername(); + + String getPassword(); + +} diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/security/SecurityStore.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/security/SecurityStore.java index 1456f7c221..466e7cf382 100644 --- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/security/SecurityStore.java +++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/security/SecurityStore.java @@ -17,13 +17,12 @@ package org.apache.activemq.artemis.core.security; import org.apache.activemq.artemis.api.core.SimpleString; -import org.apache.activemq.artemis.core.server.ServerSession; public interface SecurityStore { void authenticate(String user, String password) throws Exception; - void check(SimpleString address, CheckType checkType, ServerSession session) throws Exception; + void check(SimpleString address, CheckType checkType, SecurityAuth session) throws Exception; boolean isSecurityEnabled(); diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/security/impl/SecurityStoreImpl.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/security/impl/SecurityStoreImpl.java index 143cf05ea2..209b42415f 100644 --- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/security/impl/SecurityStoreImpl.java +++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/security/impl/SecurityStoreImpl.java @@ -25,10 +25,10 @@ import org.apache.activemq.artemis.api.core.management.CoreNotificationType; import org.apache.activemq.artemis.api.core.management.ManagementHelper; import org.apache.activemq.artemis.core.security.CheckType; import org.apache.activemq.artemis.core.security.Role; +import org.apache.activemq.artemis.core.security.SecurityAuth; import org.apache.activemq.artemis.core.security.SecurityStore; import org.apache.activemq.artemis.core.server.ActiveMQMessageBundle; import org.apache.activemq.artemis.core.server.ActiveMQServerLogger; -import org.apache.activemq.artemis.core.server.ServerSession; import org.apache.activemq.artemis.core.server.management.Notification; import org.apache.activemq.artemis.core.server.management.NotificationService; import org.apache.activemq.artemis.core.settings.HierarchicalRepository; @@ -138,7 +138,7 @@ public class SecurityStoreImpl implements SecurityStore, HierarchicalRepositoryC public void check(final SimpleString address, final CheckType checkType, - final ServerSession session) throws Exception { + final SecurityAuth session) throws Exception { if (securityEnabled) { if (trace) { ActiveMQServerLogger.LOGGER.trace("checking access permissions to " + address); diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/ActiveMQServer.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/ActiveMQServer.java index f1811baf92..d7a298d954 100644 --- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/ActiveMQServer.java +++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/ActiveMQServer.java @@ -33,6 +33,7 @@ import org.apache.activemq.artemis.core.postoffice.PostOffice; import org.apache.activemq.artemis.core.remoting.server.RemotingService; import org.apache.activemq.artemis.core.replication.ReplicationManager; import org.apache.activemq.artemis.core.security.Role; +import org.apache.activemq.artemis.core.security.SecurityAuth; import org.apache.activemq.artemis.core.security.SecurityStore; import org.apache.activemq.artemis.core.server.cluster.ClusterManager; import org.apache.activemq.artemis.core.server.cluster.ha.HAPolicy; @@ -104,6 +105,8 @@ public interface ActiveMQServer extends ActiveMQComponent { void unregisterActivateCallback(ActivateCallback callback); + void checkQueueCreationLimit(String username) throws Exception; + ServerSession createSession(String name, String username, String password, @@ -221,12 +224,12 @@ public interface ActiveMQServer extends ActiveMQComponent { void destroyQueue(SimpleString queueName) throws Exception; - void destroyQueue(SimpleString queueName, ServerSession session) throws Exception; + void destroyQueue(SimpleString queueName, SecurityAuth session) throws Exception; - void destroyQueue(SimpleString queueName, ServerSession session, boolean checkConsumerCount) throws Exception; + void destroyQueue(SimpleString queueName, SecurityAuth session, boolean checkConsumerCount) throws Exception; void destroyQueue(SimpleString queueName, - ServerSession session, + SecurityAuth session, boolean checkConsumerCount, boolean removeConsumers) throws Exception; diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/ServerSession.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/ServerSession.java index 66ebf93306..ab6dd0da7b 100644 --- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/ServerSession.java +++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/ServerSession.java @@ -23,18 +23,15 @@ import java.util.Set; import org.apache.activemq.artemis.api.core.SimpleString; import org.apache.activemq.artemis.core.message.impl.MessageInternal; import org.apache.activemq.artemis.core.persistence.OperationContext; +import org.apache.activemq.artemis.core.security.SecurityAuth; import org.apache.activemq.artemis.core.transaction.Transaction; import org.apache.activemq.artemis.spi.core.protocol.RemotingConnection; import org.apache.activemq.artemis.utils.json.JSONArray; -public interface ServerSession { +public interface ServerSession extends SecurityAuth { String getName(); - String getUsername(); - - String getPassword(); - int getMinLargeMessageSize(); Object getConnectionID(); diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java index 885315423e..07f88bc85e 100644 --- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java +++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java @@ -16,6 +16,30 @@ */ package org.apache.activemq.artemis.core.server.impl; +import javax.management.MBeanServer; +import java.io.File; +import java.io.FilenameFilter; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.lang.management.ManagementFactory; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.TimeUnit; + import org.apache.activemq.artemis.api.config.ActiveMQDefaultConfiguration; import org.apache.activemq.artemis.api.core.Pair; import org.apache.activemq.artemis.api.core.SimpleString; @@ -29,9 +53,9 @@ import org.apache.activemq.artemis.core.config.impl.ConfigurationImpl; import org.apache.activemq.artemis.core.filter.Filter; import org.apache.activemq.artemis.core.filter.impl.FilterImpl; import org.apache.activemq.artemis.core.io.IOCriticalErrorListener; -import org.apache.activemq.artemis.core.journal.JournalLoadInformation; import org.apache.activemq.artemis.core.io.SequentialFile; import org.apache.activemq.artemis.core.io.aio.AIOSequentialFileFactory; +import org.apache.activemq.artemis.core.journal.JournalLoadInformation; import org.apache.activemq.artemis.core.management.impl.ActiveMQServerControlImpl; import org.apache.activemq.artemis.core.paging.PagingManager; import org.apache.activemq.artemis.core.paging.cursor.PageSubscription; @@ -58,6 +82,7 @@ import org.apache.activemq.artemis.core.remoting.server.impl.RemotingServiceImpl import org.apache.activemq.artemis.core.replication.ReplicationManager; import org.apache.activemq.artemis.core.security.CheckType; import org.apache.activemq.artemis.core.security.Role; +import org.apache.activemq.artemis.core.security.SecurityAuth; import org.apache.activemq.artemis.core.security.SecurityStore; import org.apache.activemq.artemis.core.security.impl.SecurityStoreImpl; import org.apache.activemq.artemis.core.server.ActivateCallback; @@ -107,30 +132,6 @@ import org.apache.activemq.artemis.utils.ReusableLatch; import org.apache.activemq.artemis.utils.SecurityFormatter; import org.apache.activemq.artemis.utils.VersionLoader; -import javax.management.MBeanServer; -import java.io.File; -import java.io.FilenameFilter; -import java.io.PrintWriter; -import java.io.StringWriter; -import java.lang.management.ManagementFactory; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ScheduledThreadPoolExecutor; -import java.util.concurrent.ThreadFactory; -import java.util.concurrent.TimeUnit; - /** * The ActiveMQ Artemis server implementation */ @@ -1182,18 +1183,18 @@ public class ActiveMQServerImpl implements ActiveMQServer { destroyQueue(queueName, null, true); } - public void destroyQueue(final SimpleString queueName, final ServerSession session) throws Exception { + public void destroyQueue(final SimpleString queueName, final SecurityAuth session) throws Exception { destroyQueue(queueName, session, true); } public void destroyQueue(final SimpleString queueName, - final ServerSession session, + final SecurityAuth session, final boolean checkConsumerCount) throws Exception { destroyQueue(queueName, session, checkConsumerCount, false); } public void destroyQueue(final SimpleString queueName, - final ServerSession session, + final SecurityAuth session, final boolean checkConsumerCount, final boolean removeConsumers) throws Exception { addressSettingsRepository.clearCache(); diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ServerSessionImpl.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ServerSessionImpl.java index d9f65a91f2..7c09a4c4d8 100644 --- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ServerSessionImpl.java +++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ServerSessionImpl.java @@ -172,30 +172,6 @@ public class ServerSessionImpl implements ServerSession, FailureListener { private final TransactionFactory transactionFactory; - //create an 'empty' session. Only used by AMQServerSession - //in order to check username and password - protected ServerSessionImpl(String username, String password) { - this.username = username; - this.password = password; - - this.transactionFactory = null; - this.strictUpdateDeliveryCount = false; - this.storageManager = null; - this.server = null; - this.securityStore = null; - this.resourceManager = null; - this.remotingConnection = null; - this.preAcknowledge = false; - this.postOffice = null; - this.name = null; - this.minLargeMessageSize = 0; - this.managementService = null; - this.managementAddress = null; - this.context = null; - this.callback = null; - this.queueCreator = null; - } - public ServerSessionImpl(final String name, final String username, final String password, @@ -494,7 +470,7 @@ public class ServerSessionImpl implements ServerSession, FailureListener { securityStore.check(address, CheckType.CREATE_NON_DURABLE_QUEUE, this); } - ((ActiveMQServerImpl) server).checkQueueCreationLimit(getUsername()); + server.checkQueueCreationLimit(getUsername()); Queue queue; @@ -538,7 +514,7 @@ public class ServerSessionImpl implements ServerSession, FailureListener { final SimpleString filterString) throws Exception { securityStore.check(address, CheckType.CREATE_NON_DURABLE_QUEUE, this); - ((ActiveMQServerImpl) server).checkQueueCreationLimit(getUsername()); + server.checkQueueCreationLimit(getUsername()); server.createSharedQueue(address, name, filterString, SimpleString.toSimpleString(getUsername()), durable); }