[jboss-cvs] JBoss Messaging SVN: r7989 - in branches/Branch_1_4: integration/AS5/src/main and 12 other directories.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Mon Mar 29 23:05:40 EDT 2010
Author: gaohoward
Date: 2010-03-29 23:05:37 -0400 (Mon, 29 Mar 2010)
New Revision: 7989
Added:
branches/Branch_1_4/integration/AS5/src/main/
branches/Branch_1_4/integration/AS5/src/main/org/
branches/Branch_1_4/integration/AS5/src/main/org/jboss/
branches/Branch_1_4/integration/AS5/src/main/org/jboss/jms/
branches/Branch_1_4/integration/AS5/src/main/org/jboss/jms/server/
branches/Branch_1_4/integration/AS5/src/main/org/jboss/jms/server/container/
branches/Branch_1_4/integration/AS5/src/main/org/jboss/jms/server/container/SecurityActions.java
branches/Branch_1_4/integration/AS5/src/main/org/jboss/jms/server/container/SecurityAspect.java
branches/Branch_1_4/integration/AS5/src/main/org/jboss/jms/server/endpoint/
branches/Branch_1_4/integration/AS5/src/main/org/jboss/jms/server/endpoint/SecurityActions.java
branches/Branch_1_4/integration/AS5/src/main/org/jboss/jms/server/endpoint/ServerConnectionFactoryEndpoint.java
branches/Branch_1_4/integration/AS5/src/main/org/jboss/jms/server/security/
branches/Branch_1_4/integration/AS5/src/main/org/jboss/jms/server/security/SecurityActions.java
branches/Branch_1_4/integration/AS5/src/main/org/jboss/jms/server/security/SecurityMetadataStore.java
branches/Branch_1_4/integration/EAP4/src/main/org/jboss/jms/server/security/
branches/Branch_1_4/integration/EAP4/src/main/org/jboss/jms/server/security/SecurityActions.java
branches/Branch_1_4/integration/EAP4/src/main/org/jboss/jms/server/security/SecurityMetadataStore.java
branches/Branch_1_4/integration/EAP5/src/main/org/jboss/jms/server/security/
branches/Branch_1_4/integration/EAP5/src/main/org/jboss/jms/server/security/SecurityActions.java
branches/Branch_1_4/integration/EAP5/src/main/org/jboss/jms/server/security/SecurityMetadataStore.java
Modified:
branches/Branch_1_4/tests/src/org/jboss/test/thirdparty/jbosssx/SecurityAssociationTest.java
Log:
JBMESSAGING-1787
Added: branches/Branch_1_4/integration/AS5/src/main/org/jboss/jms/server/container/SecurityActions.java
===================================================================
--- branches/Branch_1_4/integration/AS5/src/main/org/jboss/jms/server/container/SecurityActions.java (rev 0)
+++ branches/Branch_1_4/integration/AS5/src/main/org/jboss/jms/server/container/SecurityActions.java 2010-03-30 03:05:37 UTC (rev 7989)
@@ -0,0 +1,67 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.jms.server.container;
+
+import java.security.AccessController;
+import java.security.Principal;
+import java.security.PrivilegedAction;
+
+import javax.security.auth.Subject;
+
+import org.jboss.security.SecurityAssociation;
+import org.jboss.security.SecurityContext;
+import org.jboss.security.SecurityContextAssociation;
+
+
+/** A collection of privileged actions for this package
+ * @author Scott.Stark at jboss.org
+ * @author <a href="mailto:alex at jboss.org">Alexey Loubyansky</a>
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @author <a href="mailto:anil.saldhana at jboss.com">anil saldhana</a>
+ * @author <a href="mailto:hgao at redhat.com">Howard Gao</a>
+ * @version $Revison: 1.0$
+ */
+class SecurityActions
+{
+
+ static SecurityContext getSecurityContext()
+ {
+ return AccessController.doPrivileged(new PrivilegedAction<SecurityContext>(){
+
+ public SecurityContext run()
+ {
+ return SecurityContextAssociation.getSecurityContext();
+ }});
+ }
+
+ static void setSecurityContext(final SecurityContext sc)
+ {
+ AccessController.doPrivileged(new PrivilegedAction<Object>(){
+
+ public Object run()
+ {
+ SecurityContextAssociation.setSecurityContext(sc);
+ return null;
+ }});
+ }
+
+}
Added: branches/Branch_1_4/integration/AS5/src/main/org/jboss/jms/server/container/SecurityAspect.java
===================================================================
--- branches/Branch_1_4/integration/AS5/src/main/org/jboss/jms/server/container/SecurityAspect.java (rev 0)
+++ branches/Branch_1_4/integration/AS5/src/main/org/jboss/jms/server/container/SecurityAspect.java 2010-03-30 03:05:37 UTC (rev 7989)
@@ -0,0 +1,352 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.jms.server.container;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import javax.jms.Destination;
+import javax.jms.JMSSecurityException;
+import javax.jms.Message;
+
+import org.jboss.aop.joinpoint.Invocation;
+import org.jboss.aop.joinpoint.MethodInvocation;
+import org.jboss.jms.destination.JBossDestination;
+import org.jboss.jms.message.JBossMessage;
+import org.jboss.jms.server.SecurityStore;
+import org.jboss.jms.server.endpoint.ServerConnectionEndpoint;
+import org.jboss.jms.server.endpoint.ServerConsumerEndpoint;
+import org.jboss.jms.server.endpoint.ServerSessionEndpoint;
+import org.jboss.jms.server.endpoint.advised.ConnectionAdvised;
+import org.jboss.jms.server.endpoint.advised.ConsumerAdvised;
+import org.jboss.jms.server.endpoint.advised.SessionAdvised;
+import org.jboss.jms.server.security.CheckType;
+import org.jboss.jms.server.security.SecurityMetadata;
+import org.jboss.jms.tx.ClientTransaction;
+import org.jboss.jms.tx.TransactionRequest;
+import org.jboss.logging.Logger;
+import org.jboss.security.SecurityContext;
+
+/**
+ * This aspect enforces the JBossMessaging JMS security policy.
+ *
+ * This aspect is PER_INSTANCE
+ *
+ * For performance reasons we cache access rights in the interceptor for a maximum of
+ * INVALIDATION_INTERVAL milliseconds.
+ * This is because we don't want to do a full authentication and authorization on every send,
+ * for example, since this will drastically reduce performance.
+ * This means any changes to security data won't be reflected until INVALIDATION_INTERVAL
+ * milliseconds later.
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @author <a href="mailto:ovidiu at feodorov.com">Ovidiu Feodorov</a>
+ * @version <tt>$Revision 1.1 $</tt>
+ *
+ * $Id: SecurityAspect.java 3147 2007-09-27 19:12:12Z anil.saldhana at jboss.com $
+ */
+public class SecurityAspect
+{
+ // Constants -----------------------------------------------------
+
+ private static final Logger log = Logger.getLogger(SecurityAspect.class);
+
+ // Static --------------------------------------------------------
+
+ // Attributes ----------------------------------------------------
+
+ private boolean trace = log.isTraceEnabled();
+
+ private Set readCache;
+
+ private Set writeCache;
+
+ private Set createCache;
+
+ //TODO Make this configurable
+ private static final long INVALIDATION_INTERVAL = 15000;
+
+ private long lastCheck;
+
+ // Constructors --------------------------------------------------
+
+ // Public --------------------------------------------------------
+ public SecurityAspect()
+ {
+ readCache = new HashSet();
+
+ writeCache = new HashSet();
+
+ createCache = new HashSet();
+ }
+
+ public Object handleCreateConsumerDelegate(Invocation invocation) throws Throwable
+ {
+ MethodInvocation mi = (MethodInvocation)invocation;
+
+ // read permission required on the destination
+ Destination dest = (Destination)mi.getArguments()[0];
+
+ SessionAdvised del = (SessionAdvised)invocation.getTargetObject();
+ ServerSessionEndpoint sess = (ServerSessionEndpoint)del.getEndpoint();
+
+ check(dest, CheckType.READ, sess.getConnectionEndpoint());
+
+ // if creating a durable subscription then need create permission
+
+ String subscriptionName = (String)mi.getArguments()[3];
+ if (subscriptionName != null)
+ {
+ // durable
+ check(dest, CheckType.CREATE, sess.getConnectionEndpoint());
+ }
+
+ return invocation.invokeNext();
+ }
+
+ public Object handleCreateBrowserDelegate(Invocation invocation) throws Throwable
+ {
+ // read permission required on the destination
+
+ MethodInvocation mi = (MethodInvocation)invocation;
+
+ Destination dest = (Destination)mi.getArguments()[0];
+
+ SessionAdvised del = (SessionAdvised)invocation.getTargetObject();
+ ServerSessionEndpoint sess = (ServerSessionEndpoint)del.getEndpoint();
+
+ check(dest, CheckType.READ, sess.getConnectionEndpoint());
+
+ return invocation.invokeNext();
+ }
+
+ public Object handleSend(Invocation invocation) throws Throwable
+ {
+ // anonymous producer - if destination is not null then write permissions required
+
+ MethodInvocation mi = (MethodInvocation)invocation;
+
+ Message m = (Message)mi.getArguments()[0];
+ Destination dest = m.getJMSDestination();
+
+ SessionAdvised del = (SessionAdvised)invocation.getTargetObject();
+ ServerSessionEndpoint se = (ServerSessionEndpoint)del.getEndpoint();
+ ServerConnectionEndpoint ce = se.getConnectionEndpoint();
+
+ check(dest, CheckType.WRITE, ce);
+
+ return invocation.invokeNext();
+ }
+
+
+ // An aspect over ConnectionAdvised
+ public Object handleSendTransaction(Invocation invocation) throws Throwable
+ {
+ ConnectionAdvised del = (ConnectionAdvised)invocation.getTargetObject();
+ ServerConnectionEndpoint ce = (ServerConnectionEndpoint)del.getEndpoint();
+
+ MethodInvocation mi = (MethodInvocation)invocation;
+
+ TransactionRequest t = (TransactionRequest)mi.getArguments()[0];
+
+ ClientTransaction txState = t.getState();
+
+ if (txState != null)
+ {
+ // distinct list of destinations...
+ HashSet destinations = new HashSet();
+
+ for (Iterator i = txState.getSessionStates().iterator(); i.hasNext(); )
+ {
+ ClientTransaction.SessionTxState sessionState = (ClientTransaction.SessionTxState)i.next();
+ for (Iterator j = sessionState.getMsgs().iterator(); j.hasNext(); )
+ {
+ JBossMessage message = (JBossMessage)j.next();
+ destinations.add(message.getJMSDestination());
+ }
+ }
+ for (Iterator iterDestinations = destinations.iterator();iterDestinations.hasNext();)
+ {
+ Destination destination = (Destination) iterDestinations.next();
+ check(destination, CheckType.WRITE, ce);
+ }
+
+ }
+
+ return invocation.invokeNext();
+ }
+
+
+
+ protected void checkConsumerAccess(Invocation invocation) throws Throwable
+ {
+ ConsumerAdvised del = (ConsumerAdvised)invocation.getTargetObject();
+ ServerConsumerEndpoint cons = (ServerConsumerEndpoint)del.getEndpoint();
+ ServerConnectionEndpoint conn = cons.getSessionEndpoint().getConnectionEndpoint();
+ JBossDestination dest = cons.getDestination();
+
+ check(dest, CheckType.READ, conn);
+ }
+
+ // Package protected ---------------------------------------------
+
+ // Protected -----------------------------------------------------
+
+ // Private -------------------------------------------------------
+
+ private boolean checkCached(Destination dest, CheckType checkType)
+ {
+ long now = System.currentTimeMillis();
+
+ boolean granted = false;
+
+ if (now - lastCheck > INVALIDATION_INTERVAL)
+ {
+ readCache.clear();
+
+ writeCache.clear();
+
+ createCache.clear();
+ }
+ else
+ {
+ switch (checkType.type)
+ {
+ case CheckType.TYPE_READ:
+ {
+ granted = readCache.contains(dest);
+ break;
+ }
+ case CheckType.TYPE_WRITE:
+ {
+ granted = writeCache.contains(dest);
+ break;
+ }
+ case CheckType.TYPE_CREATE:
+ {
+ granted = createCache.contains(dest);
+ break;
+ }
+ default:
+ {
+ throw new IllegalArgumentException("Invalid checkType:" + checkType);
+ }
+ }
+ }
+
+ lastCheck = now;
+
+ return granted;
+ }
+
+ private void check(Destination dest, CheckType checkType, ServerConnectionEndpoint conn)
+ throws JMSSecurityException
+ {
+ JBossDestination jbd = (JBossDestination)dest;
+
+ if (jbd.isTemporary())
+ {
+ if (trace) { log.trace("skipping permission check on temporary destination " + dest); }
+ return;
+ }
+
+ if (trace) { log.trace("checking access permissions to " + dest); }
+
+ if (checkCached(dest, checkType))
+ {
+ // OK
+ return;
+ }
+
+ boolean isQueue = jbd.isQueue();
+ String name = jbd.getName();
+
+ SecurityStore sm = conn.getSecurityManager();
+ SecurityMetadata securityMetadata = sm.getSecurityMetadata(isQueue, name);
+
+ if (securityMetadata == null)
+ {
+ throw new JMSSecurityException("No security configuration avaliable for " + name);
+ }
+
+ // Authenticate. Need to save current SecurityContext
+ SecurityContext previousSCtx = SecurityActions.getSecurityContext();
+
+ sm.authenticate(conn.getUsername(), conn.getPassword());
+
+ // Authorize
+ Set principals = checkType == CheckType.READ ? securityMetadata.getReadPrincipals() :
+ checkType == CheckType.WRITE ? securityMetadata.getWritePrincipals() :
+ securityMetadata.getCreatePrincipals();
+ try
+ {
+ if (!sm.authorize(conn.getUsername(), principals, checkType))
+ {
+ String msg = "User: " + conn.getUsername() +
+ " is not authorized to " +
+ (checkType == CheckType.READ ? "read from" :
+ checkType == CheckType.WRITE ? "write to" : "create durable sub on") +
+ " destination " + name;
+
+ throw new JMSSecurityException(msg);
+ }
+ }
+ finally
+ {
+ // Restore previous SecurityContext
+ SecurityActions.setSecurityContext(previousSCtx);
+ }
+
+ // if we get here we're granted, add to the cache
+
+ switch (checkType.type)
+ {
+ case CheckType.TYPE_READ:
+ {
+ readCache.add(dest);
+ break;
+ }
+ case CheckType.TYPE_WRITE:
+ {
+ writeCache.add(dest);
+ break;
+ }
+ case CheckType.TYPE_CREATE:
+ {
+ createCache.add(dest);
+ break;
+ }
+ default:
+ {
+ throw new IllegalArgumentException("Invalid checkType:" + checkType);
+ }
+ }
+ }
+
+ // Inner classes -------------------------------------------------
+
+}
+
+
+
+
Added: branches/Branch_1_4/integration/AS5/src/main/org/jboss/jms/server/endpoint/SecurityActions.java
===================================================================
--- branches/Branch_1_4/integration/AS5/src/main/org/jboss/jms/server/endpoint/SecurityActions.java (rev 0)
+++ branches/Branch_1_4/integration/AS5/src/main/org/jboss/jms/server/endpoint/SecurityActions.java 2010-03-30 03:05:37 UTC (rev 7989)
@@ -0,0 +1,123 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.jms.server.endpoint;
+
+import java.security.AccessController;
+import java.security.Principal;
+import java.security.PrivilegedAction;
+
+import javax.security.auth.Subject;
+
+import org.jboss.security.SecurityAssociation;
+import org.jboss.security.SecurityContext;
+import org.jboss.security.SecurityContextAssociation;
+
+/** A collection of privileged actions for this package
+ * @author Scott.Stark at jboss.org
+ * @author <a href="mailto:alex at jboss.org">Alexey Loubyansky</a>
+ * @author tim.fox at jboss.com
+ * @author anil.saldhana at jboss.com
+ * @author <a href="mailto:hgao at redhat.com">Howard Gao</a>
+ * @version $Revison: 1.0$
+ */
+class SecurityActions
+{
+
+ static SecurityContext getSecurityContext()
+ {
+ return AccessController.doPrivileged(new PrivilegedAction<SecurityContext>(){
+
+ public SecurityContext run()
+ {
+ return SecurityContextAssociation.getSecurityContext();
+ }});
+ }
+
+ static void setSecurityContext(final SecurityContext sc)
+ {
+ AccessController.doPrivileged(new PrivilegedAction<Object>(){
+
+ public Object run()
+ {
+ SecurityContextAssociation.setSecurityContext(sc);
+ return null;
+ }});
+ }
+
+
+ static ClassLoader getTCL()
+ {
+ if (System.getSecurityManager() == null)
+ {
+ return Thread.currentThread().getContextClassLoader();
+ }
+ else
+ {
+ return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>()
+ {
+ public ClassLoader run()
+ {
+ return Thread.currentThread().getContextClassLoader();
+ }
+ });
+ }
+ }
+
+ static ClassLoader getClassLoader(final Class<?> clazz)
+ {
+ if (System.getSecurityManager() == null)
+ {
+ return clazz.getClassLoader();
+ }
+ else
+ {
+ return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>()
+ {
+ public ClassLoader run()
+ {
+ return clazz.getClassLoader();
+ }
+ });
+ }
+
+ }
+
+ static void setTCL(final ClassLoader tcl)
+ {
+ if (System.getSecurityManager() == null)
+ {
+ Thread.currentThread().setContextClassLoader(tcl);
+ }
+ else
+ {
+ AccessController.doPrivileged(new PrivilegedAction<Object>()
+ {
+ public Object run()
+ {
+ Thread.currentThread().setContextClassLoader(tcl);
+ return null;
+ }
+ });
+ }
+ }
+
+}
Added: branches/Branch_1_4/integration/AS5/src/main/org/jboss/jms/server/endpoint/ServerConnectionFactoryEndpoint.java
===================================================================
--- branches/Branch_1_4/integration/AS5/src/main/org/jboss/jms/server/endpoint/ServerConnectionFactoryEndpoint.java (rev 0)
+++ branches/Branch_1_4/integration/AS5/src/main/org/jboss/jms/server/endpoint/ServerConnectionFactoryEndpoint.java 2010-03-30 03:05:37 UTC (rev 7989)
@@ -0,0 +1,418 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.jms.server.endpoint;
+
+import java.security.AccessController;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.util.Map;
+import java.util.Set;
+
+import javax.jms.JMSException;
+
+import org.jboss.aop.AspectManager;
+import org.jboss.jms.client.delegate.ClientConnectionDelegate;
+import org.jboss.jms.client.delegate.ClientConnectionFactoryDelegate;
+import org.jboss.jms.delegate.ConnectionFactoryEndpoint;
+import org.jboss.jms.delegate.CreateConnectionResult;
+import org.jboss.jms.delegate.TopologyResult;
+import org.jboss.jms.server.ServerPeer;
+import org.jboss.jms.server.connectionfactory.JNDIBindings;
+import org.jboss.jms.server.endpoint.advised.ConnectionAdvised;
+import org.jboss.jms.wireformat.ConnectionFactoryUpdate;
+import org.jboss.jms.wireformat.Dispatcher;
+import org.jboss.logging.Logger;
+import org.jboss.messaging.util.ConcurrentHashSet;
+import org.jboss.messaging.util.ExceptionUtil;
+import org.jboss.remoting.callback.Callback;
+import org.jboss.remoting.callback.InvokerCallbackHandler;
+import org.jboss.remoting.callback.ServerInvokerCallbackHandler;
+import org.jboss.security.SecurityContext;
+
+/**
+ * Concrete implementation of ConnectionFactoryEndpoint
+ *
+ * @author <a href="mailto:ovidiu at feodorov.com">Ovidiu Feodorov</a>
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 5366 $</tt>
+ *
+ * $Id: ServerConnectionFactoryEndpoint.java 5366 2008-11-14 21:46:28Z clebert.suconic at jboss.com $
+ */
+public class ServerConnectionFactoryEndpoint implements ConnectionFactoryEndpoint
+{
+ // Constants ------------------------------------------------------------------------------------
+
+ private static final Logger log = Logger.getLogger(ServerConnectionFactoryEndpoint.class);
+
+ // Static ---------------------------------------------------------------------------------------
+
+ // Attributes -----------------------------------------------------------------------------------
+
+ private ServerPeer serverPeer;
+
+ private String clientID;
+
+ private String uniqueName;
+
+ private String id;
+
+ private JNDIBindings jndiBindings;
+
+ private int prefetchSize;
+
+ private int defaultTempQueueFullSize;
+
+ private int defaultTempQueuePageSize;
+
+ private int defaultTempQueueDownCacheSize;
+
+ private int dupsOKBatchSize;
+
+ private boolean supportsFailover;
+
+ private boolean slowConsumers;
+
+ /** Cluster Topology on ClusteredConnectionFactories
+ Information to failover to other connections on clients **/
+ private ClientConnectionFactoryDelegate[] delegates;
+
+ /** Cluster Topology on ClusteredConnectionFactories
+ Information to failover to other connections on clients **/
+ private Map failoverMap;
+
+ private Set<InvokerCallbackHandler> handlers = new ConcurrentHashSet<InvokerCallbackHandler>();
+
+
+ // Constructors ---------------------------------------------------------------------------------
+
+ /**
+ * @param jndiBindings - names under which the corresponding JBossConnectionFactory is bound in
+ * JNDI.
+ */
+ public ServerConnectionFactoryEndpoint(String uniqueName, String id, ServerPeer serverPeer,
+ String defaultClientID,
+ JNDIBindings jndiBindings,
+ int preFetchSize,
+ boolean slowConsumers,
+ int defaultTempQueueFullSize,
+ int defaultTempQueuePageSize,
+ int defaultTempQueueDownCacheSize,
+ int dupsOKBatchSize,
+ boolean supportsFailover)
+ {
+ this.uniqueName = uniqueName;
+ this.serverPeer = serverPeer;
+ this.clientID = defaultClientID;
+ this.id = id;
+ this.jndiBindings = jndiBindings;
+ this.prefetchSize = preFetchSize;
+ this.defaultTempQueueFullSize = defaultTempQueueFullSize;
+ this.defaultTempQueuePageSize = defaultTempQueuePageSize;
+ this.defaultTempQueueDownCacheSize = defaultTempQueueDownCacheSize;
+ this.dupsOKBatchSize = dupsOKBatchSize;
+ this.supportsFailover = supportsFailover;
+ this.slowConsumers = slowConsumers;
+ if (slowConsumers)
+ {
+ this.prefetchSize = 1;
+ }
+ }
+
+ // ConnectionFactoryDelegate implementation -----------------------------------------------------
+
+ public CreateConnectionResult createConnectionDelegate(String username,
+ String password,
+ int failedNodeID)
+
+ throws JMSException
+ {
+ //This is never called directly
+ throw new IllegalStateException("createConnectionDelegate should never be called directly");
+ }
+
+ /**
+ * @param failedNodeID - zero or positive values mean connection creation attempt is result of
+ * failover. -1 are ignored (mean regular connection creation attempt).
+ */
+ public CreateConnectionResult createConnectionDelegate(String username,
+ String password,
+ int failedNodeID,
+ String remotingSessionID,
+ String clientVMID,
+ byte versionToUse,
+ ServerInvokerCallbackHandler callbackHandler)
+ throws JMSException
+ {
+ try
+ {
+ if (failedNodeID == -1)
+ {
+ // Just a standard createConnection
+ ClientConnectionDelegate cd =
+ createConnectionDelegateInternal(username, password, failedNodeID,
+ remotingSessionID, clientVMID,
+ versionToUse,
+ callbackHandler);
+ return new CreateConnectionResult(cd);
+ }
+ else
+ {
+ log.trace(this + " received client-side failover request. Creating failover "+
+ "connection to replace connection to failed node " + failedNodeID);
+
+ // Wait for server side failover to complete
+ int failoverNodeID = serverPeer.getFailoverWaiter().waitForFailover(failedNodeID);
+
+ if (failoverNodeID == -1 || failoverNodeID != serverPeer.getServerPeerID())
+ {
+ log.trace(this + " realized that we are on the wrong node or no failover has occured");
+ return new CreateConnectionResult(failoverNodeID);
+ }
+ else
+ {
+ log.trace(this + " received notification that server-side failover completed, " +
+ "creating connection delegate ...");
+ ClientConnectionDelegate cd =
+ createConnectionDelegateInternal(username, password, failedNodeID,
+ remotingSessionID, clientVMID,
+ versionToUse,
+ callbackHandler);
+ return new CreateConnectionResult(cd);
+ }
+ }
+ }
+ catch (Throwable t)
+ {
+ throw ExceptionUtil.handleJMSInvocation(t, this + " createFailoverConnectionDelegate");
+ }
+
+ }
+
+ /**
+ * @param failedNodeID - zero or positive values mean connection creation attempt is result of
+ * failover. Negative values are ignored (mean regular connection creation attempt).
+ */
+ private ClientConnectionDelegate
+ createConnectionDelegateInternal(final String username,
+ final String password,
+ final int failedNodeID,
+ final String remotingSessionID, final String clientVMID,
+ final byte versionToUse,
+ final ServerInvokerCallbackHandler callbackHandler)
+ throws Exception
+ {
+ log.trace("creating a new connection for user " + username);
+
+ // Authenticate. Need to save current SecurityContext
+ SecurityContext previousSCtx = SecurityActions.getSecurityContext();
+
+ if (System.getSecurityManager() == null)
+ {
+ serverPeer.getSecurityManager().authenticate(username, password);
+ }
+ else
+ {
+ try
+ {
+ AccessController.doPrivileged(new PrivilegedExceptionAction<Object>()
+ {
+ public Object run() throws Exception
+ {
+ serverPeer.getSecurityManager().authenticate(username, password);
+ return null;
+ }
+ });
+ }
+ catch (PrivilegedActionException pe)
+ {
+ throw pe.getException();
+ }
+ }
+
+ // Restore previous SecurityContext
+ SecurityActions.setSecurityContext(previousSCtx);
+
+ String clientIDUsed = clientID;
+
+ // see if there is a preconfigured client id for the user
+ if (username != null)
+ {
+ String preconfClientID =
+ serverPeer.getJmsUserManagerInstance().getPreConfiguredClientID(username);
+
+ if (preconfClientID != null)
+ {
+ clientIDUsed = preconfClientID;
+ }
+ }
+
+ // create the corresponding "server-side" connection endpoint and register it with the
+ // server peer's ClientManager
+ ServerConnectionEndpoint endpoint =
+ new ServerConnectionEndpoint(serverPeer, clientIDUsed, username, password, prefetchSize,
+ defaultTempQueueFullSize, defaultTempQueuePageSize,
+ defaultTempQueueDownCacheSize, failedNodeID, this,
+ remotingSessionID, clientVMID, versionToUse,
+ callbackHandler, dupsOKBatchSize);
+
+ String connectionID = endpoint.getConnectionID();
+
+ ConnectionAdvised connAdvised;
+
+ // Need to synchronized to prevent a deadlock
+ // See http://jira.jboss.com/jira/browse/JBMESSAGING-797
+ synchronized (AspectManager.instance())
+ {
+ connAdvised = new ConnectionAdvised(endpoint);
+ }
+
+ Dispatcher.instance.registerTarget(connectionID, connAdvised);
+
+ log.trace("created and registered " + endpoint);
+
+ // Need to synchronized to prevent a deadlock
+ // See http://jira.jboss.com/jira/browse/JBMESSAGING-797
+ synchronized (AspectManager.instance())
+ {
+ return new ClientConnectionDelegate(connectionID, serverPeer.getServerPeerID());
+ }
+ }
+
+ public byte[] getClientAOPStack() throws JMSException
+ {
+ try
+ {
+ return serverPeer.getClientAOPStack();
+ }
+ catch (Throwable t)
+ {
+ throw ExceptionUtil.handleJMSInvocation(t, this + " getClientAOPStack");
+ }
+ }
+
+ public void addCallback(String VMID, String remotingSessionID,
+ InvokerCallbackHandler callbackHandler) throws JMSException
+ {
+ log.debug("Adding callbackHandler on ConnectionFactory");
+
+ handlers.add(callbackHandler);
+
+ serverPeer.getConnectionManager().registerConnectionFactoryCallback(VMID, remotingSessionID, callbackHandler);
+ }
+
+ public void removeCallback(String VMID, String remotingSessionID,
+ ServerInvokerCallbackHandler callbackHandler) throws JMSException
+ {
+ log.debug("Removing callbackHandler on ConnectionFactory");
+
+ handlers.remove(callbackHandler);
+
+ serverPeer.getConnectionManager().unregisterConnectionFactoryCallback(VMID, remotingSessionID);
+ }
+
+ public TopologyResult getTopology() throws JMSException
+ {
+ return new TopologyResult(uniqueName, delegates, failoverMap);
+ }
+
+ public void removeCallbackhandler(InvokerCallbackHandler handler)
+ {
+ handlers.remove(handler);
+ }
+
+ // Public ---------------------------------------------------------------------------------------
+
+ public String getID()
+ {
+ return id;
+ }
+
+ public JNDIBindings getJNDIBindings()
+ {
+ return jndiBindings;
+ }
+
+ public ServerPeer getServerPeer()
+ {
+ return serverPeer;
+ }
+
+ /**
+ * Sends a cluster view update message to its associated ClusteredConnectionFactories.
+ *
+ * Observation: It is placed here, because if we decide to lock the ServerEndpoint while we send
+ * updates, we would need the method here to perform WriteLocks on objects.
+ */
+ public void updateClusteredClients(ClientConnectionFactoryDelegate[] delegates, Map failoverMap)
+ throws Exception
+ {
+ updateTopology(delegates, failoverMap);
+
+ log.debug("updateClusteredClients being called!!! clientFactoriesToUpdate.size = " + handlers.size());
+
+ ConnectionFactoryUpdate message =
+ new ConnectionFactoryUpdate(uniqueName, delegates, failoverMap);
+
+ Callback callback = new Callback(message);
+
+ for (InvokerCallbackHandler o: handlers)
+ {
+ log.debug("Updating CF on callback " + o);
+ ((ServerInvokerCallbackHandler)o).handleCallbackOneway(callback);
+ }
+ }
+
+ public void updateTopology(ClientConnectionFactoryDelegate[] delegates, Map failoverMap)
+ {
+ this.delegates = delegates;
+ this.failoverMap = failoverMap;
+ }
+
+ public boolean isSlowConsumers()
+ {
+ return slowConsumers;
+ }
+
+ public String toString()
+ {
+ return "ConnectionFactoryEndpoint[" + id + "]";
+ }
+
+ /** Method used for tests and validations only */
+ public Set getCallbackHandlers()
+ {
+ return java.util.Collections.unmodifiableSet(handlers);
+ }
+
+ // Package protected ----------------------------------------------------------------------------
+
+ boolean isSupportsFailover()
+ {
+ return supportsFailover;
+ }
+
+ // Protected ------------------------------------------------------------------------------------
+
+ // Private --------------------------------------------------------------------------------------
+
+ // Inner classes --------------------------------------------------------------------------------
+}
Added: branches/Branch_1_4/integration/AS5/src/main/org/jboss/jms/server/security/SecurityActions.java
===================================================================
--- branches/Branch_1_4/integration/AS5/src/main/org/jboss/jms/server/security/SecurityActions.java (rev 0)
+++ branches/Branch_1_4/integration/AS5/src/main/org/jboss/jms/server/security/SecurityActions.java 2010-03-30 03:05:37 UTC (rev 7989)
@@ -0,0 +1,164 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.jms.server.security;
+
+import java.security.AccessController;
+import java.security.Principal;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedExceptionAction;
+
+import javax.security.auth.Subject;
+
+import org.jboss.security.SecurityAssociation;
+import org.jboss.security.SecurityContext;
+import org.jboss.security.SecurityContextAssociation;
+import org.jboss.security.SecurityContextFactory;
+import org.jboss.security.SimplePrincipal;
+import org.jboss.security.plugins.JBossSecurityContext;
+
+
+/** A collection of privileged actions for this package
+ * @author Scott.Stark at jboss.org
+ * @author <a href="mailto:alex at jboss.org">Alexey Loubyansky</a>
+ * @author <a her="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version $Revison: 1.0$
+ */
+class SecurityActions
+{
+
+ static SecurityContext getSecurityContext()
+ {
+ return AccessController.doPrivileged(new PrivilegedAction<SecurityContext>(){
+
+ public SecurityContext run()
+ {
+ return SecurityContextAssociation.getSecurityContext();
+ }});
+ }
+
+ static void setSecurityContext(final SecurityContext sc)
+ {
+ AccessController.doPrivileged(new PrivilegedAction<Object>(){
+
+ public Object run()
+ {
+ SecurityContextAssociation.setSecurityContext(sc);
+ return null;
+ }});
+ }
+
+ interface PrincipalInfoAction
+ {
+ PrincipalInfoAction PRIVILEGED = new PrincipalInfoAction()
+ {
+ public void push(final Principal principal, final Object credential,
+ final Subject subject)
+ {
+ AccessController.doPrivileged(
+ new PrivilegedAction()
+ {
+ public Object run()
+ {
+ SecurityAssociation.pushSubjectContext(subject, principal, credential);
+ return null;
+ }
+ }
+ );
+ }
+ public void dup()
+ {
+ AccessController.doPrivileged(
+ new PrivilegedAction()
+ {
+ public Object run()
+ {
+ SecurityAssociation.dupSubjectContext();
+ return null;
+ }
+ }
+ );
+ }
+ public void pop()
+ {
+ AccessController.doPrivileged(
+ new PrivilegedAction()
+ {
+ public Object run()
+ {
+ SecurityAssociation.popSubjectContext();
+ return null;
+ }
+ }
+ );
+ }
+ };
+
+ PrincipalInfoAction NON_PRIVILEGED = new PrincipalInfoAction()
+ {
+ public void push(Principal principal, Object credential, Subject subject)
+ {
+ SecurityAssociation.pushSubjectContext(subject, principal, credential);
+ }
+ public void dup()
+ {
+ SecurityAssociation.dupSubjectContext();
+ }
+ public void pop()
+ {
+ SecurityAssociation.popSubjectContext();
+ }
+ };
+
+ void push(Principal principal, Object credential, Subject subject);
+ void dup();
+ void pop();
+ }
+
+ static void pushSubjectContext(Principal principal, Object credential,
+ Subject subject)
+ {
+ if(System.getSecurityManager() == null)
+ {
+ PrincipalInfoAction.NON_PRIVILEGED.push(principal, credential, subject);
+ }
+ else
+ {
+ PrincipalInfoAction.PRIVILEGED.push(principal, credential, subject);
+ }
+ }
+
+ public static void setSecurityContext(final SimplePrincipal principal,
+ final char[] passwordChars,
+ final Subject subject,
+ final String secDom) throws Exception
+ {
+ AccessController.doPrivileged(new PrivilegedExceptionAction<Object>(){
+
+ public Object run() throws Exception
+ {
+ SecurityContext context = SecurityContextFactory.createSecurityContext(principal, passwordChars, subject, secDom);
+ SecurityContextAssociation.setSecurityContext(context);
+ return null;
+ }});
+ }
+
+}
Added: branches/Branch_1_4/integration/AS5/src/main/org/jboss/jms/server/security/SecurityMetadataStore.java
===================================================================
--- branches/Branch_1_4/integration/AS5/src/main/org/jboss/jms/server/security/SecurityMetadataStore.java (rev 0)
+++ branches/Branch_1_4/integration/AS5/src/main/org/jboss/jms/server/security/SecurityMetadataStore.java 2010-03-30 03:05:37 UTC (rev 7989)
@@ -0,0 +1,325 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.jms.server.security;
+
+import java.security.Principal;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import javax.jms.JMSSecurityException;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import javax.security.auth.Subject;
+
+import org.jboss.jms.server.SecurityStore;
+import org.jboss.logging.Logger;
+import org.jboss.security.AuthenticationManager;
+import org.jboss.security.RealmMapping;
+import org.jboss.security.SecurityAssociation;
+import org.jboss.security.SimplePrincipal;
+import org.jboss.security.SubjectSecurityManager;
+import org.w3c.dom.Element;
+
+/**
+ * A security metadate store for JMS. Stores security information for destinations and delegates
+ * authentication and authorization to a JaasSecurityManager.
+ *
+ * @author Peter Antman
+ * @author <a href="mailto:Scott.Stark at jboss.org">Scott Stark</a>
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @author <a href="mailto:ovidiu at feodorov.com">Ovidiu Feodorov</a>
+ * @version $Revision: 4986 $
+ *
+ * $Id: SecurityMetadataStore.java 4986 2008-09-18 22:11:43Z clebert.suconic at jboss.com $
+ */
+public class SecurityMetadataStore implements SecurityStore, SecurityMetadataStoreMBean
+{
+ // Constants -----------------------------------------------------
+
+ private static final Logger log = Logger.getLogger(SecurityMetadataStore.class);
+
+ public static final String DEFAULT_SUCKER_USER_PASSWORD = "CHANGE ME!!";
+
+ // Attributes ----------------------------------------------------
+
+ private boolean trace = log.isTraceEnabled();
+
+ private Map queueSecurityConf;
+ private Map topicSecurityConf;
+
+ private AuthenticationManager authenticationManager;
+ private RealmMapping realmMapping;
+
+ private Element defaultSecurityConfig;
+ private String securityDomain = "java:/jaas/messaging";
+
+ private String suckerPassword;
+
+ // Static --------------------------------------------------------
+
+ // Constructors --------------------------------------------------
+
+ public SecurityMetadataStore()
+ {
+ queueSecurityConf = new HashMap();
+ topicSecurityConf = new HashMap();
+ }
+
+ // SecurityManager implementation --------------------------------
+
+ public SecurityMetadata getSecurityMetadata(boolean isQueue, String destName)
+ {
+ SecurityMetadata m = (SecurityMetadata)
+ (isQueue ? queueSecurityConf.get(destName) : topicSecurityConf.get(destName));
+
+ if (m == null)
+ {
+ // No SecurityMetadata was configured for the destination, apply the default
+ if (defaultSecurityConfig != null)
+ {
+ log.debug("No SecurityMetadadata was available for " + destName + ", using default security config");
+ try
+ {
+ m = new SecurityMetadata(defaultSecurityConfig);
+ }
+ catch (Exception e)
+ {
+ log.warn("Unable to apply default security for destName, using guest " + destName, e);
+ m = new SecurityMetadata();
+ }
+ }
+ else
+ {
+ // default to guest
+ log.warn("No SecurityMetadadata was available for " + destName + ", adding guest");
+ m = new SecurityMetadata();
+ }
+
+ // don't cache it! this way the callers will be able to take advantage of default security
+ // configuration updates
+ // securityConf.put(destName, m);
+ }
+ return m;
+ }
+
+ public void setSecurityConfig(boolean isQueue, String destName, Element conf) throws Exception
+ {
+ if (trace) { log.trace("adding security configuration for " + (isQueue ? "queue " : "topic ") + destName); }
+
+ if (conf == null)
+ {
+ clearSecurityConfig(isQueue, destName);
+ }
+ else
+ {
+ SecurityMetadata m = new SecurityMetadata(conf);
+
+ if (isQueue)
+ {
+ queueSecurityConf.put(destName, m);
+ }
+ else
+ {
+ topicSecurityConf.put(destName, m);
+ }
+ }
+ }
+
+ public void clearSecurityConfig(boolean isQueue, String name) throws Exception
+ {
+ if (trace) { log.trace("clearing security configuration for " + (isQueue ? "queue " : "topic ") + name); }
+
+ if (isQueue)
+ {
+ queueSecurityConf.remove(name);
+ }
+ else
+ {
+ topicSecurityConf.remove(name);
+ }
+ }
+
+ public Subject authenticate(String user, String password) throws JMSSecurityException
+ {
+ if (trace) { log.trace("authenticating user " + user); }
+
+ SimplePrincipal principal = new SimplePrincipal(user);
+ char[] passwordChars = null;
+ if (password != null)
+ {
+ passwordChars = password.toCharArray();
+ }
+
+ Subject subject = new Subject();
+
+ boolean authenticated = false;
+
+ if (SUCKER_USER.equals(user))
+ {
+ if (trace) { log.trace("Authenticating sucker user"); }
+
+ checkDefaultSuckerPassword(password);
+
+ // The special user SUCKER_USER is used for creating internal connections that suck messages between nodes
+
+ authenticated = suckerPassword.equals(password);
+ }
+ else
+ {
+ authenticated = authenticationManager.isValid(principal, passwordChars, subject);
+ }
+
+ if (authenticated)
+ {
+ // Warning! This "taints" thread local. Make sure you pop it off the stack as soon as
+ // you're done with it.
+ try
+ {
+ SecurityActions.setSecurityContext(principal, passwordChars, subject, this.getSecurityDomain());
+ }
+ catch (Exception e)
+ {
+ throw new JMSSecurityException("Failed to set SecurityContext");
+ }
+ return subject;
+ }
+ else
+ {
+ throw new JMSSecurityException("User " + user + " is NOT authenticated");
+ }
+ }
+
+ public boolean authorize(String user, Set rolePrincipals, CheckType checkType)
+ {
+ if (trace) { log.trace("authorizing user " + user + " for role(s) " + rolePrincipals.toString()); }
+
+ if (SUCKER_USER.equals(user))
+ {
+ //The special user SUCKER_USER is used for creating internal connections that suck messages between nodes
+ //It has automatic read/write access to all destinations
+ return (checkType.equals(CheckType.READ) || checkType.equals(CheckType.WRITE));
+ }
+
+ Principal principal = user == null ? null : new SimplePrincipal(user);
+
+ boolean hasRole = realmMapping.doesUserHaveRole(principal, rolePrincipals);
+
+ if (trace) { log.trace("user " + user + (hasRole ? " is " : " is NOT ") + "authorized"); }
+
+ return hasRole;
+ }
+
+ // Public --------------------------------------------------------
+
+ public void setSuckerPassword(String password)
+ {
+ checkDefaultSuckerPassword(password);
+
+ this.suckerPassword = password;
+ }
+
+ public void start() throws NamingException
+ {
+ if (trace) { log.trace("initializing SecurityMetadataStore"); }
+
+ // Get the JBoss security manager from JNDI
+ InitialContext ic = new InitialContext();
+
+ try
+ {
+ Object mgr = ic.lookup(securityDomain);
+
+ log.debug("JaasSecurityManager is " + mgr);
+
+ authenticationManager = (AuthenticationManager)mgr;
+ realmMapping = (RealmMapping)mgr;
+
+ log.trace("SecurityMetadataStore initialized");
+ }
+ catch (NamingException e)
+ {
+ // Apparently there is no security context, try adding java:/jaas
+ log.warn("Failed to lookup securityDomain " + securityDomain, e);
+
+ if (!securityDomain.startsWith("java:/jaas/"))
+ {
+ authenticationManager =
+ (SubjectSecurityManager)ic.lookup("java:/jaas/" + securityDomain);
+ }
+ else
+ {
+ throw e;
+ }
+ }
+ finally
+ {
+ ic.close();
+ }
+ }
+
+ public void stop() throws Exception
+ {
+ }
+
+ public String getSecurityDomain()
+ {
+ return this.securityDomain;
+ }
+
+ public void setSecurityDomain(String securityDomain)
+ {
+ this.securityDomain = securityDomain;
+ }
+
+ public Element getDefaultSecurityConfig()
+ {
+ return this.defaultSecurityConfig;
+ }
+
+ public void setDefaultSecurityConfig(Element conf) throws Exception
+ {
+ // Force a parse
+ new SecurityMetadata(conf);
+ defaultSecurityConfig = conf;
+ }
+
+ // Protected -----------------------------------------------------
+
+ // Package Private -----------------------------------------------
+
+ // Private -------------------------------------------------------
+
+ private void checkDefaultSuckerPassword(String password)
+ {
+ // Sanity check
+ if (DEFAULT_SUCKER_USER_PASSWORD.equals(password))
+ {
+ log.warn("WARNING! POTENTIAL SECURITY RISK. It has been detected that the MessageSucker component " +
+ "which sucks messages from one node to another has not had its password changed from the installation default. " +
+ "Please see the JBoss Messaging user guide for instructions on how to do this.");
+ }
+ }
+
+ // Inner class ---------------------------------------------------
+
+}
Added: branches/Branch_1_4/integration/EAP4/src/main/org/jboss/jms/server/security/SecurityActions.java
===================================================================
--- branches/Branch_1_4/integration/EAP4/src/main/org/jboss/jms/server/security/SecurityActions.java (rev 0)
+++ branches/Branch_1_4/integration/EAP4/src/main/org/jboss/jms/server/security/SecurityActions.java 2010-03-30 03:05:37 UTC (rev 7989)
@@ -0,0 +1,120 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.jms.server.security;
+
+import java.security.AccessController;
+import java.security.Principal;
+import java.security.PrivilegedAction;
+
+import javax.security.auth.Subject;
+
+import org.jboss.security.SecurityAssociation;
+
+
+/** A collection of privileged actions for this package
+ * @author Scott.Stark at jboss.org
+ * @author <a href="mailto:alex at jboss.org">Alexey Loubyansky</a>
+ * @author <a her="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version $Revison: 1.0$
+ */
+class SecurityActions
+{
+ interface PrincipalInfoAction
+ {
+ PrincipalInfoAction PRIVILEGED = new PrincipalInfoAction()
+ {
+ public void push(final Principal principal, final Object credential,
+ final Subject subject)
+ {
+ AccessController.doPrivileged(
+ new PrivilegedAction()
+ {
+ public Object run()
+ {
+ SecurityAssociation.pushSubjectContext(subject, principal, credential);
+ return null;
+ }
+ }
+ );
+ }
+ public void dup()
+ {
+ AccessController.doPrivileged(
+ new PrivilegedAction()
+ {
+ public Object run()
+ {
+ SecurityAssociation.dupSubjectContext();
+ return null;
+ }
+ }
+ );
+ }
+ public void pop()
+ {
+ AccessController.doPrivileged(
+ new PrivilegedAction()
+ {
+ public Object run()
+ {
+ SecurityAssociation.popSubjectContext();
+ return null;
+ }
+ }
+ );
+ }
+ };
+
+ PrincipalInfoAction NON_PRIVILEGED = new PrincipalInfoAction()
+ {
+ public void push(Principal principal, Object credential, Subject subject)
+ {
+ SecurityAssociation.pushSubjectContext(subject, principal, credential);
+ }
+ public void dup()
+ {
+ SecurityAssociation.dupSubjectContext();
+ }
+ public void pop()
+ {
+ SecurityAssociation.popSubjectContext();
+ }
+ };
+
+ void push(Principal principal, Object credential, Subject subject);
+ void dup();
+ void pop();
+ }
+
+ static void pushSubjectContext(Principal principal, Object credential,
+ Subject subject)
+ {
+ if(System.getSecurityManager() == null)
+ {
+ PrincipalInfoAction.NON_PRIVILEGED.push(principal, credential, subject);
+ }
+ else
+ {
+ PrincipalInfoAction.PRIVILEGED.push(principal, credential, subject);
+ }
+ }
+ }
Added: branches/Branch_1_4/integration/EAP4/src/main/org/jboss/jms/server/security/SecurityMetadataStore.java
===================================================================
--- branches/Branch_1_4/integration/EAP4/src/main/org/jboss/jms/server/security/SecurityMetadataStore.java (rev 0)
+++ branches/Branch_1_4/integration/EAP4/src/main/org/jboss/jms/server/security/SecurityMetadataStore.java 2010-03-30 03:05:37 UTC (rev 7989)
@@ -0,0 +1,317 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.jms.server.security;
+
+import java.security.Principal;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import javax.jms.JMSSecurityException;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import javax.security.auth.Subject;
+
+import org.jboss.jms.server.SecurityStore;
+import org.jboss.logging.Logger;
+import org.jboss.security.AuthenticationManager;
+import org.jboss.security.RealmMapping;
+import org.jboss.security.SimplePrincipal;
+import org.jboss.security.SubjectSecurityManager;
+import org.w3c.dom.Element;
+
+/**
+ * A security metadate store for JMS. Stores security information for destinations and delegates
+ * authentication and authorization to a JaasSecurityManager.
+ *
+ * @author Peter Antman
+ * @author <a href="mailto:Scott.Stark at jboss.org">Scott Stark</a>
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @author <a href="mailto:ovidiu at feodorov.com">Ovidiu Feodorov</a>
+ * @version $Revision: 4986 $
+ *
+ * $Id: SecurityMetadataStore.java 4986 2008-09-18 22:11:43Z clebert.suconic at jboss.com $
+ */
+public class SecurityMetadataStore implements SecurityStore, SecurityMetadataStoreMBean
+{
+ // Constants -----------------------------------------------------
+
+ private static final Logger log = Logger.getLogger(SecurityMetadataStore.class);
+
+ public static final String DEFAULT_SUCKER_USER_PASSWORD = "CHANGE ME!!";
+
+ // Attributes ----------------------------------------------------
+
+ private boolean trace = log.isTraceEnabled();
+
+ private Map queueSecurityConf;
+ private Map topicSecurityConf;
+
+ private AuthenticationManager authenticationManager;
+ private RealmMapping realmMapping;
+
+ private Element defaultSecurityConfig;
+ private String securityDomain = "java:/jaas/messaging";
+
+ private String suckerPassword;
+
+ // Static --------------------------------------------------------
+
+ // Constructors --------------------------------------------------
+
+ public SecurityMetadataStore()
+ {
+ queueSecurityConf = new HashMap();
+ topicSecurityConf = new HashMap();
+ }
+
+ // SecurityManager implementation --------------------------------
+
+ public SecurityMetadata getSecurityMetadata(boolean isQueue, String destName)
+ {
+ SecurityMetadata m = (SecurityMetadata)
+ (isQueue ? queueSecurityConf.get(destName) : topicSecurityConf.get(destName));
+
+ if (m == null)
+ {
+ // No SecurityMetadata was configured for the destination, apply the default
+ if (defaultSecurityConfig != null)
+ {
+ log.debug("No SecurityMetadadata was available for " + destName + ", using default security config");
+ try
+ {
+ m = new SecurityMetadata(defaultSecurityConfig);
+ }
+ catch (Exception e)
+ {
+ log.warn("Unable to apply default security for destName, using guest " + destName, e);
+ m = new SecurityMetadata();
+ }
+ }
+ else
+ {
+ // default to guest
+ log.warn("No SecurityMetadadata was available for " + destName + ", adding guest");
+ m = new SecurityMetadata();
+ }
+
+ // don't cache it! this way the callers will be able to take advantage of default security
+ // configuration updates
+ // securityConf.put(destName, m);
+ }
+ return m;
+ }
+
+ public void setSecurityConfig(boolean isQueue, String destName, Element conf) throws Exception
+ {
+ if (trace) { log.trace("adding security configuration for " + (isQueue ? "queue " : "topic ") + destName); }
+
+ if (conf == null)
+ {
+ clearSecurityConfig(isQueue, destName);
+ }
+ else
+ {
+ SecurityMetadata m = new SecurityMetadata(conf);
+
+ if (isQueue)
+ {
+ queueSecurityConf.put(destName, m);
+ }
+ else
+ {
+ topicSecurityConf.put(destName, m);
+ }
+ }
+ }
+
+ public void clearSecurityConfig(boolean isQueue, String name) throws Exception
+ {
+ if (trace) { log.trace("clearing security configuration for " + (isQueue ? "queue " : "topic ") + name); }
+
+ if (isQueue)
+ {
+ queueSecurityConf.remove(name);
+ }
+ else
+ {
+ topicSecurityConf.remove(name);
+ }
+ }
+
+ public Subject authenticate(String user, String password) throws JMSSecurityException
+ {
+ if (trace) { log.trace("authenticating user " + user); }
+
+ SimplePrincipal principal = new SimplePrincipal(user);
+ char[] passwordChars = null;
+ if (password != null)
+ {
+ passwordChars = password.toCharArray();
+ }
+
+ Subject subject = new Subject();
+
+ boolean authenticated = false;
+
+ if (SUCKER_USER.equals(user))
+ {
+ if (trace) { log.trace("Authenticating sucker user"); }
+
+ checkDefaultSuckerPassword(password);
+
+ // The special user SUCKER_USER is used for creating internal connections that suck messages between nodes
+
+ authenticated = suckerPassword.equals(password);
+ }
+ else
+ {
+ authenticated = authenticationManager.isValid(principal, passwordChars, subject);
+ }
+
+ if (authenticated)
+ {
+ // Warning! This "taints" thread local. Make sure you pop it off the stack as soon as
+ // you're done with it.
+ SecurityActions.pushSubjectContext(principal, passwordChars, subject);
+ return subject;
+ }
+ else
+ {
+ throw new JMSSecurityException("User " + user + " is NOT authenticated");
+ }
+ }
+
+ public boolean authorize(String user, Set rolePrincipals, CheckType checkType)
+ {
+ if (trace) { log.trace("authorizing user " + user + " for role(s) " + rolePrincipals.toString()); }
+
+ if (SUCKER_USER.equals(user))
+ {
+ //The special user SUCKER_USER is used for creating internal connections that suck messages between nodes
+ //It has automatic read/write access to all destinations
+ return (checkType.equals(CheckType.READ) || checkType.equals(CheckType.WRITE));
+ }
+
+ Principal principal = user == null ? null : new SimplePrincipal(user);
+
+ boolean hasRole = realmMapping.doesUserHaveRole(principal, rolePrincipals);
+
+ if (trace) { log.trace("user " + user + (hasRole ? " is " : " is NOT ") + "authorized"); }
+
+ return hasRole;
+ }
+
+ // Public --------------------------------------------------------
+
+ public void setSuckerPassword(String password)
+ {
+ checkDefaultSuckerPassword(password);
+
+ this.suckerPassword = password;
+ }
+
+ public void start() throws NamingException
+ {
+ if (trace) { log.trace("initializing SecurityMetadataStore"); }
+
+ // Get the JBoss security manager from JNDI
+ InitialContext ic = new InitialContext();
+
+ try
+ {
+ Object mgr = ic.lookup(securityDomain);
+
+ log.debug("JaasSecurityManager is " + mgr);
+
+ authenticationManager = (AuthenticationManager)mgr;
+ realmMapping = (RealmMapping)mgr;
+
+ log.trace("SecurityMetadataStore initialized");
+ }
+ catch (NamingException e)
+ {
+ // Apparently there is no security context, try adding java:/jaas
+ log.warn("Failed to lookup securityDomain " + securityDomain, e);
+
+ if (!securityDomain.startsWith("java:/jaas/"))
+ {
+ authenticationManager =
+ (SubjectSecurityManager)ic.lookup("java:/jaas/" + securityDomain);
+ }
+ else
+ {
+ throw e;
+ }
+ }
+ finally
+ {
+ ic.close();
+ }
+ }
+
+ public void stop() throws Exception
+ {
+ }
+
+ public String getSecurityDomain()
+ {
+ return this.securityDomain;
+ }
+
+ public void setSecurityDomain(String securityDomain)
+ {
+ this.securityDomain = securityDomain;
+ }
+
+ public Element getDefaultSecurityConfig()
+ {
+ return this.defaultSecurityConfig;
+ }
+
+ public void setDefaultSecurityConfig(Element conf) throws Exception
+ {
+ // Force a parse
+ new SecurityMetadata(conf);
+ defaultSecurityConfig = conf;
+ }
+
+ // Protected -----------------------------------------------------
+
+ // Package Private -----------------------------------------------
+
+ // Private -------------------------------------------------------
+
+ private void checkDefaultSuckerPassword(String password)
+ {
+ // Sanity check
+ if (DEFAULT_SUCKER_USER_PASSWORD.equals(password))
+ {
+ log.warn("WARNING! POTENTIAL SECURITY RISK. It has been detected that the MessageSucker component " +
+ "which sucks messages from one node to another has not had its password changed from the installation default. " +
+ "Please see the JBoss Messaging user guide for instructions on how to do this.");
+ }
+ }
+
+ // Inner class ---------------------------------------------------
+
+}
Added: branches/Branch_1_4/integration/EAP5/src/main/org/jboss/jms/server/security/SecurityActions.java
===================================================================
--- branches/Branch_1_4/integration/EAP5/src/main/org/jboss/jms/server/security/SecurityActions.java (rev 0)
+++ branches/Branch_1_4/integration/EAP5/src/main/org/jboss/jms/server/security/SecurityActions.java 2010-03-30 03:05:37 UTC (rev 7989)
@@ -0,0 +1,164 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.jms.server.security;
+
+import java.security.AccessController;
+import java.security.Principal;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedExceptionAction;
+
+import javax.security.auth.Subject;
+
+import org.jboss.security.SecurityAssociation;
+import org.jboss.security.SecurityContext;
+import org.jboss.security.SecurityContextAssociation;
+import org.jboss.security.SecurityContextFactory;
+import org.jboss.security.SimplePrincipal;
+import org.jboss.security.plugins.JBossSecurityContext;
+
+
+/** A collection of privileged actions for this package
+ * @author Scott.Stark at jboss.org
+ * @author <a href="mailto:alex at jboss.org">Alexey Loubyansky</a>
+ * @author <a her="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version $Revison: 1.0$
+ */
+class SecurityActions
+{
+
+ static SecurityContext getSecurityContext()
+ {
+ return AccessController.doPrivileged(new PrivilegedAction<SecurityContext>(){
+
+ public SecurityContext run()
+ {
+ return SecurityContextAssociation.getSecurityContext();
+ }});
+ }
+
+ static void setSecurityContext(final SecurityContext sc)
+ {
+ AccessController.doPrivileged(new PrivilegedAction<Object>(){
+
+ public Object run()
+ {
+ SecurityContextAssociation.setSecurityContext(sc);
+ return null;
+ }});
+ }
+
+ interface PrincipalInfoAction
+ {
+ PrincipalInfoAction PRIVILEGED = new PrincipalInfoAction()
+ {
+ public void push(final Principal principal, final Object credential,
+ final Subject subject)
+ {
+ AccessController.doPrivileged(
+ new PrivilegedAction()
+ {
+ public Object run()
+ {
+ SecurityAssociation.pushSubjectContext(subject, principal, credential);
+ return null;
+ }
+ }
+ );
+ }
+ public void dup()
+ {
+ AccessController.doPrivileged(
+ new PrivilegedAction()
+ {
+ public Object run()
+ {
+ SecurityAssociation.dupSubjectContext();
+ return null;
+ }
+ }
+ );
+ }
+ public void pop()
+ {
+ AccessController.doPrivileged(
+ new PrivilegedAction()
+ {
+ public Object run()
+ {
+ SecurityAssociation.popSubjectContext();
+ return null;
+ }
+ }
+ );
+ }
+ };
+
+ PrincipalInfoAction NON_PRIVILEGED = new PrincipalInfoAction()
+ {
+ public void push(Principal principal, Object credential, Subject subject)
+ {
+ SecurityAssociation.pushSubjectContext(subject, principal, credential);
+ }
+ public void dup()
+ {
+ SecurityAssociation.dupSubjectContext();
+ }
+ public void pop()
+ {
+ SecurityAssociation.popSubjectContext();
+ }
+ };
+
+ void push(Principal principal, Object credential, Subject subject);
+ void dup();
+ void pop();
+ }
+
+ static void pushSubjectContext(Principal principal, Object credential,
+ Subject subject)
+ {
+ if(System.getSecurityManager() == null)
+ {
+ PrincipalInfoAction.NON_PRIVILEGED.push(principal, credential, subject);
+ }
+ else
+ {
+ PrincipalInfoAction.PRIVILEGED.push(principal, credential, subject);
+ }
+ }
+
+ public static void setSecurityContext(final SimplePrincipal principal,
+ final char[] passwordChars,
+ final Subject subject,
+ final String secDom) throws Exception
+ {
+ AccessController.doPrivileged(new PrivilegedExceptionAction<Object>(){
+
+ public Object run() throws Exception
+ {
+ SecurityContext context = SecurityContextFactory.createSecurityContext(principal, passwordChars, subject, secDom);
+ SecurityContextAssociation.setSecurityContext(context);
+ return null;
+ }});
+ }
+
+}
Added: branches/Branch_1_4/integration/EAP5/src/main/org/jboss/jms/server/security/SecurityMetadataStore.java
===================================================================
--- branches/Branch_1_4/integration/EAP5/src/main/org/jboss/jms/server/security/SecurityMetadataStore.java (rev 0)
+++ branches/Branch_1_4/integration/EAP5/src/main/org/jboss/jms/server/security/SecurityMetadataStore.java 2010-03-30 03:05:37 UTC (rev 7989)
@@ -0,0 +1,325 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.jms.server.security;
+
+import java.security.Principal;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import javax.jms.JMSSecurityException;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import javax.security.auth.Subject;
+
+import org.jboss.jms.server.SecurityStore;
+import org.jboss.logging.Logger;
+import org.jboss.security.AuthenticationManager;
+import org.jboss.security.RealmMapping;
+import org.jboss.security.SecurityAssociation;
+import org.jboss.security.SimplePrincipal;
+import org.jboss.security.SubjectSecurityManager;
+import org.w3c.dom.Element;
+
+/**
+ * A security metadate store for JMS. Stores security information for destinations and delegates
+ * authentication and authorization to a JaasSecurityManager.
+ *
+ * @author Peter Antman
+ * @author <a href="mailto:Scott.Stark at jboss.org">Scott Stark</a>
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @author <a href="mailto:ovidiu at feodorov.com">Ovidiu Feodorov</a>
+ * @version $Revision: 4986 $
+ *
+ * $Id: SecurityMetadataStore.java 4986 2008-09-18 22:11:43Z clebert.suconic at jboss.com $
+ */
+public class SecurityMetadataStore implements SecurityStore, SecurityMetadataStoreMBean
+{
+ // Constants -----------------------------------------------------
+
+ private static final Logger log = Logger.getLogger(SecurityMetadataStore.class);
+
+ public static final String DEFAULT_SUCKER_USER_PASSWORD = "CHANGE ME!!";
+
+ // Attributes ----------------------------------------------------
+
+ private boolean trace = log.isTraceEnabled();
+
+ private Map queueSecurityConf;
+ private Map topicSecurityConf;
+
+ private AuthenticationManager authenticationManager;
+ private RealmMapping realmMapping;
+
+ private Element defaultSecurityConfig;
+ private String securityDomain = "java:/jaas/messaging";
+
+ private String suckerPassword;
+
+ // Static --------------------------------------------------------
+
+ // Constructors --------------------------------------------------
+
+ public SecurityMetadataStore()
+ {
+ queueSecurityConf = new HashMap();
+ topicSecurityConf = new HashMap();
+ }
+
+ // SecurityManager implementation --------------------------------
+
+ public SecurityMetadata getSecurityMetadata(boolean isQueue, String destName)
+ {
+ SecurityMetadata m = (SecurityMetadata)
+ (isQueue ? queueSecurityConf.get(destName) : topicSecurityConf.get(destName));
+
+ if (m == null)
+ {
+ // No SecurityMetadata was configured for the destination, apply the default
+ if (defaultSecurityConfig != null)
+ {
+ log.debug("No SecurityMetadadata was available for " + destName + ", using default security config");
+ try
+ {
+ m = new SecurityMetadata(defaultSecurityConfig);
+ }
+ catch (Exception e)
+ {
+ log.warn("Unable to apply default security for destName, using guest " + destName, e);
+ m = new SecurityMetadata();
+ }
+ }
+ else
+ {
+ // default to guest
+ log.warn("No SecurityMetadadata was available for " + destName + ", adding guest");
+ m = new SecurityMetadata();
+ }
+
+ // don't cache it! this way the callers will be able to take advantage of default security
+ // configuration updates
+ // securityConf.put(destName, m);
+ }
+ return m;
+ }
+
+ public void setSecurityConfig(boolean isQueue, String destName, Element conf) throws Exception
+ {
+ if (trace) { log.trace("adding security configuration for " + (isQueue ? "queue " : "topic ") + destName); }
+
+ if (conf == null)
+ {
+ clearSecurityConfig(isQueue, destName);
+ }
+ else
+ {
+ SecurityMetadata m = new SecurityMetadata(conf);
+
+ if (isQueue)
+ {
+ queueSecurityConf.put(destName, m);
+ }
+ else
+ {
+ topicSecurityConf.put(destName, m);
+ }
+ }
+ }
+
+ public void clearSecurityConfig(boolean isQueue, String name) throws Exception
+ {
+ if (trace) { log.trace("clearing security configuration for " + (isQueue ? "queue " : "topic ") + name); }
+
+ if (isQueue)
+ {
+ queueSecurityConf.remove(name);
+ }
+ else
+ {
+ topicSecurityConf.remove(name);
+ }
+ }
+
+ public Subject authenticate(String user, String password) throws JMSSecurityException
+ {
+ if (trace) { log.trace("authenticating user " + user); }
+
+ SimplePrincipal principal = new SimplePrincipal(user);
+ char[] passwordChars = null;
+ if (password != null)
+ {
+ passwordChars = password.toCharArray();
+ }
+
+ Subject subject = new Subject();
+
+ boolean authenticated = false;
+
+ if (SUCKER_USER.equals(user))
+ {
+ if (trace) { log.trace("Authenticating sucker user"); }
+
+ checkDefaultSuckerPassword(password);
+
+ // The special user SUCKER_USER is used for creating internal connections that suck messages between nodes
+
+ authenticated = suckerPassword.equals(password);
+ }
+ else
+ {
+ authenticated = authenticationManager.isValid(principal, passwordChars, subject);
+ }
+
+ if (authenticated)
+ {
+ // Warning! This "taints" thread local. Make sure you pop it off the stack as soon as
+ // you're done with it.
+ try
+ {
+ SecurityActions.setSecurityContext(principal, passwordChars, subject, this.getSecurityDomain());
+ }
+ catch (Exception e)
+ {
+ throw new JMSSecurityException("Failed to set SecurityContext");
+ }
+ return subject;
+ }
+ else
+ {
+ throw new JMSSecurityException("User " + user + " is NOT authenticated");
+ }
+ }
+
+ public boolean authorize(String user, Set rolePrincipals, CheckType checkType)
+ {
+ if (trace) { log.trace("authorizing user " + user + " for role(s) " + rolePrincipals.toString()); }
+
+ if (SUCKER_USER.equals(user))
+ {
+ //The special user SUCKER_USER is used for creating internal connections that suck messages between nodes
+ //It has automatic read/write access to all destinations
+ return (checkType.equals(CheckType.READ) || checkType.equals(CheckType.WRITE));
+ }
+
+ Principal principal = user == null ? null : new SimplePrincipal(user);
+
+ boolean hasRole = realmMapping.doesUserHaveRole(principal, rolePrincipals);
+
+ if (trace) { log.trace("user " + user + (hasRole ? " is " : " is NOT ") + "authorized"); }
+
+ return hasRole;
+ }
+
+ // Public --------------------------------------------------------
+
+ public void setSuckerPassword(String password)
+ {
+ checkDefaultSuckerPassword(password);
+
+ this.suckerPassword = password;
+ }
+
+ public void start() throws NamingException
+ {
+ if (trace) { log.trace("initializing SecurityMetadataStore"); }
+
+ // Get the JBoss security manager from JNDI
+ InitialContext ic = new InitialContext();
+
+ try
+ {
+ Object mgr = ic.lookup(securityDomain);
+
+ log.debug("JaasSecurityManager is " + mgr);
+
+ authenticationManager = (AuthenticationManager)mgr;
+ realmMapping = (RealmMapping)mgr;
+
+ log.trace("SecurityMetadataStore initialized");
+ }
+ catch (NamingException e)
+ {
+ // Apparently there is no security context, try adding java:/jaas
+ log.warn("Failed to lookup securityDomain " + securityDomain, e);
+
+ if (!securityDomain.startsWith("java:/jaas/"))
+ {
+ authenticationManager =
+ (SubjectSecurityManager)ic.lookup("java:/jaas/" + securityDomain);
+ }
+ else
+ {
+ throw e;
+ }
+ }
+ finally
+ {
+ ic.close();
+ }
+ }
+
+ public void stop() throws Exception
+ {
+ }
+
+ public String getSecurityDomain()
+ {
+ return this.securityDomain;
+ }
+
+ public void setSecurityDomain(String securityDomain)
+ {
+ this.securityDomain = securityDomain;
+ }
+
+ public Element getDefaultSecurityConfig()
+ {
+ return this.defaultSecurityConfig;
+ }
+
+ public void setDefaultSecurityConfig(Element conf) throws Exception
+ {
+ // Force a parse
+ new SecurityMetadata(conf);
+ defaultSecurityConfig = conf;
+ }
+
+ // Protected -----------------------------------------------------
+
+ // Package Private -----------------------------------------------
+
+ // Private -------------------------------------------------------
+
+ private void checkDefaultSuckerPassword(String password)
+ {
+ // Sanity check
+ if (DEFAULT_SUCKER_USER_PASSWORD.equals(password))
+ {
+ log.warn("WARNING! POTENTIAL SECURITY RISK. It has been detected that the MessageSucker component " +
+ "which sucks messages from one node to another has not had its password changed from the installation default. " +
+ "Please see the JBoss Messaging user guide for instructions on how to do this.");
+ }
+ }
+
+ // Inner class ---------------------------------------------------
+
+}
Modified: branches/Branch_1_4/tests/src/org/jboss/test/thirdparty/jbosssx/SecurityAssociationTest.java
===================================================================
--- branches/Branch_1_4/tests/src/org/jboss/test/thirdparty/jbosssx/SecurityAssociationTest.java 2010-03-30 02:41:51 UTC (rev 7988)
+++ branches/Branch_1_4/tests/src/org/jboss/test/thirdparty/jbosssx/SecurityAssociationTest.java 2010-03-30 03:05:37 UTC (rev 7989)
@@ -84,6 +84,7 @@
new Subject(false, principals, Collections.EMPTY_SET, Collections.EMPTY_SET);
Principal nebuchadrezzar = new SimplePrincipal("nebuchadrezzar");
+ SecurityAssociation.setServer();
SecurityAssociation.pushSubjectContext(subject, nebuchadrezzar, "xexe");
Connection conn = null;
More information about the jboss-cvs-commits
mailing list